SOW : Core Plugins

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

SOW : Form Advanced

Overview:
  • bulk options
  • numierc limit
  • character cont

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

	:: Plugin Init 
*/	$.SOW.core.form_advanced.init();
									

Bulk Options




<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>


				</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>
									

Limit & Counters

please, order between 1 and 48.
155 chars limit
characters left: 155

1000 chars limit
characters left: 1000
100 chars limit
characters: 0 / 100

100 chars limit
characters: 0 / 100

<!-- 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>
									

Formatters

<!-- 
	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>
									

Lists/Expanders

Expanded

<div class="form-advanced-list p-4 shadow-xs border rounded mb-5">

	<label class="form-radio form-radio-primary d-block py-3 border-bottom">
		<input type="radio" name="payment_method" class="form-advanced-list-reveal" checked>
		<i></i> Option 1
	</label>


	<label class="form-radio form-radio-primary d-block py-3 border-bottom">
		<input type="radio" name="payment_method" class="form-advanced-list-reveal" data-form-advanced-target="#option2_expand">
		<i></i> Option 2
	</label>

	<!-- Expand -->
	<div id="option2_expand" class="form-advanced-list-reveal-item hide bg-gradient-light p-4 rounded mt--n10 border bt-0">
		
		Expanded 

	</div>
	<!-- /Expand -->

</div>
									

Reset Form

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 
	to keep always visible,
	add class: .js-ignore and remove .hide-force
-->
<a href="#" data-target-reset="#form_content" class="form-advanced-reset hide-force btn btn-light">
	reset form
</a>