/**
|
<b>Load content via Ajax </b>. For more information please refer to documentation #basics/ajax
|
*/
|
|
(function($ , undefined) {
|
var ajax_loaded_scripts = {}
|
|
function AceAjax(contentArea, settings) {
|
var $contentArea = $(contentArea);
|
var self = this;
|
$contentArea.attr('data-ajax-content', 'true');
|
|
//get a list of 'data-*' attributes that override 'defaults' and 'settings'
|
var attrib_values = ace.helper.getAttrSettings(contentArea, $.fn.ace_ajax.defaults);
|
this.settings = $.extend({}, $.fn.ace_ajax.defaults, settings, attrib_values);
|
|
|
var working = false;
|
var $overlay = $();//empty set
|
|
this.force_reload = false;//set jQuery ajax's cache option to 'false' to reload content
|
this.loadUrl = function(hash, cache, manual_trigger) {
|
var url = false;
|
hash = hash.replace(/^(\#\!)?\#/, '');
|
|
this.force_reload = (cache === false)
|
|
if(typeof this.settings.content_url === 'function') url = this.settings.content_url(hash);
|
if(typeof url === 'string') this.getUrl(url, hash, manual_trigger);
|
}
|
|
this.loadAddr = function(url, hash, cache) {
|
this.force_reload = (cache === false);
|
this.getUrl(url, hash, false);
|
}
|
|
|
this.reload = function() {
|
var hash = $.trim(window.location.hash);
|
if(!hash && this.settings.default_url) hash = this.settings.default_url;
|
|
this.loadUrl(hash, false);
|
}
|
this.post = function(url, data, updateView, extraParams) {
|
var url = url || $.trim(location.href.replace(location.hash,''));
|
if(!url) return;
|
var data = data || {}
|
var updateView = updateView || false;
|
this.getUrl(url, null, false, 'POST', data, updateView, extraParams);
|
}
|
|
|
this.getUrl = function(url, hash, manual_trigger, method, data, updateView, extraParams) {
|
if(working) {
|
return;
|
}
|
|
var method = method || 'GET';
|
var updateView = (method == 'GET') || (method == 'POST' && updateView == true)
|
var data = data || null;
|
|
var event
|
$contentArea.trigger(event = $.Event('ajaxloadstart'), {url: url, hash: hash, method: method, data: data})
|
if (event.isDefaultPrevented()) return;
|
|
self.startLoading();
|
|
|
var ajax_params = method == 'GET' ? {'url': url, 'cache': !this.force_reload} : {'url': url, 'method' : 'POST', 'data': data}
|
if(method == 'POST' && typeof extraParams == 'object') ajax_params = $.extend({}, ajax_params, extraParams);
|
|
$.ajax(ajax_params)
|
.error(function() {
|
$contentArea.trigger('ajaxloaderror', {url: url, hash: hash, method: method, data: data});
|
|
self.stopLoading(true);
|
})
|
.done(function(result) {
|
$contentArea.trigger('ajaxloaddone', {url: url, hash: hash, method: method, data: data});
|
if(method == 'POST') {
|
var event
|
$contentArea.trigger(event = $.Event('ajaxpostdone', {url: url, data: data, result: result}))
|
if( event.isDefaultPrevented() ) updateView = false;
|
}
|
|
|
var link_element = null, link_text = '';
|
if(typeof self.settings.update_active === 'function') {
|
link_element = self.settings.update_active.call(null, hash, url, method, updateView);
|
}
|
else if(self.settings.update_active === true && hash) {
|
link_element = $('a[data-url="'+hash+'"]');
|
if(link_element.length > 0) {
|
var nav = link_element.closest('.nav');
|
if(nav.length > 0) {
|
nav.find('.active').each(function(){
|
var $class = 'active';
|
if( $(this).hasClass('hover') || self.settings.close_active ) $class += ' open';
|
|
$(this).removeClass($class);
|
if(self.settings.close_active) {
|
$(this).find(' > .submenu').css('display', '');
|
}
|
})
|
|
var active_li = link_element.closest('li').addClass('active').parents('.nav li').addClass('active open');
|
nav.closest('.sidebar[data-sidebar-scroll=true]').each(function() {
|
var $this = $(this);
|
$this.ace_sidebar_scroll('reset');
|
if(manual_trigger == true) $this.ace_sidebar_scroll('scroll_to_active');//first time only
|
})
|
}
|
}
|
}
|
|
/////////
|
if(typeof self.settings.update_breadcrumbs === 'function') {
|
link_text = self.settings.update_breadcrumbs.call(null, hash, url, link_element, method, updateView);
|
}
|
else if(self.settings.update_breadcrumbs === true && link_element != null && link_element.length > 0) {
|
link_text = updateBreadcrumbs(link_element);
|
}
|
/////////
|
|
$overlay.addClass('content-loaded').detach();
|
if(updateView) {
|
//convert "title" and "link" tags to "div" tags for later processing
|
result = String(result)
|
.replace(/<(title|link)([\s\>])/gi,'<div class="hidden ajax-append-$1"$2')
|
.replace(/<\/(title|link)\>/gi,'</div>')
|
$contentArea.empty().html(result);
|
}
|
|
$(self.settings.loading_overlay || $contentArea).append($overlay);
|
|
|
|
//remove previous stylesheets inserted via ajax
|
if(updateView) setTimeout(function() {
|
$('head').find('link.ace-ajax-stylesheet').remove();
|
|
var main_selectors = ['link.ace-main-stylesheet', 'link#main-ace-style', 'link[href*="/ace.min.css"]', 'link[href*="/ace.css"]']
|
var ace_style = [];
|
for(var m = 0; m < main_selectors.length; m++) {
|
ace_style = $('head').find(main_selectors[m]).first();
|
if(ace_style.length > 0) break;
|
}
|
|
$contentArea.find('.ajax-append-link').each(function(e) {
|
var $link = $(this);
|
if ( $link.attr('href') ) {
|
var new_link = jQuery('<link />', {type : 'text/css', rel: 'stylesheet', 'class': 'ace-ajax-stylesheet'})
|
if( ace_style.length > 0 ) new_link.insertBefore(ace_style);
|
else new_link.appendTo('head');
|
new_link.attr('href', $link.attr('href'));//we set "href" after insertion, for IE to work
|
}
|
$link.remove();
|
})
|
}, 10);
|
|
//////////////////////
|
|
if(typeof self.settings.update_title === 'function') {
|
self.settings.update_title.call(null, hash, url, link_text, method, updateView);
|
}
|
else if(self.settings.update_title === true && method == 'GET') {
|
updateTitle(link_text);
|
}
|
|
if( !manual_trigger && updateView ) {
|
$('html,body').animate({scrollTop: 0}, 250);
|
}
|
|
//////////////////////
|
$contentArea.trigger('ajaxloadcomplete', {url: url, hash: hash, method: method, data:data});
|
//////////////////////
|
|
|
//if result contains call to "loadScripts" then don't stopLoading now
|
var re = /\.(?:\s*)ace(?:_a|A)jax(?:\s*)\((?:\s*)(?:\'|\")loadScripts(?:\'|\")/;
|
if(result.match(re)) self.stopLoading();
|
else self.stopLoading(true);
|
})
|
}
|
|
|
///////////////////////
|
var fixPos = false;
|
var loadTimer = null;
|
this.startLoading = function() {
|
if(working) return;
|
working = true;
|
|
if(!this.settings.loading_overlay && $contentArea.css('position') == 'static') {
|
$contentArea.css('position', 'relative');//for correct icon positioning
|
fixPos = true;
|
}
|
|
$overlay.remove();
|
$overlay = $('<div class="ajax-loading-overlay"><i class="ajax-loading-icon '+(this.settings.loading_icon || '')+'"></i> '+this.settings.loading_text+'</div>')
|
|
if(this.settings.loading_overlay == 'body') $('body').append($overlay.addClass('ajax-overlay-body'));
|
else if(this.settings.loading_overlay) $(this.settings.loading_overlay).append($overlay);
|
else $contentArea.append($overlay);
|
|
|
if(this.settings.max_load_wait !== false)
|
loadTimer = setTimeout(function() {
|
loadTimer = null;
|
if(!working) return;
|
|
var event
|
$contentArea.trigger(event = $.Event('ajaxloadlong'))
|
if (event.isDefaultPrevented()) return;
|
|
self.stopLoading(true);
|
}, this.settings.max_load_wait * 1000);
|
}
|
|
this.stopLoading = function(stopNow) {
|
if(stopNow === true) {
|
working = false;
|
|
$overlay.remove();
|
if(fixPos) {
|
$contentArea.css('position', '');//restore previous 'position' value
|
fixPos = false;
|
}
|
|
if(loadTimer != null) {
|
clearTimeout(loadTimer);
|
loadTimer = null;
|
}
|
}
|
else {
|
$overlay.addClass('almost-loaded');
|
|
$contentArea.one('ajaxscriptsloaded.inner_call', function() {
|
self.stopLoading(true);
|
/**
|
if(window.Pace && Pace.running == true) {
|
Pace.off('done');
|
Pace.once('done', function() { self.stopLoading(true) })
|
}
|
else self.stopLoading(true);
|
*/
|
})
|
}
|
}
|
|
this.working = function() {
|
return working;
|
}
|
///////////////////////
|
|
|
|
function updateBreadcrumbs(link_element) {
|
var link_text = '';
|
|
//update breadcrumbs
|
var breadcrumbs = $('.breadcrumb');
|
if(breadcrumbs.length > 0 && breadcrumbs.is(':visible')) {
|
breadcrumbs.find('> li:not(:first-child)').remove();
|
|
var i = 0;
|
link_element.parents('.nav li').each(function() {
|
var link = $(this).find('> a');
|
|
var link_clone = link.clone();
|
link_clone.find('i,.fa,.glyphicon,.ace-icon,.menu-icon,.badge,.label').remove();
|
var text = link_clone.text();
|
link_clone.remove();
|
|
var href = link.attr('href');
|
|
if(i == 0) {
|
var li = $('<li class="active"></li>').appendTo(breadcrumbs);
|
li.text(text);
|
link_text = text;
|
}
|
else {
|
var li = $('<li><a /></li>').insertAfter(breadcrumbs.find('> li:first-child'));
|
li.find('a').attr('href', href).text(text);
|
}
|
i++;
|
})
|
}
|
|
return link_text;
|
}
|
|
function updateTitle(link_text) {
|
var $title = $contentArea.find('.ajax-append-title');
|
if($title.length > 0) {
|
document.title = $title.text();
|
$title.remove();
|
}
|
else if(link_text.length > 0) {
|
var extra = $.trim(String(document.title).replace(/^(.*)[\-]/, ''));//for example like " - Ace Admin"
|
if(extra) extra = ' - ' + extra;
|
link_text = $.trim(link_text) + extra;
|
}
|
}
|
|
|
this.loadScripts = function(scripts, callback) {
|
var scripts = scripts || [];
|
$.ajaxPrefilter('script', function(opts) {opts.cache = true});
|
setTimeout(function() {
|
//let's keep a list of loaded scripts so that we don't load them more than once!
|
|
function finishLoading() {
|
if(typeof callback === 'function') callback();
|
$('.btn-group[data-toggle="buttons"] > .btn').button();
|
|
$contentArea.trigger('ajaxscriptsloaded');
|
}
|
|
//var deferreds = [];
|
var deferred_count = 0;//deferreds count
|
var resolved = 0;
|
for(var i = 0; i < scripts.length; i++) if(scripts[i]) {
|
(function() {
|
var script_name = "js-"+scripts[i].replace(/[^\w\d\-]/g, '-').replace(/\-\-/g, '-');
|
if( ajax_loaded_scripts[script_name] !== true ) deferred_count++;
|
})()
|
}
|
|
|
function nextScript(index) {
|
index += 1;
|
if(index < scripts.length) loadScript(index);
|
else {
|
finishLoading();
|
}
|
}
|
|
function loadScript(index) {
|
index = index || 0;
|
if(!scripts[index]) {//could be null sometimes
|
return nextScript(index);
|
}
|
|
var script_name = "js-"+scripts[index].replace(/[^\w\d\-]/g, '-').replace(/\-\-/g, '-');
|
//only load scripts that are not loaded yet!
|
if( ajax_loaded_scripts[script_name] !== true ) {
|
$.getScript(scripts[index])
|
.done(function() {
|
ajax_loaded_scripts[script_name] = true;
|
})
|
//.fail(function() {
|
//})
|
.complete(function() {
|
resolved++;
|
if(resolved >= deferred_count && working) {
|
finishLoading();
|
}
|
else {
|
nextScript(index);
|
}
|
})
|
}
|
else {//script previoisly loaded
|
nextScript(index);
|
}
|
}
|
|
|
if (deferred_count > 0) {
|
loadScript();
|
}
|
else {
|
finishLoading();
|
}
|
|
}, 10)
|
}
|
|
|
|
/////////////////
|
$(window)
|
.off('hashchange.ace_ajax')
|
.on('hashchange.ace_ajax', function(e, manual_trigger) {
|
var hash = $.trim(window.location.hash);
|
if(!hash || hash.length == 0) return;
|
|
if(self.settings.close_mobile_menu) {
|
try {$(self.settings.close_mobile_menu).ace_sidebar('mobileHide')} catch(e){}
|
}
|
if(self.settings.close_dropdowns) {
|
$('.dropdown.open .dropdown-toggle').dropdown('toggle');
|
}
|
|
self.loadUrl(hash, null, manual_trigger);
|
}).trigger('hashchange.ace_ajax', [true]);
|
|
var hash = $.trim(window.location.hash);
|
if(!hash && this.settings.default_url) window.location.hash = this.settings.default_url;
|
|
}//AceAjax
|
|
|
|
$.fn.aceAjax = $.fn.ace_ajax = function (option, value, value2, value3, value4) {
|
var method_call;
|
|
var $set = this.each(function () {
|
var $this = $(this);
|
var data = $this.data('ace_ajax');
|
var options = typeof option === 'object' && option;
|
|
if (!data) $this.data('ace_ajax', (data = new AceAjax(this, options)));
|
if (typeof option === 'string' && typeof data[option] === 'function') {
|
if(value4 !== undefined) method_call = data[option](value, value2, value3, value4);
|
else if(value3 !== undefined) method_call = data[option](value, value2, value3);
|
else if(value2 !== undefined) method_call = data[option](value, value2);
|
else method_call = data[option](value);
|
}
|
});
|
|
return (method_call === undefined) ? $set : method_call;
|
}
|
|
|
|
$.fn.aceAjax.defaults = $.fn.ace_ajax.defaults = {
|
content_url: false,
|
default_url: false,
|
loading_icon: 'fa fa-spin fa-spinner fa-2x orange',
|
loading_text: '',
|
loading_overlay: null,
|
update_breadcrumbs: true,
|
update_title: true,
|
update_active: true,
|
close_active: false,
|
max_load_wait: false,
|
close_mobile_menu: false,
|
close_dropdowns: false
|
}
|
|
})(window.jQuery);
|