SOW : Core Plugins

SOW = Step Of Web (Smarty author).
SOW plugins are part of Smarty Core, written from scratch!

SOW : File Upload

Overview:
  • image preview
  • filter by file extension
  • filter by file size
  • filter by size of all files (on multiple upload)
  • enabled multiple uploads using the same file input
  • ajax instant uploads
  • fancy progress bar & custom progress bar (all based on bootstrap progress)
  • drag and drop reorder (dependnecies: sortablejs vendor)
  • lightweight 24Kb minified (6.4Kb gzipped).

Because debug is enabled in config.sow.js, watch your console to see ajax requests.

Important note: because of borwser security, delete/reorder are working in ajax mode only!
Not possible to delete/reorder the queue files before uploading because input file is readonly in all browsers and file manipulation is restricted (security reasons).


/* 
	:: Plugin File
	src/js/sow.core/sow.file_upload.js

	:: Plugin Init
*/	$.SOW.core.file_upload.init('input[type="file"].custom-file-input');


/*
	:: Plugin Destroy
*/	$.SOW.core.file_upload.file_upload__destroy('#optional_container');
									

<!-- PARAMS / ATTRIBUTES
 -- -- -- -- -- -- -- -- -->

data-file-ext="jpg, png, mp3" 
data-file-max-size-kb-per-file="1024"  		0 = no limit
data-file-max-size-kb-total="10240"  		0 = no limit
data-file-max-total-files="10" 			0 = no limit
data-file-ext-err-msg="Allowed:" 
data-file-exist-err-msg="File already exists:"
data-file-size-err-item-msg="File too large!"
data-file-size-err-total-msg="Total allowed size exceeded!"
data-file-size-err-max-msg="Maximum allowed files:"
data-file-toast-position="bottom-center"
data-file-preview-container=".my-container" 
data-file-preview-img-height="120"
data-file-preview-show-info="true" 
data-file-preview-class="shadow-md m-2 rounded float-start" 
data-file-btn-clear="a.js-file-upload-clear"
data-file-btn-submit="button.js-file-upload-submit"

data-file-ajax-upload-enable="true"
data-file-ajax-upload-url="../demo.files/php/demo.ajax_file_upload.php"
data-file-ajax-upload-params="['action','upload']['param2','value2']"

data-file-ajax-delete-enable="true"
data-file-ajax-delete-url="../demo.files/php/demo.ajax_file_upload.php"
data-file-ajax-delete-params="['action','delete_file']"
data-file-ajax-delete-toast-txt="Successfully Deleted!" 
data-file-ajax-delete-toast-position="bottom-center" 

data-file-ajax-reorder-enable="true"
data-file-ajax-reorder-url="../demo.files/php/demo.ajax_file_upload.php"
data-file-ajax-reorder-params="['action','reorder']"
data-file-ajax-reorder-toast-success="Order Saved!" 
data-file-ajax-reorder-toast-position="bottom-center" 

data-file-ajax-toast-success-txt="Successfully Uploaded!"
data-file-ajax-toast-error-txt="One or more files not uploaded!"
data-file-ajax-progressbar-custom=".my-progess-container"
data-file-ajax-progressbar-disable="false"
data-file-ajax-callback-function=""
									

// -- -- -- -- -- -- --
// AJAX UPLOAD ONLY
// SERVER RESPONSE
// PHP EXAMPLE
// -- -- -- -- -- -- --


// When using ajax, to immediately be able to reorder/delete uploaded files,
// the backend must return the internal file id and the original filename.
// This is a PHP example:

$response = array(
	'file_list'	=> array(

		// original filename 		internal id
		'orig_file_name_1.jpg'		=> 1,
		'orig_file_name_2.jpg'		=> 345,
		
		// ...

	),

	// more stuff for callback (optional)
	'something_else'	=> array(/* ... */),
);

echo json_encode($response);
exit;

// The JSON response looks like this":
 {"file_list":{"orig_file_name_1.jpg":"1","orig_file_name_2.jpg":"345"}}
// "file_list" is the key the plugin is looking for!
// So this is the format we should see int the browser console as debug,
// right now we see a PHP array (what the plugin is sending to the backend).

// -- --
// "original filename" in PHP: $_FILES['name'] (no alteration/modification)
// "internal id" can be anything - database id, the same as file name, etc.
// but this is sent to the backend when you click "delete" button, reorder, etc.
// Also is used on preadded files for attribute: data-id="..."
// -- --

									

// -- -- -- -- -- -- --
// AJAX UPLOAD ONLY
// -- -- -- -- -- -- --


callbak_example = function(response, el) {
	// response 	= server response
	// el 		= input file element: 	$(input)
}
									

Regular Input

Multiple Files & Preview
Single File & Preview

<!-- 1. MULTIPLE FILE UPLOAD -->

<div class="input-group">
  <div class="custom-file custom-file-secondary">

	<!--

		Params for multiple files
    		data-file-ext="jpg, png, gif, mp3"  										file extendion allowed
    		data-file-max-size-kb-per-file="100"  										size per file in Kb
    		data-file-max-size-kb-total="300" 											size of total files
    		data-file-max-total-files="3" 												maximum files allowed to upload
    		data-file-ext-err-msg="Allowed:"  											file extension error message (default: "Allowed:" )
    		data-file-exist-err-msg="File already exists:" 								file already exists message (default: "File already exists:")
    		data-file-size-err-item-msg="File too large!" 								file too large error message (default: "File too large!")
    		data-file-size-err-total-msg="Total allowed size exceeded!" 				files total size allowed message (default: "Total allowed size exceeded!")
    		data-file-size-err-max-msg="Maximum allowed files:" 						no of files error (default: "Maximum allowed files:")
    		data-file-toast-position="bottom-center" 									toastr error position
    		data-file-preview-container=".js-file-input-preview-single-container"  	container preview (id or class)
    		data-file-preview-img-height="120"  										image preview height in pixels (default: 120)
    		data-file-preview-show-info="true"  										true = display image name and size in Kb (default: false)
    		data-file-btn-clear="a.js-file-upload-clear" 								clear button (id or class)

		Optional - customize preview item container:
			data-file-preview-class="shadow-md m-2 rounded" 							(default: "shadow-md m-2 rounded")

	-->
    <input 	name="file_input_name[]" 
    		multiple="" 
    		type="file" 

    		data-file-ext="jpg, png, gif, mp3" 
    		data-file-max-size-kb-per-file="0" 
    		data-file-max-size-kb-total="0" 
    		data-file-max-total-files="5"
    		data-file-ext-err-msg="Allowed:" 
    		data-file-exist-err-msg="File already exists:"
    		data-file-size-err-item-msg="File too large!"
    		data-file-size-err-total-msg="Total allowed size exceeded!"
    		data-file-size-err-max-msg="Maximum allowed files:"
    		data-file-toast-position="bottom-center"
    		data-file-preview-container=".js-file-input-preview-multiple-container" 
    		data-file-preview-img-height="120" 
    		data-file-preview-show-info="true" 
    		data-file-btn-clear="a.js-file-upload-clear"

    		class="custom-file-input" 
    		id="inputGroupFile01" 
    		aria-describedby="inputGroupFileAddon01">
    
    <label class="custom-file-label" for="inputGroupFile01">Choose file</label>

  </div>
</div>

<div class="js-file-input-preview-multiple-container ml--n6 mr--n6"><!-- preview container --></div>

<!-- 
	clear files button
	hidden by default 
-->
<div class="mt-1">
	<a href="#" class="hide js-file-upload-clear btn btn-light btn-sm">
		Clear Files
	</a>
</div>







<!-- 2. SINGLE FILE UPLOAD -->
<div class="input-group">
  <div class="custom-file custom-file-primary">

	<!--

		Params for single file
			data-file-ext="jpg, png, gif, mp3"  										file extendion allowed
			data-file-max-size-kb-per-file="100"  										size per file in Kb
			data-file-ext-err-msg="Allowed:"  											file extension error message (default: "Allowed:" )
			data-file-size-err-item-msg="File too large!" 								file too large error message (default: "File too large!")
			data-file-toast-position="bottom-center" 									toastr error position
			data-file-preview-container=".js-file-input-preview-single-container"  	container preview (id or class)
			data-file-preview-img-height="120"  										image preview height in pixels (default: 120)
			data-file-preview-show-info="true"  										true = display image name and size in Kb (default: false)
			data-file-btn-clear="a.js-file-upload-clear" 								clear button (id or class)

		Optional - customize preview item container:
			data-file-preview-class="shadow-md m-2 rounded" 							(default: "shadow-md m-2 rounded")
	
	-->
    <input 	name="file_input_name" 
    		type="file" 

    		data-file-ext="jpg, png, gif, mp3" 
    		data-file-max-size-kb-per-file="30000"
    		data-file-ext-err-msg="Allowed:" 
    		data-file-size-err-item-msg="File too large!"
    		data-file-size-err-total-msg="Total allowed size exceeded!"
    		data-file-toast-position="bottom-center"
    		data-file-preview-container=".js-file-input-preview-single-container2" 
    		data-file-preview-img-height="auto" 
    		data-file-preview-show-info="false" 
    		data-file-btn-clear="a.js-file-upload-clear2"
    		
    		class="custom-file-input" 
    		id="inputGroupFile02">
    
    <label class="custom-file-label" for="inputGroupFile02">Choose file</label>

  </div>
