/*
:: Plugin File
src/js/sow.core/sow.form_advanced.js
:: Plugin Init
*/ $.SOW.core.form_advanced.init();
required
attribute is removed when containers are hidden so the form can work! The attribute is added back on visible visible containers!disable
attribute is added when containers are hidden. .js-form-advanced-list-ignore
class added on element will cancel this feature!
<!-- Simple List -->
<div class="form-advanced-list px-4 py-2 shadow-primary-md rounded-xl">
<!-- Trigger : 1 -->
<label class="form-radio form-radio-primary d-block py-3">
<input type="radio" name="adancedlist_1" class="form-advanced-list-reveal" checked>
<i></i> Option 1
</label>
<!-- Trigger : 2 -->
<label class="form-radio form-radio-danger d-block py-3">
<input type="radio" name="adancedlist_1" class="form-advanced-list-reveal" data-form-advanced-target="#simple2_expand">
<i></i> Option 2
</label>
<!-- Expand 3 -->
<div id="simple2_expand" class="form-advanced-list-reveal-item bg-light rounded hide p-4">
Simple & Advanced examples are woring exactly the same!
</div>
<!-- /Expand -->
<!-- Trigger : 3 -->
<label class="form-radio form-radio-warning d-block py-3">
<input type="radio" name="adancedlist_1" class="form-advanced-list-reveal" data-form-advanced-target="#simple3_expand">
<i></i> Option 3
</label>
<!-- Expand 3 -->
<div id="simple3_expand" class="form-advanced-list-reveal-item bg-warning-soft rounded hide p-4">
So this is just a very simple example!
</div>
</div>
<!-- Simple List -->
<!-- form-advanced-list -->
<form novalidate class="bs-validate" id="listExpandersForm" method="post" action="#">
<!--
Disabled elements (within hidden containers) are not included in form submit (get or post)
.js-form-advanced-list-ignore skip disable function within hidden container (inputs/textarea/etc)
data-form-advanced-list-hidden-required="true" remove required when container is hidden (default: false)
data-form-advanced-list-hidden-disable="true" disable when container is hidden (skipped if disable class used) (default: false)
data-form-advanced-list-hidden-disable-class=".js-advanced-list-hidden-disable-class" disable when container is hidden using a class (default: '')
-->
<div class="form-advanced-list p-4 shadow rounded"
data-form-advanced-list-hidden-required="true"
data-form-advanced-list-hidden-disable="true"
data-form-advanced-list-hidden-disable-class=".advanced-list-hidden-disable-class">
<!-- Trigger 1 -->
<label class="form-radio form-radio-primary d-block py-3">
<input type="radio" name="form_advanced_list" class="form-advanced-list-reveal" value="1" checked="" data-form-advanced-target="#optionA_expand">
<i></i> Using form reset!
</label>
<!-- Expand 1 -->
<div id="optionA_expand" class="form-advanced-list-reveal-item border-bottom">
<!--
REQUIRED INPUT
when this container is hidden, "required" is removed.
Is added back when/if the container is visible again!
Only add the required param to any input, datepicker, etc
-->
<label class="d-block">Required input</label>
<input required type="text" class="form-control" value="">
<!--
DISABLE BY A CLASS
required input and also disabled
disabled input using class
-->
<label class="d-block mt-4">Disabled when hidden, using a class<small></small></label>
<input required type="text" class="form-control js-advanced-list-hidden-disable-class" value="">
<code class="fs--12">.js-advanced-list-hidden-disable-class</code>
<!--
IGNORE (required/disabled are not affecting this field)
disabled input and ignored by the plugin
js-form-advanced-list-ignore = ignore plugin
-->
<label class="d-block mt-4">Always Disabled <small>.js-form-advanced-list-ignore</small></label>
<input disabled type="text" class="form-control js-form-advanced-list-ignore" value="">
<!--
Reset Button
data-target-reset="" (id or class ; multiple separated by comma ; href might be used instead for a single #id)
data-exclude-reset="" (id or class ; multiple separated by comma)
.js-ignore (always visible ; also remove .hide-force)
-->
<div class="my-4">
<a href="#optionA_expand" class="form-advanced-reset js-ignore btn btn-sm btn-light">
<i class="fi fi-close"></i>
reset section
</a>
</div>
</div>
<!-- Trigger 2 -->
<label class="form-radio form-radio-primary d-block py-3">
<input type="radio" name="form_advanced_list" class="form-advanced-list-reveal" value="2" data-form-advanced-target="#optionB_expand">
<i></i> Required fields
</label>
<!-- Expand 2 -->
<div id="optionB_expand" class="form-advanced-list-reveal-item border-bottom hide">
<!--
REQUIRED INPUT
when this container is hidden, "required" is removed.
Is added back when/if the container is visible again!
Only add the required param to any input, datepicker, etc
-->
<label class="d-block">Required input</label>
<input required type="text" class="form-control" value="">
<!--
DISABLE BY A CLASS
required input and also disabled
disabled input using class
-->
<label class="d-block mt-4">Disabled when hidden, using a class<small></small></label>
<input required type="text" class="form-control js-advanced-list-hidden-disable-class" value="">
<code class="fs--12">.js-advanced-list-hidden-disable-class</code>
</div>
<!-- /Expand -->
<!-- Trigger 3 : Ajax -->
<label class="form-radio form-radio-primary d-block py-3">
<input type="radio" name="form_advanced_list" class="form-advanced-list-reveal" value="3" data-form-advanced-target="#optionC_expand" data-form-advanced-ajax-url="_ajax/dummy_text2.html" data-form-advanced-ajax-icon="true">
<i></i> Ajax Content
</label>
<!-- Expand 3 : Ajax -->
<div id="optionC_expand" class="form-advanced-list-reveal-item border-top hide">
<!-- populated by ajax -->
</div>
</div>
<div class="mt-4">
<!--
SUBMIT FORM
-->
<button type="submit" class="btn btn-primary">submit</button>
<!--
Reset Button
data-target-reset="" (id or class ; multiple separated by comma)
data-exclude-reset="" (id or class ; multiple separated by comma)
.js-ignore (always visible ; also remove .hide-force)
-->
<a href="#" data-target-reset="#listExpandersForm" data-exclude-reset=".form-advanced-list-reveal" class="form-advanced-reset js-ignore btn btn-light">
Reset All
</a>
</div>
</form>
<!-- form-advanced-list -->
There are situations we have required fields but hidden inside a container.
This is solved by adding .js-form-advanced-required
to the container that is hidden/visible.
<form novalidate class="bs-validate" action="#!" method="get">
<!--
TOGGLER
Note: if multiple IDs used (data-target="#id1, id2")
add class: .js-form-advanced-required-toggler
-->
<label class="form-checkbox form-checkbox-primary d-block">
<input type="checkbox" value="1" data-toggle="collapse" data-target="#option_example">
<i></i> <span>Hide/show option</span>
</label>
<!--
CONTAINER
.js-form-advanced-required class
-->
<div id="option_example" class="collapse js-form-advanced-required">
<!--
REQUIRED
-->
<div class="form-label-group mb-3">
<input required placeholder="Required" id="required_field" type="text" value="" class="form-control">
<label for="required_field" class="w-100">
Required
</label>
</div>
<!--
NOT REQUIRED
-->
<div class="form-label-group mb-3">
<input placeholder="Not Required" id="not_required_field" type="text" value="" class="form-control">
<label for="not_required_field" class="w-100">
Not Required
</label>
</div>
</div>
<button type="submit" class="btn btn-sm btn-primary mt-4">Submit</button>
</form>
Useful to ecommerce admin to create variants or if dynamic inputs are needed!
<!--
default
data-table-clone-method="append|prepend"
-->
<div class="js-form-advanced-table mb-6"
data-table-column-insert-before=".js-clone-before"
data-table-column-insert-element='<input type="text" class="form-control form-control-sm" value="">'
data-table-column-delete-button='<span class="btn-table-column-delete fi fi-close fs--15 cursor-pointer px-1 d-inline-block"></span>'
data-table-column-limit="3"
data-table-row-limit="5"
data-table-row-method="append">
<!--
ADD COLUMN
The name of this input (name="option" in this demo)
is used to generate input fields with names like this:
name="option[color]"
if no input name used, field name is generated like this:
name="color"
-->
<div class="js-form-advanced-table-column-add input-group mb-3 max-w-300">
<!--
Optional Plugin used:
SOW : Search Inline
-->
<input type="text" name="variant" class="form-control form-control-sm input-suggest"
placeholder="Ex: color, size"
aria-label="Table Cloner"
aria-describedby="button-table-cloner"
data-input-suggest-type="text"
data-input-suggest-name="variant"
data-input-suggest-ajax-url="_ajax/input_suggest_variants.json"
data-input-suggest-ajax-method="GET"
data-input-suggest-ajax-limit="100">
<div class="input-group-append">
<button class="btn btn-sm btn-outline-secondary" type="button" id="button-table-cloner">Add</button>
</div>
</div>
<table class="table table-bordered table-align-middle table-sm">
<thead>
<tr>
<th>SKU</th>
<th>Barcode</th>
<th class="js-clone-before">Price</th>
<th>BS Select</th>
<th>Date</th>
<th class="w--90">Image</th>
<th class="w--80"> </th>
</tr>
</thead>
<tbody>
<tr>
<!-- SKU -->
<td>
<input type="text" class="form-control form-control-sm" name="variant[sku]" value="">
</td>
<!-- Barcode -->
<td>
<input type="text" class="form-control form-control-sm" name="variant[barcode]" value="">
</td>
<!-- Price -->
<td class="js-clone-before">
<input type="number" class="form-control form-control-sm" name="variant[price]" value="">
</td>
<!-- Select -->
<td>
<select class="form-control form-control-sm bs-select" name="variant[select]" title="Please Select...">
<option value="0">Basic</option>
<option value="1">Mustard</option>
<option value="2">Ketchup</option>
<option value="3">Barbecue</option>
</select>
</td>
<!-- Date -->
<td>
<input autocomplete="off" type="text" name="variant[date]" class="form-control form-control-sm rangepicker"
data-layout-rounded="false"
data-single-datepicker="true"
data-timepicker="false"
data-timepicker-24h="true"
data-timepicker-show-seconds="false"
data-disable-past-dates="true"
data-date-format="MM/DD/YYYY"
data-disable-auto-update-input="true"
data-quick-locale='{
"lang_apply" : "Apply",
"lang_cancel" : "Cancel",
"lang_crange" : "Custom Range",
"lang_months" : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
"lang_weekdays" : ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
}'>
</td>
<!-- Image -->
<td>
<!--
AJAX IMAGE UPLOAD
-->
<label class="rounded text-center position-relative d-block cursor-pointer border border-secondary border-dashed mb-0 h--50">
<!-- remove button -->
<a href="#!" class="js-table-file-remove position-absolute absolute-top start-0 z-index-3 btn btn-sm btn-secondary p-0 w--20 h--20 m--1 line-height-1 text-center hide">
<i class="fi fi-close m-0"></i>
</a>
<!-- image container -->
<span class="js-table-file-preview z-index-2 d-block absolute-full z-index-1 hide-empty"></span>
<!-- hidden file input -->
<input name="variant[image]"
type="file"
data-file-ext="jpg, jpeg, png"
data-file-max-size-kb-per-file="1024"
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-table-file-preview"
data-file-btn-clear=".js-table-file-remove"
data-file-preview-show-info="false"
data-file-preview-class="m-0 p-0 rounded"
data-file-preview-img-height="auto"
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">
<!-- icon -->
<span class="absolute-full d-middle">
<i class="fi fi-image fs--30 text-muted"></i>
</span>
</label>
</td>
<!-- Option -->
<td class="text-center">
<a href="#" class="btn btn-sm btn-primary btn-table-clone rounded-circle">
<span class="group-icon">
<i class="fi fi-plus"></i>
<i class="fi fi-thrash"></i>
</span>
</a>
</td>
</tr>
</tbody>
</table>
</div>
<!--
preadded columns
data-table-clone-method="append|prepend"
-->
<div class="js-form-advanced-table mb-6"
data-table-column-insert-before=".js-clone-before"
data-table-column-insert-element='<input type="text" class="form-control form-control-sm" value="">'
data-table-column-delete-button='<span class="btn-table-column-delete fi fi-close fs--15 cursor-pointer px-1 d-inline-block"></span>'
data-table-column-limit="3"
data-table-row-limit="5"
data-table-row-method="prepend">
<!--
ADD COLUMN
The name of this input (name="option" in this demo)
is used to generate input fields with names like this:
name="option[color]"
if no input name used, field name is generated like this:
name="color"
-->
<div class="js-form-advanced-table-column-add input-group mb-3 max-w-300">
<!--
Optional Plugin used:
SOW : Search Inline
-->
<input type="text" name="variant" class="form-control form-control-sm input-suggest"
placeholder="Ex: color, size"
aria-label="Table Cloner"
aria-describedby="button-table-cloner"
data-input-suggest-type="text"
data-input-suggest-name="variant"
data-input-suggest-ajax-url="_ajax/input_suggest_variants.json"
data-input-suggest-ajax-method="GET"
data-input-suggest-ajax-limit="100">
<div class="input-group-append">
<button class="btn btn-sm btn-outline-secondary" type="button" id="button-table-cloner">Add</button>
</div>
</div>
<table class="table table-bordered table-align-middle table-sm">
<thead>
<tr>
<th>SKU</th>
<th>Barcode</th>
<th data-id="column-size" class="js-table-option">Size</th>
<th data-id="column-material" class="js-table-option">Material</th>
<th class="js-clone-before">Price</th>
<th>BS Select</th>
<th>Date</th>
<th class="w--90">Image</th>
<th class="w--80 text-center">
<a href="#" class="btn btn-sm btn-primary btn-table-clone rounded-circle">
<i class="fi fi-plus"></i>
</a>
</th>
</tr>
</thead>
<!--
See Sortable doumentation if ajax reorder is needed
-->
<tbody class="sortable">
<!--
OPTIONAL
ACTING AS A TEMPLATE TO CLONE
IS REMOVED ON LOAD IF .hide CLASS IS PRESENT
Else, the first TR is used by default!
.js-ignore = optional, used by sortable to igore from drag/drop reorder
-->
<tr class="js-ignore hide">
<!-- SKU -->
<td>
<input type="text" class="form-control form-control-sm" name="variant[sku]" value="">
</td>
<!-- Barcode -->
<td>
<input type="text" class="form-control form-control-sm" name="variant[barcode]" value="">
</td>
<!-- Preadded Option 1 -->
<td class="js-table-option column-size">
<input type="number" class="form-control form-control-sm" name="variant[size]" value="">
</td>
<!-- Preadded Option 2 -->
<td class="js-table-option column-material">
<input type="number" class="form-control form-control-sm" name="variant[material]" value="">
</td>
<!-- Price -->
<td class="js-clone-before">
<input type="number" class="form-control form-control-sm" name="variant[price]" value="">
</td>
<!-- Select -->
<td>
<select class="form-control form-control-sm bs-select" name="variant[select]" title="Please Select...">
<option value="0">Basic</option>
<option value="1">Mustard</option>
<option value="2">Ketchup</option>
<option value="3">Barbecue</option>
</select>
</td>
<!-- Date -->
<td>
<input autocomplete="off" type="text" name="variant[date]" class="form-control form-control-sm rangepicker"
data-layout-rounded="false"
data-single-datepicker="true"
data-timepicker="false"
data-timepicker-24h="true"
data-timepicker-show-seconds="false"
data-disable-past-dates="true"
data-date-format="MM/DD/YYYY"
data-disable-auto-update-input="true"
data-quick-locale='{
"lang_apply" : "Apply",
"lang_cancel" : "Cancel",
"lang_crange" : "Custom Range",
"lang_months" : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
"lang_weekdays" : ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
}'>
</td>
<!-- Image -->
<td>
<!--
AJAX IMAGE UPLOAD
-->
<label class="rounded text-center position-relative d-block cursor-pointer border border-secondary border-dashed mb-0 h--50">
<!-- remove button -->
<a href="#!" class="js-table-file-remove-1 js-file-item-del position-absolute absolute-top start-0 z-index-3 btn btn-sm btn-secondary p-0 w--20 h--20 m--1 line-height-1 text-center hide">
<i class="fi fi-close m-0"></i>
</a>
<!-- image container -->
<span class="js-table-file-preview-1 z-index-2 d-block absolute-full z-index-1 hide-empty"></span>
<!-- hidden file input -->
<input name="variant[image]"
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-table-file-preview-1"
data-file-preview-show-info="false"
data-file-preview-class="rounded-circle m-0 p-0 animate-bouncein"
data-file-preview-img-height="auto"
data-file-btn-clear=".js-table-file-remove-1"
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">
<!-- icon -->
<span class="absolute-full d-middle">
<i class="fi fi-image fs--30 text-muted"></i>
</span>
</label>
</td>
<!-- Option -->
<td class="position-relative text-center">
<!-- direct delete -->
<!--
<a href="#" class="btn btn-sm btn-light btn-table-clone-remove rounded-circle">
<i class="fi fi-thrash"></i>
</a>
-->
<!-- remove button (confirm trigger) -->
<a href="#" class="btn btn-table-clone-remove-confirm btn-sm btn-light rounded-circle">
<i class="fi fi-thrash"></i>
</a>
<!-- confirm -->
<div class="position-absolute bg-warning shadow top-0 bottom-0 end-0 w--200 z-index-10 hide">
<i class="arrow arrow-lg arrow-start arrow-center border-warning"></i>
<label class="d-block fs--13 mb--2">Are you sure?</label>
<a href="#!" class="btn btn-table-clone-remove btn-danger btn-sm px-2 pt--2 pb--2">Delete</a>
<a href="#!" class="btn btn-table-clone-remove-cancel btn-secondary btn-sm px-2 pt--2 pb--2">Cancel</a>
</div>
</td>
</tr>
<!-- preadded -->
<tr>
<!-- SKU -->
<td>
<input type="text" class="form-control form-control-sm" name="variant[sku]" value="">
</td>
<!-- Barcode -->
<td>
<input type="text" class="form-control form-control-sm" name="variant[barcode]" value="">
</td>
<!-- Preadded Option 1 -->
<td class="js-table-option column-size">
<input type="number" class="form-control form-control-sm" name="variant[size]" value="">
</td>
<!-- Preadded Option 2 -->
<td class="js-table-option column-material">
<input type="number" class="form-control form-control-sm" name="variant[material]" value="">
</td>
<!-- Price -->
<td class="js-clone-before">
<input type="number" class="form-control form-control-sm" name="variant[price]" value="">
</td>
<!-- Select -->
<td>
<select class="form-control form-control-sm bs-select" name="variant[select]" title="Please Select...">
<option value="0">Basic</option>
<option value="1">Mustard</option>
<option value="2">Ketchup</option>
<option value="3">Barbecue</option>
</select>
</td>
<!-- Date -->
<td>
<input autocomplete="off" type="text" name="variant[date]" class="form-control form-control-sm rangepicker"
data-layout-rounded="false"
data-single-datepicker="true"
data-timepicker="false"
data-timepicker-24h="true"
data-timepicker-show-seconds="false"
data-disable-past-dates="true"
data-date-format="MM/DD/YYYY"
data-disable-auto-update-input="true"
data-quick-locale='{
"lang_apply" : "Apply",
"lang_cancel" : "Cancel",
"lang_crange" : "Custom Range",
"lang_months" : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
"lang_weekdays" : ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
}'>
</td>
<!-- Image -->
<td>
<!--
AJAX IMAGE UPLOAD
-->
<label class="rounded text-center position-relative d-block cursor-pointer border border-secondary border-dashed mb-0 h--50">
<!-- remove button -->
<a href="#!" class="js-table-file-remove-1 js-file-item-del position-absolute absolute-top start-0 z-index-3 btn btn-sm btn-secondary p-0 w--20 h--20 m--1 line-height-1 text-center">
<i class="fi fi-close m-0"></i>
</a>
<!-- image container -->
<span class="js-table-file-preview-1 z-index-2 d-block absolute-full z-index-1 hide-empty">
<span data-id="0"
data-file-name="mutzii-fmDCrqPQKog-unsplash-min.jpg"
style="background-image:url('../demo.files/images/unsplash/products/sneakers/thumb_330/mutzii-fmDCrqPQKog-unsplash-min.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>
<!-- hidden file input -->
<input name="variant[image]"
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-table-file-preview-1"
data-file-preview-show-info="false"
data-file-preview-class="rounded-circle m-0 p-0 animate-bouncein"
data-file-preview-img-height="auto"
data-file-btn-clear=".js-table-file-remove-1"
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">
<!-- icon -->
<span class="absolute-full d-middle">
<i class="fi fi-image fs--30 text-muted"></i>
</span>
</label>
</td>
<!-- Option -->
<td class="position-relative text-center">
<!-- direct delete -->
<!--
<a href="#" class="btn btn-sm btn-light btn-table-clone-remove rounded-circle">
<i class="fi fi-thrash"></i>
</a>
-->
<!-- remove button (confirm trigger) -->
<a href="#" class="btn btn-table-clone-remove-confirm btn-sm btn-light rounded-circle">
<i class="fi fi-thrash"></i>
</a>
<!-- confirm -->
<div class="position-absolute bg-warning shadow top-0 bottom-0 end-0 w--200 z-index-10 hide">
<i class="arrow arrow-lg arrow-start arrow-center border-warning"></i>
<label class="d-block fs--13 mb--2">Are you sure?</label>
<a href="#!" class="btn btn-table-clone-remove btn-danger btn-sm px-2 pt--2 pb--2">Delete</a>
<a href="#!" class="btn btn-table-clone-remove-cancel btn-secondary btn-sm px-2 pt--2 pb--2">Cancel</a>
</div>
</td>
</tr>
<!-- preadded -->
<tr>
<!-- SKU -->
<td>
<input type="text" class="form-control form-control-sm" value="">
</td>
<!-- Barcode -->
<td>
<input type="text" class="form-control form-control-sm" value="">
</td>
<!-- Preadded Option 1 -->
<td class="js-table-option column-size">
<input type="number" class="form-control form-control-sm" name="variant[size]" value="">
</td>
<!-- Preadded Option 2 -->
<td class="js-table-option column-material">
<input type="number" class="form-control form-control-sm" name="variant[material]" value="">
</td>
<!-- Price -->
<td class="js-clone-before">
<input type="number" class="form-control form-control-sm" value="">
</td>
<!-- Select -->
<td>
<select class="form-control form-control-sm bs-select" title="Please Select...">
<option value="0">Basic</option>
<option value="1">Mustard</option>
<option value="2">Ketchup</option>
<option value="3">Barbecue</option>
</select>
</td>
<!-- Date -->
<td>
<input autocomplete="off" type="text" name="my_daterange" class="form-control form-control-sm rangepicker"
data-layout-rounded="false"
data-single-datepicker="true"
data-timepicker="false"
data-timepicker-24h="true"
data-timepicker-show-seconds="false"
data-disable-past-dates="true"
data-date-format="MM/DD/YYYY"
data-disable-auto-update-input="true"
data-quick-locale='{
"lang_apply" : "Apply",
"lang_cancel" : "Cancel",
"lang_crange" : "Custom Range",
"lang_months" : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
"lang_weekdays" : ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
}'>
</td>
<!-- Image -->
<td>
<!--
AJAX IMAGE UPLOAD
-->
<label class="rounded text-center position-relative d-block cursor-pointer border border-secondary border-dashed mb-0 h--50">
<!-- remove button -->
<a href="#!" class="js-table-file-remove-2 js-file-item-del position-absolute absolute-top start-0 z-index-3 btn btn-sm btn-secondary p-0 w--20 h--20 m--1 line-height-1 text-center">
<i class="fi fi-close m-0"></i>
</a>
<!-- image container -->
<span class="js-table-file-preview-2 z-index-2 d-block absolute-full z-index-1 hide-empty">
<span data-id="0"
data-file-name="nikita-kachanovsky-ad_0wMHtvlU-unsplash-min.jpg"
style="background-image:url('../demo.files/images/unsplash/products/sneakers/thumb_330/nikita-kachanovsky-ad_0wMHtvlU-unsplash-min.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>
<!-- hidden file input -->
<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-table-file-preview-2"
data-file-preview-show-info="false"
data-file-preview-class="rounded-circle m-0 p-0 animate-bouncein"
data-file-preview-img-height="auto"
data-file-btn-clear=".js-table-file-remove-2"
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">
<!-- icon -->
<span class="absolute-full d-middle">
<i class="fi fi-image fs--30 text-muted"></i>
</span>
</label>
</td>
<!-- Option -->
<td class="position-relative text-center">
<!-- direct delete -->
<!--
<a href="#" class="btn btn-sm btn-light btn-table-clone-remove rounded-circle">
<i class="fi fi-thrash"></i>
</a>
-->
<!-- remove button (confirm trigger) -->
<a href="#" class="btn btn-table-clone-remove-confirm btn-sm btn-light rounded-circle">
<i class="fi fi-thrash"></i>
</a>
<!-- confirm -->
<div class="position-absolute bg-warning shadow top-0 bottom-0 end-0 w--200 z-index-10 hide">
<i class="arrow arrow-lg arrow-start arrow-center border-warning"></i>
<label class="d-block fs--13 mb--2">Are you sure?</label>
<a href="#!" class="btn btn-table-clone-remove btn-danger btn-sm px-2 pt--2 pb--2">Delete</a>
<a href="#!" class="btn btn-table-clone-remove-cancel btn-secondary btn-sm px-2 pt--2 pb--2">Cancel</a>
</div>
</td>
</tr>
</tbody>
</table>
<small class="d-block text-muted mt-1">drag and drop rows</small>
</div>
<form class="bs-validate" novalidate id="form_id" method="post" action="#">
<!--
IMPORTANT
The "action" hidden input is updated by javascript according to button params/action:
data-js-form-advanced-hidden-action-id="#action"
data-js-form-advanced-hidden-action-value="delete"
In your backend, should process data like this (PHP example):
if($_POST['action'] === 'delete') {
foreach($_POST['item_id'] as $item_id) {
// ... delete $item_id from database
}
}
-->
<input type="hidden" id="action" name="action" value=""><!-- value populated by js -->
<label class="form-checkbox form-checkbox-primary d-block">
<input class="checkall" data-checkall-container="#item_list" type="checkbox" name="checkbox">
<i></i> Check All
</label>
<hr>
<div id="item_list">
<label class="form-checkbox form-checkbox-primary d-block">
<input type="checkbox" name="item_id[]" value="1">
<i></i> Item 1
</label>
<label class="form-checkbox form-checkbox-primary d-block">
<input type="checkbox" name="item_id[]" value="2">
<i></i> Item 2
</label>
<label class="form-checkbox form-checkbox-primary d-block">
<input type="checkbox" name="item_id[]" value="3">
<i></i> Item 3
</label>
</div>
<hr>
<label class="form-checkbox form-checkbox-primary d-block">
<input class="checkall" data-checkall-container="#item_list" type="checkbox" name="checkbox">
<i></i> Check All
</label>
<!-- options -->
<div class="mt-4 text-center-xs">
<!-- SELECTED ITEMS -->
<div class="clearfix"><!-- using .dropdown, autowidth not working -->
<a href="#" class="btn btn-sm btn-pill btn-light" data-toggle="dropdown" aria-expanded="false" aria-haspopup="true">
<span class="group-icon">
<i class="fi fi-dots-vertical-full"></i>
<i class="fi fi-close"></i>
</span>
<span>Selected Items</span>
</a>
<div class="dropdown-menu dropdown-menu-clean dropdown-click-ignore max-w-250">
<div class="scrollable-vertical max-h-50vh">
<a href="#"
class="dropdown-item text-truncate js-form-advanced-bulk"
data-js-form-advanced-bulk-hidden-action-id="#action"
data-js-form-advanced-bulk-hidden-action-value="active"
data-js-form-advanced-bulk-container-items="#item_list"
data-js-form-advanced-bulk-required-selected="true"
data-js-form-advanced-bulk-required-txt-error="No Selected Items!"
data-js-form-advanced-bulk-required-txt-position="top-center"
data-js-form-advanced-bulk-required-custom-modal=""
data-js-form-advanced-bulk-required-custom-modal-content-ajax=""
data-js-form-advanced-bulk-required-modal-type="success"
data-js-form-advanced-bulk-required-modal-size="modal-md"
data-js-form-advanced-bulk-required-modal-txt-title="Please Confirm"
data-js-form-advanced-bulk-required-modal-txt-subtitle="Selected Products: {{no_selected}}"
data-js-form-advanced-bulk-required-modal-txt-body-txt="Set active {{no_selected}} selected products?"
data-js-form-advanced-bulk-required-modal-txt-body-info=""
data-js-form-advanced-bulk-required-modal-btn-text-yes="Confirm"
data-js-form-advanced-bulk-required-modal-btn-text-no="Cancel"
data-js-form-advanced-bulk-submit-without-confirmation="false"
data-js-form-advanced-form-id="#form_id">
<i class="fi fi-check"></i>
Set : Active
</a>
<a href="#"
class="dropdown-item text-truncate js-form-advanced-bulk"
data-js-form-advanced-bulk-hidden-action-id="#action"
data-js-form-advanced-bulk-hidden-action-value="inactive"
data-js-form-advanced-bulk-container-items="#item_list"
data-js-form-advanced-bulk-required-selected="true"
data-js-form-advanced-bulk-required-txt-error="No Selected Items!"
data-js-form-advanced-bulk-required-txt-position="top-center"
data-js-form-advanced-bulk-required-custom-modal=""
data-js-form-advanced-bulk-required-custom-modal-content-ajax=""
data-js-form-advanced-bulk-required-modal-type="warning"
data-js-form-advanced-bulk-required-modal-size="modal-md"
data-js-form-advanced-bulk-required-modal-txt-title="Please Confirm"
data-js-form-advanced-bulk-required-modal-txt-subtitle="Selected Products: {{no_selected}}"
data-js-form-advanced-bulk-required-modal-txt-body-txt="Set inactive {{no_selected}} selected products?"
data-js-form-advanced-bulk-required-modal-txt-body-info=""
data-js-form-advanced-bulk-required-modal-btn-text-yes="Confirm"
data-js-form-advanced-bulk-required-modal-btn-text-no="Cancel"
data-js-form-advanced-bulk-submit-without-confirmation="false"
data-js-form-advanced-form-id="#form_id">
<i class="fi fi-close"></i>
Set : Inactive
</a>
<a href="#"
class="dropdown-item text-truncate js-form-advanced-bulk"
data-js-form-advanced-bulk-hidden-action-id="#action"
data-js-form-advanced-bulk-hidden-action-value="delete"
data-js-form-advanced-bulk-container-items="#item_list"
data-js-form-advanced-bulk-required-selected="true"
data-js-form-advanced-bulk-required-txt-error="No Selected Items!"
data-js-form-advanced-bulk-required-txt-position="top-center"
data-js-form-advanced-bulk-required-custom-modal=""
data-js-form-advanced-bulk-required-custom-modal-content-ajax=""
data-js-form-advanced-bulk-required-modal-type="danger"
data-js-form-advanced-bulk-required-modal-size="modal-md"
data-js-form-advanced-bulk-required-modal-txt-title="Please Confirm"
data-js-form-advanced-bulk-required-modal-txt-subtitle="Selected Products: {{no_selected}}"
data-js-form-advanced-bulk-required-modal-txt-body-txt="Are you sure? Delete {{no_selected}} selected products?"
data-js-form-advanced-bulk-required-modal-txt-body-info="Please note: this is a permanent action!"
data-js-form-advanced-bulk-required-modal-btn-text-yes="Yes, Delete"
data-js-form-advanced-bulk-required-modal-btn-text-no="Cancel"
data-js-form-advanced-bulk-submit-without-confirmation="false"
data-js-form-advanced-form-id="#form_id">
<i class="fi fi-thrash text-danger"></i>
Set : Delete
</a>
<div class="dropdown-divider"></div>
<a href="#"
class="dropdown-item text-truncate js-form-advanced-bulk"
data-js-form-advanced-bulk-hidden-action-id="#action"
data-js-form-advanced-bulk-hidden-action-value="myactionhere3"
data-js-form-advanced-bulk-container-items="#item_list"
data-js-form-advanced-bulk-required-selected="true"
data-js-form-advanced-bulk-required-txt-error="No Selected Items!"
data-js-form-advanced-bulk-required-txt-position="top-center"
data-js-form-advanced-bulk-submit-without-confirmation="true"
data-js-form-advanced-form-id="#form_id">
<i class="fi fi-mollecules text-danger"></i>
Submit : No Confirm.
</a>
<div class="dropdown-divider"></div>
<a href="#"
class="dropdown-item text-truncate js-form-advanced-bulk"
data-js-form-advanced-bulk-hidden-action-id="#action"
data-js-form-advanced-bulk-hidden-action-value="myactionhere1"
data-js-form-advanced-bulk-container-items="#item_list"
data-js-form-advanced-bulk-required-selected="true"
data-js-form-advanced-bulk-required-txt-error="No Selected Items!"
data-js-form-advanced-bulk-required-custom-modal="#my_custom_modal"
data-js-form-advanced-bulk-required-custom-modal-content-ajax=""
data-js-form-advanced-bulk-submit-without-confirmation="false"
data-js-form-advanced-form-id="#form_id">
<i class="fi fi-heart-slim text-success"></i>
Inline Custom Modal
</a>
<a href="#"
class="dropdown-item text-truncate js-form-advanced-bulk"
data-js-form-advanced-bulk-hidden-action-id="#action"
data-js-form-advanced-bulk-hidden-action-value="myactionhere2"
data-js-form-advanced-bulk-container-items="#item_list"
data-js-form-advanced-bulk-required-selected="true"
data-js-form-advanced-bulk-required-txt-error="No Customers Selected!"
data-js-form-advanced-bulk-required-custom-modal="#my_custom_modal_ajax"
data-js-form-advanced-bulk-required-custom-modal-content-ajax="../_ajax/form_advanced_bulk_custom_modal_content.html"
data-js-form-advanced-bulk-submit-without-confirmation="false"
data-js-form-advanced-form-id="#form_id"
>
<i class="fi fi-heart-slim"></i> Inline + Ajax Content
</a>
<!--
NO INLINE HTML CODE NEEDED!
Fully customizable
see html_frontend/ajax/form_advanced_bulk_custom_modal_content_full.html
-->
<a href="#"
class="dropdown-item text-truncate js-form-advanced-bulk"
data-js-form-advanced-bulk-hidden-action-id="#action"
data-js-form-advanced-bulk-hidden-action-value="myactionhere1"
data-js-form-advanced-bulk-container-items="#item_list"
data-js-form-advanced-bulk-required-selected="true"
data-js-form-advanced-bulk-required-txt-error="No Items Selected!"
data-js-form-advanced-bulk-required-txt-position="top-center"
data-js-form-advanced-bulk-submit-without-confirmation="false"
data-js-form-advanced-bulk-required-modal-size="modal-md"
data-js-form-advanced-bulk-required-modal-type="custom"
data-js-form-advanced-bulk-required-modal-backdrop="static"
data-js-form-advanced-bulk-required-custom-modal-content-ajax="../_ajax/form_advanced_bulk_custom_modal_content_full.html"
data-js-form-advanced-form-id="#form_id">
<i class="fi fi-lightning text-warning"></i>
Full Ajax Content
</a>
</div>
</div>
</div>
<!-- /SELECTED ITEMS -->
</div>
<!-- /options -->
<!-- Inline custom modal (should stay inside <form> to be able to post data) -->
<div class="modal fade show" id="my_custom_modal" role="dialog" tabindex="-1" aria-labelledby="modal-title-confirm" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<!--
Header color - optional
.bg-[primary|danger|warning|success|info|pink|indigo]-soft
-->
<div class="modal-header b-0 bg-primary-soft">
<h5 id="modal-title-confirm" class="modal-title font-weight-light fs--18">
Inline custom modal
</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span class="fi fi-close fs--18" aria-hidden="true"></span>
</button>
</div>
<!-- /header -->
<!-- body -->
<div class="modal-body pt--30 pb--30">
Selected items: <span class="js-form-advanced-selected-items">0</span>
<div class="fs--18">
Customize as you like! <br><br>
<!-- FILE UPLOADER -->
<div class="clearfix">
<!--
2. AJAX UPLOAD : DYNAMIC PROGRESS UNDER BUTTON
No any extra html code needed for the progress bar.
-->
<label class="btn btn-warning btn-sm cursor-pointer position-relative">
<!--
We use .absolute-full class instead of .viewport-out
Just to make sure the element is working crossbrowser!
.show-hover-container = show delete button only on hover (always visible on mobile)
-->
<input name="ajax_files_progress_dynamic[]"
multiple=""
type="file"
data-file-ext="jpg,png,gif"
data-file-max-size-kb-per-file="3000"
data-file-max-size-kb-total="5000"
data-file-max-total-files="3"
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-form-advanced-container-table-form-test"
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-btn-clear="a.js-form-advanced-btn-multiple-ajax-remove"
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</span>
</label>
<div class="js-form-advanced-container-table-form-test position-relative mt-3 clearfix hide-empty"></div>
<small class="d-block text-gray-400">Upload few images and then... reorder them :)</small>
</div>
<!-- /FILE UPLOADER -->
<br>
<small>Yes, ajax content for modals also supported!</small><br>
<small>Check <a href="plugins-sow-form-advanced.html" class="js-ajax link-muted">SOW : Form Advanced</a> for more & documentation!</small>
</div>
</div>
<!-- /body -->
<!-- footer ; buttons -->
<div class="modal-footer">
<!-- submit button - actually submitting the form -->
<button type="submit" class="btn pt--10 pb--10 fs--16 btn-primary">
<i class="fi fi-check"></i> Oh, Great!
</button>
<!-- cancel|close button -->
<a href="#" class="btn pt--10 pb--10 fs--16 btn-light" data-dismiss="modal">
<i class="fi fi-close"></i> Close
</a>
</div>
<!-- /footer ; buttons -->
</div>
</div>
</div>
<!-- /Inline custom modal -->
<!-- Inline custom modal + Ajax Content -->
<div class="modal fade show" id="my_custom_modal_ajax" role="dialog" tabindex="-1" aria-labelledby="modal-title-confirm" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<!-- Ajax content is added here -->
<!--
Content: ../_ajax/form_advanced_bulk_custom_modal_content.html
Note: is full modal content: header, body and footer.
So you can fully customize each ajax content.
-->
<!-- ajax loading icon : optional -->
<div class="p--30 text-center">
<i class="fi fi-circle-spin fi-spin fs--30 text-muted"></i>
</div>
<!-- /ajax loading icon : optional -->
</div>
</div>
</div>
<!-- /Inline custom modal + Ajax Content -->
</form>
<!-- input limit + hidden message -->
<div class="position-relative">
<span class="js-form-advanced-limit-info badge badge-warning hide animate-bouncein position-absolute absolute-top m--2">
please, order between 1 and 48.
</span>
<input type="number" value="8" min="1" max="48" class="form-control js-form-advanced-limit">
</div>
<!-- char count down : input -->
<div class="position-relative">
<span class="js-form-advanced-limit-info badge badge-warning hide animate-bouncein position-absolute absolute-top m--2">
155 chars limit
</span>
<input type="text" name="-" class="form-control js-form-advanced-char-count-down" data-output-target=".js-form-advanced-char-left" value="" maxlength="155">
<div class="fs--12 text-muted text-align-end mt--3">
characters left: <span class="js-form-advanced-char-left">155</span>
</div>
</div>
<!-- char count down : textarea -->
<div class="position-relative">
<span class="js-form-advanced-limit-info badge badge-warning hide animate-bouncein position-absolute absolute-top m--2">
1000 chars limit
</span>
<textarea class="js-form-advanced-char-count-down form-control" data-output-target=".js-form-advanced-char-left2" maxlength="1000"></textarea>
<div class="fs--12 text-muted text-align-end mt--3">
characters left: <span class="js-form-advanced-char-left2">1000</span>
</div>
</div>
<!-- char count up : input -->
<div class="position-relative">
<span class="js-form-advanced-limit-info badge badge-warning hide animate-bouncein position-absolute absolute-top m--2">
100 chars limit
</span>
<input type="text" name="-" class="form-control js-form-advanced-char-count-up" data-output-target=".js-form-advanced-char-total" value="" maxlength="100">
<div class="fs--12 text-muted text-align-end mt--3">
characters: <span class="js-form-advanced-char-total">0</span> / 100
</div>
</div>
<!-- char count up : textarea -->
<div class="position-relative">
<span class="js-form-advanced-limit-info badge badge-warning hide animate-bouncein position-absolute absolute-top m--2">
100 chars limit
</span>
<textarea class="js-form-advanced-char-count-up form-control" data-output-target=".js-form-advanced-char-total2" maxlength="100"></textarea>
<div class="fs--12 text-muted text-align-end mt--3">
characters: <span class="js-form-advanced-char-total2">0</span> / 100
</div>
</div>
<!--
credit card type : autodetected on user type
amex
diners
jcb
laser
visa
mastercard
maestro
discover
-->
<input type="text" name="cc_type" id="cc_type" value="" class="form-control form-control-sm mb-3" readonly="">
<div class="form-label-group">
<input placeholder="Card Number" id="cc_number" type="text" data-card-type="#cc_type" class="form-control cc-format cc-number">
<label for="cc_number">Card Number</label>
</div>
<!-- date -->
<div class="form-label-group">
<input placeholder="MM / YY" id="cc_date" type="text" value="" class="form-control cc-format cc-expire" maxlength="5">
<label for="cc_date">MM / YY</label>
</div>
Type/select something
<!-- form content example -->
<div id="form_content">
<div class="form-label-group mb-3">
<input placeholder="Full Name" id="full_name" type="text" class="form-control">
<label for="full_name">Full Name</label>
</div>
<div class="form-label-group mb-3">
<textarea placeholder="Textarea" id="description" class="form-control" rows="3"></textarea>
<label for="description">Textarea</label>
</div>
<label class="form-radio form-radio-primary clearfix d-block">
<input type="radio" name="radio_form" value="1">
<i></i> option 1
</label>
<label class="form-radio form-radio-primary clearfix d-block">
<input type="radio" name="radio_form" value="1">
<i></i> option 2
</label>
</div>
<!--
Reset Button
data-target-reset="" (id or class ; multiple separated by comma)
data-exclude-reset="" (id or class ; multiple separated by comma)
.js-ignore (always visible ; also remove .hide-force)
-->
<a href="#" data-target-reset="#form_content" data-exclude-reset="" class="form-advanced-reset hide-force btn btn-light">
reset form
</a>