JSFiddle - React, Tailwind, and code Playground

by darxide

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<div style="padding:20px">

<div class="input-group primary">
	<span class="input-group-addon pseudo-file" id="basic-addon1"><div>Browse...</div></span>
	<span class="form-control pseudo-label">
		<div class="progress pseudo-progress">
	  		<div class="progress-bar progress-bar-primary" role="progressbar" style="width: 0%"></div>
		</div>	
		<span>no files selected</span>
	</span>
	<form id='file'>
		<input type='file' class='form-control' multiple />
	</form>
	<span class="input-group-addon pseudo-upload file-upload"><div>upload</div></span>
</div>

</div>

CSS

*{transition: all .2s ease}

.input-group.primary {
	border: 1px solid rgb(30, 89, 217);
	border-radius: 5px;
}
.input-group.primary .input-group-addon:hover {
	background-color: rgb(30, 89, 217);
	color:#fff;
}
input[type=file] {
	display: none !important;
}
.pseudo-label {
	text-align: right;
	overflow: hidden;
	line-height: 23px;
	position: relative;
  border-top:none;
  border-bottom:none;
}
.pseudo-progress {
	position: absolute;
	width: calc(100% - 25px);
	opacity: 0;
  top:7px;
}
.pseudo-progress-in {
	opacity: 1 !important
}
.file-upload {
	cursor: pointer;
}
.pseudo-file > div,
.file-upload > div {
	padding: 0 14px;
}
.opacity-out {
	opacity: 0 !important;
}
.input-group-addon {
	border:none;
  background-color: #fff;
  border-color: #e9e9e9;
  color: #88939C;
  padding-left: 0;
  padding-right: 0;
  text-align: center;
  cursor:pointer;
}

JavaScript

$(document).on('click' , '.pseudo-file' , function() {
    $(this)
        .parent()
        .find('input[type=file]')
        .click()
})

$(document).on('change' , 'input[type=file]' , function() {

    var files = $('input[type=file]').prop("files")
    var names = ''
    var list = $.map(files , function(val) {
        return val.name; 
    })

    for(var i = 0;i<list.length;i++){
        names += list[i] + ', '
    }

    $(this)
        .parent()
        .parent()
        .find('.pseudo-label span')
        .text(names)
})

$(document).on('click' , '.pseudo-upload' , function() {
    upload_files()
})


function upload_files()
{
    var data = new FormData();
    $.each($('#file input')[0].files, function(i, file) {
        data.append(i, file)
    })

    $('.pseudo-progress').addClass('pseudo-progress-in')
    $('.pseudo-label span').addClass('opacity-out')

    $.ajax({
        url:'/echo/json/',
        data: data,
        xhr: function() {
            var myXhr = $.ajaxSettings.xhr();
            if(myXhr.upload){
                myXhr.upload.addEventListener('progress',progressHandlingFunction, false);
            }
            return myXhr;
        },        
        cache: false,
        contentType: false,
        processData: false,
        type: 'POST',
        success: function(data){
            
            //doSuccess(['done huehue'])
            $('.pseudo-progress').removeClass('pseudo-progress-in')
            $('.pseudo-label span').removeClass('opacity-out')            
            $('#file input').val("")
            $('.pseudo-label span').text('upload complete')
            $('.pseudo-progress .progress-bar').css({width:'0%'})
        },
        fail : function(){
            //doAlert(['very fail huehue'])
            $('.pseudo-progress').removeClass('pseudo-progress-in')            
            $('.pseudo-label span').removeClass('opacity-out')            
            $('.pseudo-progress .progress-bar').css({width:'0%'})          ...