File: public/assets/local/js/global.min.js

Recommend this page to a friend!
  Classes of Aby Dahana  >  Aksara  >  public/assets/local/js/global.min.js  >  Download  
File: public/assets/local/js/global.min.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: Aksara
A CodeIgniter based API and CRUD generator
Author: By
Last change: Initial commit for update 4.2.7

##### Bug Fixed:
Core: Fix the CRUD function both back end and front end;
Core: Fix the query string parameter for each returned data;
Core: Fix the table data that return nothing when no data exists;
Model: Fix the multiple database connection when switching the main connection to the second connection;
Model: Fix the field check when table using alias;
Javascript: Fix the query string extraction that return null value;
Javascript: Fix the geocoding (place search) on the map when using Google or OpenStreet provider;
Galleries: Fix the link that turned image not found when clicked from gallery category;
Dashboard: Fix RecursiveIterator that return error when catch unreadable upload folder;

##### Changes:
Modules: Change the "not found" page message to matched with modules;
Group: Replace the module structure for permission with path;
Permission: Change the permission check with module path;
Permission: Remove the field of module, submodule and controller and replaced with path instead;
Activity Log: Remove the field of module, submodule and controller and replaced with path instead;
Group Privileges: Remove the field of module, submodule and controller and replaced with path instead;

##### Improvements:
Core: Replace the permission with module path so it will work with unlimited sub module;
Core: Add title trim to prevent blank title when the requested data was not found;
Core: Block the Internet Explorer under version 11 that no longer supports common used javascript;
Modules: Change the "not found" page message to matched with modules;
Installer: Add the character restriction for encryption key and cookie name to prevent breaking the configuration parameter;
Javascript: Increase the maximum depth of menu builder;
Seeder: Apply column modification related to app__activity_logs, app__groups_privileges and app__settings table;
Redesign the "not found" page;
Add new language phrases;

##### New Features:
Galleries: Add the slide view for next and previous image if available;
Settings: Add the action sound toggle;
Addon: Install the add on directly from the Aksara Market;
Addon: Customize the installed theme;
Authentication: Add the annually sign in when active years is presents;
Date: 1 month ago
Size: 53,268 bytes
 

Contents

Class file image Download
/**
 * Global
 *
 * @version			1.0.1
 *
 * @author			Aby Dahana
 * @profile			abydahana.github.io
 *
 * Property of Aksara Laboratory
 * www.aksaracms.com
 */

var xhr												= null,
	UA												= ($(window).outerWidth() < 1024 ? 'mobile' : 'desktop'),
	FB												= [],
	exception										= null,
	barcode											= '',
	leave_page										= false,
	per_page										= 0,
	success											= new Audio(config.asset_url + 'local/sound/success.mp3'),
	fail											= new Audio(config.asset_url + 'local/sound/fail.mp3'),
	warning											= new Audio(config.asset_url + 'local/sound/alert.mp3');

$.ajaxSetup
({
	cache: true
}),