</div>


<div class="js-file-input-preview-single-container2 ml--n6 mr--n6"><!-- preview container --></div>

<!-- 
	clear files button
	hidden by default 
-->
<div class="mt-1">
	<a href="#" class="hide js-file-upload-clear2 btn btn-light btn-sm">
		Remove Image
	</a>
</div>

								

Button Type

Clear files

<!-- STATIC -->
<div class="mb-1">

	<label class="btn btn-primary cursor-pointer position-relative">

	    <input 	name="file_input_name[]" 
	    		multiple=""
	    		type="file" 

	    		data-file-ext="mp3, jpg, png, gif" 
	    		data-file-max-size-kb-per-file="0"
	    		data-file-max-size-kb-total="0" 
	    		data-file-max-total-files="100"
	    		data-file-ext-err-msg="Allowed:" 
	    		data-file-exist-err-msg="File already exists:"
	    		data-file-size-err-item-msg="File too large!"
	    		data-file-size-err-total-msg="Total allowed size exceeded!"
	    		data-file-size-err-max-msg="Maximum allowed files:"
	    		data-file-toast-position="bottom-center"
	    		data-file-preview-container=".js-file-input-container-multiple-example" 
	    		data-file-preview-img-height="120" 
	    		data-file-preview-show-info="false" 
	    		data-file-preview-class="shadow-md m-2 rounded float-start" 
	    		data-file-btn-clear="a.js-file-input-btn-multiple-example-remove"
	    		data-file-preview-img-cover="false" 

	    		class="custom-file-input absolute-full">

		Select Files

	</label>

	<!-- remove button -->
	<a href="#" title="Clear Files" data-toggle="tooltip" class="js-file-input-btn-multiple-example-remove hide btn btn-secondary mb-2">
		<i class="fi fi-close"></i>
		Clear files
	</a>

</div>


<!--
		
	Container : files are pushed here!
	.hide-empty = container hidden if empty

-->
<div class="js-file-input-container-multiple-example d-inline-block position-relative clearfix hide-empty"><!-- container --></div>









<!-- AJAX -->
<div class="mb-1">

	<label class="btn btn-primary btn-soft cursor-pointer position-relative">

	    <input 	name="file_input_name[]" 
			multiple=""
			type="file" 

			data-file-ext="mp3, jpg, png, gif" 
			data-file-max-size-kb-per-file="0"
			data-file-max-size-kb-total="0" 
			data-file-max-total-files="100"
			data-file-ext-err-msg="Allowed:" 
			data-file-exist-err-msg="File already exists:"
			data-file-size-err-item-msg="File too large!"
			data-file-size-err-total-msg="Total allowed size exceeded!"
			data-file-size-err-max-msg="Maximum allowed files:"
			data-file-toast-position="bottom-center"
			data-file-preview-container=".js-file-input-container-multiple-example-ajax" 
			data-file-preview-img-height="120" 
			data-file-preview-show-info="false" 
			data-file-preview-class="show-hover-container shadow-md m-2 rounded float-start" 
			data-file-preview-img-cover="false" 

			data-file-ajax-upload-enable="true"
			data-file-ajax-upload-url="../demo.files/php/demo.ajax_file_upload.php"
			data-file-ajax-upload-params="['action','upload']['param2','value2']"

			data-file-ajax-delete-enable="true"
			data-file-ajax-delete-url="../demo.files/php/demo.ajax_file_upload.php"
			data-file-ajax-delete-params="['action','delete_file']"

			data-file-ajax-reorder-enable="true"
			data-file-ajax-reorder-url="../demo.files/php/demo.ajax_file_upload.php"
			data-file-ajax-reorder-params="['action','reorder']"
			data-file-ajax-reorder-toast-success="Order Saved!" 
			data-file-ajax-reorder-toast-position="bottom-center" 

			data-file-ajax-toast-success-txt="Successfully Uploaded!"
			data-file-ajax-toast-error-txt="One or more files not uploaded!"
			data-file-ajax-callback-function=""
			data-file-ajax-progressbar-custom=""
			data-file-ajax-progressbar-disable="false"

	    		class="custom-file-input absolute-full">

		Ajax : Select Files

	</label>

</div>


<!--
		
	Ajax container : files are pushed here!
	.hide-empty = container hidden if empty

-->
<div class="js-file-input-container-multiple-example-ajax d-inline-block position-relative clearfix hide-empty"><!-- container --></div>

								

Submit Button Reveal

Regular preview
Cancel
List type preview
Cancel

<!--
	Regular preview
-->

<!-- upload files button -->
<label class="btn btn-indigo cursor-pointer position-relative">

	<!-- 
		We use .absolute-full class instead of .viewport-out
		Just to make sure the element is working crossbrowser!
	 -->
    <input 	name="file_input_name[]" 
    		multiple=""
    		type="file" 

    		data-file-ext="mp3, jpg, png, gif, csv" 
    		data-file-max-size-kb-per-file="0"
    		data-file-max-size-kb-total="0" 
    		data-file-max-total-files="5"
    		data-file-ext-err-msg="Allowed:" 
    		data-file-exist-err-msg="File already exists:"
    		data-file-size-err-item-msg="File too large!"
    		data-file-size-err-total-msg="Total allowed size exceeded!"
    		data-file-size-err-max-msg="Maximum allowed files:"
    		data-file-toast-position="bottom-center"
    		data-file-preview-container=".js-file-input-container__reveal_example" 
    		data-file-preview-img-height="120" 
    		data-file-preview-show-info="false" 
    		data-file-preview-class="shadow-md m-2 rounded float-start" 
    		data-file-btn-clear="a.js-input-clear__reveal_example"
    		data-file-btn-submit="button.js-file-btn-submit__reveal_example"
    		data-file-preview-img-cover="false" 

    		class="custom-file-input absolute-full">

    	<i class="fi fi-arrow-upload"></i>
		<span>Select Files</span>

</label>

<!-- preview container -->
<div class="js-file-input-container__reveal_example position-relative clearfix hide-empty"><!-- container --></div>

<!-- buttons -->
<div class="mt-3">

	<!-- submit button -->
	<button type="submit" class="js-file-btn-submit__reveal_example hide btn btn-primary">
		<i class="fi fi-check"></i>
		Upload Files
	</button>

	<!-- clear button -->
	<a href="#" class="js-input-clear__reveal_example hide btn btn-light">
		<i class="fi fi-close"></i>
		Cancel
	</a>

</div>










<!--
	List type preview
-->

<!-- upload files button -->
<label class="btn btn-indigo cursor-pointer position-relative">

	<!-- 
		We use .absolute-full class instead of .viewport-out
		Just to make sure the element is working crossbrowser!
	 -->
    <input 	name="file_input_name[]" 
    		multiple=""
    		type="file" 

    		data-file-ext="mp3, jpg, png, gif, csv" 
    		data-file-max-size-kb-per-file="0"
    		data-file-max-size-kb-total="0" 
    		data-file-max-total-files="5"
    		data-file-ext-err-msg="Allowed:" 
    		data-file-exist-err-msg="File already exists:"
    		data-file-size-err-item-msg="File too large!"
    		data-file-size-err-total-msg="Total allowed size exceeded!"
    		data-file-size-err-max-msg="Maximum allowed files:"
    		data-file-toast-position="bottom-center"
    		data-file-preview-container=".js-file-input-container__reveal_example2" 
    		data-file-preview-img-height="60" 
    		data-file-preview-show-info="true" 
    		data-file-btn-clear="a.js-input-clear__reveal_example2"
    		data-file-btn-submit="button.js-file-btn-submit__reveal_example2"
    		data-file-preview-img-cover="false" 
    		data-file-preview-list-type="list" 

    		class="custom-file-input absolute-full">

    	<i class="fi fi-arrow-upload"></i>
		<span>Select Files</span>

