/** Load content via Ajax . 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,'') $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('', {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 = $('
'+this.settings.loading_text+'
') 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 = $('
  • ').appendTo(breadcrumbs); li.text(text); link_text = text; } else { var 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);