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

Recommend this page to a friend!
  Classes of Aby Dahana  >  Aksara  >  public/assets/local/js/component.min.js  >  Download  
File: public/assets/local/js/component.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: 100,917 bytes
 

Contents

Class file image Download
/**
 * Component Module
 *
 * This component is translated from the context that running in PHP, the return data
 * of rest server were JSON Object. Style of writing is valid with ES5, so it must be
 * compatible with outdated browser.
 *
 * @author			Aby Dahana
 * @profile			abydahana.github.io
 *
 * Property of Aksara Laboratory
 * www.aksaracms.com
 */
var UA												= ($(window).outerWidth() < 1024 ? 'mobile' : 'desktop'),
	component										= {
	/**
	 * CRUD: table list
	 */
	table: function(response)
	{
		var	primary									= {},
			extra_toolbar							= '',
			fields									= '',
			search_columns							= '',
			items									= '',
			colspan									= ($.inArray('delete', response.unset_action) === -1 ? 2 : 1);
		
		/**
		 * Add the extra toolbar / option button if any
		 */
		if(response.results.extra_action.toolbar)
		{
			/* loop, the jQuery is required */
			$.each(response.results.extra_action.toolbar, function(key, val)
			{
				/* toolbar button is available */
				extra_toolbar						+= '<a href="' + go_to(val.url, val.parameter) + '" class="btn btn-sm ' + (val.class ? val.class : 'btn-default ajax') + '"' + (val.new_tab && val.new_tab == 1 ? ' target="_blank"' : null) + '><i class="' + (val.icon ? val.icon : 'mdi mdi-link') + '"></i> ' + val.label + '</a>';
			})
		}
		
		/**
		 * Check the permission of module include create, read, update, delete and export
		 */
		if(response.results.extra_action.option || $.inArray('read', response.results.unset_action) === -1 || $.inArray('update', response.results.unset_action) === -1 || $.inArray('delete', response.results.unset_action) === -1 || $.inArray('print', response.results.unset_action) === -1 || $.inArray('pdf', response.results.unset_action) === -1)
		{
			/* check if delete is allowed */
			if($.inArray('delete', response.results.unset_action) === -1)
			{
				/* delete action is allowed, create checkbox to add bulk delete */
				fields								+= '<th width="1" class="border-top-0"><input type="checkbox" role="checker" data-parent="table" class="bulk-delete" /></th>';
			}
			
			/* some of action is allowed, add column to table row */
			fields									+= '<th width="1" class="border-top-0">' + (phrase.options ? phrase.options : 'Options') + '</th>';
		}
		
		/**
		 * loop to initialize the list of fields, jQuery is required
		 */
		if(typeof response.results.columns !== 'undefined')
		{
			$.each(response.results.columns, function(key, val)
			{
				/* add new field to list */
				var parameter						= $.extend({}, {'aksara': val.aksara}, response.query_string, {'order': val.field, 'sort': val.sort});
				
				search_columns						+= '<option value="' + val.field + '"' + (val.field == get_query_string('column') ? ' selected' : null) + '>' + val.label + '</option>';
				fields								+= '<th class="border-top-0' + ('right' == val['align'] ? ' text-right' : '') + '"><a href="' + go_to('', parameter) + '" class="--xhr' + (key == get_query_string('order') ? ' text-primary' : ' text-default') + '"><i class="mdi mdi-sort-' + (key == get_query_string('order') && 'asc' == get_query_string('sort') ? 'ascending' : 'descending') + ' float-right' + (key == get_query_string('order') ? ' text-primary' : ' text-muted') + '"></i> ' + val['label'] + '</a></th>';
				colspan++;
			})
		}
		
		if(typeof response.total !== 'undefined' && response.total && typeof response.results.table_data !== 'undefined')
		{
			/**
			 * loop to initialize the item list, jQuery is required
			 */
			$.each(response.results.table_data, function(key, val)
			{
				/* add new item to list */
				var columns							= '',
					options							= '',
					extra_option					= '',
					extra_dropdown					= '',
					reading							= true,
					updating						= true,
					deleting						= true;
					
				if(typeof response.results.extra_action.option[key] !== 'undefined')
				{
					$.each(response.results.extra_action.option[key], function(extra_key, extra_val)
					{
						var _class					= null,
							label					= null,
							icon					= null;
							
						if(typeof extra_val.new_tab === 'object')
						{
							if(typeof extra_val.new_tab.restrict !== 'undefined')
							{
								var id				= Object.keys(extra_val.new_tab.restrict)[0];
								
								if($.inArray(val[id].original, extra_val.new_tab.restrict[id]) !== -1) return;
							}
							else if(typeof extra_val.new_tab.key !== 'undefined' && typeof extra_val.new_tab.value !== 'undefined' && typeof val[extra_val.new_tab.key] !== 'undefined' && typeof val[extra_val.new_tab.key]['original'] !== 'undefined' && val[extra_val.new_tab.key]['original'] == extra_val.new_tab.value)
							{
								_class				= (typeof extra_val.new_tab.class !== 'undefined' ? extra_val.new_tab.class : null);
								label				= (typeof extra_val.new_tab.label !== 'undefined' ? extra_val.new_tab.label : null);
								icon				= (typeof extra_val.new_tab.icon !== 'undefined' ? extra_val.new_tab.icon : null);
							}
						}
						
						/* extra option found, add to item */
						extra_option				+= '<a href="' + go_to(extra_val.url, extra_val.parameter) + '" class="btn btn-xs ' + (_class ? _class : (extra_val.class ? extra_val.class : 'btn-secondary --xhr')) + '" data-toggle="tooltip" title="' + (label ? label : extra_val.label) + '"' + (extra_val.new_tab && extra_val.new_tab == 1 ? ' target="_blank"' : '') + '><i class="' + (icon ? icon : (extra_val.icon ? extra_val.icon : 'mdi mdi-link')) + '"></i> </a>';
					})
				}
				
				if(typeof response.results.extra_action.dropdown[key] !== 'undefined')
				{
					$.each(response.results.extra_action.dropdown[key], function(extra_key, extra_val)
					{
						/* extra dropdown found, add to item */
						extra_dropdown				+= '<a href="' + go_to(extra_val.url, extra_val.parameter) + '" class="list-group-item pt-1 pr-0 pb-1 pl-0 ' + (extra_val.class ? extra_val.class : '--xhr') + '" data-toggle="tooltip" title="' + extra_val.label + '"' + (extra_val.new_tab ? ' target="_blank"' : '') + '><i class="' + (extra_val.icon ? extra_val.icon : 'mdi mdi-link') + '"></i> ' + extra_val.label + '</a>';
					})
				}
				
				/**
				 * loop the row to get formatted columns
				 */
				var primary_key						= {},
					bulk							= {};
					
				$.each(val, function(field, params)
				{
					/* check the primary key */
					if(params.primary)
					{
						/* primary key found, use it as primary id */
						primary_key[field]			= params.primary;
						bulk[field]					= params.primary;
						
						/* check if the item row is individually restricted */
						if(typeof response.results.unset_read[field] !== 'undefined' && $.isArray(response.results.unset_read[field]) && $.inArray(params.original, response.results.unset_read[field].toString()) !== -1)
						{
							/* unset read */
							reading					= false;
						}
						
						if(typeof response.results.unset_update[field] !== 'undefined' && $.isArray(response.results.unset_update[field]) && $.inArray(params.original, response.results.unset_update[field].toString()) !== -1)
						{
							/* unset update */
							updating				= false;
						}
						
						if(typeof response.results.unset_delete[field] !== 'undefined' && $.isArray(response.results.unset_delete[field]) && $.inArray(params.original, response.results.unset_delete[field].toString()) !== -1)
						{
							/* unset delete */
							deleting				= false;
						}
					}
					
					/* continue if column is marked as unset / hidden */
					if(params.hidden) return;
					
					/* push to columns to displayed in next step */
					columns							+= '<td id="__c_' + field + '">' + params.content + '</td>';
				});
				
				/* check if there are option button */
				options								= ($.inArray('delete', response.results.unset_action) === -1 ? '<td>' + (deleting ? '<input type="checkbox" name="bulk_delete[]" class="checker-children" value="' + htmlspecialchars(JSON.stringify(bulk)) + '" />' : '') + '</td>' : '') +
				(response.results.extra_action.option || $.inArray('read', response.results.unset_action) === -1 || $.inArray('update', response.results.unset_action) === -1 || $.inArray('print', response.results.unset_action) === -1 || $.inArray('pdf', response.results.unset_action) === -1 ?
				'<td>' +
					'<div class="btn-group">' +
						
						/* update button if action is allowed */
						(reading && $.inArray('read', response.results.unset_action) === -1 ?
						'<a href="' + go_to('read', response.results.query_string[key]) + '" class="btn btn-primary btn-xs --open-modal-read" data-toggle="tooltip" title="' + (phrase.read ? phrase.read : 'Read') + '">' +
							'<i class="mdi mdi-magnify"></i>' +
						'</a>' : '') +
						
						/* update button if action is allowed */
						(updating && $.inArray('update', response.results.unset_action) === -1 ? '<a href="' + go_to('update', response.results.query_string[key]) + '" class="btn btn-info btn-xs ' + (response.modal_html ? '--modal' : '--open-modal-form') + '" data-toggle="tooltip" title="' + (phrase.update ? phrase.update : 'Update') + '"><i class="mdi mdi-square-edit-outline"></i></a>' : '') +
						
						/* add extra option to button group */
						extra_option +
						
						/* print button if action is allowed */
						(extra_dropdown || (reading && $.inArray('print', response.results.unset_action) === -1) || (reading && $.inArray('pdf', response.results.unset_action) === -1) ? '<button type="button" class="btn btn-xs btn-secondary toggle-tooltip" data-title="' + (phrase.more_options ? phrase.more_options : 'More options') + '" data-toggle="popover" data-trigger="focus" data-content=\'' +
						
							/* add extra action to the popover */
							'<div class="list-group list-group-flush">' +
						
								/* add extra dropdown to dropdown group */
								extra_dropdown +
							
								/* print button if action is allowed */
								(reading && $.inArray('print', response.results.unset_action) === -1 ? '<a href="' + go_to('print', response.results.query_string[key]) + '" class="list-group-item pt-1 pr-0 pb-1 pl-0" target="_blank"><i class="mdi mdi-printer" style="width:22px"></i> ' + (phrase.print ? phrase.print : 'Print') + '</a>' : '') +
							
								/* pdf button if action is allowed */
								(reading && $.inArray('pdf', response.results.unset_action) === -1 ? '<a href="' + go_to('pdf', response.results.query_string[key]) + '" class="list-group-item pt-1 pr-0 pb-1 pl-0" target="_blank"><i class="mdi mdi-file-pdf text-danger" style="width:22px"></i> ' + (phrase.pdf ? phrase.pdf : 'PDF') + '</a>' : '') + 
							'</div>\' ' +
							/* end of popover wrapping */
						'data-container="body" data-html="true"><i class="mdi mdi-chevron-down"></i></button>' : '') +
						
						/* delete button if action is allowed */
						(deleting && $.inArray('delete', response.results.unset_action) === -1 ? '<a href="' + go_to('delete', response.results.query_string[key]) + '" class="btn btn-danger btn-xs --open-delete-confirm" data-toggle="tooltip" title="' + (phrase.delete ? phrase.delete : 'Delete') + '"><i class="mdi mdi-trash-can-outline"></i></a>' : '') +
					'</div>' +
				'</td>' : '');
				
				/* push columns include the action button into table row */
				items								+= '<tr id="item__' + response.results.query_string[key].aksara + '">' + ($.inArray('read', response.results.unset_action) === -1 || $.inArray('update', response.unset_action) === -1 || $.inArray('delete', response.results.unset_action) === -1 || $.inArray('print', response.results.unset_action) === -1 || $.inArray('pdf', response.results.unset_action) === -1 ? options : '') + columns + '</tr>';
			})
		}
		else
		{
			/**
			 * Uh oh! No data were found, throw the notification into table row
			 */
			items									= '<tr class="no-hover"><td colspan="' + colspan + '"><div class="text-center pt-5 pb-5"><i class="mdi mdi-text mdi-5x text-muted"></i><br /><p class="lead text-muted">' + (phrase.no_matching_record_were_found ? phrase.no_matching_record_were_found : 'No matching record were found') + '</p></div></td></tr>';
		}
		
		/**
		 * Add the form format into the local storage
		 */
		if($.inArray('create', response.results.unset_action) === -1)
		{
			/* generate the response data */
			$.ajax
			({
				method: 'POST',
				url: go_to('create', response.query_string),
				data:
				{
					prefer: 'modal'
				},
				beforeSend: function()
				{
					sessionStorage.setItem('form', '')
				}
			})
			.done(function(data)
			{
				sessionStorage.setItem('form', JSON.stringify(data));
			})
		}
		else if($.inArray('update', response.results.unset_action) === -1)
		{
			/* generate the response data */
			$.ajax
			({
				method: 'POST',
				url: go_to('update', response.query_string),
				data:
				{
					prefer: 'modal'
				},
				beforeSend: function()
				{
					sessionStorage.setItem('form', '')
				}
			})
			.done(function(data)
			{
				sessionStorage.setItem('form', JSON.stringify(data));
			})
		}
		
		/**
		 * Add the view format into the local storage
		 */
		if($.inArray('read', response.results.unset_action) === -1)
		{
			$.ajax
			({
				method: 'POST',
				url: go_to('read', response.query_string),
				data:
				{
					prefer: 'modal'
				},
				beforeSend: function()
				{
					sessionStorage.setItem('read', '')
				}
			})
			.done(function(data)
			{
				sessionStorage.setItem('read', JSON.stringify(data));
			})
		}
		
		var input_exists							= '';
		
		if(response.query_string)
		{
			$.each(response.query_string, function(key, val)
			{
				if($.inArray(key, ['aksara', 'q', 'per_page', 'column']) === -1)
				{
					input_exists					+= '<input type="hidden" name="' + key + '" value="' + val + '" />';
				}
			})
		}
		
		/**
		 * return the result to the temporary DOM
		 */
		return (
			'<div class="container-fluid">' +
				'<div class="row pt-1 pb-1 alias-table-toolbar border-bottom">' +
					'<div class="col">' +
						'<div class="btn-group btn-group-sm">' +
							/* add create button if action is allowed */
							($.inArray('create', response.results.unset_action) === -1 ?
							'<a href="' + go_to('create', response.query_string) + '" class="btn btn-primary --btn-create ' + (response.modal_html ? '--modal' : '--open-modal-form') + '">' +
								'<i class="mdi mdi-plus"></i> ' +
								(phrase.create ? phrase.create : 'Create') +
							'</a>' : '') +
							
							/* add extra button if available */
							extra_toolbar +
							
							/* add export button if action is allowed */
							($.inArray('export', response.results.unset_action) === -1 ?
							'<a href="' + go_to('export', response.query_string) + '" class="btn btn-success --btn-export" target="_blank">' +
								'<i class="mdi mdi-file-excel"></i> ' +
								(phrase.export ? phrase.export : 'Export') +
							'</a>' : '') +
							
							/* add print button if action is allowed */
							($.inArray('print', response.results.unset_action) === -1 ?
							'<a href="' + go_to('print', response.query_string) + '" class="btn btn-warning --btn-print" target="_blank">' +
								'<i class="mdi mdi-printer"></i> ' +
								(phrase.print ? phrase.print : 'Print') +
							'</a>' : '') +
							
							/* add pdf button if action is allowed */
							($.inArray('pdf', response.results.unset_action) === -1 ?
							'<a href="' + go_to('pdf', response.query_string) + '" class="btn btn-info --btn-pdf" target="_blank">' +
								'<i class="mdi mdi-file-pdf"></i> ' +
								(phrase.pdf ? phrase.pdf : 'PDF') +
							'</a>' : '') +
							
							/* add de;ete button if action is allowed */
							($.inArray('delete', response.results.unset_action) === -1 ?
							'<a href="' + go_to('delete', response.query_string) + '" class="btn btn-danger disabled d-none --open-delete-confirm" data-toggle="tooltip" title="' + (phrase.delete_checked ? phrase.delete_checked : 'Delete Checked') + '" data-bulk-delete="true">' +
								'<i class="mdi mdi-trash-can-outline"></i>' +
							'</a>' : '') +
						'</div>' +
					'</div>' +
					'<div class="col' + (typeof response.results !== 'undefined' && typeof response.results.filter !== 'undefined' && !response.results.filter ? '-4' : '') + '">' +
						'<form action="' + go_to('', response.query_string) + '" method="POST" class="--xhr-form">' +
							input_exists +
							'<div class="input-group input-group-sm">' +
								(typeof response.results !== 'undefined' && typeof response.results.filter !== 'undefined' ? response.results.filter : '') +
								'<input type="text" name="q" class="form-control" placeholder="' + (phrase.keyword_to_search ? phrase.keyword_to_search : 'Keyword to search') + '" value="' + (get_query_string('q') ? decodeURIComponent(decodeURI(get_query_string('q'))).replace(/\+/g, ' ') : '') + '" role="autocomplete" autocomplete="off" />' +
								'<select name="column" class="form-control">' +
									'<option value="all">' + (phrase.all_columns ? phrase.all_columns : 'All Columns') + '</option>' +
									search_columns +
								'</select>' +
								'<span class="input-group-append">' +
									'<button type="submit" class="btn btn-primary">' +
										'<i class="mdi mdi-magnify"></i>' +
									'</button>' +
								'</span>' +
							'</div>' +
						'</form>' +
					'</div>' +
				'</div>' +
				'<div class="table-responsive alias-table-index">' +
					'<table class="table table-sm table-hover">' +
						'<thead>' +
							'<tr>' +
								/* the above field loop is placed here */
								fields +
							'</tr>' +
						'</thead>' +
						'<tbody>' +
							/* the column and row looping, including the action button above is placed here */
							items +
						'</tbody>' +
					'</table>' +
				'</div>' +
				'<div class="row alias-pagination border-top pt-2 pb-2">' +
					'<div class="col-12">' +
						this.pagination(response.pagination) +
					'</div>' +
				'</div>' +
			'</div>'
		)
	},
	
	pagination: function(response)
	{
		var output									= '';
		$.each(response.results, function(key, val)
		{
			output									+= '<li class="' + val.parentClass + '"><a href="' + val.href + '" class="' + val.class + '">' + val.label + '</a></li>';
		});
		
		return (
			'<div class="row">' +
				'<div class="col-sm-6 text-center-sm">' +
					'<label class="text-muted">' +
						'<small class="result-for">' +
							'<i class="mdi mdi-information-outline"></i> ' +
							response.text +
						'</small>' +
					'</label>' +
				'</div>' +
				'<div class="col-sm-6">' +
					'<nav class="d-flex justify-content-center justify-content-sm-end justify-content-md-end justify-content-lg-end justify-content-xl-end" aria-label="Page navigation">' +
						'<ul class="pagination pagination-sm">' +
							output +
						'</ul>' +
						(response.last_page > 1 ?
						'<form action="' + go_to('', {'per_page': ''}) + '" method="POST" class="--xhr-form ml-2">' +
							'<div class="input-group">' +
								'<input type="number" name="per_page" class="form-control form-control-sm text-center" value="' + (get_query_string('per_page') ? get_query_string('per_page') : 1) + '" min="1" max="' + response.last_page + '" />' +
								'<div class="input-group-append">' +
									'<button type="submit" class="btn btn-sm btn-primary">' +
										(phrase.go ? phrase.go : 'Go') +
									'</button>' +
								'</div>' +
							'</div>' +
						'</form>' : '') +
					'</nav>' +
				'</div>' +
			'</div>'
		);
	},
	
	form: function(_this, response)
	{
		if(response && typeof response._token !== 'undefined')
		{
			sessionStorage.setItem('_token', response._token)
		}
		
		if(response)
		{
			/* loop the result */
			var output								= '',
				col									= '',
				column_1							= '',
				column_2							= '',
				column_3							= '',
				column_4							= '',
				merged								= new Array(),
				extra_submit						= '',
				map									= '';
				
			if(response.results.extra_action.submit)
			{
				/* loop, the jQuery is required */
				$.each(response.results.extra_action.submit, function(key, val)
				{
					/* submit button is available */
					extra_submit					+= '<a href="' + go_to(val.url, val.parameter) + '" class="' + (val.class ? val.class : 'btn-default --xhr') + ' float-right ml-1"' + (val.new_tab ? ' target="_blank"' : null) + '><i class="' + (val.icon ? val.icon : 'mdi mdi-link') + '"></i>' + val.label + '</a>';
				})
			}
			
			$.each(response.results.form_data, function(field, params)
			{
				if($.inArray('coordinate', params.type) !== -1 || $.inArray('point', params.type) !== -1 || $.inArray('polygon', params.type) !== -1 || $.inArray('linestring', params.type) !== -1)
				{
					map								= '<div class="form-group" style="margin-left:-1rem; margin-right:-1rem">' + params.content + '</div>';
					return;
				}
				
				if(typeof response.results.merged_field[field] !== 'undefined')
				{
					var col							= '';
					
					$.each(response.results.merged_field[field], function(key, val)
					{
						if($.inArray(val, merged) !== -1 || typeof response.results.form_data[val] === 'undefined') return;
						
						col							+= 
						'<div class="' + (typeof response.results.field_size[val] !== 'undefined' ? response.results.field_size[val] : 'col') + '">' +
							'<div class="form-group">' +
								'<label class="text-muted d-block" for="' + val + '_input">' +
									response.results.form_data[val]['label'] +
									(response.results.form_data[val]['tooltip'] ? ' <i class="mdi mdi-information-outline text-primary" data-toggle="tooltip" title="' + response.results.form_data[val]['tooltip'] + '"></i>' : '') +
									(response.results.form_data[val]['required'] ? '<b class="text-danger"> *</b>' : '') +
								'</label>' +
								(response.results.form_data[val]['prepend'] || response.results.form_data[val]['append'] ? '<div class="input-group">' : '') +
									(response.results.form_data[val]['prepend'] ?
									'<div class="input-group-prepend">' +
										'<span class="input-group-text">' +
											response.results.form_data[val]['prepend'] +
										'</span>' +
									'</div>' : '') +
									
									response.results.form_data[val]['content'] +
									
									(response.results.form_data[val]['append'] ?
									'<div class="input-group-append">' +
										'<span class="input-group-text">' +
											response.results.form_data[val]['append'] +
										'</span>' +
									'</div>' : '') +
								(response.results.form_data[val]['prepend'] || response.results.form_data[val]['append'] ? '</div>' : '') +
							'</div>' +
						'</div>';
						
						merged.push(val);
					});
					
					if(4 == params.position)
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_4				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_4					+= '<div class="row">' + col + '</div>';
					}
					else if(3 == params.position)
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_3				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_3					+= '<div class="row">' + col + '</div>';
					}
					else if(2 == params.position)
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_2				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_2					+= '<div class="row">' + col + '</div>';
					}
					else
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_1				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_1					+= '<div class="row">' + col + '</div>';
					}
				}
				else
				{
					if($.inArray(field, merged) !== -1) return;
					
					output							= '<div class="form-group"><label class="text-muted d-block" for="' + field + '_input">' + params.label + (params.tooltip ? ' <i class="mdi mdi-information-outline text-primary" data-toggle="tooltip" title="' + params.tooltip + '"></i>' : '') + (params.required ? '<b class="text-danger"> *</b>' : '') + '</label>' + (params.prepend || params.append ? '<div class="input-group">' : '') + (params.prepend ? '<div class="input-group-prepend"><span class="input-group-text">' + params.prepend + '</span></div>' : '') + params.content + (params.append ? '<div class="input-group-append"><span class="input-group-text">' + params.append + '</span></div>' : '') + (params.prepend || params.append ? '</div>' : '') + '</div>';
					
					if(4 == params.position)
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_4				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_4					+= output;
					}
					else if(3 == params.position)
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_3				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_3					+= output;
					}
					else if(2 == params.position)
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_2				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_2					+= output;
					}
					else
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_1				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_1					+= output;
					}
				}
			});
			
			if(4 == response.results.column_total)
			{
				modal_size							= 'modal-xl';
				
				output								= 
					'<div class="row">' +
						'<div class="' + (response.results.column_size[0] ? response.results.column_size[0] : (col ? 'col-md-3' : 'col')) + '">' +
							column_1 +
						'</div>' +
						'<div class="' + (response.results.column_size[1] ? response.results.column_size[1] : (col ? 'col-md-3' : 'col')) + '">' +
							column_2 +
						'</div>' +
						'<div class="' + (response.results.column_size[2] ? response.results.column_size[2] : (col ? 'col-md-3' : 'col')) + '">' +
							column_3 +
						'</div>' +
						'<div class="' + (response.results.column_size[3] ? response.results.column_size[3] : (col ? 'col-md-3' : 'col')) + '">' +
							column_4 +
						'</div>' +
					'</div>';
			}
			else if(3 == response.results.column_total)
			{
				modal_size							= 'modal-xl';
				
				output								= 
					'<div class="row">' +
						'<div class="' + (response.results.column_size[0] ? response.results.column_size[0] : (col ? 'col-md-4' : 'col')) + '">' +
							column_1 +
						'</div>' +
						'<div class="' + (response.results.column_size[1] ? response.results.column_size[1] : (col ? 'col-md-4' : 'col')) + '">' +
							column_2 +
						'</div>' +
						'<div class="' + (response.results.column_size[2] ? response.results.column_size[2] : (col ? 'col-md-4' : 'col')) + '">' +
							column_3 +
						'</div>' +
					'</div>';
			}
			else if(2 == response.results.column_total)
			{
				modal_size							= 'modal-lg';
				
				output								= 
					'<div class="row">' +
						'<div class="' + (response.results.column_size[0] ? response.results.column_size[0] : (col ? 'col-md-6' : 'col')) + '">' +
							column_1 +
						'</div>' +
						'<div class="' + (response.results.column_size[1] ? response.results.column_size[1] : (col ? 'col-md-6' : 'col')) + '">' +
							column_2 +
						'</div>' +
					'</div>';
			}
			else
			{
				modal_size							= '';
				
				output								= column_1 + column_2 + column_3 + column_4;
			}
			
			$(config.content_wrapper).html
			(
				'<div class="container-fluid ' + (map ? 'pb-3' : 'pt-3 pb-3') + '">' +
					'<form action="' + response.current_page + '" method="POST" class="--validate-form" enctype="multipart/form-data">' +
						map +
						'<div class="row">' +
							'<div class="col-md-' + (1 == response.results.column_total ? 6 : (2 == response.results.column_total ? 10 : 10)) + '">' +
								output +
								'<div class="--validation-callback mb-0"></div>' +
							'</div>' +
						'</div>' +
						'<div class="opt-btn-overlap-fix"></div><!-- fix the overlap -->' +
						'<div class="row opt-btn">' +
							'<div class="col-md-' + (1 == response.results.column_total ? 6 : (2 == response.results.column_total ? 10 : 10)) + '">' +
								'<a href="' + go_to('..', response.results.query_string) + '" class="btn btn-link --xhr">' +
									'<i class="mdi mdi-arrow-left"></i> ' +
									(phrase.back ? phrase.back : 'Back') +
								'</a>' +
								extra_submit +
								'<button type="submit" class="btn btn-primary float-right">' +
									'<i class="mdi mdi-check"></i> ' +
									(phrase.submit ? phrase.submit : 'Submit') +
									' <em class="text-sm">(ctrl+s)</em>' +
								'</button>' +
							'</div>' +
						'</div>' +
					'</form>' +
				'</div>'
			),
			
			_reactivate();
			
			return;
		}
		else if(sessionStorage.getItem('form'))
		{
			this.load_modal(JSON.parse(sessionStorage.getItem('form')), 'form')
		}
		else
		{
			/* fire modal to show */
			$(
				'<div class="modal" id="form-modal" role="dialog" aria-labelledby="form-modal-title" aria-hidden="true">' +
					'<div class="modal-dialog modal-dialog-centered" role="document">' +
						'<form action="' + _this.attr('href') + '" method="POST" class="modal-content" enctype="multipart/form-data">' +
							'<div class="modal-header">' +
								'<h5 class="modal-title" id="form-modal-title">' +
									'<i class="mdi mdi-loading mdi-spin"></i> ' +
									'<span class="modal-title-text">' +
										(phrase.loading ? phrase.loading : 'Loading...') +
									'</span>' +
								'</h5>' +
								'<button type="button" class="close" data-dismiss="modal" aria-label="' + (phrase.close ? phrase.close : 'Close') + '">' +
									'<span aria-hidden="true">&times;</span>' +
								'</button>' +
							'</div>' +
							'<div class="modal-body">' +
								'<div class="d-flex justify-content-center">' +
									'<div class="spinner-border text-primary" role="status">' +
										'<span class="sr-only">' + (phrase.loading ? phrase.loading : 'Loading...') + '</span>' +
									'</div>' +
								'</div>' +								
							'</div>' +
							'<div class="modal-footer">' +
								'<button type="button" class="btn btn-light mr-1" data-dismiss="modal">' +
									(phrase.close ? phrase.close : 'Close') +
									' <em class="text-sm">(esc)</em>' +
								'</button>' +
								'<button type="submit" class="btn btn-primary disabled" disabled>' +
									'<i class="mdi mdi-check"></i> ' +
									(phrase.submit ? phrase.submit : 'Submit') +
									' <em class="text-sm">(ctrl+s)</em>' +
								'</button>' +
							'</div>' +
						'</form>' +
					'</div>' +
				'</div>'
			)
			.appendTo('body')
			.modal({backdrop:'static', keyboard: false})
		}
		
		$.ajax
		({
			method: 'POST',
			url: _this.attr('href'),
			data:
			{
				prefer: 'modal'
			},
			beforeSend: function()
			{
			},
			complete: function(progress)
			{
			},
			statusCode:
			{
				301: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					if(typeof response.redirect !== 'undefined' && response.redirect)
					{
						return window.location.replace(response.target);
					}
					
					$('.modal').modal('hide');
					
					return throw_exception(response.status, (typeof response.message !== 'undefined' ? response.message : error));
				},
				403: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					if(typeof response.redirect !== 'undefined' && response.redirect)
					{
						return window.location.replace(response.target);
					}
					
					$('.modal').modal('hide');
					
					return throw_exception(response.status, (typeof response.message !== 'undefined' ? response.message : error));
				},
				404: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					if(typeof response.redirect !== 'undefined' && response.redirect)
					{
						return window.location.replace(response.target);
					}
					
					$('.modal').modal('hide');
					
					return throw_exception(response.status, (typeof response.message !== 'undefined' ? response.message : error));
				},
				500: function(response, status, error)
				{
					$('#form-modal').find('.modal-body').addClass('bg-dark text-center p-3').html('<p><code>' + response + '</code></p><p class="mt-5"><a href="#" class="btn btn-outline-light btn-sm --report-to-admin">' + (phrase.report_to_admin ? phrase.report_to_admin : 'Report to Admin') + '</a></p>');
					
					return throw_exception(500, (typeof response.message !== 'undefined' ? response.message : error));
				}
			}
		})
		.done(function(response)
		{
			if(response && typeof response._token !== 'undefined')
			{
				sessionStorage.setItem('_token', response._token)
			}
			
			if(sessionStorage.getItem('form'))
			{
				/* variable to check if form already rendered */
				var rendered						= true,
					output							= null;
				
				$.each(response.results.form_data, function(field, params)
				{
					/* check if form if already rendered, otherwise mark it as invisible and use second method */
					if(!$('#' + field + '_input').length)
					{
						rendered					= false;
						
						/* break the loop */
						return;
					}
					
					$('#' + field + '_input').replaceWith(params.content)
				});
				
				/* form is not rendered, use second method */
				if(!rendered)
				{
					/* loop the result */
					var col							= '',
						column_1					= '',
						column_2					= '',
						column_3					= '',
						column_4					= '',
						merged						= new Array(),
						map							= '',
						method						= ($.inArray(response.method, ['create', 'update']) !== -1 ? 'form' : 'view');
					
					$.each(response.results.form_data, function(field, params)
					{
						if($.inArray('coordinate', params.type) !== -1 || $.inArray('point', params.type) !== -1 || $.inArray('polygon', params.type) !== -1 || $.inArray('linestring', params.type) !== -1)
						{
							map						= '<div class="form-group" style="margin-left:-1rem; margin-right:-1rem">' + params.content + '</div>';
							
							return;
						}
						
						if(typeof response.results.merged_field[field] !== 'undefined')
						{
							var col					= '';
							
							$.each(response.results.merged_field[field], function(key, val)
							{
								if($.inArray(val, merged) !== -1 || typeof response.results.form_data[val] === 'undefined') return;
								
								col					+= 
								'<div class="' + (typeof response.results.field_size[val] !== 'undefined' ? response.results.field_size[val] : 'col') + '">' +
									'<div class="form-group">' +
										'<label class="text-muted d-block" for="' + val + ('form' == method ? '_input' : '_label') + '">' +
											response.results.form_data[val]['label'] +
											('form' == method && response.results.form_data[val]['tooltip'] ? ' <i class="mdi mdi-information-outline text-primary" data-toggle="tooltip" title="' + response.results.form_data[val]['tooltip'] + '"></i>' : '') +
											('form' == method && params.required ? '<b class="text-danger"> *</b>' : '') +
										'</label>' +
										('form' == method ? (response.results.form_data[val]['prepend'] || response.results.form_data[val]['append'] ? '<div class="input-group">' : '') + (response.results.form_data[val]['prepend'] ? '<div class="input-group-prepend"><span class="input-group-text">' + response.results.form_data[val]['prepend'] + '</span></div>' : '') + response.results.form_data[val]['content'] + (response.results.form_data[val]['append'] ? '<div class="input-group-append"><span class="input-group-text">' + response.results.form_data[val]['append'] + '</span></div>' : '') + (response.results.form_data[val]['prepend'] || response.results.form_data[val]['append'] ? '</div>' : '') : '<p id="' + val + '_label" class="text-break-word">' + (phrase.loading ? phrase.loading : 'Loading...') + '</p>') +
									'</div>' +
								'</div>';
								
								merged.push(val)
							});
							
							if(4 == params.position)
							{
								if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
								{
									column_4		+= '<h5>' + response.results.set_heading[field] + '</h5>';
								}
								
								column_4			+= '<div class="row">' + col + '</div>';
							}
							else if(3 == params.position)
							{
								if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
								{
									column_3		+= '<h5>' + response.results.set_heading[field] + '</h5>';
								}
								
								column_3			+= '<div class="row">' + col + '</div>';
							}
							else if(2 == params.position)
							{
								if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
								{
									column_2		+= '<h5>' + response.results.set_heading[field] + '</h5>';
								}
								
								column_2			+= '<div class="row">' + col + '</div>';
							}
							else
							{
								if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
								{
									column_1		+= '<h5>' + response.results.set_heading[field] + '</h5>';
								}
								
								column_1			+= '<div class="row">' + col + '</div>';
							}
						}
						else
						{
							if($.inArray(field, merged) !== -1) return;
							
							output					= '<div class="form-group"><label class="text-muted d-block" for="' + field + ('form' == method ? '_input' : '_label') + '">' + params.label + ('form' == method && params.tooltip ? ' <i class="mdi mdi-information-outline text-primary" data-toggle="tooltip" title="' + params.tooltip + '"></i>' : '') + (params.required ? '<b class="text-danger"> *</b>' : '') + '</label>' + ('form' == method ? (params.prepend || params.append ? '<div class="input-group">' : '') + (params.prepend ? '<div class="input-group-prepend"><span class="input-group-text">' + params.prepend + '</span></div>' : '') + params.content + (params.append ? '<div class="input-group-append"><span class="input-group-text">' + params.append + '</span></div>' : '') + (params.prepend || params.append ? '</div>' : '') : params.content) + '</div>';
							
							if(4 == params.position)
							{
								if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
								{
									column_4		+= '<h5>' + response.results.set_heading[field] + '</h5>';
								}
								
								column_4			+= output;
							}
							else if(3 == params.position)
							{
								if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
								{
									column_3		+= '<h5>' + response.results.set_heading[field] + '</h5>';
								}
								
								column_3			+= output;
							}
							else if(2 == params.position)
							{
								if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
								{
									column_2		+= '<h5>' + response.results.set_heading[field] + '</h5>';
								}
								
								column_2			+= output;
							}
							else
							{
								if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
								{
									column_1		+= '<h5>' + response.results.set_heading[field] + '</h5>';
								}
								
								column_1			+= output;
							}
						}
					});
					
					if(4 == response.results.column_total)
					{
						modal_size					= 'modal-xl';
						
						output						= 
							'<div class="row">' +
								'<div class="' + (response.results.column_size[0] ? response.results.column_size[0] : (col ? 'col-md-3' : 'col')) + '">' +
									column_1 +
								'</div>' +
								'<div class="' + (response.results.column_size[1] ? response.results.column_size[1] : (col ? 'col-md-3' : 'col')) + '">' +
									column_2 +
								'</div>' +
								'<div class="' + (response.results.column_size[2] ? response.results.column_size[2] : (col ? 'col-md-3' : 'col')) + '">' +
									column_3 +
								'</div>' +
								'<div class="' + (response.results.column_size[3] ? response.results.column_size[3] : (col ? 'col-md-3' : 'col')) + '">' +
									column_4 +
								'</div>' +
							'</div>';
					}
					else if(3 == response.results.column_total)
					{
						modal_size					= 'modal-xl';
						
						output						= 
							'<div class="row">' +
								'<div class="' + (response.results.column_size[0] ? response.results.column_size[0] : (col ? 'col-md-4' : 'col')) + '">' +
									column_1 +
								'</div>' +
								'<div class="' + (response.results.column_size[1] ? response.results.column_size[1] : (col ? 'col-md-4' : 'col')) + '">' +
									column_2 +
								'</div>' +
								'<div class="' + (response.results.column_size[2] ? response.results.column_size[2] : (col ? 'col-md-4' : 'col')) + '">' +
									column_3 +
								'</div>' +
							'</div>';
					}
					else if(2 == response.results.column_total)
					{
						modal_size					= 'modal-lg';
						
						output						= 
							'<div class="row">' +
								'<div class="' + (response.results.column_size[0] ? response.results.column_size[0] : (col ? 'col-md-6' : 'col')) + '">' +
									column_1 +
								'</div>' +
								'<div class="' + (response.results.column_size[1] ? response.results.column_size[1] : (col ? 'col-md-6' : 'col')) + '">' +
									column_2 +
								'</div>' +
							'</div>';
					}
					else
					{
						modal_size					= '';
						
						output						= column_1 + column_2 + column_3 + column_4;
					}
					
					output							= map + output + '<div class="--validation-callback mb-0"></div>';
				}
				
				$('#form-modal').find('.modal-title').find('i').removeClass('mdi-plus mdi-square-edit-outline mdi-loading mdi-spin').addClass((typeof response.meta !== 'undefined' && typeof response.meta.icon !== 'undefined' ? response.meta.icon : 'mdi-alert-outline')),
				$('#form-modal').find('.modal-title').find('.modal-title-text').text((typeof response.meta !== 'undefined' && typeof response.meta.title !== 'undefined' ? response.meta.title : (phrase.error ? phrase.error : 'Error'))),
				(typeof response.meta !== 'undefined' && typeof response.meta.description !== 'undefined' ? $('#form-modal').find('.modal-body').addClass('pt-0').prepend(response.meta.description) : null),
				
				$('#form-modal').find('.modal-dialog').addClass((response.meta.modal_size ? response.meta.modal_size : modal_size)),
				$('#form-modal').find('form').attr('action', response.current_page).addClass('--validate-form'),
				$('#form-modal').find('form').find('button[type=submit]').removeClass('disabled').attr('disabled', null),
				(output ? $('#form-modal').find('.modal-body').html(output) : null),
				
				_reactivate()
			}
			else
			{
				/* loop the result */
				var output							= '',
					col								= '',
					column_1						= '',
					column_2						= '',
					column_3						= '',
					column_4						= '',
					merged							= new Array(),
					map								= '',
					method							= ($.inArray(response.method, ['create', 'update']) !== -1 ? 'form' : 'view');
				
				$.each(response.results.form_data, function(field, params)
				{
					if($.inArray('coordinate', params.type) !== -1 || $.inArray('point', params.type) !== -1 || $.inArray('polygon', params.type) !== -1 || $.inArray('linestring', params.type) !== -1)
					{
						map							= '<div class="form-group" style="margin-left:-1rem; margin-right:-1rem">' + params.content + '</div>';
						
						return;
					}
					
					if(typeof response.results.merged_field[field] !== 'undefined')
					{
						var col						= '';
						
						$.each(response.results.merged_field[field], function(key, val)
						{
							if($.inArray(val, merged) !== -1 || typeof response.results.form_data[val] === 'undefined') return;
							
							col						+= 
							'<div class="' + (typeof response.results.field_size[val] !== 'undefined' ? response.results.field_size[val] : 'col') + '">' +
								'<div class="form-group">' +
									'<label class="text-muted d-block" for="' + val + ('form' == method ? '_input' : '_label') + '">' +
										response.results.form_data[val]['label'] +
										('form' == method && response.results.form_data[val]['tooltip'] ? ' <i class="mdi mdi-information-outline text-primary" data-toggle="tooltip" title="' + response.results.form_data[val]['tooltip'] + '"></i>' : '') +
										('form' == method && params.required ? '<b class="text-danger"> *</b>' : '') +
									'</label>' +
									('form' == method ? (response.results.form_data[val]['prepend'] || response.results.form_data[val]['append'] ? '<div class="input-group">' : '') + (response.results.form_data[val]['prepend'] ? '<div class="input-group-prepend"><span class="input-group-text">' + response.results.form_data[val]['prepend'] + '</span></div>' : '') + response.results.form_data[val]['content'] + (response.results.form_data[val]['append'] ? '<div class="input-group-append"><span class="input-group-text">' + response.results.form_data[val]['append'] + '</span></div>' : '') + (response.results.form_data[val]['prepend'] || response.results.form_data[val]['append'] ? '</div>' : '') : '<p id="' + val + '_label" class="text-break-word">' + (phrase.loading ? phrase.loading : 'Loading...') + '</p>') +
								'</div>' +
							'</div>';
							
							merged.push(val)
						});
						
						if(4 == params.position)
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_4			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_4				+= '<div class="row">' + col + '</div>';
						}
						else if(3 == params.position)
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_3			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_3				+= '<div class="row">' + col + '</div>';
						}
						else if(2 == params.position)
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_2			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_2				+= '<div class="row">' + col + '</div>';
						}
						else
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_1			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_1				+= '<div class="row">' + col + '</div>';
						}
					}
					else
					{
						if($.inArray(field, merged) !== -1) return;
						
						output						= '<div class="form-group"><label class="text-muted d-block" for="' + field + ('form' == method ? '_input' : '_label') + '">' + params.label + ('form' == method && params.tooltip ? ' <i class="mdi mdi-information-outline text-primary" data-toggle="tooltip" title="' + params.tooltip + '"></i>' : '') + (params.required ? '<b class="text-danger"> *</b>' : '') + '</label>' + ('form' == method ? (params.prepend || params.append ? '<div class="input-group">' : '') + (params.prepend ? '<div class="input-group-prepend"><span class="input-group-text">' + params.prepend + '</span></div>' : '') + params.content + (params.append ? '<div class="input-group-append"><span class="input-group-text">' + params.append + '</span></div>' : '') + (params.prepend || params.append ? '</div>' : '') : params.content) + '</div>';
						
						if(4 == params.position)
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_4			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_4				+= output;
						}
						else if(3 == params.position)
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_3			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_3				+= output;
						}
						else if(2 == params.position)
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_2			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_2				+= output;
						}
						else
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_1			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_1				+= output;
						}
					}
				});
				
				if(4 == response.results.column_total)
				{
					modal_size						= 'modal-xl';
					
					output							= 
						'<div class="row">' +
							'<div class="' + (response.results.column_size[0] ? response.results.column_size[0] : (col ? 'col-md-3' : 'col')) + '">' +
								column_1 +
							'</div>' +
							'<div class="' + (response.results.column_size[1] ? response.results.column_size[1] : (col ? 'col-md-3' : 'col')) + '">' +
								column_2 +
							'</div>' +
							'<div class="' + (response.results.column_size[2] ? response.results.column_size[2] : (col ? 'col-md-3' : 'col')) + '">' +
								column_3 +
							'</div>' +
							'<div class="' + (response.results.column_size[3] ? response.results.column_size[3] : (col ? 'col-md-3' : 'col')) + '">' +
								column_4 +
							'</div>' +
						'</div>';
				}
				else if(3 == response.results.column_total)
				{
					modal_size						= 'modal-xl';
					
					output							= 
						'<div class="row">' +
							'<div class="' + (response.results.column_size[0] ? response.results.column_size[0] : (col ? 'col-md-4' : 'col')) + '">' +
								column_1 +
							'</div>' +
							'<div class="' + (response.results.column_size[1] ? response.results.column_size[1] : (col ? 'col-md-4' : 'col')) + '">' +
								column_2 +
							'</div>' +
							'<div class="' + (response.results.column_size[2] ? response.results.column_size[2] : (col ? 'col-md-4' : 'col')) + '">' +
								column_3 +
							'</div>' +
						'</div>';
				}
				else if(2 == response.results.column_total)
				{
					modal_size						= 'modal-lg';
					
					output							= 
						'<div class="row">' +
							'<div class="' + (response.results.column_size[0] ? response.results.column_size[0] : (col ? 'col-md-6' : 'col')) + '">' +
								column_1 +
							'</div>' +
							'<div class="' + (response.results.column_size[1] ? response.results.column_size[1] : (col ? 'col-md-6' : 'col')) + '">' +
								column_2 +
							'</div>' +
						'</div>';
				}
				else
				{
					modal_size						= '';
					
					output							= column_1 + column_2 + column_3 + column_4;
				}
				
				output								= map + output + '<div class="--validation-callback mb-0"></div>';
				
				$('#form-modal').find('.modal-title').find('i').removeClass('mdi-plus mdi-square-edit-outline mdi-loading mdi-spin').addClass((typeof response.meta !== 'undefined' && typeof response.meta.icon !== 'undefined' ? response.meta.icon : 'mdi-alert-outline')),
				$('#form-modal').find('.modal-title').find('.modal-title-text').text((typeof response.meta !== 'undefined' && typeof response.meta.title !== 'undefined' ? response.meta.title : (phrase.error ? phrase.error : 'Error'))),
				(typeof response.meta !== 'undefined' && typeof response.meta.description !== 'undefined' ? $('#form-modal').find('.modal-body').addClass('pt-0').prepend(response.meta.description) : null),
				
				$('#form-modal').find('.modal-dialog').addClass((response.meta.modal_size ? response.meta.modal_size : modal_size)),
				$('#form-modal').find('form').attr('action', response.current_page).addClass('--validate-form'),
				$('#form-modal').find('form').find('button[type=submit]').removeClass('disabled').attr('disabled', null),
				(output ? $('#form-modal').find('.modal-body').html(output) : null),
				
				_reactivate()
			}
		})
	},
	
	/**
	 * CRUD: read modal
	 */
	view: function(_this, response)
	{
		if(response)
		{
			var output								= '',
				col									= '',
				column_1							= '',
				column_2							= '',
				column_3							= '',
				column_4							= '',
				merged								= new Array(),
				map									= '';
			
			$.each(response.results.form_data, function(field, params)
			{
				if($.inArray('coordinate', params.type) !== -1 || $.inArray('point', params.type) !== -1 || $.inArray('polygon', params.type) !== -1 || $.inArray('linestring', params.type) !== -1)
				{
					map								= '<div class="form-group" style="margin-left:-1rem; margin-right:-1rem">' + params.content + '</div>';
					
					return;
				}
				if(typeof response.results.merged_field[field] !== 'undefined')
				{
					var col							= '';
					
					$.each(response.results.merged_field[field], function(key, val)
					{
						if($.inArray(val, merged) !== -1 || typeof response.results.form_data[val] === 'undefined') return;
						
						col							+= 
						'<div class="' + (typeof response.results.field_size[val] !== 'undefined' ? response.results.field_size[val] : 'col') + '">' +
							'<div class="form-group border-bottom">' +
								'<label class="text-muted d-block" for="' + val + '_label">' +
									response.results.form_data[val]['label'] +
								'</label>' +
								'<p id="' + val + '_label" class="text-break-word">' +
									response.results.form_data[val]['content'] +
								'</p>' +
							'</div>' +
						'</div>';
						
						merged.push(val)
					});
					
					if(4 == params.position)
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_4				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_4					+= '<div class="row">' + col + '</div>';
					}
					else if(3 == params.position)
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_3				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_3					+= '<div class="row">' + col + '</div>';
					}
					else if(2 == params.position)
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_2				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_2					+= '<div class="row">' + col + '</div>';
					}
					else
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_1				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_1					+= '<div class="row">' + col + '</div>';
					}
				}
				else
				{
					if($.inArray(field, merged) !== -1) return;
					
					output							= '<div class="form-group border-bottom"><label class="text-muted d-block" for="' + field + '_label">' + params.label + '</label><p id="' + field + '_label" class="text-break-word">' + params.content + '</p></div>';
					
					if(4 == params.position)
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_4				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_4					+= output;
					}
					else if(3 == params.position)
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_3				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_3					+= output;
					}
					else if(2 == params.position)
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_2				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_2					+= output;
					}
					else
					{
						if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
						{
							column_1				+= '<h5>' + response.results.set_heading[field] + '</h5>';
						}
						
						column_1					+= output;
					}
				}
			});
			
			if(4 == response.results.column_total)
			{
				modal_size							= 'modal-xl';
				
				output								= 
					'<div class="row">' +
						'<div class="column ' + (response.results.column_size[0] ? response.results.column_size[0] : (col ? 'col-md-3' : 'col')) + '">' +
							column_1 +
						'</div>' +
						'<div class="column ' + (response.results.column_size[1] ? response.results.column_size[1] : (col ? 'col-md-3' : 'col')) + '">' +
							column_2 +
						'</div>' +
						'<div class="column ' + (response.results.column_size[2] ? response.results.column_size[2] : (col ? 'col-md-3' : 'col')) + '">' +
							column_3 +
						'</div>' +
						'<div class="column ' + (response.results.column_size[3] ? response.results.column_size[3] : (col ? 'col-md-3' : 'col')) + '">' +
							column_4 +
						'</div>' +
					'</div>';
			}
			else if(3 == response.results.column_total)
			{
				modal_size							= 'modal-xl';
				
				output								= 
					'<div class="row">' +
						'<div class="column ' + (response.results.column_size[0] ? response.results.column_size[0] : (col ? 'col-md-4' : 'col')) + '">' +
							column_1 +
						'</div>' +
						'<div class="column ' + (response.results.column_size[1] ? response.results.column_size[1] : (col ? 'col-md-4' : 'col')) + '">' +
							column_2 +
						'</div>' +
						'<div class="column ' + (response.results.column_size[2] ? response.results.column_size[2] : (col ? 'col-md-4' : 'col')) + '">' +
							column_3 +
						'</div>' +
					'</div>';
			}
			else if(2 == response.results.column_total)
			{
				modal_size							= 'modal-lg';
				
				output								= 
					'<div class="row">' +
						'<div class="column ' + (response.results.column_size[0] ? response.results.column_size[0] : (col ? 'col-md-6' : 'col')) + '">' +
							column_1 +
						'</div>' +
						'<div class="column ' + (response.results.column_size[1] ? response.results.column_size[1] : (col ? 'col-md-6' : 'col')) + '">' +
							column_2 +
						'</div>' +
					'</div>';
			}
			else
			{
				modal_size							= '';
				
				output								= column_1 + column_2 + column_3 + column_4;
			}
			
			$(config.content_wrapper).html
			(
				'<div class="container-fluid ' + (map ? 'pb-3' : 'pt-3 pb-3') + '">' +
					map +
					'<div class="row">' +
						'<div class="column col-md-' + (1 == response.results.column_total ? 6 : (2 == response.results.column_total ? 10 : 10)) + '">' +
							output +
						'</div>' +
					'</div>' +
					'<div class="opt-btn-overlap-fix"></div><!-- fix the overlap -->' +
					'<div class="row opt-btn">' +
						'<div class="col-md-' + (1 == response.results.column_total ? 6 : (2 == response.results.column_total ? 10 : 10)) + ' col-md-offset-1">' +
							'<a href="' + go_to('..', response.results.query_string) + '" class="btn btn-link --xhr">' +
								'<i class="mdi mdi-arrow-left"></i> ' +
								(phrase.back ? phrase.back : 'Back') +
							'</a>' +
							'<a href="' + response.current_page.replace('/read?', '/update?') + '" class="btn btn-primary float-right --open-modal-form">' +
								'<i class="mdi mdi-square-edit-outline"></i> ' +
								(phrase.update ? phrase.update : 'Update') +
							'</a>' +
						'</div>' +
					'</div>' +
				'</div>'
			),
			
			_reactivate();
			
			return;
		}
		else if(sessionStorage.getItem('read'))
		{
			this.load_modal(JSON.parse(sessionStorage.getItem('read')), 'read');
		}
		else
		{
			/* fire modal to show */
			$(
				'<div class="modal" id="read-modal" role="dialog" aria-labelledby="read-modal-title" aria-hidden="true">' +
					'<div class="modal-dialog modal-dialog-centered" role="document">' +
						'<div class="modal-content">' +
							'<div class="modal-header">' +
								'<h5 class="modal-title" id="read-modal-title">' +
									'<i class="mdi mdi-information-outline"></i> ' +
									'<span class="modal-title-text">' +
										(phrase.showing_data ? phrase.showing_data : 'Showing Data') +
									'</span>' +
								'</h5>' + 
								'<button type="button" class="close" data-dismiss="modal" aria-label="' + (phrase.close ? phrase.close : 'Close') + '">' +
									'<span aria-hidden="true">&times;</span>' +
								'</button>' +
							'</div>' +
							'<div class="modal-body">' +
								'<div class="d-flex justify-content-center">' +
									'<div class="spinner-border text-primary" role="status">' +
										'<span class="sr-only">' + (phrase.loading ? phrase.loading : 'Loading...') + '</span>' +
									'</div>' +
								'</div>' +
							'</div>' +
							'<div class="modal-footer">' +
								'<button type="button" class="btn btn-light mr-1" data-dismiss="modal">' +
									(phrase.close ? phrase.close : 'Close') +
									' <em class="text-sm">(esc)</em>' +
								'</button>' +
							'</div>' +
						'</div>' +
					'</div>' +
				'</div>'
			)
			.appendTo('body')
			.modal({backdrop:'static', keyboard: false})
		}
		
		/* generate the response data */
		$.ajax
		({
			method: 'POST',
			data:
			{
				prefer: 'modal'
			},
			url: _this.attr('href'),
			statusCode:
			{
				301: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					if(typeof response.redirect !== 'undefined' && response.redirect)
					{
						return window.location.replace(response.target);
					}
					
					$('.modal').modal('hide');
					
					return throw_exception(response.status, (typeof response.message !== 'undefined' ? response.message : error));
				},
				403: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					if(typeof response.redirect !== 'undefined' && response.redirect)
					{
						return window.location.replace(response.target);
					}
					
					$('.modal').modal('hide');
					
					return throw_exception(response.status, (typeof response.message !== 'undefined' ? response.message : error));
				},
				404: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					if(typeof response.redirect !== 'undefined' && response.redirect)
					{
						return window.location.replace(response.target);
					}
					
					$('.modal').modal('hide');
					
					return throw_exception(response.status, (typeof response.message !== 'undefined' ? response.message : error));
				},
				500: function(response, status, error)
				{
					/* throw warning exception */
					$('#read-modal').find('.modal-body').addClass('bg-dark text-center p-3').html('<p><code>' + response + '</code></p><p class="mt-5"><a href="#" class="btn btn-outline-light btn-sm --report-to-admin">' + (phrase.report_to_admin ? phrase.report_to_admin : 'Report to Admin') + '</a></p>');
					
					return throw_exception(500, (typeof response.message !== 'undefined' ? response.message : error));
				}
			}
		})
		.done(function(response)
		{
			if(sessionStorage.getItem('read'))
			{
				/* loop response */
				$.each(response.results.form_data, function(key, val)
				{
					$('#' + key + '_label').replaceWith(val.content)
				}),
				
				/* looping is done. now show in the element */
				_reactivate()
			}
			else
			{
				/* loop the result */
				var output							= '',
					col								= '',
					column_1						= '',
					column_2						= '',
					column_3						= '',
					column_4						= '',
					merged							= new Array(),
					map								= '';
				
				$.each(response.results.form_data, function(field, params)
				{
					if($.inArray('coordinate', params.type) !== -1 || $.inArray('point', params.type) !== -1 || $.inArray('polygon', params.type) !== -1 || $.inArray('linestring', params.type) !== -1)
					{
						map							= '<div class="form-group" style="margin-left:-1rem; margin-right:-1rem">' + params.content + '</div>';
						
						return;
					}
					if(typeof response.results.merged_field[field] !== 'undefined')
					{
						var col						= '';
						
						$.each(response.results.merged_field[field], function(key, val)
						{
							if($.inArray(val, merged) !== -1 || typeof response.results.form_data[val] === 'undefined') return;
							
							col						+= 
							'<div class="' + (typeof response.results.field_size[val] !== 'undefined' ? response.results.field_size[val] : 'col') + '">' +
								'<div class="form-group border-bottom">' +
									'<label class="text-muted d-block" for="' + val + '_label">' +
										response.results.form_data[val]['label'] +
									'</label>' +
									'<p id="' + val + '_label" class="text-break-word">' +
										response.results.form_data[val]['content'] +
									'</p>' +
								'</div>' +
							'</div>';
							
							merged.push(val)
						});
						
						if(4 == params.position)
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_4			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_4				+= '<div class="row">' + col + '</div>';
						}
						else if(3 == params.position)
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_3			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_3				+= '<div class="row">' + col + '</div>';
						}
						else if(2 == params.position)
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_2			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_2				+= '<div class="row">' + col + '</div>';
						}
						else
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_1			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_1				+= '<div class="row">' + col + '</div>';
						}
					}
					else
					{
						if($.inArray(field, merged) !== -1) return;
						
						output						= '<div class="form-group border-bottom"><label class="text-muted d-block" for="' + field + '_input">' + params.label + (params.tooltip ? ' <i class="mdi mdi-information-outline text-primary" data-toggle="tooltip" title="' + params.tooltip + '"></i>' : '') + (params.required ? '<b class="text-danger"> *</b>' : '') + '</label>' + params.content + '</div>';
						
						if(4 == params.position)
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_4			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_4				+= output;
						}
						else if(3 == params.position)
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_3			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_3				+= output;
						}
						else if(2 == params.position)
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_2			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_2				+= output;
						}
						else
						{
							if(typeof response.results.set_heading !== 'undefined' && typeof response.results.set_heading[field] !== 'undefined')
							{
								column_1			+= '<h5>' + response.results.set_heading[field] + '</h5>';
							}
							
							column_1				+= output;
						}
					}
				});
				
				if(4 == response.results.column_total)
				{
					modal_size						= 'modal-xl';
					
					output							= 
						'<div class="row">' +
							'<div class="column ' + (response.results.column_size[0] ? response.results.column_size[0] : (col ? 'col-md-3' : 'col')) + '">' +
								column_1 +
							'</div>' +
							'<div class="column ' + (response.results.column_size[1] ? response.results.column_size[1] : (col ? 'col-md-3' : 'col')) + '">' +
								column_2 +
							'</div>' +
							'<div class="column ' + (response.results.column_size[2] ? response.results.column_size[2] : (col ? 'col-md-3' : 'col')) + '">' +
								column_3 +
							'</div>' +
							'<div class="column ' + (response.results.column_size[3] ? response.results.column_size[3] : (col ? 'col-md-3' : 'col')) + '">' +
								column_4 +
							'</div>' +
						'</div>';
				}
				else if(3 == response.results.column_total)
				{
					modal_size						= 'modal-xl';
					
					output							= 
						'<div class="row">' +
							'<div class="column ' + (response.results.column_size[0] ? response.results.column_size[0] : (col ? 'col-md-4' : 'col')) + '">' +
								column_1 +
							'</div>' +
							'<div class="column ' + (response.results.column_size[1] ? response.results.column_size[1] : (col ? 'col-md-4' : 'col')) + '">' +
								column_2 +
							'</div>' +
							'<div class="column ' + (response.results.column_size[2] ? response.results.column_size[2] : (col ? 'col-md-4' : 'col')) + '">' +
								column_3 +
							'</div>' +
						'</div>';
				}
				else if(2 == response.results.column_total)
				{
					modal_size						= 'modal-lg';
					
					output							= 
						'<div class="row">' +
							'<div class="column ' + (response.results.column_size[0] ? response.results.column_size[0] : (col ? 'col-md-6' : 'col')) + '">' +
								column_1 +
							'</div>' +
							'<div class="column ' + (response.results.column_size[1] ? response.results.column_size[1] : (col ? 'col-md-6' : 'col')) + '">' +
								column_2 +
							'</div>' +
						'</div>';
				}
				else
				{
					modal_size						= '';
					
					output							= '<div class="column">' + column_1 + column_2 + column_3 + column_4 + '</div>';
				}
				
				/* looping is done. now show in the element */
				$('#read-modal').find('.modal-dialog').addClass((response.meta.modal_size ? response.meta.modal_size : modal_size)),
				$('#read-modal').find('.modal-body').html(map + output),
				
				_reactivate()
			}
		})
	},
	
	/**
	 * CRUD: delete confirm
	 */
	delete: function(_this)
	{
		/* delete button. it will open the bootstrap 4 modal */
		$(
			'<div class="modal" id="delete-modal" role="dialog" aria-labelledby="delete-modal-title" aria-hidden="true">' +
				'<div class="modal-dialog modal-dialog-centered" role="document" style="max-width:400px">' +
					'<div class="modal-content border">' +
						'<div class="modal-header">' +
							'<h5 class="modal-title" id="delete-modal-title">' +
								'<i class="mdi mdi-trash-can-outline"></i> ' +
								'<span class="modal-title-text">' +
									(phrase.delete_data ? phrase.delete_data : 'Delete Data') +
								'</span>' +
							'</h5>' +
							'<button type="button" class="close" data-dismiss="modal" aria-label="' + (phrase.close ? phrase.close : 'Close') + '">' +
								'<span aria-hidden="true">&times;</span>' +
							'</button>' +
						'</div>' +
						'<div class="modal-body text-center">' +
							(_this.attr('data-bulk-delete') ? $('input[name^=bulk_delete]:checked').length + ' ' + (phrase.data_will_be_deleted ? phrase.data_will_be_deleted : 'Data will be deleted') : (phrase.are_you_sure_want_to_delete_this_data ? phrase.are_you_sure_want_to_delete_this_data : 'Are you sure want to delete this data?')) +
						'</div>' +
						'<div class="modal-footer" style="display:block">' +
							'<div class="row">' +
								'<div class="col-6">' +
									'<button type="button" class="btn btn-light btn-block" data-dismiss="modal">' +
										(phrase.cancel ? phrase.cancel : 'Cancel') +
									'</button>' +
								'</div>' +
								'<div class="col-6">' +
									'<a href="' + _this.attr('href') + '" class="btn btn-danger btn-block --delete-anyway"' + (_this.attr('data-bulk-delete') ? ' data-bulk-delete="true"' : '') + '>' +
										'<i class="mdi mdi-check"></i> ' +
										(phrase.delete ? phrase.delete : 'Delete') +
									'</a>' +
								'</div>' +
							'</div>' +
						'</div>' +
					'</div>' +
				'</div>' +
			'</div>'
		)
		.appendTo('body')
		.modal({keyboard: false})
	},
	
	/**
	 * CRUD: open modal
	 */
	load_modal: function(response, method)
	{
		if(response && typeof response.results !== 'undefined' && typeof response.results.form_data !== 'undefined')
		{
			/* loop the result */
			var output								= '',
				column_1							= '',
				column_2							= '',
				column_3							= '',
				column_4							= '',
				merged								= new Array(),
				extra_submit						= '',
				map									= '';
				
			if(typeof response.results.extra_action !== 'undefined' && typeof response.results.extra_action.submit !== 'undefined')
			{
				/* loop, the jQuery is required */
				$.each(response.results.extra_action.submit, function(key, val)
				{
					/* submit button is available */
					extra_submit					+= '<a href="' + go_to(val.url, val.parameter) + '" class="' + (val.class ? val.class : 'btn-default --xhr') + '"' + (val.new_tab ? ' target="_blank"' : null) + '><i class="' + (val.icon ? val.icon : 'mdi mdi-link') + '"></i>' + val.label + '</a>';
				})
			}
			
			$.each(response.results.form_data, function(field, params)
			{
				$('#' + field + '_input, #' + field + '_label').remove();
				
				if($.inArray('coordinate', params.type) !== -1 || $.inArray('point', params.type) !== -1 || $.inArray('polygon', params.type) !== -1 || $.inArray('linestring', params.type) !== -1)
				{
					map								= '<div class="form-group" style="margin-left:-1rem; margin-right:-1rem"><div id="' + field + ('form' == method ? '_input' : '_label') + '"></div></div>';
					
					return;
				}
				
				if(typeof response.results.merged_field[field] !== 'undefined')
				{
					var col							= '';
					
					$.each(response.results.merged_field[field], function(key, val)
					{
						if($.inArray(val, merged) !== -1 || typeof response.results.form_data[val] === 'undefined') return;
						
						col							+= 
						'<div class="' + (typeof response.results.field_size[val] !== 'undefined' ? response.results.field_size[val] : 'col') + '">' +
							'<div class="form-group' + ('form' != method ? ' border-bottom' : '') + '">' +
								'<label class="text-muted d-block" for="' + val + ('form' == method ? '_input' : '_label') + '">' +
									response.results.form_data[val]['label'] +
									('form' == method && response.results.form_data[val]['tooltip'] ? ' <i class="mdi mdi-information-outline text-primary" data-toggle="tooltip" title="' + response.results.form_data[val]['tooltip'] + '"></i>' : '') +
									('form' == method && response.results.form_data[val]['required'] ? '<b class="text-danger"> *</b>' : '') +
								'</label>' +
								('form' == method ? (response.results.form_data[val]['prepend'] || response.results.form_data[val]['append'] ? '<div class="input-group">' : '') + (response.results.form_data[val]['prepend'] ? '<div class="input-group-prepend"><span class="input-group-text">' + response.results.form_data[val]['prepend'] + '</span></div>' : '') + '<input type="text" class="form-control disabled" id="' + val + '_input" placeholder="' + (phrase.loading ? phrase.loading : 'Loading...') + '" disabled />' + (response.results.form_data[val]['append'] ? '<div class="input-group-append"><span class="input-group-text">' + response.results.form_data[val]['append'] + '</span></div>' : '') + (response.results.form_data[val]['prepend'] || response.results.form_data[val]['append'] ? '</div>' : '') : '<p id="' + val + '_label" class="text-break-word">' + (phrase.loading ? phrase.loading : 'Loading...') + '</p>') +
							'</div>' +
						'</div>';
						
						merged.push(val)
					});
					
					if(4 == params.position)
					{
						column_4					+= '<div class="row">' + col + '</div>';
					}
					else if(3 == params.position)
					{
						column_3					+= '<div class="row">' + col + '</div>';
					}
					else if(2 == params.position)
					{
						column_2					+= '<div class="row">' + col + '</div>';
					}
					else
					{
						column_1					+= '<div class="row">' + col + '</div>';
					}
				}
				else
				{
					if($.inArray(field, merged) !== -1) return;
					
					output							= '<div class="form-group' + ('form' != method ? ' border-bottom' : '') + '"><label class="text-muted d-block" for="' + field + ('form' == method ? '_input' : '_label') + '">' + params.label + ('form' == method && params.tooltip ? ' <i class="mdi mdi-information-outline text-primary" data-toggle="tooltip" title="' + params.tooltip + '"></i>' : '') + ('form' == method && params.required ? '<b class="text-danger"> *</b>' : '') + '</label>' + ('form' == method ? (params.prepend || params.append ? '<div class="input-group">' : '') + (params.prepend ? '<div class="input-group-prepend"><span class="input-group-text">' + params.prepend + '</span></div>' : '') + '<input type="text" class="form-control disabled" id="' + field + '_input" placeholder="' + (phrase.loading ? phrase.loading : 'Loading...') + '" disabled />' + (params.append ? '<div class="input-group-append"><span class="input-group-text">' + params.append + '</span></div>' : '') + (params.prepend || params.append ? '</div>' : '') : '<p id="' + field + '_label" class="text-break-word">' + (phrase.loading ? phrase.loading : 'Loading...') + '</p>') + '</div>';
					
					if(4 == params.position)
					{
						column_4					+= output;
					}
					else if(3 == params.position)
					{
						column_3					+= output;
					}
					else if(2 == params.position)
					{
						column_2					+= output;
					}
					else
					{
						column_1					+= output;
					}
				}
			});
			
			if(4 == response.results.column_total)
			{
				modal_size							= 'modal-xl';
				
				output								= 
					'<div class="row">' +
						'<div class="column ' + (response.results.column_size[0] ? response.results.column_size[0] : 'col') + '">' +
							column_1 +
						'</div>' +
						'<div class="column ' + (response.results.column_size[1] ? response.results.column_size[1] : 'col') + '">' +
							column_2 +
						'</div>' +
						'<div class="column ' + (response.results.column_size[2] ? response.results.column_size[2] : 'col') + '">' +
							column_3 +
						'</div>' +
						'<div class="column ' + (response.results.column_size[3] ? response.results.column_size[3] : 'col') + '">' +
							column_4 +
						'</div>' +
					'</div>';
			}
			else if(3 == response.results.column_total)
			{
				modal_size							= 'modal-xl';
				
				output								= 
					'<div class="row">' +
						'<div class="column ' + (response.results.column_size[0] ? response.results.column_size[0] : 'col') + '">' +
							column_1 +
						'</div>' +
						'<div class="column ' + (response.results.column_size[1] ? response.results.column_size[1] : 'col') + '">' +
							column_2 +
						'</div>' +
						'<div class="column ' + (response.results.column_size[2] ? response.results.column_size[2] : 'col') + '">' +
							column_3 +
						'</div>' +
					'</div>';
			}
			else if(2 == response.results.column_total)
			{
				modal_size							= 'modal-lg';
				
				output								= 
					'<div class="row">' +
						'<div class="column ' + (response.results.column_size[0] ? response.results.column_size[0] : 'col') + '">' +
							column_1 +
						'</div>' +
						'<div class="column ' + (response.results.column_size[1] ? response.results.column_size[1] : 'col') + '">' +
							column_2 +
						'</div>' +
					'</div>';
			}
			else
			{
				modal_size							= '';
				
				output								= '<div class="column">' + column_1 + column_2 + column_3 + column_4 + '</div>';
			}
			
			$(
				'<div class="modal" id="' + ('form' == method ? 'form' : 'read') + '-modal" role="dialog" aria-labelledby="' + ('form' == method ? 'form' : 'read') + '-modal-title" aria-hidden="true">' +
					'<div class="modal-dialog modal-dialog-centered' + (response.meta.modal_size ? ' ' + response.meta.modal_size : (modal_size ? ' ' + modal_size : '')) + '" role="document">' +
						('form' == method ? '<form action="#" method="POST" class="modal-content" enctype="multipart/form-data">' : '<div class="modal-content">') +
							'<div class="modal-header">' +
								'<h5 class="modal-title" id="' + ('form' == method ? 'form' : 'read') + '-modal-title">' +
									'<i class="' + response.meta.icon + '"></i> ' +
									'<span class="modal-title-text">' +
										response.meta.title +
									'</span>' +
								'</h5>' + 
								'<button type="button" class="close" data-dismiss="modal" aria-label="' + (phrase.close ? phrase.close : 'Close') + '">' +
									'<span aria-hidden="true">&times;</span>' +
								'</button>' +
							'</div>' +
							'<div class="modal-body' + (map ? ' pt-0' : '') + '">' +
								
								map +
								
								output +
								
								'<div class="--validation-callback mb-0"></div>' +
								
							'</div>' +
							'<div class="modal-footer">' +
								'<button type="button" class="btn btn-light mr-1' + (extra_submit ? ' mr-auto' : '') + '" data-dismiss="modal">' +
									(phrase.close ? phrase.close : 'Close') +
									' <em class="text-sm">(esc)</em>' +
								'</button>' +
								('form' == method ?
								extra_submit +
								'<button type="submit" class="btn btn-primary disabled" disabled>' +
									'<i class="mdi mdi-check"></i> ' +
									(phrase.submit ? phrase.submit : 'Submit') +
									' <em class="text-sm">(ctrl+s)</em>' +
								'</button>' : '') +
							'</div>' +
						'</div>' +
					'</div>' +
				'</div>'
			)
			.appendTo('body')
			.modal({backdrop:'static', keyboard: false})
		}
	},
	
	/**
	 * Load content inside modal
	 */
	modal: function(_this)
	{
		var identifier								= Date.now();
		
		/* it will open the bootstrap 4 modal */
		$(
			'<div class="modal" id="dynamic-modal-' + identifier +'" role="dialog" aria-labelledby="dynamic-modal-title" aria-hidden="true">' +
				'<div class="modal-dialog modal-dialog-centered" role="document">' +
					'<div class="modal-content' + ($('.modal').length ? ' border shadow' : '') + '">' +
						'<div class="modal-header">' +
							'<h5 class="modal-title" id="dynamic-modal-title">' +
								'<i class="mdi mdi-loading mdi-spin"></i> ' +
								'<span class="modal-title-text">' +
									(phrase.loading ? phrase.loading : 'Loading') +
								'</span>' +
							'</h5>' +
							'<button type="button" class="close" data-dismiss="modal" aria-label="' + (phrase.close ? phrase.close : 'Close') + '">' +
								'<span aria-hidden="true">&times;</span>' +
							'</button>' +
						'</div>' +
						'<div class="modal-body p-0">' +
							'<div class="d-flex justify-content-center pt-5 pb-5">' +
								'<div class="spinner-border" role="status">' +
									'<span class="sr-only">' + (phrase.loading ? phrase.loading : 'Loading...') + '</span>' +
								'</div>' +
							'</div>' +
						'</div>' +
					'</div>' +
				'</div>' +
			'</div>'
		)
		.appendTo('body')
		.modal({backdrop:'static', keyboard: false}),
		
		$.ajax
		({
			url: _this.attr('href'),
			context: this,
			method: 'POST',
			data:
			{
				prefer: 'modal'
			},
			statusCode:
			{
				301: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					if(response.redirect)
					{
						return window.location.replace(response.target);
					}
					
					$('.modal').modal('hide');
					
					return throw_exception(response.status, (typeof response.message !== 'undefined' ? response.message : error));
				},
				403: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					if(response.redirect)
					{
						return window.location.replace(response.target);
					}
					
					$('.modal').modal('hide');
					
					return throw_exception(response.status, (typeof response.message !== 'undefined' ? response.message : error));
				},
				404: function(response, status, error)
				{
					if(typeof response.responseJSON !== 'undefined')
					{
						response					= response.responseJSON;
					}
					
					if(response.redirect)
					{
						return window.location.replace(response.target);
					}
					
					$('.modal').modal('hide');
					
					return throw_exception(response.status, (typeof response.message !== 'undefined' ? response.message : error));
				}
			}
		})
		.done(function(response)
		{
			if(response && typeof response._token !== 'undefined')
			{
				sessionStorage.setItem('_token', response._token)
			}
			
			if(response)
			{
				$('#dynamic-modal-' + identifier).find('.modal-body').html(response.html),
				(response && typeof response.meta !== 'undefined' && typeof response.meta.modal_size !== 'undefined' ? $('.modal-dialog').addClass(response.meta.modal_size) : null),
				
				(!_this.hasClass('--prevent-remove') ? _reactivate() : null)
			}
			else
			{
				$('#dynamic-modal-' + identifier).find('.modal-body').html
				(
					'<div class="container-fluid">' +
						'<div class="row bg-dark full-height">' +
							'<div class="col-12">' +
								'<div class="pt-3 pb-3 text-success text-monospace">' +
									'<p class="mb-0">' +
										'[info@localhost ~]# aksara -tell readonly' +
									'</p>' +
									'<p class="mb-0 text-danger">' +
										(phrase.no_response_could_be_loaded ? phrase.no_response_could_be_loaded : 'No response could be loaded') +
										'<br />' +
										(phrase.make_sure_to_check_the_following_mistake ? phrase.make_sure_to_check_the_following_mistake : 'Make sure to check the following mistake') + ':' +
										'<ol class="text-danger">' +
											'<li>' +
												(phrase.module_structure ? phrase.module_structure : 'Module structure') + ',' +
											'</li>' +
											'<li>' +
												(phrase.incorrect_view_path ? phrase.incorrect_view_path : 'Incorrect view path') + ',' +
											'</li>' +
											'<li>' +
												(phrase.database_table_existence ? phrase.database_table_existence : 'Database table existence') + ',' +
											'</li>' +
											'<li>' +
												(phrase.something_caused_by_typo ? phrase.something_caused_by_typo : 'Something caused by typo') + '.' +
											'</li>' +
										'</ol>' +
									'</p>' +
									'<p class="mb-0">' +
										'[info@localhost ~]# <blink>_</blink>' +
									'</p>' +
								'</div>' +
							'</div>' +
						'</div>' +
					'</div>'
				)
			}
			
			$('#dynamic-modal-' + identifier).find('.modal-title').find('.mdi').removeClass('mdi mdi-loading mdi-spin').addClass((response && typeof response.meta !== 'undefined' && typeof response.meta.icon !== 'undefined' ? response.meta.icon : 'mdi mdi-alert-outline')),
			$('#dynamic-modal-' + identifier).find('.modal-title').find('.modal-title-text').text((response && typeof response.meta !== 'undefined' && typeof response.meta.title !== 'undefined' ? response.meta.title : (phrase.title_was_not_set ? phrase.title_was_not_set : 'Title was not set')))
		})
	},
	
	/**
	 * CRUD: option menu that visible to mobile browser
	 */
	option: function(_this)
	{
		var extra_opt								= '';
		
		if(_this.attr('data-additional-option'))
		{
			var opt									= JSON.parse(_this.attr('data-additional-option'));
			
			$.each(opt, function(key, val)
			{
				extra_opt							+= '<a href="' + val.href + '" class="list-group-item list-group-item-action border-left-0 border-right-0 ' + (val.class ? val.class : '--xhr') + '"' + (val.new_tab ? ' target="_blank"' : null) + '><i class="' + (val.icon ? val.icon : 'mdi mdi-link') + '"></i> ' + val.label + '</a>';
			})
		}
		
		/* it will open the option modal to control clicked item */
		$(
			'<div class="modal" id="option-modal" role="dialog" aria-labelledby="option-modal-title" aria-hidden="true">' +
				'<div class="modal-dialog modal-dialog-centered" role="document">' +
					'<div class="modal-content">' +
						'<div class="modal-header">' +
							'<h5 class="modal-title" id="option-modal-title">' +
								'<i class="mdi mdi-cogs"></i> ' +
								'<span class="modal-title-text">' +
									(phrase.options ? phrase.options : 'Options') +
								'</span>' +
							'</h5>' +
						'</div>' +
						'<div class="modal-body pr-0 pl-0">' +
							'<div class="list-group list-group-flush">' +
								
								extra_opt +
								
							'</div>' +
						'</div>' +
					'</div>' +
				'</div>' +
			'</div>'
		)
		.appendTo('body')
		.modal({keyboard: false})
	},
	
	login: function(_this, event)
	{
		(event.preventDefault ? event.preventDefault() : event.returnValue = false);
		
		var years									= '';
		
		$.each(config.active_years, function(key, val)
		{
			years									+= '<option value="' + val.value + '"' + (val.selected ? ' selected' : '') + '>' + val.label + '</option>';
		}),
		
		/* it will open the bootstrap 4 modal */
		$(
			'<div class="modal" id="login-modal" role="dialog" aria-labelledby="login-modal-title" aria-hidden="true">' +
				'<div class="modal-dialog modal-dialog-centered' + (config.registration_enabled ? ' modal-lg' : '" style="max-width:400px') + '" role="document">' +
					'<div class="modal-content bg-transparent">' +
						'<div class="modal-body p-0">' +
							'<div class="card-group">' +
								'<div class="card shadow">' +
									'<div class="modal-header">' +
										'<h5 class="modal-title" id="login-modal-title">' +
											'<i class="mdi mdi-account-key-outline"></i> ' +
											'<span class="modal-title-text">' +
												(phrase.authentication ? phrase.authentication : 'Authentication') +
											'</span>' +
										'</h5>' +
										'<button type="button" class="close" data-dismiss="modal" aria-label="' + (phrase.close ? phrase.close : 'Close') + '">' +
											'<span aria-hidden="true">&times;</span>' +
										'</button>' +
									'</div>' +
									'<div class="card-body">' +
										'<form action="' + _this.href + '" method="POST" class="--validate-form" enctype="multipart/form-data">' +
											'<p class="text-center text-muted">' +
												'<i class="mdi mdi-lock-open-outline mdi-5x"></i>' +
											'</p>' +
											'<p class="pb-3 text-center">' +
												(phrase.use_your_account_information_to_start_session ? phrase.use_your_account_information_to_start_session : 'Use your account information to start session') +
											'</p>' +
											'<div style="margin-left:-6px;margin-right:-6px">' +
												'<div class="row bg-secondary pt-4 pb-3">' +
													'<div class="col">' +
														'<div class="form-group">' +
															'<div class="input-group flex-nowrap">' +
																'<input type="text" name="username" class="form-control bg-dark text-light border-0" id="username_input" placeholder="' + (phrase.enter_your_username_or_email ? phrase.enter_your_username_or_email : 'Enter your username or email') + '" />' +
																'<div class="input-group-append">' +
																	'<span class="input-group-text bg-dark text-light border-0">' +
																		'<i class="mdi mdi-account-outline" style="width:22px"></i>' +
																	'</span>' +
																'</div>' +
															'</div>' +
														'</div>' +
														'<div class="form-group">' +
															'<div class="input-group flex-nowrap">' +
																'<input type="password" name="password" class="form-control bg-dark text-light border-0" id="password_input" placeholder="' + (phrase.enter_password ? phrase.enter_password : 'Enter password') + '" />' +
																'<div class="input-group-append">' +
																	'<span class="input-group-text bg-dark text-light border-0">' +
																		'<i class="mdi mdi-fingerprint" style="width:22px"></i>' +
																	'</span>' +
																'</div>' +
															'</div>' +
														'</div>' +
														(years ?
														'<div class="form-group">' +
															'<div class="input-group flex-nowrap">' +
																'<select name="year" class="form-control bg-dark text-light border-0" placeholder="' + phrase.choose_year + '" id="year_input">' +
																	years +
																'</select>' +
																'<div class="input-group-append">' +
																	'<span class="input-group-text bg-dark text-light border-0">' +
																		'<i class="mdi mdi-calendar-check" style="width:22px"></i>' +
																	'</span>' +
																'</div>' +
															'</div>' +
														'</div>' : '') +
														
														'<div class="--validation-callback mb-0"></div>' +
														
													'</div>' +
												'</div>' +
											'</div>' +
											'<div style="margin-left:-6px;margin-right:-6px">' +
												'<div class="row mt-3">' +
													'<div class="col-7">' +
														'<label class="mt-2">' +
															'<a href="' + config.base_url + 'auth/forgot" class="--xhr"> ' +
																(phrase.forgot_password ? phrase.forgot_password : 'Forgot Password?') +
															'</a>' +
														'</label>' +
													'</div>' +
													'<div class="col-5">' +
														'<button type="submit" class="btn btn-primary btn-block">' +
															'<i class="mdi mdi-check"></i> ' +
															(phrase.sign_in ? phrase.sign_in : 'Sign In') + 
														'</button>' +
													'</div>' +
												'</div>' +
											'</div>' +
										'</form>' +
									'</div>' +
								'</div>' +
								(config.registration_enabled ? '<div class="card shadow">' +
									'<div class="card-body d-flex align-items-center justify-content-center">' +
										'<div>' +
											'<p class="lead text-center text-muted">' +
												(phrase.do_not_have_an_account ? phrase.do_not_have_an_account : 'Don\'t have an account?') +
											'</p>' +
											(config.google_auth ?
											'<p class="lead text-center">' +
												'<a href="' + config.base_url + 'auth/google" class="btn btn-outline-danger btn-block">' +
													'<i class="mdi mdi-google"></i> ' +
													(phrase.sign_with_google ? phrase.sign_with_google : 'Sign With Google') +
												'</a>' +
											'</p>'
											: '') +
											(config.facebook_auth ?
											'<p class="lead text-center">' +
												'<a href="' + config.base_url + 'auth/facebook" class="btn btn-outline-primary btn-block">' +
													'<i class="mdi mdi-facebook"></i> ' +
													(phrase.sign_with_facebook ? phrase.sign_with_facebook : 'Sign With Facebook') +
												'</a>' +
											'</p>'
											: '') +
											'<p class="lead text-center">' +
												'<a href="' + config.base_url + 'auth/register" class="btn btn-outline-info btn-block --xhr">' +
													'<i class="mdi mdi-account-plus"></i> ' +
													(phrase.register_an_account ? phrase.register_an_account : 'Register an Account') +
												'</a>' +
											'</p>' +
										'</div>' +
									'</div>' +
								'</div>' : '') +
							'</div>' +
						'</div>' +
					'</div>' +
				'</div>' +
			'</div>'
		)
		.appendTo('body')
		.modal({backdrop:'static', keyboard: false}),
		
		$('#username_input').trigger('focus'),
		
		_reactivate(),
		
		$.post(_this.href, {request: '_token'}, function(response)
		{
			if(typeof response._token !== 'undefined')
			{
				sessionStorage.setItem('_token', response._token)
			}
		})
	},
	
	profile: function(_this, event)
	{
		if(!config.is_logged)
		{
			$('<a href="' + config.base_url + 'auth" class="--xhr"></a>').appendTo('body').trigger('click').remove();
			
			return;
		}
		
		var translations							= '';
		
		$.each(JSON.parse(_this.attr('data-translations')), function(key, val)
		{
			translations							+= '<a href="' + config.base_url + 'xhr/language/' + key + '" class="list-group-item list-group-item-action --xhr pt-1 pb-1">' + val + '</a>';
		}),
		
		/* it will open the bootstrap 4 modal */
		$(
			'<div class="modal" id="profile-modal" role="dialog" aria-labelledby="profile-modal-title" aria-hidden="true">' +
				'<div class="modal-dialog modal-dialog-centered modal-sm" role="document">' +
					'<div class="modal-content bg-transparent">' +
						'<div class="modal-body p-0">' +
							'<div class="card-group">' +
								'<div class="card shadow">' +
									'<div class="modal-header">' +
										'<h5 class="modal-title" id="profile-modal-title">' +
											'<i class="mdi mdi-menu"></i> ' +
											'<span class="modal-title-text">' +
												(phrase.options ? phrase.options : 'Options') +
											'</span>' +
										'</h5>' +
										'<button type="button" class="close" data-dismiss="modal" aria-label="' + (phrase.close ? phrase.close : 'Close') + '">' +
											'<span aria-hidden="true">&times;</span>' +
										'</button>' +
									'</div>' +
									'<div class="card-body p-0">' +
										'<div class="p-3">' +
											'<button type="button" class="btn btn-outline-secondary btn-block btn-sm" data-toggle="collapse" data-target="#languageSelection" aria-haspopup="true" aria-expanded="false">' +
												'<i class="mdi mdi-translate"></i>' +
												(phrase.language ? phrase.language : 'Language') +
											'</button>' +
											'<div class="collapse" id="languageSelection">' +
												'<div class="list-group mt-3">' +
													translations +
												'</div>' +
											'</div>' +
										'</div>' +
										'<div class="list-group list-group-flush">' +
											'<a href="' + config.base_url + 'dashboard' + '" class="list-group-item pr-3 pl-3">' +
												'<i class="mdi mdi-monitor-dashboard"></i> ' +
												(phrase.dashboard ? phrase.dashboard : 'Dashboard') +
											'</a>' +
											'<a href="' + config.base_url + 'user" class="list-group-item pr-3 pl-3" target="_blank">' +
												'<i class="mdi mdi-account-circle-outline"></i> ' +
												(phrase.profile ? phrase.profile : 'Profile') +
											'</a>' +
											'<a href="' + config.base_url + 'administrative/account" class="list-group-item pr-3 pl-3 --xhr">' +
												'<i class="mdi mdi-account-outline"></i> ' +
												(phrase.account ? phrase.account : 'Account') +
											'</a>' +
											'<a href="' + config.base_url + 'auth/sign_out" class="list-group-item pr-3 pl-3 text-danger --xhr">' +
												'<i class="mdi mdi-logout"></i> ' +
												(phrase.sign_out ? phrase.sign_out : 'Sign Out') +
											'</a>' +
										'</div>' +
									'</div>' +
								'</div>' +
							'</div>' +
						'</div>' +
					'</div>' +
				'</div>' +
			'</div>'
		)
		.appendTo('body')
		.modal()
	},
	
	/**
	 * breadcrumb
	 */
	breadcrumb: function(response)
	{
		if(!response) return;
		
		var content									= '';
		
		$.each(response, function(key, val)
		{
			content									+= '<li class="breadcrumb-item"><a href="' + val.url + '" class="--xhr">' + (val.icon ? '<i class="' + val.icon + '"></i> ' : ' ') + val.label + '</a></li>';
		}),
		
		$('.breadcrumb').html('').html(content)
	}
};

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