</label>

<!-- preview container -->
<div class="js-file-input-container__reveal_example2 position-relative clearfix hide-empty"><!-- container --></div>

<!-- buttons -->
<div class="mt-3">

	<!-- submit button -->
	<button type="submit" class="js-file-btn-submit__reveal_example2 hide btn btn-primary">
		<i class="fi fi-check"></i>
		Upload Files
	</button>

	<!-- clear button -->
	<a href="#" class="js-input-clear__reveal_example2 hide btn btn-light">
		<i class="fi fi-close"></i>
		Cancel
	</a>

</div>
								

Customizable & Preadded

0% Completed
Preadded Files (drag to reorder)
filename.jpg 124 Kb ... filename.mp3 159.34 Mb mp3

<!--

	1. AJAX : CUSTOM PROGRESS BAR

	Able to place it anywhere on page

		Ideas:  - as a bar fixed on top
				- as a bar fixed on footer
				- as a thin line (1px using class .h--1) over the header separator 
				- fullscreen with overlay
				... anything you can imagine :)
				All the above can be achived using helpers, without any CSS code!

-->
<div class="mb-1">

	<label class="btn btn-danger cursor-pointer position-relative">

	    <input 	name="ajax_files[]" 
	    		multiple=""
	    		type="file" 

	    		data-file-ext="" 
	    		data-file-max-size-kb-per-file=""
	    		data-file-max-size-kb-total="0" 
	    		data-file-max-total-files="6"
	    		data-file-ext-err-msg="Allowed:" 
	    		data-file-exist-err-msg="File already exists:"
	    		data-file-size-err-item-msg="File too large!"
	    		data-file-size-err-total-msg="Total allowed size exceeded!"
	    		data-file-size-err-max-msg="Maximum allowed files:"
	    		data-file-toast-position="bottom-center"
	    		data-file-preview-container=".js-file-input-container-multiple-ajax" 
	    		data-file-preview-class="shadow-md m-2 rounded float-start" 
	    		data-file-preview-img-height="120" 
	    		data-file-preview-show-info="false" 
	    		data-file-preview-img-cover="false" 

	    		data-file-ajax-upload-enable="true"
	    		data-file-ajax-upload-url="../demo.files/php/demo.ajax_file_upload.php"
	    		data-file-ajax-upload-params="['action','upload']['param2','value2']"

	    		data-file-ajax-delete-enable="true"
	    		data-file-ajax-delete-url="../demo.files/php/demo.ajax_file_upload.php"
	    		data-file-ajax-delete-params="['action','delete_file']"

	    		data-file-ajax-reorder-enable="true"
	    		data-file-ajax-reorder-url="../demo.files/php/demo.ajax_file_upload.php"
	    		data-file-ajax-reorder-params="['action','reorder']"
				data-file-ajax-reorder-toast-success="Order Saved!" 
				data-file-ajax-reorder-toast-position="bottom-center" 

	    		data-file-ajax-toast-success-txt="Successfully Uploaded!"
	    		data-file-ajax-toast-error-txt="One or more files not uploaded!"
	    		data-file-ajax-callback-function=""
	    		data-file-ajax-progressbar-custom=".js-file-input-progress-multiple-ajax"
	    		data-file-ajax-progressbar-disable="false"

	    		class="custom-file-input absolute-full">

    	<!-- 

    		optional loader indicator only - instead of group-icon (if needed)
    			<i class="js-file-input-ajax-loader hide-force fi fi-circle-spin fi-spin"></i>

    	-->
		<span class="group-icon">
			<i class="fi fi-arrow-upload"></i>
			<i class="fi fi-circle-spin fi-spin"></i>
		</span> 

		<span>Ajax : Custom Progressbar</span>

	</label>


	<!-- 

		Custom Ajax Progress Bar 
		Hidden by default (.hide)

		Add .js-ignore class to keep always visible
		Else, the plugin will autohide the progress after each finished upload.

	-->
	<div class="js-ignore js-file-input-progress-multiple-ajax">


		<!-- 

			[%] percent indicator 

			Requirements: 
				to be found inside this container (specified with data-file-ajax-progressbar-custom=".js-file-input-progress-multiple-ajax")
				.js-file-input-upload-percent to any element (i, span, etc)

		-->
		<div class="fs--13 text-gray-500">
			<span class="js-file-input-upload-percent">0%</span> Completed
		</div>
		<!-- /percent indicator -->



		<!-- 

			bootstrap progress 

			If other progress is used, make sure the .progress-bar  
			class is found beacuse bar is updated accesing style="width: ..."

			Height of the progress can be changed by chnging the class .h--5
				Height examples: h--[1|2|3|4|5|6|8|10|15|20|30]
				See the Documentation: Utilities->Width / Height

			For "pill" progress, add .progress.rounded-xl
		-->
		<div class="progress h--5">
			<div class="progress-bar bg-success" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
		</div>
		<!-- /bootstrap progress -->

	</div>







	<!-- Ajax container : files are pushed here! -->
	<div class="js-file-input-container-multiple-ajax position-relative clearfix hide-empty"><!-- container --></div>


</div>











<!--

	2. AJAX UPLOAD : DYNAMIC PROGRESS UNDER BUTTON
	No any extra html code needed for the progress bar.

