SOW : File upload
SOW plugins are part of Smarty Core, written from scratch!
src/js/sow.core/sow.file_upload.js
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 to reorder (dependnecies: sortablejs vendor)
- lightweight - 24Kb minified (6.4Kb gzipped).
While playing around, watch your console to see ajax requests.
Regular File input
<!-- Single File & Preview -->
<div class="mb-3">
<input type="file" name="file_input_name"
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="form-control">
</div>
<div class="js-file-input-preview-single-container2 ms--n6 me--n6 mt-4 hide-empty"><!-- 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>
<!-- Multiple Files & Preview -->
<div class="mb-3">
<input multiple type="file" name="file_input_name[]"
data-file-ext="html, jpg, png, gif, mp3"
data-file-max-size-kb-per-file="0"
data-file-max-size-kb-total="0"
data-file-max-total-files="12"
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-preview-class="shadow-md m-2 rounded float-start"
data-file-btn-clear="a.js-file-upload-clear"
class="form-control">
</div>
<div class="js-file-input-preview-multiple-container ms--n6 me--n6 clearfix hide-empty"><!-- 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>
Button File upload
<!-- non-ajax buton -->
<div class="mb-1">
<label class="btn btn-primary cursor-pointer position-relative">
<input multiple type="file" name="file_input_name[]"
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-bs-toggle="tooltip" class="js-file-input-btn-multiple-example-remove hide btn btn-secondary">
<i class="fi fi-close"></i>
Clear files
</a>
</div>
<!--
Ajax container : files are pushed here!
Each upload button/input has a preview container.
You can delete it if no file preview is needed and also no need to use on button/input the preview params.
A little css trick:
.hide-empty class is hidding the container as long as its empty (comments allowed, without space/new line)
Become visible when content is pushed by ajax!
-->
<div class="js-file-input-container-multiple-example d-inline-block position-relative clearfix hide-empty"><!-- container --></div>
<!-- ajax button -->
<div class="mb-1">
<label class="btn btn-primary cursor-pointer position-relative">
<input multiple type="file" name="file_input_name[]"
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!
Each upload button/input has a preview container.
You can delete it if no file preview is needed and also no need to use on button/input the preview params.
A little css trick:
.hide-empty class is hidding the container as long as its empty (comments allowed, without space/new line)
Become visible when content is pushed by ajax!
-->
<div class="js-file-input-container-multiple-example-ajax d-inline-block position-relative clearfix hide-empty"><!-- container --></div>
Button Submit reveal
<!-- Regular preview -->
<label class="btn btn-primary cursor-pointer position-relative">
<input multiple type="file" name="file_input_name[]"
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 -->
<label class="btn btn-primary cursor-pointer position-relative">
<input multiple type="file" name="file_input_name[]"
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 mt-3"><!-- 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>
Ajax Progressbar
<!-- Ajax : Progressbar -->
<label class="btn btn-danger cursor-pointer position-relative">
<input multiple type="file" name="ajax_files[]"
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="show-hover-container 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 : 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="small text-gray-500">
<span class="js-file-input-upload-percent">0%</span> Completed
</div>
<!-- /percent indicator -->
<!-- progress bar -->
<div class="progress" style="height:5px">
<div class="progress-bar bg-success" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<!-- Ajax container : files are pushed here! -->
<div class="js-file-input-container-multiple-ajax position-relative clearfix hide-empty"><!-- container --></div>
<!-- Ajax : Dynamic Progressbar -->
<label class="btn btn-warning cursor-pointer position-relative">
<input multiple type="file" name="ajax_files_progress_dynamic[]"
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 : 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="fw-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 py-1 px-2 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 smaller px-2">
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 smaller px-2">
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 py-1 px-2 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 smaller px-2">
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 smaller px-2">
159.34 Mb
</span>
</span>
<!-- file extension -->
<span class="absolute-full d-flex align-items-center justify-content-center fs-1 opacity-6 text-uppercase text-truncate">
mp3
</span>
</span>
<!-- /PREADDED FILES -->
</div>
Inner Variations
Static
Ajax
<!-- 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 py-1 px-2 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 type="file" name="showcase_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">
<span class="absolute-full d-flex flex-column align-items-center justify-content-center">
<i class="fi fi-image h1 text-muted"><!-- icon --></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>
</span>
<!-- ratio maintained using a `blank` image -->
<img class="w-100" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt="...">
</label>
<!-- 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 py-1 px-2 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 type="file" name="showcase_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">
<span class="absolute-full d-flex flex-column align-items-center justify-content-center">
<i class="fi fi-image h1 text-muted"><!-- icon --></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>
</span>
<!-- ratio maintained using a `blank` image -->
<img class="w-100" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt="...">
</label>
Upload 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
1.22 Mb
mp3
No image, extension only.mp3
159.34 Mb
159.34 Mb
mov
My great movie file.mov
1.12 Gb
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
15.3 Kb
Bigger example by changing:
data-file-preview-img-height="50"
data-file-preview-img-height="50"
USED CLAESSES
data-file-preview-class="shadow-md mb-2 rounded"
<!-- static list -->
<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-start border-2 mb-1"
data-file-preview-class="show-hover-container bg-light rounded overflow-hidden p-2 mb-1"
data-file-preview-class="show-hover-container bg-light rounded overflow-hidden p-1 mb-1 border"
data-file-preview-class="show-hover-container bg-primary-soft rounded overflow-hidden p-1 mb-1"
.show-hover-container = show delete button only on hover (always visible on mobile)
-->
<input multiple type="file" name="file_list_name[]"
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-bs-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>
<!-- static ajax -->
<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-start border-2 mb-1"
data-file-preview-class="show-hover-container bg-light rounded overflow-hidden p-2 mb-1"
data-file-preview-class="show-hover-container bg-light rounded overflow-hidden p-1 mb-1 border"
data-file-preview-class="show-hover-container bg-primary-soft rounded overflow-hidden p-1 mb-1"
.show-hover-container = show delete button only on hover (always visible on mobile)
-->
<input multiple type="file" name="file_list_name[]"
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>