JSFiddle - React, Tailwind, and code Playground

by Alexander

HTML

<div class="dash-content-main-uploadBox">
  <form class="box has-advanced-upload" method="post" action="/?" enctype="multipart/form-data" novalidate="">
    <div class="box__input">
      <svg class="box__icon" xmlns="http://www.w3.org/2000/svg" width="50" height="43" viewbox="0 0 50 43">
        <path d="M48.4 26.5c-.9 0-1.7.7-1.7 1.7v11.6h-43.3v-11.6c0-.9-.7-1.7-1.7-1.7s-1.7.7-1.7 1.7v13.2c0 .9.7 1.7 1.7 1.7h46.7c.9 0 1.7-.7 1.7-1.7v-13.2c0-1-.7-1.7-1.7-1.7zm-24.5 6.1c.3.3.8.5 1.2.5.4 0 .9-.2 1.2-.5l10-11.6c.7-.7.7-1.7 0-2.4s-1.7-.7-2.4 0l-7.1 8.3v-25.3c0-.9-.7-1.7-1.7-1.7s-1.7.7-1.7 1.7v25.3l-7.1-8.3c-.7-.7-1.7-.7-2.4 0s-.7 1.7 0 2.4l10 11.6z"></path>
      </svg>
      <input class="box__file" id="file" type="file" name="files[]" data-multiple-caption="{count} files selected" multiple=""/>
      <label for="file"><strong>Escoge un archivo</strong><span class="box__dragndrop"> o arrastralo hasta aquí</span>.</label>
      <button class="box__button" type="submit">Subir</button>
    </div>
    <div class="box__uploading">Subiendo…</div>
    <div class="box__success">Hecho! <a class="box__restart" href="/?" role="button">¿Subir mas?</a></div>
    <div class="box__error">Error! <span></span>. <a class="box__restart" href="/?" role="button">Intenta Nuevamente!</a></div>
    <input type="hidden" name="ajax" value="1"/>
  </form>
</div>

CSS

.box {
  font-size: 1.25rem;
  background-color: #c8dadf;
  margin: 0 auto;
  position: relative;
  padding: 100px 20px;
  width: 70%;
}
.box.has-advanced-upload {
  outline: 2px dashed #92b0b3;
  outline-offset: -10px;
  -webkit-transition: outline-offset 0.15s ease-in-out, background-color 0.15s linear;
  transition: outline-offset 0.15s ease-in-out, background-color 0.15s linear;
}
.box.has-advanced-upload .box__dragndrop {
  display: inline;
}
.box.has-advanced-upload .box__icon {
  width: 100%;
  height: 80px;
  fill: #92b0b3;
  display: block;
  margin-bottom: 40px;
}
.box.is-dragover {
  outline-offset: -20px;
  outline-color: #c8dadf;
  background-color: #fff;
}
.box__dragndrop,
.box__icon {
  display: none;
}
.box__input {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
}
.box__input label {
  width: 100%;
  text-align: center;
}
.box__input label strong {
  cursor: pointer;
  font-size: 1.5rem;
  font-weight: bold !important;
}
.box__input label span {
  font-size: 1.5rem;
  font-style: italic;
  font-weight: 100;
}
.box.is-uploading .box__input,
.box.is-success .box__input,
.box.is-error .box__input {
  visibility: hidden;
}
.box__uploading,
.box__success,
.box__error {
  display: none;
}
.box.is-uploading .box__uploading,
.box.is-success .box__success,
.box.is-error .box__error {
  display: block;
  position: absolute;
  top: 50%;
  right: 0;
  left: 0;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}
.box__uploading {
  font-style: italic;
}
.box__success {
  -webkit-animation: appear-from-inside 0.25s ease-in-out;
  animation: appear-from-inside 0.25s ease-in-out;
}
@-webkit-keyframes  {
  appear-from-inside {
from
    -webkit-transform: translateY(-50%) scale(0);
  }
}
75% {
  -webkit-transform: translateY(-50%) scale(1.1);
  transform: translateY(-50%) scale(1.1);
}
to {
  -webkit-transform: translateY(-50%) scale(1);
  transform: translateY(-50%) scale(1);
}
to .box__restart {
  font-weight:...

JavaScript

'use strict';;( function( $, window, document, undefined )
	{
		// feature detection for drag&drop upload

		var isAdvancedUpload = function()
			{
				var div = document.createElement( 'div' );
				return ( ( 'draggable' in div ) || ( 'ondragstart' in div && 'ondrop' in div ) ) && 'FormData' in window && 'FileReader' in window;
			}();


		// applying the effect for every form

		$( '.box' ).each( function()
		{
			var $form		 = $( this ),
				$input		 = $form.find( 'input[type="file"]' ),
				$label		 = $form.find( 'label' ),
				$errorMsg	 = $form.find( '.box__error span' ),
				$restart	 = $form.find( '.box__restart' ),
				droppedFiles = false,
				showFiles	 = function( files )
				{
					$label.text( files.length > 1 ? ( $input.attr( 'data-multiple-caption' ) || '' ).replace( '{count}', files.length ) : files[ 0 ].name );
				};

			// letting the server side to know we are going to make an Ajax request
			$form.append( '<input type="hidden" name="ajax" value="1" />' );

			// automatically submit the form on file select
			$input.on( 'change', function( e )
			{
				showFiles( e.target.files );

				
				$form.trigger( 'submit' );

				
			});


			// drag&drop files if the feature is available
			if( isAdvancedUpload )
			{
				$form
				.addClass( 'has-advanced-upload' ) // letting the CSS part to know drag&drop is supported by the browser
				.on( 'drag dragstart dragend dragover dragenter dragleave drop', function( e )
				{
					// preventing the unwanted behaviours
					e.preventDefault();
					e.stopPropagation();
				})
				.on( 'dragover dragenter', function() //
				{
					$form.addClass( 'is-dragover' );
				})
				.on( 'dragleave dragend drop', function()
				{
					$form.removeClass( 'is-dragover' );
				})
				.on( 'drop', function( e )
				{
					droppedFiles = e.originalEvent.dataTransfer.files; // the files that were dropped
					showFiles( droppedFiles );

					
					$form.trigger( 'submit' ); // automatically submit the form on file...