-->
<div class="mb-1">

	<label class="btn btn-warning cursor-pointer position-relative">

	    <input 	name="ajax_files_progress_dynamic[]" 
	    		multiple=""
	    		type="file" 

	    		data-file-ext=""
	    		data-file-max-size-kb-per-file=""
	    		data-file-max-size-kb-total="0" 
	    		data-file-max-total-files="6"
	    		data-file-ext-err-msg="Allowed:" 
	    		data-file-exist-err-msg="File already exists:"
	    		data-file-size-err-item-msg="File too large!"
	    		data-file-size-err-total-msg="Total allowed size exceeded!"
	    		data-file-size-err-max-msg="Maximum allowed files:"
	    		data-file-toast-position="bottom-center"
	    		data-file-preview-container=".js-file-input-container-multiple-ajax-dynamic-progress" 
	    		data-file-preview-img-height="120" 
	    		data-file-preview-show-info="true" 
	    		data-file-preview-class="show-hover-container shadow-md m-2 rounded float-start" 
	    		data-file-preview-img-cover="false" 

	    		data-file-ajax-upload-enable="true"
	    		data-file-ajax-upload-url="../demo.files/php/demo.ajax_file_upload.php"
	    		data-file-ajax-upload-params="['action','upload']['param2','value2']"

	    		data-file-ajax-delete-enable="true"
	    		data-file-ajax-delete-url="../demo.files/php/demo.ajax_file_upload.php"
	    		data-file-ajax-delete-params="['action','delete_file']"

	    		data-file-ajax-reorder-enable="true"
	    		data-file-ajax-reorder-url="../demo.files/php/demo.ajax_file_upload.php"
	    		data-file-ajax-reorder-params="['action','reorder']"
				data-file-ajax-reorder-toast-success="Order Saved!" 
				data-file-ajax-reorder-toast-position="bottom-center" 

	    		data-file-ajax-toast-success-txt="Successfully Uploaded!"
	    		data-file-ajax-toast-error-txt="One or more files not uploaded!"
	    		data-file-ajax-callback-function=""
	    		data-file-ajax-progressbar-custom=""
	    		data-file-ajax-progressbar-disable="false"

	    		class="custom-file-input absolute-full">

		<span class="group-icon">
			<i class="fi fi-arrow-upload"></i>
			<i class="fi fi-circle-spin fi-spin"></i>
		</span> 

		<span>Ajax Uploader : Dynamic Progressbar</span>

	</label>



	<!--

		Ajax container : files are pushed here!

	-->
	<div class="mt-3 js-file-input-container-multiple-ajax-dynamic-progress position-relative clearfix hide-empty">


		<!-- 

			PREADDED FILES 

			In order to be able to delete preadded files using Form Advanced Plugin,
			one of the following params is required to each .js-file-input-item:

				data-id="0" 							your database file id
				data-file-name="filename.jpg" 			optional; required if data-id not set (or set to "0")
			
			When a file is deleted, a POST request is sent:
				Following params are sent (array):

					action 		=> 'delete_file', 				// see: data-file-ajax-delete-params="['action','delete_file']" (action => "delete_file" is anyway added by default)
					file_name 	=> 'filename.jpg',
					file_id 	=> 1,
					ajax 		=> true

				So in your backend you should be able to delete the files by 
					- file_id (your database file id)
					- file_name

			Delete POST request is sent to data-file-ajax-delete-url="../demo.files/php/demo.ajax_file_upload.php"
				If `data-file-ajax-delete-url` is empty or not set, `data-file-ajax-upload-url` is used.
				So you are able to set different URLs for each action.

				** 	No response is waited from the server! Callback not supported on delete!
					404 status is considered "failed" so the message will be "404 Server Error!"

		-->
		<h6 class="m-0">
			Preadded Files <span class="font-weight-light">(drag to reorder)</span>
		</h6>


		<!--
			
			Image Example

		-->
		<span data-id="0" data-file-name="filename.jpg" class="js-file-input-item d-inline-block position-relative overflow-hidden text-center show-hover-container shadow-md m-2 rounded float-start">

			<!-- delete button -->
			<a href="#" class="js-file-item-del position-absolute absolute-top show-hover-item left-0 z-index-2">
				<span class="d-inline-block btn btn-sm bg-danger text-white pt--4 pb--4 pl--10 pr--10 m--1">
					<i class="fi fi-close m-0"></i>
				</span>
			</a>

			<!-- info : header -->
			<span class="js-file-input-preview-header text-white position-absolute w-100 top-0 left-0 right-0 clearfix overlay-dark overlay-opacity-2">
				<span class="text-truncate d-block fs--12 pl--5 pr--5">
					filename.jpg
				</span>
			</span>

			<!-- info : footer -->
			<span class="js-file-input-preview-footer text-white position-absolute w-100 bottom-0 left-0 right-0 clearfix overlay-dark overlay-opacity-2">
				<span class="js-file-input-file-info-size text-truncate d-block fs--12 pl--5 pr--5">
					124 Kb
				</span>
			</span>

			<!-- 
				image 

				height="120" 	 same with file input attribute: data-file-preview-img-height="120" 
				It's adjusted if not set but there is a small delay so height is recommended to avoid "jump" effect!

			-->
			<img height="120" src="../demo.files/images/unsplash/brooke-cagle-g1Kr4Ozfoac-unsplash.jpg" alt="...">

		</span>






		<!-- 

			File Example

			Required (same with file input attribute: data-file-preview-img-height="120")
				style="min-width: 120px; min-height: 120px;"

		-->
		<span data-id="0" data-file-name="filename.mp3" style="min-width: 120px; min-height: 120px;" class="js-file-input-item d-inline-block position-relative overflow-hidden text-center show-hover-container shadow-md m-2 rounded float-start">

			<a href="#" class="js-file-item-del position-absolute absolute-top show-hover-item left-0 z-index-2">
				<span class="d-inline-block btn btn-sm bg-danger text-white pt--4 pb--4 pl--10 pr--10 m--1">
					<i class="fi fi-close m-0"></i>
				</span>
			</a>

			<!-- info : header -->
			<span class="js-file-input-preview-header text-white position-absolute w-100 top-0 left-0 right-0 clearfix overlay-dark overlay-opacity-2">
				<span class="text-truncate d-block fs--12 pl--5 pr--5">
					filename.mp3
				</span>
			</span>

			<!-- info : footer -->
			<span class="js-file-input-preview-footer text-white position-absolute w-100 bottom-0 left-0 right-0 clearfix overlay-dark overlay-opacity-2">
				<span class="js-file-input-file-info-size text-truncate d-block fs--12 pl--5 pr--5">
					159.34 Mb
				</span>
			</span>

			<!-- file extension -->
			<span class="absolute-full d-flex align-items-center justify-content-center fs--30 opacity-6 text-uppercase text-truncate">
				mp3
			</span>

		</span>

		<!-- /PREADDED FILES -->

	</div>
	

</div>
								

Inner Image

Quick Layout
* hover the item below to see the <label> class
  

Regular, inner preview

  

Ajax, inner preview


<!-- 

	1. INNER : STATIC : CIRCLE
	Width and Height are the same (because we use data-file-preview-img-cover="true")

-->
<label class="w--120 h--120 rounded-circle text-center position-relative d-inline-block cursor-pointer border border-secondary border-dashed bg-white">

	<!-- remove button -->
	<a href="#" class="js-file-upload-avatar-circle-remove hide position-absolute absolute-top w-100 z-index-3">
		<span class="d-inline-block btn btn-sm btn-pill bg-secondary text-white pt--4 pb--4 pl--10 pr--10 m--1 mt--n15" title="remove avatar" data-tooltip="tooltip">
			<i class="fi fi-close m-0"></i>
		</span>
	</a>

	<span class="z-index-2 js-file-input-avatar-circle-container d-block absolute-full z-index-1 hide-empty"><!-- avatar container --></span>

	<!-- hidden input (out of viewport, or safari will ignore it) -->
	<!-- NOTE: data-file-preview-img-height="118 and <label> has .h--12 (120px). This is because we have a border - so we cut 2px (1px for each side) -->
    <input 	name="name_avatar_static_circle" 
    		type="file" 

    		data-file-ext="" 
    		data-file-max-size-kb-per-file=""
    		data-file-ext-err-msg="Allowed:" 
    		data-file-size-err-item-msg="File too large!"
    		data-file-size-err-total-msg="Total allowed size exceeded!"
    		data-file-toast-position="bottom-center"
    		data-file-preview-container=".js-file-input-avatar-circle-container" 
    		data-file-preview-show-info="false" 
    		data-file-preview-class="rounded-circle m-0 p-0 animate-bouncein" 
    		data-file-preview-img-height="118" 
    		data-file-btn-clear="a.js-file-upload-avatar-circle-remove"
    		data-file-preview-img-cover="true"

    		class="custom-file-input absolute-full">

	<svg class="fill-gray-600 rounded-circle m-4 z-index-0" viewBox="0 0 60 60">
		<path d="M41.014,45.389l-9.553-4.776C30.56,40.162,30,39.256,30,38.248v-3.381c0.229-0.28,0.47-0.599,0.719-0.951c1.239-1.75,2.232-3.698,2.954-5.799C35.084,27.47,36,26.075,36,24.5v-4c0-0.963-0.36-1.896-1-2.625v-5.319c0.056-0.55,0.276-3.824-2.092-6.525C30.854,3.688,27.521,2.5,23,2.5s-7.854,1.188-9.908,3.53c-2.368,2.701-2.148,5.976-2.092,6.525v5.319c-0.64,0.729-1,1.662-1,2.625v4c0,1.217,0.553,2.352,1.497,3.109c0.916,3.627,2.833,6.36,3.503,7.237v3.309c0,0.968-0.528,1.856-1.377,2.32l-8.921,4.866C1.801,46.924,0,49.958,0,53.262V57.5h46v-4.043C46,50.018,44.089,46.927,41.014,45.389z"/>
		<path d="M55.467,46.526l-9.723-4.21c-0.23-0.115-0.485-0.396-0.704-0.771l6.525-0.005c0,0,0.377,0.037,0.962,0.037c1.073,0,2.638-0.122,4-0.707c0.817-0.352,1.425-1.047,1.669-1.907c0.246-0.868,0.09-1.787-0.426-2.523c-1.865-2.654-6.218-9.589-6.354-16.623c-0.003-0.121-0.397-12.083-12.21-12.18c-1.187,0.01-2.309,0.156-3.372,0.413c0.792,2.094,0.719,3.968,0.665,4.576v4.733c0.648,0.922,1,2.017,1,3.141v4c0,1.907-1.004,3.672-2.607,4.662c-0.748,2.022-1.738,3.911-2.949,5.621c-0.15,0.213-0.298,0.414-0.443,0.604v2.86c0,0.442,0.236,0.825,0.631,1.022l9.553,4.776c3.587,1.794,5.815,5.399,5.815,9.41V57.5H60v-3.697C60,50.711,58.282,47.933,55.467,46.526z"/>
	</svg>

</label>









<!-- 

	2. INNER : STATIC : SQUARED
	Width and Height are the same (because we use data-file-preview-img-cover="true")

