Formulaire d'upload customisé

by oilvier

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
<label for="attachment" class="forms-file">
	<input class="forms-file__input" aria-label="Sélectionnez votre pièce jointe" name="attachment" id="attachment" type="file">
	<span class="forms-file__placeholder" data-field="Aucun fichier sélectionné.">
		<span class="btn" data-btn="Parcourir"></span>
	</span>
</label>

SCSS

///  
/// Transformer une valeur en pixels en em  
/// 
/// Utilise la variable `$body-font-size` comme taille de référence pour
/// la conversion
/// 
/// @param {number} $value - Valeur en pixel
/// 
/// @require $base-font-size
///
/// @example scss - Usage
///   .foo {
///     font-size: em(12px); 
///     width: em(200px, 12px); 
///     padding: em(5px, 12px);
///   }
/// 
/// @example css - Result
///   .foo {
///     font-size: 0.750em; 
///     width: 16.667em; 
///     padding: 0.417em;
///   }
/// 
@function em($px, $base: $body-font-size) {
    @return ($px / $base) * 1em;
}

$input-font-size:16px;

*, 
*:before, 
*:after {box-sizing: border-box;}

label {display: table;}

/* ### Styles communs
   ========================================================================== */
input:not(.btn), 
textarea, 
select {font-size:$input-font-size; border-radius:0; -webkit-appearance:none;
	
	&:focus {outline:none; box-shadow:inset 0 0 2px 1px rgba(lightgray, 0.5);}
	
	&[disabled] {background:lightgray;}
}

/* ### Style des input et select
   ========================================================================== */
input:not(.btn),
select {padding:0 em(10px, $input-font-size); height:em(30px, $input-font-size);}

.js {
	.forms-file {position:relative; margin:0; padding:0;}
		.forms-file__input {width:100%; opacity:0;/* [1] */}
		
		/* [2] */
		.forms-file__placeholder {position:absolute; top:0; right:0; bottom:0; left:0; display:flex;
			&:before {content:attr(data-field); display:block; flex:1 1 0%; text-overflow:ellipsis; white-space:nowrap; overflow:hidden; /* [3] */}
			.btn:after {content:attr(data-btn);}
		}
}
/* [4] */
.no-js .forms-file__placeholder {display:none;}

	/* Mise en forme */
	.forms-file__placeholder{
		&:before {/* Reprise du style des input */border:1px solid gray; padding:0 em(10px, $input-font-size); background:white; line-height:em(30px, $input-font-size); font-size:$input-font-size;}

		.forms-file__input:focus ~ & {box-shadow:0 0...

JavaScript

var customInputFile = function customInputFile() {
	$(document).on("change", ".forms-file__input", function () {
		var input		= $(this);
		var numFiles	= input.get(0).files ? input.get(0).files.length : 1;
		var label		= input.val().replace(/\\/g, "/").replace(/.*\//, "");

		input.trigger("fileselect", [numFiles, label]);
	});

	$(document).on("fileselect", ".forms-file__input", function (event, numFiles, label) {
		var inputPlaceholder = $(this).parents(".forms-file").find(".forms-file__placeholder");
		var log				 = numFiles > 1 ? numFiles + " files selected" : label;

		if (inputPlaceholder.length) {
			inputPlaceholder.addClass('is-filled').attr('data-field', log);
		}
	});
}

//customInputFile();