Widget visual tweaks

  • This documentation is for the version 3.6.1 of the widget. If you're looking for the widget v2 docs, check here.

Here’s some inspiration to amplify your widget integration workflow,

Color Buttons

That’s one of the most common cases, changing the button color. It can be easily done with CSS,

.uploader-green-button .uploadcare--widget__button_type_open {
    background-color: #16d061;
}
.uploader-green-button .uploadcare--widget__button_type_open:hover {
    background-color: #15c25a;
}
.uploader-yellow-button .uploadcare--widget__button_type_open {
    background-color: #fbc701;
}
.uploader-yellow-button .uploadcare--widget__button_type_open:hover {
    background-color: #edc218;
}
  
<p class="uploader-normal-button">
  <input type="hidden" role="uploadcare-uploader">
</p>
<p class="uploader-green-button">
  <input type="hidden" role="uploadcare-uploader">
</p>
<p class="uploader-yellow-button">
  <input type="hidden" role="uploadcare-uploader">
</p>
  

Crazy Button

Time for some fun, CSS can really drive your buttons crazy,

.uploader-demo-crazy .uploadcare--widget__button_type_open {
  cursor: pointer;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 24px;
  font-weight: bold;
  text-shadow: 0 -1px 1px rgba(0,0,0,0.25);
  padding: 1px 14px;
  background-color: #e22092;
  background: linear-gradient(#e85eac, #e02a91);
  border-bottom: 1px solid rgba(0,0,0,0.25);
  box-shadow: 0 1px 3px rgba(0,0,0,0.6);
  -webkit-transition: -webkit-transform .25s;
     -moz-transition: -moz-transform .25s;
          transition: transform .25s;
}
.uploader-demo-crazy .uploadcare--widget__button_type_open:hover {
  background: linear-gradient(#e14296, #d71876);
  -webkit-transform: scale(1.05);
     -moz-transform: scale(1.05);
          transform: scale(1.05);
}
.uploader-demo-crazy .uploadcare--widget__dragndrop-area {
  line-height: 3.4;
  margin-top: -1.8em;
}
  
<p class="uploader-demo-crazy">
  <input type="hidden" role="uploadcare-uploader" data-clearable="">
</p>
  

Uploading Indicator Color

In our case, uploading indicator is the circle that’s filling with color while an upload is in progress. The fill color can be changed via the CSS color property, and the background color can be changed via border-color.

#demo-circle {
  width: 3em;
  height: 3em;
  color: #56a8ff;
  border-color: #d4dfe5;
}
  
$(function() {
  (new uploadcare.Circle('#demo-circle')).renderer.setValue(.33);
});
  
<div id="demo-circle"></div>
  

.uploader-demo-circle .uploadcare--widget_status_loaded .uploadcare--widget_status {
  display: inline-block !important;
}
.uploader-demo-circle .uploadcare--progress_type_canvas {
  color: #56a8ff;
  border-color: #d4dfe5;
}
  
<p class="uploader-demo-circle">
  Try to upload new file:<br>
  <input type="hidden" role="uploadcare-uploader" data-clearable="">
</p>
  

Try to upload new file:

Custom Progress Bar

If you wish to replace the built-in progress bar, you need to listen the current widget object. You can get it in the onChange callback. It will be a file object for regular widgets or a group object for multiple widgets. Then, you need to listen to the progress event and change your progress bar in according to a current uploadProgress.

The following installProgressBar function does all that. It receives the two arguments: Uploadcare Widget instance and your progress bar DOM element. Everything else, including animation, runs on CSS.

/* Hide builtin progress bar */
.custom-progress + .uploadcare--widget .uploadcare--widget__progress {
  display: none !important;
}
.meter {
  height: 25px;
  position: relative;
  display: block;
  margin: 10px 0;
}
.meter > span {
  position: relative;
  display: block;
  width: 0;
  height: 100%;
  border-radius: 8px;
  background-color: rgb(43,194,83);
  background-image: linear-gradient(
    to top,
    rgb(43,194,83) 37%,
    rgb(84,240,84) 69%
   );
  box-shadow:
    inset 0 2px 9px rgba(255,255,255,0.3),
    inset 0 -2px 6px rgba(0,0,0,0.4);
  transition: width .25s;
}
.meter > span:after {
  content: "";
  position: absolute;
  top: 0; left: 0; bottom: 0; right: 0;
  background-image:
    linear-gradient(
      -45deg,
        rgba(255, 255, 255, .2) 25%,
        transparent 25%,
        transparent 50%,
        rgba(255, 255, 255, .2) 50%,
        rgba(255, 255, 255, .2) 75%,
        transparent 75%
     );
  z-index: 1;
  background-size: 50px 50px;
  -webkit-animation: meter-move 2s linear infinite;
          animation: meter-move 2s linear infinite;
  border-radius: 8px;
}
@-webkit-keyframes meter-move {
    0% { background-position: 0 0 }
    100% { background-position: 50px 50px }
}
@keyframes meter-move {
    0% { background-position: 0 0 }
    100% { background-position: 50px 50px }
}
  
function installProgressBar(widget, progress) {
  var currentObject;
  var progress = $(progress);
  widget.onChange(function(widgetObject) {
    currentObject = widgetObject;
    if (widgetObject) {
      progress.width(0).show();
      widgetObject
        .promise()
        .progress(function(info) {
          if (currentObject === widgetObject) {
            progress.width((info.uploadProgress * 100).toFixed(2) + '%');
          }
        })
        .always(function() {
          if (currentObject === widgetObject) {
            progress.hide();
          }
        });
    } else {
      progress.hide();
    }
  });
}
$(function() {
  $('.custom-progress').each(function() {
    var input = $(this);
    var widget = uploadcare.Widget(input);
    installProgressBar(widget, input.nextAll('.meter').eq(0).children());
  });
});
  
<p>
  One file uploader:
  <input type="hidden" role="uploadcare-uploader" data-clearable="" class="custom-progress">
  <span class="meter"><span></span></span>
</p>
<p>
  Multiple files:
  <input type="hidden" role="uploadcare-uploader" data-clearable="" class="custom-progress" data-multiple="true">
  <span class="meter"><span></span></span>
</p>
  

One file uploader:

Multiple files:

Uploaded Image Preview

The default widget behavior is when a user selects an image, its preview is then shown in the upload dialog. What if you would like this preview to appear right on your page, somewhere around the widget button. That kind of a preview would definitely be more informative for a user than just showing filenames and sizes.

.image-preview-single {
  padding: 10px 0;
}
.image-preview-single > img {
  width: 128px;
  height: 96px;
  vertical-align: middle;
  visibility: hidden;
  display: inline-block;
}
function installWidgetPreviewSingle(widget, img) {
  widget.onChange(function(file) {
    img.css('visibility', 'hidden');
    img.attr('src', '');
    if (file) {
      file.done(function(fileInfo) {
        var size = '' + (img.width() * 2) + 'x' + (img.height() * 2);
        var previewUrl = fileInfo.cdnUrl + '-/scale_crop/' + size + '/center/';
        img.attr('src', previewUrl);
        img.css('visibility', 'visible');
      });
    }
  });
}
$(function() {
  $('.image-preview-single').each(function() {
    installWidgetPreviewSingle(
      uploadcare.SingleWidget($(this).children('input')),
      $(this).children('img')
    );
  });
});
  
<div class="image-preview-single">
  <img src="" alt="">
  <input type="hidden" role="uploadcare-uploader" data-clearable="" data-images-only="" data-public-key="1c86ca998ba22e75fbc6" value="a15a0473-5262-48c7-82e3-2fefcd14e293">
</div>
<div class="image-preview-single">
  <img src="" alt="">
  <input type="hidden" role="uploadcare-uploader" data-clearable="" data-images-only="" data-public-key="1c86ca998ba22e75fbc6" value="9dd2f080-cc52-442d-aa06-1d9eec7f40d1">
</div>
  

Note, you have full control over size and position, just use CSS.

Image preview for a multi-file widget may look different:

.image-preview-multiple ._list {
  padding-top: 20px;
}
.image-preview-multiple ._item {
  padding: 0 0 10px;
  display: inline-block;
  text-align: center;
  vertical-align: top;
  width: 100px;
  word-break: break-word;
  font-size: 12px;
  line-height: normal;
}
.image-preview-multiple ._item img {
  display: block;
  width: 80px;
  height: 80px;
  padding: 0 10px 6px;
}
function installWidgetPreviewMultiple(widget, list) {
  widget.onChange(function(fileGroup) {
    list.empty();
    if (fileGroup) {
      $.when.apply(null, fileGroup.files()).done(function() {
        $.each(arguments, function(i, fileInfo) {
          var src = fileInfo.cdnUrl + '-/scale_crop/160x160/center/';
          list.append(
            $('<div/>', {'class': '_item'}).append(
              [$('<img/>', {src: src}), fileInfo.name])
          );
        });
      });
    }
  });
}
$(function() {
  $('.image-preview-multiple').each(function() {
    installWidgetPreviewMultiple(
      uploadcare.MultipleWidget($(this).children('input')),
      $(this).children('._list')
    );
  });
});
  
<div class="image-preview-multiple">
  <input type="hidden" role="uploadcare-uploader" data-clearable="" data-images-only="" data-multiple="" data-public-key="1c86ca998ba22e75fbc6" value="cd334b26-c641-4393-bcce-b5041546430d~11">
  <div class="_list"></div>
</div>
  

You can choose different images or rearrange the existing ones, all changes in the widget are then reflected in the thumbnail list.

We’re always happy to help with code, integration, and other stuff. Search our site for more info or post your question in our Community Area.