-->
<label class="w--120 h--120 rounded text-center position-relative d-inline-block cursor-pointer border border-secondary border-dashed bg-white">

	<!-- remove button -->
	<a href="#" class="js-file-upload-avatar-squared-remove hide position-absolute absolute-top text-align-start w-100 z-index-3">
		<span class="d-inline-block btn btn-sm bg-secondary text-white pt--4 pb--4 pl--10 pr--10 m--1" title="remove avatar" data-tooltip="tooltip">
			<i class="fi fi-close m-0"></i>
		</span>
	</a>

	<span class="z-index-2 js-file-input-avatar-squared-container d-block absolute-full z-index-1 hide-empty"><!-- avatar container --></span>

	<!-- hidden input (out of viewport, or safari will ignore it) -->
	<!-- NOTE: data-file-preview-img-height="118 and <label> has .h--12 (120px). This is because we have a border - so we cut 2px (1px for each side) -->
    <input 	name="name_avatar_static_squared" 
    		type="file" 

    		data-file-ext="jpg, png, gif" 
    		data-file-max-size-kb-per-file="11500"
    		data-file-ext-err-msg="Allowed:" 
    		data-file-size-err-item-msg="File too large!"
    		data-file-size-err-total-msg="Total allowed size exceeded!"
    		data-file-toast-position="bottom-center"
    		data-file-preview-container=".js-file-input-avatar-squared-container" 
    		data-file-preview-show-info="false" 
    		data-file-preview-class="m-0 p-0 rounded animate-bouncein" 
    		data-file-preview-img-height="118" 
    		data-file-btn-clear="a.js-file-upload-avatar-squared-remove"
    		data-file-preview-img-cover="true"

    		class="custom-file-input absolute-full">

	<svg class="fill-gray-600 m--25 z-index-0" viewBox="0 0 60 60">
		<path d="M41.014,45.389l-9.553-4.776C30.56,40.162,30,39.256,30,38.248v-3.381c0.229-0.28,0.47-0.599,0.719-0.951c1.239-1.75,2.232-3.698,2.954-5.799C35.084,27.47,36,26.075,36,24.5v-4c0-0.963-0.36-1.896-1-2.625v-5.319c0.056-0.55,0.276-3.824-2.092-6.525C30.854,3.688,27.521,2.5,23,2.5s-7.854,1.188-9.908,3.53c-2.368,2.701-2.148,5.976-2.092,6.525v5.319c-0.64,0.729-1,1.662-1,2.625v4c0,1.217,0.553,2.352,1.497,3.109c0.916,3.627,2.833,6.36,3.503,7.237v3.309c0,0.968-0.528,1.856-1.377,2.32l-8.921,4.866C1.801,46.924,0,49.958,0,53.262V57.5h46v-4.043C46,50.018,44.089,46.927,41.014,45.389z"/>
		<path d="M55.467,46.526l-9.723-4.21c-0.23-0.115-0.485-0.396-0.704-0.771l6.525-0.005c0,0,0.377,0.037,0.962,0.037c1.073,0,2.638-0.122,4-0.707c0.817-0.352,1.425-1.047,1.669-1.907c0.246-0.868,0.09-1.787-0.426-2.523c-1.865-2.654-6.218-9.589-6.354-16.623c-0.003-0.121-0.397-12.083-12.21-12.18c-1.187,0.01-2.309,0.156-3.372,0.413c0.792,2.094,0.719,3.968,0.665,4.576v4.733c0.648,0.922,1,2.017,1,3.141v4c0,1.907-1.004,3.672-2.607,4.662c-0.748,2.022-1.738,3.911-2.949,5.621c-0.15,0.213-0.298,0.414-0.443,0.604v2.86c0,0.442,0.236,0.825,0.631,1.022l9.553,4.776c3.587,1.794,5.815,5.399,5.815,9.41V57.5H60v-3.697C60,50.711,58.282,47.933,55.467,46.526z"/>
	</svg>

</label>








<!-- 

	3. INNER : AJAX : CIRCLE
	Width and Height are the same (because we use data-file-preview-img-cover="true")

-->
<label class="w--120 h--120 rounded-circle text-center position-relative d-inline-block cursor-pointer border border-secondary border-dashed bg-white">

	<!-- remove button -->
	<a href="#" class="js-file-upload-avatar-ajax-circle-remove hide position-absolute absolute-top w-100 z-index-3">
		<span class="d-inline-block btn btn-sm btn-pill bg-secondary text-white pt--4 pb--4 pl--10 pr--10 m--1 mt--n15" title="remove avatar" data-tooltip="tooltip">
			<i class="fi fi-close m-0"></i>
		</span>
	</a>

	<span class="z-index-2 js-file-input-avatar-ajax-circle-container d-block absolute-full z-index-1 hide-empty"><!-- avatar container --></span>

	<!-- hidden input (out of viewport, or safari will ignore it) -->
	<!-- NOTE: data-file-preview-img-height="118 and <label> has .h--12 (120px). This is because we have a border - so we cut 2px (1px for each side) -->
    <input 	name="name_avatar_ajax_circle" 
    		type="file" 

    		data-file-ext="jpg, png, gif" 
    		data-file-max-size-kb-per-file="11500"
    		data-file-ext-err-msg="Allowed:" 
    		data-file-size-err-item-msg="File too large!"
    		data-file-size-err-total-msg="Total allowed size exceeded!"
    		data-file-toast-position="bottom-center"
    		data-file-preview-container=".js-file-input-avatar-ajax-circle-container" 
    		data-file-preview-show-info="false" 
    		data-file-preview-class="rounded-circle m-0 p-0 animate-bouncein" 
    		data-file-preview-img-height="118" 
    		data-file-btn-clear="a.js-file-upload-avatar-ajax-circle-remove"
    		data-file-preview-img-cover="true"

    		data-file-ajax-upload-enable="true"
    		data-file-ajax-upload-url="../demo.files/php/demo.ajax_file_upload.php"
    		data-file-ajax-upload-params="['action','upload']['param2','value2']"

    		data-file-ajax-delete-enable="true"
    		data-file-ajax-delete-url="../demo.files/php/demo.ajax_file_upload.php"
    		data-file-ajax-delete-params="['action','delete_file']"

    		data-file-ajax-toast-success-txt="Successfully Uploaded!"
    		data-file-ajax-toast-error-txt="One or more files not uploaded!"

    		class="custom-file-input absolute-full">

	<svg class="fill-gray-600 rounded-circle m-4 z-index-0" viewBox="0 0 60 60">
		<path d="M41.014,45.389l-9.553-4.776C30.56,40.162,30,39.256,30,38.248v-3.381c0.229-0.28,0.47-0.599,0.719-0.951c1.239-1.75,2.232-3.698,2.954-5.799C35.084,27.47,36,26.075,36,24.5v-4c0-0.963-0.36-1.896-1-2.625v-5.319c0.056-0.55,0.276-3.824-2.092-6.525C30.854,3.688,27.521,2.5,23,2.5s-7.854,1.188-9.908,3.53c-2.368,2.701-2.148,5.976-2.092,6.525v5.319c-0.64,0.729-1,1.662-1,2.625v4c0,1.217,0.553,2.352,1.497,3.109c0.916,3.627,2.833,6.36,3.503,7.237v3.309c0,0.968-0.528,1.856-1.377,2.32l-8.921,4.866C1.801,46.924,0,49.958,0,53.262V57.5h46v-4.043C46,50.018,44.089,46.927,41.014,45.389z"/>
		<path d="M55.467,46.526l-9.723-4.21c-0.23-0.115-0.485-0.396-0.704-0.771l6.525-0.005c0,0,0.377,0.037,0.962,0.037c1.073,0,2.638-0.122,4-0.707c0.817-0.352,1.425-1.047,1.669-1.907c0.246-0.868,0.09-1.787-0.426-2.523c-1.865-2.654-6.218-9.589-6.354-16.623c-0.003-0.121-0.397-12.083-12.21-12.18c-1.187,0.01-2.309,0.156-3.372,0.413c0.792,2.094,0.719,3.968,0.665,4.576v4.733c0.648,0.922,1,2.017,1,3.141v4c0,1.907-1.004,3.672-2.607,4.662c-0.748,2.022-1.738,3.911-2.949,5.621c-0.15,0.213-0.298,0.414-0.443,0.604v2.86c0,0.442,0.236,0.825,0.631,1.022l9.553,4.776c3.587,1.794,5.815,5.399,5.815,9.41V57.5H60v-3.697C60,50.711,58.282,47.933,55.467,46.526z"/>
	</svg>

</label>







<!-- 

	4. INNER : AJAX : SQUARED
	Width and Height are the same (because we use data-file-preview-img-cover="true")