$(document).ready(function()
{
	"use strict";
	
	/**
	 * prepare to clear the previous exception if any
	 */
	exception										= setTimeout(function()
	{
		$('.alert.exception').trigger('click')
	}, 5000);
	
	/**
	 * set the color scheme of browser status bar
	 */
	var color_scheme								= rgb_to_hex($('.navbar').css('backgroundColor'));
	document.querySelector('meta[name=msapplication-navbutton-color]').setAttribute('content',  color_scheme),
	document.querySelector('meta[name=theme-color]').setAttribute('content',  color_scheme),
	document.querySelector('meta[name=apple-mobile-web-app-status-bar-style]').setAttribute('content',  color_scheme),
	
	/**
	 * clear previous storage
	 */
	localStorage.clear(),
	sessionStorage.clear(),
	
	/**
	 * reactivate in first load
	 */
	_reactivate(),
	
	/**
	 * store the request to browser history
	 */
	history.replaceState({path: window.location.href}, ''),
	
	/**
	 * override the jQuery error exception
	 */
	$(window).on('error', function(response)
	{
		/* throw log to console */
		throw_exception(500, (typeof response.originalEvent.message !== 'undefined' ? response.originalEvent.message : response.originalEvent.srcElement))
	}),
	
	/**
	 * describe the back button of browser to fix the SPA
	 */
	$(window).bind("popstate", function(e)
	{
		if(!e.originalEvent.state) return;
		var _old_title								= $('.will-be-replace-with-title').text(),
			_old_icon								= $('#will-be-replace-with-icon').attr('class'),
			_old_btn_icon							= $(this).find('i.mdi').attr('class');
		$.ajax
		({
			url: location.href,
			context: this,
			method: 'POST',
			data:
			{
				prefer: (UA === 'mobile' ? 'html' : null)
			},
			beforeSend: function(progress)
			{
				$('.will-be-replace-with-title').text((phrase.loading ? phrase.loading : 'Loading...')),
				$('#will-be-replace-with-icon').removeAttr('class').addClass('mdi mdi-loading mdi-spin'),
				$('#description-collapse').removeClass('show'),
				$('#refresh-btn').attr('href', location.href),
				$('*').modal('hide')
			},
			complete: function(progress)
			{
				/* additional command if any */
			},
			statusCode:
			{
				301: function(response, status, error)
				{
					_response_template($(this), response, {icon: _old_icon, btn_icon: _old_btn_icon, title: _old_title})
				},
				403: function(response, status, error)
				{
					_response_template($(this), response, {icon: _old_icon, btn_icon: _old_btn_icon, title: _old_title})
				},
				404: function(response, status, error)
				{
					_response_template($(this), response, {icon: _old_icon, btn_icon: _old_btn_icon, title: _old_title})
				},
				500: function(response, status, error)
				{
					/* throw log to console */
					$(config.content_wrapper).html
					(
						'<div class="container-fluid">' +
							'<div class="mt-3 mb-3 p-3 bg-dark rounded">' +
								'<pre class="text-warning mb-0" style="white-space:pre-wrap">' +
									(typeof response.responseJSON !== 'undefined' ? JSON.stringify(response.responseJSON, null, 4) : (error ? error : (phrase.consider_to_check_your_internet_connection ? phrase.consider_to_check_your_internet_connection : 'Consider to check your internet connection'))) +
								'</pre>' +
							'</div>' +
						'</div>'
					),
					throw_exception(response.status, (error ? error : (phrase.consider_to_check_your_internet_connection ? phrase.consider_to_check_your_internet_connection : 'Consider to check your internet connection'))),
					$('.will-be-replace-with-title').text((phrase.error ? phrase.error : 'Error')),
					$('#will-be-replace-with-icon').removeAttr('class').addClass('mdi mdi-alert-outline'),
					$('#description-collapse').removeClass('show')
				}
			}
		})
		.done(function(response)
		{
			if(typeof response._token !== 'undefined')
			{
				sessionStorage.setItem('_token', response._token)
			}
			
			_response_template($(this), response, {icon: _old_icon, btn_icon: _old_btn_icon, title: _old_title}, true)
		})
		.fail(function(response, status, error)
		{
			if(response.statusText == 'abort')
			{
				return;
			}
		})
	}),
	
	/**
	 * Overtake the keyboard shortcut
	 */
	$('body').on('keydown', function(e)
	{
		var keycode									= (e.which ? e.which : e.keyCode);
		if(e.which === 116)
		{
			/* overtake f5 */
			e.preventDefault(),
			($('a.--btn-refresh').length ? $('a.--btn-refresh').trigger('click') : $('<a href="' + window.location.href + '" class="--xhr"></a>').appendTo('body').trigger('click').remove())
		}
		else if(e.ctrlKey && e.which === 83 && $('form.--validate-form:visible').length)
		{
			/* overtake ctrl + s */
			e.preventDefault(),
			$('form.--validate-form:visible').trigger('submit')
		}
		else if(e.ctrlKey && e.which === 80 && $('a.--btn-print').length)
		{
			/* overtake ctrl + prtsc */
			e.preventDefault(),
			window.open($('a.--btn-print').attr('href'), '_blank')
		}
		else if(e.which === 27 && $('.modal:visible').length)
		{
			/* overtake esc */
			e.preventDefault(),
			$('.modal:visible').find('[data-dismiss="modal"]').trigger('click')
		}
		else if(e.ctrlKey && e.which === 70 && !$('.modal:visible').length && $('input[name="q"]').length)
		{
			/* overtake ctrl+f */
			e.preventDefault(),
			$('input[name="q"]').focus()
		}
	}),
	
	/**
	 * expand sidebar on hover
	 */
	$('body').on('mouseover', '#sidebar-wrapper', function(e)
	{
		e.preventDefault(),
		($('body').hasClass('sidebar-collapsed') ? ($('html').addClass('overflow-hidden'), $('body').addClass('sidebar-expanded sidebar-hovered')) : null)
	})
	.on('mouseout', '#sidebar-wrapper', function(e)
	{
		e.preventDefault(),
		($('body').hasClass('sidebar-collapsed') ? ($('html').removeClass('overflow-hidden'), $('body').removeClass('sidebar-expanded sidebar-hovered')) : null)
	}),
	
	/**
	 * apply filter to map
	 */
	$('body').on('submit', '[role=map-filter]', function(e)
	{
		e.preventDefault();
		var action									= $(this).attr('action'),
			params									= $(this).serializeArray();
		
		/* otherwise, request new token */
		$.ajax
		({
			url: action + '?' + $.param(params),
			method: 'POST',
			context: this,
			data:
			{
				request: 'aksara'
			}
		})
		.done(function(response)
		{
			$(this).find('[role=map]').attr('data-json-file', response.callback),
			$(this).find('[role=map]').html(''),
			openlayers.render($(this).find('[role=map]'))
		})
	}),
	
	/**
	 * toggle fullscreen
	 */
	$('body').on('click touch', '.--toggle-full-screen', function(e)
	{
		e.preventDefault();
		
		if((document.fullScreenElement && document.fullScreenElement !== null) || (!document.mozFullScreen && !document.webkitIsFullScreen))
		{
			var success								= false;
			
			if(document.documentElement.requestFullScreen)
			{
				success								= true;
				
				document.documentElement.requestFullScreen()
			}
			else if(document.documentElement.mozRequestFullScreen)
			{
				success								= true;
				
				document.documentElement.mozRequestFullScreen()
			}
			else if(document.documentElement.webkitRequestFullScreen)
			{
				success								= true;
				
				document.documentElement.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)
			}
			
			if(success)
			{
				$(this).find('.mdi').removeClass('mdi-fullscreen').addClass('mdi-fullscreen-exit')
			}
		}
		else
		{
			var success								= false;
			
			if(document.cancelFullScreen)
			{
				success								= true;
				
				document.cancelFullScreen()
			}
			else if(document.mozCancelFullScreen)
			{
				success								= true;
				
				document.mozCancelFullScreen()
			}
			else if(document.webkitCancelFullScreen)
			{
				success								= true;
				
				document.webkitCancelFullScreen()
			}
			
			if(success)
			{
				$(this).find('.mdi').removeClass('mdi-fullscreen-exit').addClass('mdi-fullscreen')
			}
		}
	}),
	
	/**
	 * toggle filter
	 */
	$('body').on('click touch', '.side .btn-toggle', function(e)
	{
		e.preventDefault(),
		$(this).closest('.side').toggleClass('side-collapse')
	}),
	
	/**
	 * scroll to element
	 */
	$('body').on('click touch', '.scroll-to', function(e)
	{
		e.preventDefault(),
		$('html, body').animate
		({
			scrollTop: $($(this).attr('href')).offset().top - 60
		}, 500)
	}),
	
	/**
	 * initial of hyperlink that use XHR Request
	 */
	$('body').on('click touch', '.--xhr', function(e)
	{
		leave_page									= true,
		per_page									= 0;
		
		var _old_title								= $('.will-be-replace-with-title:first').text(),
			_old_icon								= $('#will-be-replace-with-icon:first').attr('class'),
			_old_btn_icon							= $(this).find('i.mdi').attr('class');
		
		if('_blank' != $(this).attr('target'))
		{
			/* prevent browser to take place as well */
			e.preventDefault(),
			
			xhr										= $.ajax
			({
				method: 'POST',
				context: this,
				url: $(this).attr('href'),
				data:
				{
					prefer: ($(this).attr('data-prefer-result') ? $(this).attr('data-prefer-result') : (UA === 'mobile' ? 'html' : null))
				},
				beforeSend: function(progress)
				{
					if(xhr)
					{
						xhr.abort()
					}
					
					/* check if progress need to be shown in the clicked element */
					if($(this).hasClass('show-progress'))
					{
						/* trigger icon to spin */
						if($(this).find('i.mdi').length)
						{
							$(this).find('i.mdi').removeAttr('class').addClass('mdi mdi-loading mdi-spin --mdi-working')
						}
					}
					else if(!$(this).hasClass('--prevent-modify'))
					{
						/* otherwise */
						$('.will-be-replace-with-title').text((phrase.loading ? phrase.loading : 'Loading...')),
						$('#will-be-replace-with-icon').removeAttr('class').addClass('mdi mdi-loading mdi-spin'),
						$('.nav-item').removeClass('active'),
						$('.dropdown-menu, .dropdown').removeClass('show')
					}
					
					if(!$(this).hasClass('--keep-modal'))
					{
						$('*').modal('hide')
					}
					
					$('*').tooltip('hide'),
					$('*').popover('hide'),
					$('body').css
					({
						cursor: 'wait'
					})
				},
				complete: function(progress)
				{
					if(!$(this).hasClass('--prevent-modify'))
					{
						$(this).parents('.nav-item').addClass('active'),
						$(this).closest('.sidebar-menu').find('ul').not($(this).parents()).removeClass('show').find('.nav-item').not($(this).parents()).removeClass('active'),
						$(this).closest('.sidebar-menu').find('.nav-item').not($(this).parents()).children('.nav-link').removeClass('is-expanded'),
						(UA === 'mobile' && $(this).closest('.dropdown').length ? $(this).parents('.dropdown').addClass('show') : null)
					}
					
					$('body').css
					({
						cursor: 'default'
					})
				},
				statusCode:
				{
					301: function(response, status, error)
					{
						$('*').modal('hide'),
						
						_response_template($(this), response, {icon: _old_icon, btn_icon: _old_btn_icon, title: _old_title})
					},
					403: function(response, status, error)
					{
						_response_template($(this), response, {icon: _old_icon, btn_icon: _old_btn_icon, title: _old_title})
					},
					404: function(response, status, error)
					{
						_response_template($(this), response, {icon: _old_icon, btn_icon: _old_btn_icon, title: _old_title})
					},
					500: function(response, status, error)
					{
						/* play sound */
						(config.action_sound ? fail.play() : null),
						
						/* throw log to console */
						$(config.content_wrapper).html
						(
							'<div class="container-fluid">' +
								'<div class="mt-3 mb-3 p-3 bg-dark rounded">' +
									'<pre class="text-warning mb-0" style="white-space:pre-wrap">' +
										(typeof response.responseJSON !== 'undefined' ? JSON.stringify(response.responseJSON, null, 4) : (error ? error : (phrase.consider_to_check_your_internet_connection ? phrase.consider_to_check_your_internet_connection : 'Consider to check your internet connection'))) +
									'</pre>' +
								'</div>' +
							'</div>'
						),
						throw_exception(response.status, (error ? error : (phrase.consider_to_check_your_internet_connection ? phrase.consider_to_check_your_internet_connection : 'Consider to check your internet connection'))),
						$('.will-be-replace-with-title').text((phrase.error ? phrase.error : 'Error')),
						$('#will-be-replace-with-icon').removeAttr('class').addClass('mdi mdi-alert-outline'),
						$('#description-collapse').removeClass('show'),
						$('*').modal('hide'),
						$('body').css
						({
							cursor: 'default'
						})
					}
				}
			})
			.done(function(response)
			{
				if(typeof response.responseJSON !== 'undefined')
				{
					response						= response.responseJSON;
				}
				
				if(typeof response.meta !== 'undefined' && typeof response.meta.popup !== 'undefined' && response.meta.popup)
				{
					/* check if progress is shown on the clicked element */
					if($(this).hasClass('show-progress'))
					{
						/* trigger icon to spin */
						if($(this).find('i.mdi').length)
						{
							$(this).find('i.mdi').removeAttr('class').addClass(_old_btn_icon)
						}
					}
					
					/* it will open the bootstrap 4 modal */
					$('*').modal('hide'),
					(response.target ? $('<a href="' + response.target + '" class="--xhr"></a>').appendTo('body').trigger('click').remove() : null),
					$(
						'<div class="modal" id="alert-modal" role="dialog" aria-labelledby="alert-modal-title" aria-hidden="true">' +
							'<div class="modal-dialog modal-dialog-centered ' + (typeof response.meta.modal_size !== 'undefined' ? response.meta.modal_size : '') + '" role="document">' +
								'<div class="modal-content">' +
									'<div class="modal-header">' +
										'<h5 class="modal-title" id="alert-modal-title">' +
											'<i class="' + (typeof response.meta.icon !== 'undefined' ? response.meta.icon : 'mdi mdi-information-outline') + '"></i>' +
											'<span class="modal-title-text">' +
												(typeof response.meta.title !== 'undefined' ? response.meta.title : (phrase.loading ? phrase.loading : 'Loading...')) +
											'</span>' +
										'</h5>' +
										'<button type="button" class="close" data-dismiss="modal" aria-label="' + (phrase.close ? phrase.close : 'Close') + '" style="margin-left: 0">' +
											'<span aria-hidden="true">&times;</span>' +
										'</button>' +
									'</div>' +
									'<div class="modal-body">' +
										(typeof response.meta.button !== 'undefined' ? '<a href="' + response.meta.button + '" class="btn btn-outline-secondary btn-sm btn-block" target="_blank">' +
											'<i class="mdi mdi-printer"></i>' +
											(phrase.print ? phrase.print : 'Print') +
										'</a><br /><br />' : '') +
										(typeof response.html !== 'undefined' ? response.html : '...') +
									'</div>' +
								'</div>' +
							'</div>' +
						'</div>'
					)
					.appendTo('body')
					.modal({backdrop:'static', keyboard: false}),
					
					(typeof response.reactivate !== 'undefined' ? _reactivate() : null)
				}
				else
				{
					if(typeof response._token !== 'undefined')
					{
						sessionStorage.setItem('_token', response._token)
					}
					
					_response_template($(this), response, {icon: _old_icon, btn_icon: _old_btn_icon, title: _old_title})
				}
			})
			.fail(function(response, status, error)
			{
				if(response.statusText == 'abort')
				{
					return;
				}
			})
		}
	}),
	
	/**
	 * submit and validate form
	 */
	$('body').on('submit', '.--validate-form', function(e)
	{
		/* prevent form resubmission when previous request is on progress */
		if($(this).find('button[type=submit]').hasClass('disabled')) return false;
		
		var formData								= new FormData(this);
		
		formData.append('_token', (sessionStorage.getItem('_token') ? sessionStorage.getItem('_token') : $('meta[name=_token]').attr('content')));
		
		/* prevent browser to take place as well */
		e.preventDefault(),
		
		$('[role=price]').each(function()
		{
			if(typeof $.fn.autoNumeric !== 'undefined')
			{
				formData.set($(this).attr('name'), $(this).autoNumeric('get'))
			}
		}),
		
		$.ajax
		({
			method: 'POST',
			context: this,
			url: $(this).attr('action'),
			data: formData,
			contentType: false,
			processData: false,
			beforeSend: function(progress)
			{
				/* focus to the submit button */
				$(this).find('button[type=submit]').focus().blur(),
				
				/* animate the submit button */
				$(this).find('button[type=submit]:not(.btn-link)').addClass('disabled').find('i.mdi').removeClass('mdi-check').addClass('mdi-loading mdi-spin'),
				
				/* remove all previous field checker */
				$('input, textarea, select').removeClass('is-invalid'),
				
				/* remove all previous field error message */
				$('.--validation-callback').removeClass('alert alert-warning mt-4 mb-3').html('')
			},
			complete: function(progress)
			{
				/* animate the submit button */
				$(this).find('button[type=submit]:not(.btn-link)').removeClass('disabled').find('i.mdi').removeClass('mdi-loading mdi-spin').addClass('mdi-check')
			},
			statusCode:
			{
				301: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					if(typeof response.redirect !== 'undefined' && response.redirect)
					{
						/* redirect to target */
						return window.location.replace(response.target)
					}
					
					/* play sound */
					(config.action_sound ? success.play() : null),
					
					/* close modal */
					$('.modal').modal('hide'),
					
					/* throw success messages */
					throw_exception(response.status, response.message);
					
					if($('.alias-table-index').length)
					{
						return $('.--btn-refresh').trigger('click')
					}
					
					/* or load target page instead */
					$.ajax
					({
						method: 'POST',
						context: this,
						url: response.target,
						data:
						{
							prefer: (UA === 'mobile' ? 'html' : null)
						},
						beforeSend: function(progress)
						{
							/* additional command if any */
						},
						complete: function(progress)
						{
							/* additional command if any */
						}
					})
					.done(function(new_response)
					{
						if(typeof new_response._token !== 'undefined')
						{
							sessionStorage.setItem('_token', new_response._token)
						}
						
						/* push to browser tab title */
						document.title	= (typeof new_response.meta !== 'undefined' && typeof new_response.meta.title !== 'undefined' ? new_response.meta.title : (phrase.error ? phrase.error : 'Error')) + ' | ' + config.app_name,
						
						/* store into browser history */
						history.pushState({path: response.target}, config.app_name, response.target),
						
						/* display the html result into page wrapper */
						$(config.content_wrapper).html((UA != 'mobile' && typeof new_response.results !== 'undefined' && typeof new_response.results.table_data !== 'undefined' ? component.table(new_response) : new_response.html)),
						
						/* replace title, icon and description */
						$('.will-be-replace-with-title').text(' ' + new_response.meta.title),
						$('#will-be-replace-with-icon').removeAttr('class').addClass(new_response.meta.icon),
						$('#refresh-btn').attr('href', new_response.current_page);
						if(new_response.meta.description)
						{
							$('#description-btn').removeClass('d-none'),
							$('#description-collapse').html(new_response.meta.description).addClass('show')
						}
						else
						{
							$('#description-btn').addClass('d-none'),
							$('#description-collapse').html('').removeClass('show')
						}
						
						/* add the breadcrumb */
						component.breadcrumb(new_response.breadcrumb),
						
						/* reactivate the plugin */
						_reactivate(true)
					})
				},
				400: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					/* form validation */
					var _focus_to					= null,
						_this						= $(this),
						_num						= '';
					
					if(!_this.find('.--validation-callback').length)
					{
						_this.prepend('<div class="--validation-callback mb-0"></div>')
					}
					
					/* play sound */
					(config.action_sound ? warning.play() : null),
					
					/* loop the exception response */
					$.each(response.message, function(key, val)
					{
						/* add the highlight class to the field */
						_this.find('#' + key.replace(/(:|\.|\[|\])/g,'\\$1') + '_input').addClass('is-invalid'),
						
						/* append the callback messages to field */
						$('<p class="mb-1 mt-1' + (_num ? ' border-top border-warning' : '') + '">' + val + '</p>').appendTo(_this.find('.--validation-callback'));
						
						_num++;
					}),
					
					$('.--validation-callback').addClass('alert alert-warning mt-4 mb-3'),
					
					/* scroll to the first error field */
					$($(_this.closest('.modal:visible').length ? '.modal' : 'html, body'))
					.animate
					({
						/* scroll, scroll */
						scrollTop: $('.--validation-callback').offset().top - (_this.closest('.modal').length ? 0 : $('.navbar.fixed-top').outerHeight(true))
					}, 200)
				},
				403: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					/* play sound */
					(config.action_sound ? warning.play() : null),
					
					/* throw warning messages */
					throw_exception(response.status, response.message)
				},
				404: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					/* play sound */
					(config.action_sound ? warning.play() : null),
					
					/* throw warning messages */
					throw_exception(response.status, response.message)
				},
				500: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					/* play sound */
					(config.action_sound ? fail.play() : null),
					
					/* ajax failed, it's commonly caused by the internal server error, throw error messages */
					throw_exception(500, (typeof response.message !== 'undefined' ? response.message : error))
				}
			}
		})
		.done(function(response)
		{
			if(typeof response.responseJSON !== 'undefined')
			{
				response							= response.responseJSON;
			}
			
			if(typeof response.meta !== 'undefined' && typeof response.meta.popup !== 'undefined' && response.meta.popup)
			{
				/* it will open the bootstrap 4 modal */
				$('*').modal('hide'),
				(response.target ? $('<a href="' + response.target + '" class="--xhr"></a>').appendTo('body').trigger('click').remove() : null),
				$(
					'<div class="modal" id="alert-modal" role="dialog" aria-labelledby="alert-modal-title" aria-hidden="true">' +
						'<div class="modal-dialog modal-dialog-centered ' + (typeof response.meta.modal_size !== 'undefined' ? response.meta.modal_size : '') + '" role="document">' +
							'<div class="modal-content">' +
								'<div class="modal-header">' +
									'<h5 class="modal-title" id="alert-modal-title">' +
										'<i class="' + (typeof response.meta.icon !== 'undefined' ? response.meta.icon : 'mdi mdi-information-outline') + '"></i>' +
										'<span class="modal-title-text">' +
											(typeof response.meta.title !== 'undefined' ? response.meta.title : (phrase.loading ? phrase.loading : 'Loading...')) +
										'</span>' +
									'</h5>' +
									'<button type="button" class="close" data-dismiss="modal" aria-label="' + (phrase.close ? phrase.close : 'Close') + '" style="margin-left: 0">' +
										'<span aria-hidden="true">&times;</span>' +
									'</button>' +
								'</div>' +
								'<div class="modal-body">' +
									(typeof response.meta.button !== 'undefined' ? '<a href="' + response.meta.button + '" class="btn btn-outline-secondary btn-sm btn-block" target="_blank">' +
										'<i class="mdi mdi-printer"></i>' +
										(phrase.print ? phrase.print : 'Print') +
									'</a><br /><br />' : '') +
									(typeof response.html !== 'undefined' ? response.html : '...') +
								'</div>' +
							'</div>' +
						'</div>' +
					'</div>'
				)
				.appendTo('body')
				.modal({backdrop:'static', keyboard: false}),
				
				(typeof response.reactivate !== 'undefined' ? _reactivate() : null)
			}
			else
			{
				/* play sound */
				(config.action_sound ? success.play() : null),
				
				/* throw success messages */
				throw_exception(response.status, response.message)
			}
		})
	}),
	
	/**
	 * on submit form method get, such a search form
	 */
	$('body').on('submit', '.--xhr-form', function(e)
	{
		e.preventDefault(),
		
		$('input[role=datepicker]', $(this)).each(function()
		{
			var date								= new Date($(this).val());
			
			$(this).val(date.toLocaleString('en', {year: 'numeric'}) + '-' + sprintf('%02d', date.toLocaleString('en', {month: 'numeric'})) + '-' + sprintf('%02d', date.toLocaleString('en', {day: 'numeric'})))
		});
		
		var formData								= new FormData(this),
			sandbox									= $.now();
		
		formData.append('request', '_token');
		
		if($(this).find('button[type=submit]:focus').attr('name') && $(this).find('button[type=submit]:focus').attr('value'))
		{
			formData.append($(this).find('button[type=submit]:focus').attr('name'), $(this).find('button[type=submit]:focus').attr('value'));
		}
		
		if('_blank' === $(this).attr('target') && UA !== 'mobile')
		{
			/* prepare the new window if it have a _blank target */
			window.open(config.base_url + 'pages/blank', 'placeholder_' + sandbox);
		}
		
		/* otherwise, request new token */
		$.ajax
		({
			url: $(this).attr('action'),
			method: 'POST',
			data: formData,
			context: this,
			contentType: false,
			processData: false
		})
		.done(function(response)
		{
			/* create and click the temporary link */
			if('_blank' === $(this).attr('target'))
			{
				/* reopen the new window placeholder with current url */
				if(UA !== 'mobile')
				{
					window.open(response.callback, 'placeholder_' + sandbox)
				}
				else
				{
					window.location.href			= response.callback;
				}
			}
			else
			{
				$('<a href="' + response.callback + '" class="--xhr"></a>').appendTo('body').trigger('click').remove()
			}
		})
	}),
	
	/**
	 * toggle button
	 */
	$('body').on('click touch', '.--toggle-btn', function(e)
	{
		e.preventDefault(),
		$.ajax
		({
			url: $(this).attr('href'),
			method: 'POST',
			context: this,
			beforeSend: function(progress)
			{
				$(this).find('i.mdi').removeAttr('class').addClass('mdi mdi-refresh mdi-spin'),
				$('*').tooltip('dispose')
			}
		})
		.done(function(response)
		{
			$(this).removeClass('btn-primary btn-secondary btn-success btn-danger btn-warning btn-info btn-light btn-dark').addClass(response.class),
			$(this).attr('title', response.label),
			$(this).attr('data-original-title', response.label),
			$(this).find('i.mdi').removeAttr('class').addClass(response.icon),
			$('[data-toggle=tooltip]').tooltip()
		})
	}),
	
	/**
	 * delete item after confirmed
	 */
	$('body').on('click touch', '.--delete-anyway', function(e)
	{
		/* prevent browser to take place as well */
		e.preventDefault(),
		
		/* generate the response data */
		$.ajax
		({
			url: $(this).attr('href'),
			method: 'POST',
			context: this,
			data:
			{
				batch: ($(this).attr('data-bulk-delete') ? 1 : 0),
				items: $('input[name^=bulk_delete]:checked').map(function(){return $(this).val()}).get()
			},
			beforeSend: function(progress)
			{
				$(this).find('i.mdi').removeAttr('class').addClass('mdi mdi-refresh mdi-spin')
			},
			complete: function(progress)
			{
				$(this).find('i.mdi').removeAttr('class').addClass('mdi mdi-check')
			},
			statusCode:
			{
				301: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					var token						= get_query_string('aksara', $(this).attr('href'));
					
					if($('#item__' + token).length)
					{
						$('#item__' + token).remove()
					}
					
					/* refresh table data */
					$('.--btn-refresh').trigger('click'),
					
					/* hide the confirmation modal */
					$('*').modal('hide'),
					
					/* play sound */
					(config.action_sound ? success.play() : null),
					
					/* throw success messages */
					throw_exception(response.status, (typeof response.message !== 'undefined' ? response.message : response.statusText))
				},
				403: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					/* play sound */
					(config.action_sound ? warning.play() : null),
					
					/* throw success messages */
					throw_exception(response.status, (typeof response.message !== 'undefined' ? response.message : response.statusText))
				},
				404: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					/* play sound */
					(config.action_sound ? warning.play() : null),
					
					/* throw success messages */
					throw_exception(response.status, (typeof response.message !== 'undefined' ? response.message : response.statusText))
				},
				500: function(response, status, error)
				{
					if(response && typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					/* play sound */
					(config.action_sound ? fail.play() : null),
					
					/* throw success messages */
					throw_exception(response.status, (typeof response.message !== 'undefined' ? response.message : response.statusText))
				}
			}
		})
		.done(function(response)
		{
			/* hide the confirmation modal */
			$('*').modal('hide'),
			
			/* play sound */
			(config.action_sound ? success.play() : null),
			
			/* throw success messages */
			throw_exception(response.status, response.message)
		})
		.fail(function(response, status, error)
		{
			if(response.statusText == 'abort')
			{
				return;
			}
		})
	}),
	
	/**
	 * on click expandable
	 */
	$('body').on('click touch', '.--expandable', function(e)
	{
		/* prevent browser to take place as well */
		e.preventDefault(),
		($(this).find('.mdi').hasClass('mdi-arrow-expand') ? ($(this).attr('data-original-title', (phrase.collapse ? phrase.collapse : 'Collapse')), $(this).find('.mdi').removeClass('mdi-arrow-expand').addClass('mdi-arrow-collapse')) : ($(this).attr('data-original-title', (phrase.expand ? phrase.expand : 'Expand')), $(this).find('.mdi').removeClass('mdi-arrow-collapse').addClass('mdi-arrow-expand'))),
		$('[data-toggle=tooltip]').tooltip('dispose'),
		$('[data-toggle=tooltip]').tooltip(),
		$('body').toggleClass('content-expanded'),
		$('.alias-table-index').height(function (index, height)
		{
			return (($('#breadcrumb-wrapper:visible').length ? height - $('#breadcrumb-wrapper:visible').outerHeight(true) : height + $('#breadcrumb-wrapper').outerHeight(true)))
		})
	}),
	
	/**
	 * on click removable
	 */
	$('body').on('click touch', '.--removable', function(e)
	{
		/* prevent browser to take place as well */
		e.preventDefault()
	}),
	
	/**
	 * move element up / down
	 */
	$('body').on('click touch', '.--move-up', function(e)
	{
		/* move element down */
		e.preventDefault(),
		$(this).closest($(this).attr('data-element')).insertBefore($(this).closest($(this).attr('data-element')).prev($(this).attr('data-element')))
	})
	.on('click touch', '.--move-down', function(e)
	{
		/* move element up */
		e.preventDefault(),
		$(this).closest($(this).attr('data-element')).insertAfter($(this).closest($(this).attr('data-element')).next($(this).attr('data-element')))
	}),
	
	/**
	 * on bootstrap modal hidden
	 */
	$('body').on('shown.bs.modal', '.modal', function(e)
	{
		/* fix the scrollbar for creating duplicate object */
		$('html').addClass('fix-scrollbar')
	})
	.on('shown.bs.modal', '.modal:not(.dragless)', function(e)
	{
		var _this									= $(this).find('.modal-dialog');
		
		/* apply jquery-ui draggable */
		require.js([config.asset_url + 'draggable/jquery-ui.draggable.min.js'], function()
		{
			_this.draggable
			({
				cursor: 'move',
				handle: '.modal-header'
			}),
			$('.ui-draggable-handle').css('cursor', 'move')
		})
		/* end applying jquery-ui draggable */
		
	}),
	
	/**
	 * on bootstrap modal hidden
	 */
	$('body').on('hidden.bs.modal', '.modal', function(e)
	{
		$('html').removeClass('fix-scrollbar'),
		$('.dcalendarpicker, #sortableListsBase, .note-popover').remove();
		if ($('.modal:visible').length)
		{
			$('html').addClass('fix-scrollbar'),
			$('body').addClass('modal-open');
		}
		if(!$(this).hasClass('--prevent-remove'))
		{
			$(this).remove()
		}
	}),
	
	/**
	 * on navbar collapse
	 */
	$('body').on('shown.bs.collapse', '.navbar-collapse', function(e)
	{
		($('html').addClass('overflow-hidden'), $('body').addClass('sidebar-expanded').removeClass('sidebar-collapsing sidebar-collapsed'), $('.navbar').first().removeClass('bg-transparent'))
	})
	.on('show.bs.collapse', '.navbar-collapse', function(e)
	{
		$('body').addClass('sidebar-collapsing')
	})
	.on('hidden.bs.collapse', '.navbar-collapse', function(e)
	{
		($('html').removeClass('overflow-hidden'), $('body').removeClass('sidebar-collapsing sidebar-expanded').addClass('sidebar-collapsed')),
		($('.leading').visible(true) ? $('.navbar').first().addClass('bg-transparent') : '')
	})
	.on('hide.bs.collapse', '.navbar-collapse', function(e)
	{
		$('body').addClass('sidebar-collapsing')
	}),
	
	/**
	 * on bootstrap collapse shown / collapsed
	 */
	$('body').on('hide.bs.collapse show.bs.collapse', '#description-collapse', function(e)
	{
		($('.alias-table-index').length ? $('body').css('overflow-y', 'hidden') : null)
	}),
	$('body').on('hidden.bs.collapse', '#description-collapse', function(e)
	{
		$('.alias-table-index').animate({height: $(window).outerHeight(true) - (($('#breadcrumb-wrapper').length ? $('#breadcrumb-wrapper').outerHeight(true) : ($('.navbar').length ? $('.navbar').outerHeight(true) : 0)) + ($('.alias-table-header').length ? $('.alias-table-header').outerHeight(true) : 0) + ($('.alias-description-collapse:visible').length ? $('.alias-description-collapse').outerHeight(true) : 0) + ($('.alias-table-toolbar').length ? $('.alias-table-toolbar').outerHeight(true) : 0) + ($('.alias-pagination').length ? $('.alias-pagination').outerHeight(true) : 0) + ($('.alias-announcements-ticker').length ? 30 : 0))}, {complete:function(){$('body').css('overflow-y', 'auto')}})
	})
	.on('shown.bs.collapse', '#description-collapse', function(e)
	{
		$('.alias-table-index').animate({height: $(window).outerHeight(true) - (($('#breadcrumb-wrapper').length ? $('#breadcrumb-wrapper').outerHeight(true) : ($('.navbar').length ? $('.navbar').outerHeight(true) : 0)) + ($('.alias-table-header').length ? $('.alias-table-header').outerHeight(true) : 0) + ($('.alias-description-collapse:visible').length ? $('.alias-description-collapse').outerHeight(true) : 0) + ($('.alias-table-toolbar').length ? $('.alias-table-toolbar').outerHeight(true) : 0) + ($('.alias-pagination').length ? $('.alias-pagination').outerHeight(true) : 0) + ($('.alias-announcements-ticker').length ? 30 : 0))}, {complete:function(){$('body').css('overflow-y', 'auto')}})
	}),
	
	/**
	 * sidebar for mobile device
	 */
	$('body').on('click touch', '[data-toggle=sidebar]', function(e)
	{
		$('.navbar-collapse').collapse('hide'),
		($('body').hasClass('sidebar-collapsed') ? ($('body').addClass('sidebar-expanded').removeClass('sidebar-collapsed'), (UA === 'mobile' ? $('html').addClass('overflow-hidden') : null)) : ($('body').hasClass('sidebar-expanded') ? ($('body').removeClass('sidebar-expanded').addClass('sidebar-collapsed'), $('html').removeClass('overflow-hidden')) : (UA === 'mobile' ? ($('body').addClass('sidebar-expanded'), $('html').addClass('overflow-hidden')) : ($('body').addClass('sidebar-collapsed')))))
	}),
	
	/**
	 * expand and collapse for sidebar menu
	 */
	$('body').on('click touch', '[data-toggle=expand-collapse]', function(e)
	{
		/* prevent browser to take place as well */
		e.preventDefault(),
		$(this).closest('li').siblings().find('[data-toggle=expand-collapse]').removeClass('is-expanded'),
		$(this).closest('li').siblings().find('ul').collapse('hide');
		if($(this).next('ul').hasClass('show'))
		{
			$(this).removeClass('is-expanded'),
			$(this).next('ul').collapse('hide')
		}
		else
		{
			$(this).addClass('is-expanded'),
			$(this).next('ul').collapse('show')
		}
	}),
	
	/**
	 * dependent dropdown
	 */
	$('body').on('change', 'select[data-next]', function(e)
	{
		e.preventDefault(),
		$.ajax
		({
			url: $(this).attr('data-next'),
			method: 'POST',
			data:
			{
				trigger: 'dropdown',
				value: $(this).val()
			},
			context: this
		})
		.done(function(response)
		{
			$(this).closest('form').find('select[name=' + response.selector + ']').html(response.html).attr('disabled', false)
		})
	}),
	
	/**
	 * preview image before upload
	 */
	$('body').on('change', '[role=image-upload]', function(e)
	{
		/* prevent browser to take place as well */
		e.preventDefault();
		var t							= $(this);
		if(this.files && this.files[0])
		{
			var o									= new FileReader;
			o.onload								= function(e)
			{
				if(t.hasClass("multiple"))
				{
					t.parents(".fileupload").clone().appendTo(t.parents(".multiple-upload"));
				}
				t.parents(".btn-file").find(".upload_preview").attr("src", e.target.result);
			},
			o.readAsDataURL(this.files[0])
		}
	}),
	
	/**
	 * checklist all
	 */
	$('body').on('change', '[role=checker]', function(e)
	{
		var _parent									= $(this).attr('data-parent');
		if($(this).is(':checked'))
		{
			$(this).closest(_parent).find(':checkbox.checker-children').prop('checked', true),
			$('[data-bulk-delete=true]').prev('.btn').removeClass('rounded-right'),
			$('[data-bulk-delete=true]').removeClass('d-none disabled')
		}
		else
		{
			$(this).closest(_parent).find(':checkbox.checker-children').prop('checked', false),
			$('[data-bulk-delete=true]').prev('.btn').addClass('rounded-right'),
			$('[data-bulk-delete=true]').addClass('d-none disabled')
		}
	})
	.on('change', '.checker-children', function(e)
	{
		var _parent									= $(this).parents('div').find('[role=checker]').attr('data-parent');
		if($(this).closest(_parent).find('input.checker-children').is(':checked') > 0)
		{
			$(this).closest(_parent).find('[role=checker]').prop('checked', true),
			$('[data-bulk-delete=true]').prev('.btn').removeClass('rounded-right'),
			$('[data-bulk-delete=true]').removeClass('d-none disabled')
		}
		else
		{
			$(this).closest(_parent).find('[role=checker]').prop('checked', false),
			$('[data-bulk-delete=true]').prev('.btn').addClass('rounded-right'),
			$('[data-bulk-delete=true]').addClass('d-none disabled')
		}
	}),
	
	/**
	 * attributes type field, add attribute
	 */
	$('body').on('click touch', '[role=add-attribute]', function(e)
	{
		e.preventDefault(),
		$('<div class="row mb-1"><div class="col-4 pr-0"><input type="text" name="' + $(this).attr('data-label') + '" class="form-control form-control-sm" placeholder="' + $(this).attr('data-label-placeholder') + '" autocomplete="off" /></div><div class="col-5 pr-0"><input type="text" name="' + $(this).attr('data-value') + '" class="form-control form-control-sm" placeholder="' + $(this).attr('data-value-placeholder') + '" autocomplete="off" /></div><div class="col-3"><div class="btn-group btn-group-sm float-right"><a href="javascript:void(0)" class="btn btn-secondary --move-up" data-element=".row" data-toggle="tooltip" title="' + (phrase.move_up ? phrase.move_up : 'Move up') + '"><i class="mdi mdi-arrow-collapse-up"></i></a><a href="javascript:void(0)" class="btn btn-secondary --move-down" data-element=".row" data-toggle="tooltip" title="' + (phrase.move_down ? phrase.move_down : 'Move down') + '"><i class="mdi mdi-arrow-collapse-down"></i></a><a href="javascript:void(0)" class="btn btn-secondary" role="remove-attribute" data-element=".row"><i class="mdi mdi-window-close" data-toggle="tooltip" title="' + (phrase.remove ? phrase.remove : 'Remove') + '"></i></a></div></div></div>').appendTo($(this).closest('.attribute-input').find('.attribute-input-body')),
		$('[data-toggle=tooltip]').tooltip()
	}),
	
	/**
	 * attributes type field, remove existing
	 */
	$('body').on('click touch', '[role=remove-attribute]', function(e)
	{
		e.preventDefault(),
		$(this).closest($(this).attr('data-element')).fadeOut(200, function()
		{
			$(this).remove()
		})
	}),
	
	/**
	 * faq type field, add faq
	 */
	$('body').on('click touch', '[role=add-faq]', function(e)
	{
		e.preventDefault(),
		$('<div class="card mb-3"><div class="card-header p-2"><div class="input-group input-group-sm"><input type="text" name="' + $(this).attr('data-field') + '[question][]" class="form-control" placeholder="' + (phrase.question ? phrase.question : 'Question') + '" id="' + $(this).attr('data-field') + '_input" /><div class="input-group-append"><a href="javascript:void(0)" class="btn btn-secondary --move-up" data-element=".card" data-toggle="tooltip" title="' + (phrase.move_up ? phrase.move_up : 'Move up') + '"><i class="mdi mdi-arrow-collapse-up"></i></a><a href="javascript:void(0)" class="btn btn-secondary --move-down" data-element=".card" data-toggle="tooltip" title="' + (phrase.move_down ? phrase.move_down : 'Move down') + '"><i class="mdi mdi-arrow-collapse-down"></i></a><a href="javascript:void(0)" class="btn btn-secondary" role="remove-carousel" data-element=".card"><i class="mdi mdi-window-close" data-toggle="tooltip" title="' + (phrase.remove ? phrase.remove : 'Remove') + '"></i></a></div></div></div><div class="card-body p-2"><textarea name="' + $(this).attr('data-field') + '[answer][]" class="form-control" role="wysiwyg" placeholder="' + (phrase.detailed_answer_for_above_question ? phrase.detailed_answer_for_above_question : 'Detailed answer for above question') + '" id="' + $(this).attr('data-field') + '_input" rows="1"></textarea></div></div>').insertBefore($(this)),
		$('[data-toggle=tooltip]').tooltip(),
		$('[role=wysiwyg]').each(function()
		{
			$(this).summernote
			({
				airMode: (UA == 'mobile' ? true : false),
				dialogsInBody: true,
				dialogsFade: false,
				disableDragAndDrop: true,
				toolbar:
				[
					['style', ['bold', 'italic', 'underline']],
					['para', ['ul', 'ol', 'paragraph']],
					(UA != 'mobile' ? ['insert', ['link', 'picture']] : null),
					['clear']
				],
				placeholder: ($(this).attr('placeholder') ? $(this).attr('placeholder') : (phrase.your_content_goes_here ? phrase.your_content_goes_here : 'Your content goes here...')),
				disableResizeEditor: true,
				callbacks:
				{
					onImageUpload: function(image)
					{
						var data					= new FormData();
						data.append("image", image[0]);
						$.ajax
						({
							url: config.base_url + 'xhr/summernote/upload',
							contentType: false,
							processData: false,
							data: data,
							method: 'POST',
							beforeSend: function()
							{
							},
							success: function(response)
							{
								_this.summernote('insertImage', response.source)
							}
						})
					},
					onMediaDelete: function(image)
					{
						$.ajax
						({
							url: config.base_url + 'xhr/summernote/delete',
							method: 'POST',
							data:
							{
								source: image[0].src
							}
						})
					}
				}
			})
		})
	}),
	
	/**
	 * faq type field, remove existing
	 */
	$('body').on('click touch', '[role=remove-faq]', function(e)
	{
		e.preventDefault(),
		$(this).closest($(this).attr('data-element')).fadeOut(200, function()
		{
			$(this).remove()
		})
	}),
	
	/**
	 * step type field, add step
	 */
	$('body').on('click touch', '[role=add-step]', function(e)
	{
		e.preventDefault(),
		$('<div class="card mb-3"><div class="card-body p-2 relative"><div class="btn-group btn-group-xs absolute" style="top: 5px; right: 10px; z-index: 1"><a href="javascript:void(0)" class="btn btn-secondary --move-up" data-element=".card" data-toggle="tooltip" title="' + (phrase.move_up ? phrase.move_up : 'Move up') + '"><i class="mdi mdi-arrow-collapse-up"></i></a><a href="javascript:void(0)" class="btn btn-secondary --move-down" data-element=".card" data-toggle="tooltip" title="' + (phrase.move_down ? phrase.move_down : 'Move down') + '"><i class="mdi mdi-arrow-collapse-down"></i></a><a href="javascript:void(0)" class="btn btn-secondary" role="remove-carousel" data-element=".card"><i class="mdi mdi-window-close" data-toggle="tooltip" title="' + (phrase.remove ? phrase.remove : 'Remove') + '"></i></a></div><textarea name="' + $(this).attr('data-field') + '[answer][]" class="form-control" role="wysiwyg" placeholder="' + (phrase.add_step ? phrase.add_step : 'Add step') + '" id="' + $(this).attr('data-field') + '_input" rows="1"></textarea></div></div>').insertBefore($(this)),
		$('[data-toggle=tooltip]').tooltip(),
		$('[role=wysiwyg]').each(function()
		{
			$(this).summernote
			({
				airMode: (UA == 'mobile' ? true : false),
				dialogsInBody: true,
				dialogsFade: false,
				disableDragAndDrop: true,
				toolbar:
				[
					['style', ['bold', 'italic', 'underline']],
					['para', ['ul', 'ol', 'paragraph']],
					(UA != 'mobile' ? ['insert', ['link', 'picture']] : null),
					['clear']
				],
				placeholder: ($(this).attr('placeholder') ? $(this).attr('placeholder') : (phrase.your_content_goes_here ? phrase.your_content_goes_here : 'Your content goes here...')),
				disableResizeEditor: true,
				callbacks:
				{
					onImageUpload: function(image)
					{
						var data					= new FormData();
						data.append("image", image[0]);
						$.ajax
						({
							url: config.base_url + 'xhr/summernote/upload',
							contentType: false,
							processData: false,
							data: data,
							method: 'POST',
							beforeSend: function()
							{
							},
							success: function(response)
							{
								_this.summernote('insertImage', response.source)
							}
						})
					},
					onMediaDelete: function(image)
					{
						$.ajax
						({
							url: config.base_url + 'xhr/summernote/delete',
							method: 'POST',
							data:
							{
								source: image[0].src
							}
						})
					}
				}
			})
		})
	}),
	
	/**
	 * step type field, remove existing
	 */
	$('body').on('click touch', '[role=remove-step]', function(e)
	{
		e.preventDefault(),
		$(this).closest($(this).attr('data-element')).fadeOut(200, function()
		{
			$(this).remove()
		})
	}),
	
	/**
	 * carousel type field, add carousel
	 */
	$('body').on('click touch', '[role=add-carousel]', function(e)
	{
		e.preventDefault(),
		$('<div class="card mb-3"><div class="card-body"><div class="row"><div class="col-md-6"><div class="form-group"><label class="text-muted">' + (phrase.background ? phrase.background : 'Background') + '</label><div data-provides="fileupload" class="fileupload fileupload-new"><span class="btn btn-light btn-file btn-block"><input type="file" name="' + $(this).attr('data-field') + '[background][]" accept="images/*" role="image-upload" id="' + $(this).attr('data-field') + '_input" /><div class="fileupload-new text-center"><img class="img-fluid upload_preview rounded" src="' + $(this).attr('data-image-placeholder') + '" alt="" /></div></span></div></div></div><div class="col-md-6"><div class="form-group"><label class="text-muted">' + (phrase.thumbnail ? phrase.thumbnail : 'Thumbnail') + '</label><div data-provides="fileupload" class="fileupload fileupload-new"><span class="btn btn-light btn-file btn-block"><input type="file" name="' + $(this).attr('data-field') + '[thumbnail][]" accept="images/*" role="image-upload" id="' + $(this).attr('data-field') + '_input" /><div class="fileupload-new text-center"><img class="img-fluid upload_preview rounded" src="' + $(this).attr('data-image-placeholder') + '" alt="" /></div></span></div></div></div></div><div class="form-group"><input type="text" name="' + $(this).attr('data-field') + '[title][]" class="form-control" placeholder="' + (phrase.title ? phrase.title : 'Title') + '" id="' + $(this).attr('data-field') + '_input" /></div><div class="form-group"><textarea name="' + $(this).attr('data-field') + '[description][]" class="form-control" placeholder="' + (phrase.description ? phrase.description : 'Description') + '" id="' + $(this).attr('data-field') + '_input" rows="1"></textarea></div><div class="row"><div class="col-md-6"><div class="form-group"><input type="text" name="' + $(this).attr('data-field') + '[link][]" class="form-control" placeholder="' + (phrase.target_url ? phrase.target_url : 'Target URL') + '" id="' + $(this).attr('data-field') + '_input" /></div></div><div class="col-md-6"><div class="form-group"><input type="text" name="' + $(this).attr('data-field') + '[label][]" class="form-control" placeholder="' + (phrase.button_label ? phrase.button_label : 'Button Label') + '" id="' + $(this).attr('data-field') + '_input" /></div></div></div></div><div class="card-footer"><div class="btn-group btn-group-xs"><a href="javascript:void(0)" class="btn btn-secondary --move-up" data-element=".card" data-toggle="tooltip" title="' + (phrase.move_up ? phrase.move_up : 'Move up') + '"><i class="mdi mdi-arrow-collapse-up"></i></a><a href="javascript:void(0)" class="btn btn-secondary --move-down" data-element=".card" data-toggle="tooltip" title="' + (phrase.move_down ? phrase.move_down : 'Move down') + '"><i class="mdi mdi-arrow-collapse-down"></i></a><a href="javascript:void(0)" class="btn btn-secondary" role="remove-carousel" data-element=".card"><i class="mdi mdi-window-close" data-toggle="tooltip" title="' + (phrase.remove ? phrase.remove : 'Remove') + '"></i></a></div></div></div>').insertBefore($(this)),
		$('[data-toggle=tooltip]').tooltip()
	}),
	
	/**
	 * carousel type field, remove existing
	 */
	$('body').on('click touch', '[role=remove-carousel]', function(e)
	{
		e.preventDefault(),
		$(this).closest($(this).attr('data-element')).fadeOut(200, function()
		{
			$(this).remove()
		})
	}),
	
	/**
	 * open create and update form in modal
	 */
	$('body').on('click touch', '.--modal', function(e)
	{
		e.preventDefault(),
		$(this).blur();
		
		if(UA == 'mobile')
		{
			$('<a href="' + $(this).attr('href') + '" class="--xhr"></a>').appendTo('body').trigger('click').remove()
		}
		else
		{
			return component.modal($(this))
		}
	}),
	
	/**
	 * open create and update form in modal
	 */
	$('body').on('click touch', '.--open-modal-form', function(e)
	{
		e.preventDefault(),
		$(this).blur();
		return component.form($(this))
	}),
	
	/**
	 * open read in modal
	 */
	$('body').on('click touch', '.--open-modal-read', function(e)
	{
		e.preventDefault(),
		$(this).blur();
		return component.view($(this))
	}),
	
	/**
	 * open option
	 */
	$('body').on('click touch', '.--open-item-option', function(e)
	{
		e.preventDefault(),
		$(this).blur();
		return component.option($(this))
	}),
	
	/**
	 * open delete confirmation
	 */
	$('body').on('click touch', '.--open-delete-confirm', function(e)
	{
		e.preventDefault(),
		$(this).blur();
		return component.delete($(this))
	}),
	
	/**
	 * remove previous dom when user start typing in the field
	 */
	$('body').on('change keyup', 'input, textarea, select', function(e)
	{
		/* remove highlighter class in the field */
		$(this).removeClass('is-invalid'),
		
		/* remove error messages that appended in previous request */
		$(this).closest('.form-group').find('.invalid-feedback').remove()
	}),
	
	/**
	 * instant form submit if textarea entered
	 */
	$('body').on('keydown keyup', 'textarea.--instant-submit', function(e)
	{
		if(UA != 'mobile')
		{
			if(e.which == 13 && !e.shiftKey)
			{
				e.preventDefault(),
				$(this).blur(),
				$(this).closest('form').submit()
			}
		}
		else
		{
			if($(this).val())
			{
				$(this).next('button').removeClass('d-none');
			}
			else
			{
				$(this).next('button').addClass('d-none');
			}
		}
	}),
	
	/**
	 * on click remove exception
	 */
	$('body').on('click touch', '.alert.exception', function(e)
	{
		/* prevent browser to take place as well */
		e.preventDefault(),
		$(this).fadeOut(200, function()
		{
			$(this).remove()
		})
	}),
	
	/**
	 * override bootstrap dropdown-menu
	 */
	$('body').on('click', '.dropdown-menu a.dropdown-toggle', function(e)
	{
		if(!$(this).next().hasClass('show'))
		{
			$(this).parents('.dropdown-menu').first().find('.show').removeClass('show')
		}
		$(this).next('.dropdown-menu').toggleClass('show'),
		$(this).parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', function(e)
		{
			$('.dropdown-submenu .show').removeClass('show');
		});
		return false
	})
});

For more information send a message to info at phpclasses dot org.