-->
<label class="w--120 h--120 rounded text-center position-relative d-inline-block cursor-pointer border border-secondary border-dashed bg-white">

	<!-- remove button -->
	<a href="#" class="js-file-upload-avatar-ajax-squared-remove hide position-absolute absolute-top text-align-start w-100 z-index-3">
		<span class="d-inline-block btn btn-sm bg-secondary text-white pt--4 pb--4 pl--10 pr--10 m--1" title="remove avatar" data-tooltip="tooltip">
			<i class="fi fi-close m-0"></i>
		</span>
	</a>

	<span class="z-index-2 js-file-input-avatar-ajax-squared-container d-block absolute-full z-index-1 hide-empty"><!-- avatar container --></span>

	<!-- hidden input (out of viewport, or safari will ignore it) -->
	<!-- NOTE: data-file-preview-img-height="118 and <label> has .h--12 (120px). This is because we have a border - so we cut 2px (1px for each side) -->
    <input 	name="name_avatar_ajax_squared" 
    		type="file" 

    		data-file-ext="jpg, png, gif" 
    		data-file-max-size-kb-per-file="11500"
    		data-file-ext-err-msg="Allowed:" 
    		data-file-size-err-item-msg="File too large!"
    		data-file-size-err-total-msg="Total allowed size exceeded!"
    		data-file-toast-position="bottom-center"
    		data-file-preview-container=".js-file-input-avatar-ajax-squared-container" 
    		data-file-preview-show-info="false" 
    		data-file-preview-class="m-0 p-0 rounded animate-bouncein" 
    		data-file-preview-img-height="118" 
    		data-file-btn-clear="a.js-file-upload-avatar-ajax-squared-remove"
    		data-file-preview-img-cover="true"

    		data-file-ajax-upload-enable="true"
    		data-file-ajax-upload-url="../demo.files/php/demo.ajax_file_upload.php"
    		data-file-ajax-upload-params="['action','upload']['param2','value2']"

    		data-file-ajax-delete-enable="true"
    		data-file-ajax-delete-url="../demo.files/php/demo.ajax_file_upload.php"
    		data-file-ajax-delete-params="['action','delete_file']"

    		data-file-ajax-toast-success-txt="Successfully Uploaded!"
    		data-file-ajax-toast-error-txt="One or more files not uploaded!"

    		class="custom-file-input absolute-full">

	<svg class="fill-gray-600 m--25 z-index-0" viewBox="0 0 60 60">
		<path d="M41.014,45.389l-9.553-4.776C30.56,40.162,30,39.256,30,38.248v-3.381c0.229-0.28,0.47-0.599,0.719-0.951c1.239-1.75,2.232-3.698,2.954-5.799C35.084,27.47,36,26.075,36,24.5v-4c0-0.963-0.36-1.896-1-2.625v-5.319c0.056-0.55,0.276-3.824-2.092-6.525C30.854,3.688,27.521,2.5,23,2.5s-7.854,1.188-9.908,3.53c-2.368,2.701-2.148,5.976-2.092,6.525v5.319c-0.64,0.729-1,1.662-1,2.625v4c0,1.217,0.553,2.352,1.497,3.109c0.916,3.627,2.833,6.36,3.503,7.237v3.309c0,0.968-0.528,1.856-1.377,2.32l-8.921,4.866C1.801,46.924,0,49.958,0,53.262V57.5h46v-4.043C46,50.018,44.089,46.927,41.014,45.389z"/>
		<path d="M55.467,46.526l-9.723-4.21c-0.23-0.115-0.485-0.396-0.704-0.771l6.525-0.005c0,0,0.377,0.037,0.962,0.037c1.073,0,2.638-0.122,4-0.707c0.817-0.352,1.425-1.047,1.669-1.907c0.246-0.868,0.09-1.787-0.426-2.523c-1.865-2.654-6.218-9.589-6.354-16.623c-0.003-0.121-0.397-12.083-12.21-12.18c-1.187,0.01-2.309,0.156-3.372,0.413c0.792,2.094,0.719,3.968,0.665,4.576v4.733c0.648,0.922,1,2.017,1,3.141v4c0,1.907-1.004,3.672-2.607,4.662c-0.748,2.022-1.738,3.911-2.949,5.621c-0.15,0.213-0.298,0.414-0.443,0.604v2.86c0,0.442,0.236,0.825,0.631,1.022l9.553,4.776c3.587,1.794,5.815,5.399,5.815,9.41V57.5H60v-3.697C60,50.711,58.282,47.933,55.467,46.526z"/>
	</svg>

</label>











<!-- 5. PREADDED : CIRCLE -->
<label class="w--120 h--120 rounded-circle text-center position-relative d-inline-block cursor-pointer border border-secondary border-dashed bg-white">

	<!-- remove button -->
	<a href="#" class="js-file-upload-avatar-ajax-circle-remove-preadded position-absolute absolute-top w-100 z-index-3">
		<span class="d-inline-block btn btn-sm btn-pill bg-secondary text-white pt--4 pb--4 pl--10 pr--10 m--1 mt--n15" data-tooltip="tooltip" data-original-title="remove avatar">
			<i class="fi fi-close m-0"></i>
		</span>
	</a>

	<span class="z-index-2 js-file-input-avatar-ajax-circle-container-preadded d-block absolute-full z-index-1">
		<span 	data-id="0" 
				data-file-name="pi.jpg" 
				style="background-image:url('../demo.files/images/unsplash/brooke-cagle-g1Kr4Ozfoac-unsplash.jpg')" 
				class="js-file-input-item d-inline-block position-relative overflow-hidden text-center rounded-circle m-0 p-0 animate-bouncein bg-cover w-100 h-100">
		</span>
	</span>

	<!-- NOTE: data-file-preview-img-height="118 and <label> has .h--12 (120px). This is because we have a border - so we cut 2px (1px for each side) -->
    <input 	name="name_avatar_ajax_circle" 
    		type="file" 

    		data-file-ext="jpg, png, gif" 
    		data-file-max-size-kb-per-file="11500"
    		data-file-ext-err-msg="Allowed:" 
    		data-file-size-err-item-msg="File too large!"
    		data-file-size-err-total-msg="Total allowed size exceeded!"
    		data-file-toast-position="bottom-center"
    		data-file-preview-container=".js-file-input-avatar-ajax-circle-container-preadded" 
    		data-file-preview-show-info="false" 
    		data-file-preview-class="rounded-circle m-0 p-0 animate-bouncein" 
    		data-file-preview-img-height="118" 
    		data-file-btn-clear="a.js-file-upload-avatar-ajax-circle-remove-preadded"
    		data-file-preview-img-cover="true"

    		data-file-ajax-upload-enable="true"
    		data-file-ajax-upload-url="../demo.files/php/demo.ajax_file_upload.php"
    		data-file-ajax-upload-params="['action','upload']['param2','value2']"

    		data-file-ajax-delete-enable="true"
    		data-file-ajax-delete-url="../demo.files/php/demo.ajax_file_upload.php"
    		data-file-ajax-delete-params="['action','delete_file']"

    		data-file-ajax-toast-success-txt="Successfully Uploaded!"
    		data-file-ajax-toast-error-txt="One or more files not uploaded!"

    		class="custom-file-input absolute-full">

	<svg class="fill-gray-600 rounded-circle m-4 z-index-0" viewBox="0 0 60 60">
		<path d="M41.014,45.389l-9.553-4.776C30.56,40.162,30,39.256,30,38.248v-3.381c0.229-0.28,0.47-0.599,0.719-0.951c1.239-1.75,2.232-3.698,2.954-5.799C35.084,27.47,36,26.075,36,24.5v-4c0-0.963-0.36-1.896-1-2.625v-5.319c0.056-0.55,0.276-3.824-2.092-6.525C30.854,3.688,27.521,2.5,23,2.5s-7.854,1.188-9.908,3.53c-2.368,2.701-2.148,5.976-2.092,6.525v5.319c-0.64,0.729-1,1.662-1,2.625v4c0,1.217,0.553,2.352,1.497,3.109c0.916,3.627,2.833,6.36,3.503,7.237v3.309c0,0.968-0.528,1.856-1.377,2.32l-8.921,4.866C1.801,46.924,0,49.958,0,53.262V57.5h46v-4.043C46,50.018,44.089,46.927,41.014,45.389z"/>
		<path d="M55.467,46.526l-9.723-4.21c-0.23-0.115-0.485-0.396-0.704-0.771l6.525-0.005c0,0,0.377,0.037,0.962,0.037c1.073,0,2.638-0.122,4-0.707c0.817-0.352,1.425-1.047,1.669-1.907c0.246-0.868,0.09-1.787-0.426-2.523c-1.865-2.654-6.218-9.589-6.354-16.623c-0.003-0.121-0.397-12.083-12.21-12.18c-1.187,0.01-2.309,0.156-3.372,0.413c0.792,2.094,0.719,3.968,0.665,4.576v4.733c0.648,0.922,1,2.017,1,3.141v4c0,1.907-1.004,3.672-2.607,4.662c-0.748,2.022-1.738,3.911-2.949,5.621c-0.15,0.213-0.298,0.414-0.443,0.604v2.86c0,0.442,0.236,0.825,0.631,1.022l9.553,4.776c3.587,1.794,5.815,5.399,5.815,9.41V57.5H60v-3.697C60,50.711,58.282,47.933,55.467,46.526z"/>
	</svg>

</label>











<!-- 6. PREADDED : SQUARED -->
<label class="w--120 h--120 text-center position-relative d-inline-block cursor-pointer border border-secondary border-dashed bg-white">

	<!-- remove button -->
	<a href="#" class="js-file-upload-avatar-ajax-squared-remove-preadded position-absolute absolute-top w-100 z-index-3">
		<span class="d-inline-block btn btn-sm btn-pill bg-secondary text-white pt--4 pb--4 pl--10 pr--10 m--1 mt--n15" data-tooltip="tooltip" data-original-title="remove avatar">
			<i class="fi fi-close m-0"></i>
		</span>
	</a>

	<span class="z-index-2 js-file-input-avatar-ajax-squared-container-preadded d-block absolute-full z-index-1">
		<span 	data-id="0" 
				data-file-name="pi.jpg" 
				style="background-image:url('../demo.files/images/unsplash/brooke-cagle-g1Kr4Ozfoac-unsplash.jpg')" 
				class="js-file-input-item d-inline-block position-relative overflow-hidden text-center m-0 p-0 animate-bouncein bg-cover w-100 h-100">
		</span>
	</span>

	<!-- NOTE: data-file-preview-img-height="118 and <label> has .h--12 (120px). This is because we have a border - so we cut 2px (1px for each side) -->
    <input 	name="name_avatar_ajax_circle" 
    		type="file" 

    		data-file-ext="jpg, png, gif" 
    		data-file-max-size-kb-per-file="11500"
    		data-file-ext-err-msg="Allowed:" 
    		data-file-size-err-item-msg="File too large!"
    		data-file-size-err-total-msg="Total allowed size exceeded!"
    		data-file-toast-position="bottom-center"
    		data-file-preview-container=".js-file-input-avatar-ajax-squared-container-preadded" 
    		data-file-preview-show-info="false" 
    		data-file-preview-class="m-0 p-0 animate-bouncein" 
    		data-file-preview-img-height="118" 
    		data-file-btn-clear="a.js-file-upload-avatar-ajax-squared-remove-preadded"
    		data-file-preview-img-cover="true"

    		data-file-ajax-upload-enable="true"
    		data-file-ajax-upload-url="../demo.files/php/demo.ajax_file_upload.php"
    		data-file-ajax-upload-params="['action','upload']['param2','value2']"

    		data-file-ajax-delete-enable="true"
    		data-file-ajax-delete-url="../demo.files/php/demo.ajax_file_upload.php"
    		data-file-ajax-delete-params="['action','delete_file']"

    		data-file-ajax-toast-success-txt="Successfully Uploaded!"
    		data-file-ajax-toast-error-txt="One or more files not uploaded!"

    		class="custom-file-input absolute-full">

	<svg class="fill-gray-600 rounded-circle m-4 z-index-0" viewBox="0 0 60 60">
		<path d="M41.014,45.389l-9.553-4.776C30.56,40.162,30,39.256,30,38.248v-3.381c0.229-0.28,0.47-0.599,0.719-0.951c1.239-1.75,2.232-3.698,2.954-5.799C35.084,27.47,36,26.075,36,24.5v-4c0-0.963-0.36-1.896-1-2.625v-5.319c0.056-0.55,0.276-3.824-2.092-6.525C30.854,3.688,27.521,2.5,23,2.5s-7.854,1.188-9.908,3.53c-2.368,2.701-2.148,5.976-2.092,6.525v5.319c-0.64,0.729-1,1.662-1,2.625v4c0,1.217,0.553,2.352,1.497,3.109c0.916,3.627,2.833,6.36,3.503,7.237v3.309c0,0.968-0.528,1.856-1.377,2.32l-8.921,4.866C1.801,46.924,0,49.958,0,53.262V57.5h46v-4.043C46,50.018,44.089,46.927,41.014,45.389z"/>
		<path d="M55.467,46.526l-9.723-4.21c-0.23-0.115-0.485-0.396-0.704-0.771l6.525-0.005c0,0,0.377,0.037,0.962,0.037c1.073,0,2.638-0.122,4-0.707c0.817-0.352,1.425-1.047,1.669-1.907c0.246-0.868,0.09-1.787-0.426-2.523c-1.865-2.654-6.218-9.589-6.354-16.623c-0.003-0.121-0.397-12.083-12.21-12.18c-1.187,0.01-2.309,0.156-3.372,0.413c0.792,2.094,0.719,3.968,0.665,4.576v4.733c0.648,0.922,1,2.017,1,3.141v4c0,1.907-1.004,3.672-2.607,4.662c-0.748,2.022-1.738,3.911-2.949,5.621c-0.15,0.213-0.298,0.414-0.443,0.604v2.86c0,0.442,0.236,0.825,0.631,1.022l9.553,4.776c3.587,1.794,5.815,5.399,5.815,9.41V57.5H60v-3.697C60,50.711,58.282,47.933,55.467,46.526z"/>
	</svg>

</label>
								

Inner, Variations

Static
Ajax

<!-- 

	INNER : STATIC

-->
<label class="rounded text-center position-relative d-block cursor-pointer border border-secondary border-dashed">

	<!-- remove button -->
	<a href="#" class="js-file-input-showcase-remove hide position-absolute absolute-top text-align-start w-100 z-index-3">
		<span class="d-inline-block btn btn-sm bg-secondary text-white pt--4 pb--4 pl--10 pr--10 m--1" title="remove image" data-tooltip="tooltip">
			<i class="fi fi-close m-0"></i>
		</span>
	</a>

	<span class="z-index-2 js-file-input-showcase-container d-block absolute-full z-index-1 hide-empty"><!-- image container --></span>

    <input 	name="showcase_file" 
    		type="file" 
    		data-file-ext="jpg, jpeg, png" 
    		data-file-max-size-kb-per-file="10240"
    		data-file-ext-err-msg="Allowed:" 
    		data-file-size-err-item-msg="File too large!"
    		data-file-size-err-total-msg="Total allowed size exceeded!"
    		data-file-toast-position="top-center"
    		data-file-preview-container=".js-file-input-showcase-container" 
    		data-file-preview-show-info="false" 
    		data-file-preview-class="m-0 p-0 rounded" 
    		data-file-preview-img-height="auto" 
    		data-file-btn-clear="a.js-file-input-showcase-remove"
    		data-file-preview-img-cover="true"
    		class="custom-file-input absolute-full">

	<div class="absolute-full">
		<div class="d-table">
			<div class="d-table-cell align-middle text-center">

				<i class="fi fi-image fs--50 text-muted"></i>
				<small class="d-block text-muted">
					<b>IMAGE/COVER OF YOUR WORK</b>
					<span class="d-block mt-1">
						squared is preffered<br>
						please upload 600x600 px minimum.
					</span>
				</small>

			</div>
		</div>
	</div>

	<!-- ratio maintained using a `blank` image -->
	<img class="w-100" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt="...">

</label>




<!-- 

	INNER : AJAX

-->
<label class="rounded text-center position-relative d-block cursor-pointer border border-secondary border-dashed">

	<!-- remove button -->
	<a href="#" class="js-file-input-showcase-remove2 hide position-absolute absolute-top text-align-start w-100 z-index-3">
		<span class="d-inline-block btn btn-sm bg-secondary text-white pt--4 pb--4 pl--10 pr--10 m--1" title="remove image" data-tooltip="tooltip">
			<i class="fi fi-close m-0"></i>
		</span>
	</a>

	<span class="z-index-2 js-file-input-showcase-container2 d-block absolute-full z-index-1 hide-empty"><!-- image container --></span>

    <input 	name="showcase_file" 
    		type="file" 
    		data-file-ext="jpg, jpeg, png" 
    		data-file-max-size-kb-per-file="10240"
    		data-file-ext-err-msg="Allowed:" 
    		data-file-size-err-item-msg="File too large!"
    		data-file-size-err-total-msg="Total allowed size exceeded!"
    		data-file-toast-position="top-center"
    		data-file-preview-container=".js-file-input-showcase-container2" 
    		data-file-preview-show-info="false" 
    		data-file-preview-class="m-0 p-0 rounded" 
    		data-file-preview-img-height="auto" 
    		data-file-btn-clear="a.js-file-input-showcase-remove2"
    		data-file-preview-img-cover="true"

    		data-file-ajax-upload-enable="true"
    		data-file-ajax-upload-url="../demo.files/php/demo.ajax_file_upload.php"
    		data-file-ajax-upload-params="['action','upload']['param2','value2']"

    		data-file-ajax-delete-enable="true"
    		data-file-ajax-delete-url="../demo.files/php/demo.ajax_file_upload.php"
    		data-file-ajax-delete-params="['action','delete_file']"

    		data-file-ajax-toast-success-txt="Successfully Uploaded!"
    		data-file-ajax-toast-error-txt="One or more files not uploaded!"

    		class="custom-file-input absolute-full">

	<div class="absolute-full">
		<div class="d-table">
			<div class="d-table-cell align-middle text-center">

				<i class="fi fi-image fs--50 text-muted"></i>
				<small class="d-block text-muted">
					<b>IMAGE/COVER OF YOUR WORK</b>
					<span class="d-block mt-1">
						squared is preffered<br>
						please upload 600x600 px minimum.
					</span>
				</small>

			</div>
		</div>
	</div>

	<!-- ratio maintained using a `blank` image -->
	<img class="w-100" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt="...">

</label>
									

List Type


Layout Examples

Copy the bottom class and add to data-file-preview-class

You can combine the utility class to create more layouts. No CSS code!

Item with image preview.jpg
1.22 Mb
mp3
No image, extension only.mp3
159.34 Mb
mov
My great movie file.mov
1.12 Gb
mov
Lorem ipsum dolor sit amet adipiscium because this is a very very very very very long long long long text.txt
15.3 Kb
Bigger example by changing:
data-file-preview-img-height="50"
USED CLAESSES data-file-preview-class="shadow-md mb-2 rounded"

<!--

	LIST TYPE : STATIC

-->
<div class="mb-1">

	<label class="btn btn-primary cursor-pointer position-relative">

		<!-- 
			We use .absolute-full class instead of .viewport-out
			Just to make sure the element is working crossbrowser!

			data-file-preview-img-height="50" 	- min. 50

				Layouts
					data-file-preview-class="show-hover-container shadow-md mb-2 rounded overflow-hidden" 
					data-file-preview-class="show-hover-container shadow-md mb-2 rounded overflow-hidden border" 
					data-file-preview-class="show-hover-container mb-2 rounded border overflow-hidden" 
					data-file-preview-class="show-hover-container border-bottom" 
					data-file-preview-class="show-hover-container border-left bw--2 mb-1" 
					data-file-preview-class="show-hover-container bg-light rounded overflow-hidden p--6 mb-1" 
					data-file-preview-class="show-hover-container bg-light rounded overflow-hidden p--3 mb-1 border" 
					data-file-preview-class="show-hover-container bg-primary-soft rounded overflow-hidden p--3 mb-1" 

				.show-hover-container  	= show delete button only on hover (always visible on mobile)

		 -->
	    <input 	name="file_list_name[]" 
	    		multiple=""
	    		type="file" 

	    		data-file-ext="mp3, jpg, png, gif" 
	    		data-file-max-size-kb-per-file=""
	    		data-file-max-size-kb-total="0" 
	    		data-file-max-total-files="100"
	    		data-file-ext-err-msg="Allowed:" 
	    		data-file-exist-err-msg="File already exists:"
	    		data-file-size-err-item-msg="File too large!"
	    		data-file-size-err-total-msg="Total allowed size exceeded!"
	    		data-file-size-err-max-msg="Maximum allowed files:"
	    		data-file-toast-position="bottom-center"
	    		data-file-preview-container=".js-file-input-container-multiple-list-static" 
	    		data-file-preview-img-height="80" 
	    		data-file-btn-clear="a.js-file-input-btn-multiple-list-static-remove"
	    		data-file-preview-show-info="true" 
	    		data-file-preview-list-type="list" 

	    		class="custom-file-input absolute-full">

			<span class="group-icon">
				<i class="fi fi-arrow-upload"></i>
				<i class="fi fi-circle-spin fi-spin"></i>
    		</span> 

			<span>Select Files</span>
			

	</label>


	<div class="js-file-input-container-multiple-list-static position-relative hide-empty mt-4"><!-- container --></div>


	<!-- remove button -->
	<div class="mt-3">
		<a href="#" title="Clear Images" data-toggle="tooltip" class="js-file-input-btn-multiple-list-static-remove hide btn btn-secondary mb-2">
			<i class="fi fi-close"></i>
			Clear files
		</a>
	</div>

</div>








<!--

	LIST TYPE : AJAX

-->
<div class="mb-1">

	<label class="btn btn-primary btn-soft cursor-pointer position-relative">

		<!-- 
			We use .absolute-full class instead of .viewport-out
			Just to make sure the element is working crossbrowser!

			data-file-preview-img-height="50" 	- min. 50

				Layouts
					data-file-preview-class="show-hover-container shadow-md mb-2 rounded overflow-hidden" 
					data-file-preview-class="show-hover-container shadow-md mb-2 rounded overflow-hidden border" 
					data-file-preview-class="show-hover-container mb-2 rounded border overflow-hidden" 
					data-file-preview-class="show-hover-container border-bottom" 
					data-file-preview-class="show-hover-container border-left bw--2 mb-1" 
					data-file-preview-class="show-hover-container bg-light rounded overflow-hidden p--6 mb-1" 
					data-file-preview-class="show-hover-container bg-light rounded overflow-hidden p--3 mb-1 border" 
					data-file-preview-class="show-hover-container bg-primary-soft rounded overflow-hidden p--3 mb-1" 

				.show-hover-container  	= show delete button only on hover (always visible on mobile)

		 -->
	    <input 	name="file_list_name[]" 
	    		multiple=""
	    		type="file" 

	    		data-file-ext="mp3, jpg, png, gif" 
	    		data-file-max-size-kb-per-file=""
	    		data-file-max-size-kb-total="0" 
	    		data-file-max-total-files="100"
	    		data-file-ext-err-msg="Allowed:" 
	    		data-file-exist-err-msg="File already exists:"
	    		data-file-size-err-item-msg="File too large!"
	    		data-file-size-err-total-msg="Total allowed size exceeded!"
	    		data-file-size-err-max-msg="Maximum allowed files:"
	    		data-file-toast-position="bottom-center"
	    		data-file-preview-container=".js-file-input-container-multiple-list" 
	    		data-file-preview-img-height="80" 
	    		data-file-btn-clear="a.js-file-input-btn-multiple-list-remove"
	    		data-file-preview-show-info="true" 
	    		data-file-preview-list-type="list" 

	    		data-file-ajax-upload-enable="true"
	    		data-file-ajax-upload-url="../demo.files/php/demo.ajax_file_upload.php"
	    		data-file-ajax-upload-params="['action','upload']['param2','value2']"

	    		data-file-ajax-delete-enable="true"
	    		data-file-ajax-delete-url="../demo.files/php/demo.ajax_file_upload.php"
	    		data-file-ajax-delete-params="['action','delete_file']"

	    		data-file-ajax-reorder-enable="true"
	    		data-file-ajax-reorder-url="../demo.files/php/demo.ajax_file_upload.php"
	    		data-file-ajax-reorder-params="['action','reorder']"
				data-file-ajax-reorder-toast-success="Order Saved!" 
				data-file-ajax-reorder-toast-position="bottom-center" 

	    		data-file-ajax-toast-success-txt="Successfully Uploaded!"
	    		data-file-ajax-toast-error-txt="One or more files not uploaded!"
	    		data-file-ajax-callback-function=""
	    		data-file-ajax-progressbar-custom=""
	    		data-file-ajax-progressbar-disable="false"

	    		class="custom-file-input absolute-full">

			<span class="group-icon">
				<i class="fi fi-arrow-upload"></i>
				<i class="fi fi-circle-spin fi-spin"></i>
    		</span> 

			<span>Ajax : Select Files</span>
			

	</label>


	<div class="js-file-input-container-multiple-list position-relative hide-empty mt-4"><!-- container --></div>

</div>