ntopng/httpdocs/js/bootstrap.ajaxpager-0.8.js
2015-04-30 12:22:35 +02:00

560 lines
No EOL
20 KiB
JavaScript

/**
* @depends /core/jquery-1.7.2.js
* @depends /bootstrap/bootstrap.js
* @depends /bootstrap/html5.js
*/
(function($) {
$.fn.ajaxPager = function(options) {
if($.ajaxPager.methods[options]){
return $.ajaxPager.methods[options].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof options === 'object' || ! options ) {
return $.ajaxPager.methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + options + ' does not exist on jQuery.ajaxPager' );
}
var settings = {};
var privatevars = {};
var handlers = {};
var getAccessor = null;
var makeRequest = null;
var changePage = null;
var mask = null;
var unmask = null;
};
// publicly accessible defaults
$.fn.ajaxPager.defaults = {
position : 'top', // top|bottom|both
classes : '', // for additional classes
stripedrows : false,
loadtext : 'Loading...',
page : 1,
limit : 25, // number of records
limitdd : true,
limitoptions : [25,50,75,100],
sortcolumn : null,
sortdir : 'asc',
sortby : {},
searchtext : null,
ajaxoptions : {
url : '',
type : 'POST',
data : {},
dataType : 'json'
},
reader : {
success : 'success',
message : 'message',
totalpages : 'totalpages',
totalrecords : 'totalrecords',
root : ''
},
params : {
start : 'start',
limit : 'limit',
page : 'page',
sort : 'sort',
dir : 'dir',
search : 'search'
},
renderoutput : null,
listeners: {
init : null,
render : null,
preprocess : null,
beforeload : null,
load : null,
destroy : null
}
};
$.fn.ajaxPager.privatevars = {
dataloaded : false,
rendered : false,
totalpages : 12,
totalrecords: 293,
firstrecord : 0,
lastrecord : 0,
pagers: null
};
// These are the methods of the plugin
$.ajaxPager = {
methods: {
init: function(options){
var options = options||{};
settings = $.extend(true, {}, $.fn.ajaxPager.defaults, options);
handlers = $.ajaxPager.handlers;
getAccessor = $.ajaxPager._getAccessor;
makeRequest = $.ajaxPager._makeRequest;
changePage = $.ajaxPager._changePage;
mask = $.ajaxPager._maskContent;
unmask = $.ajaxPager._unmaskContent;
return this.each(function(){
var $self = $(this),
data = $self.data('ajaxPager');
// setup bindings
$self.bind('optionchange.ajaxPager', handlers.optionChangeHandler);
$self.bind('pagechange.ajaxPager', handlers.pageChangeHandler);
$self.bind('firstpage.ajaxPager', handlers.firstPageHandler);
$self.bind('previouspage.ajaxPager', handlers.previousPageHandler);
$self.bind('nextpage.ajaxPager', handlers.nextPageHandler);
$self.bind('lastpage.ajaxPager', handlers.lastPageHandler);
$self.bind('init.ajaxPager', handlers.initHandler);
$self.bind('render.ajaxPager', handlers.renderHandler);
$self.bind('beforeload.ajaxPager', handlers.beforeLoadHandler);
$self.bind('load.ajaxPager', handlers.loadHandler);
$self.bind('destroy.ajaxPager', handlers.destroyHandler);
// Create some UI
var barUI = $.ajaxPager._buildPagerBar(settings);
$self.wrap('<div class="ajaxPagerContainer" />').addClass('pagingContent');
switch (settings.position) {
case "both":
$self.before(barUI).after(barUI);
break;
case "top":
$self.before(barUI);
break;
case "bottom":
$self.after(barUI);
break;
}
if(!data){
$self.data('ajaxPager',$.extend({}, $.fn.ajaxPager.privatevars, {
target: $self,
pagers: $('.pagingbar', $self.parent()),
origcontent: $(this).html()
}));
}
//console.log('data init ', $self.data('ajaxPager'));
$self.trigger('init').trigger('render');
});
},
destroy: function(){
return this.each(function(){
var $self = $(this),
data = $self.data('ajaxPager');
if (settings.listeners.destroy && typeof settings.listeners.destroy === 'function'){
settings.listeners.destroy.call($self, 'destroy');
}
$self.unbind('.ajaxPager');
$('a.paging-nav', data.pagers).unbind('click');
if (!$.isEmptyObject(settings.sortby)) {
$('a.paging-filter', data.pagers).unbind('click');
}
if (settings.limitdd) {
$('a.paging-limit', data.pagers).unbind('click');
}
$('.navbar-form', data.pagers).unbind('submit');
$('.navbar-form input', data.pagers).unbind('keypress');
$self.html(data.origcontent);
data.pagers.remove();
$self.unwrap().removeClass('pagingContent');
$self.removeData('ajaxPager');
});
},
option: function(options){
var orig = $.extend({}, settings);
var $self = $(this);
if (typeof options === 'object'){
settings = $.extend(true, settings, options);
} else if (arguments.length === 2) {
settings[arguments[0]] = arguments[1];
} else {
return settings[arguments[0]];
}
$.each(orig, function(ind,el){
if(settings[ind]!==el){
$self.trigger('optionchange', [ind, el, settings[ind]]);
}
})
return;
},
reload: function() {
var $self = $(this),
data = $(this).data('ajaxPager');
$.ajaxPager._makeRequest.call($self, settings.page);
}
},
handlers: {
optionChangeHandler: function(event, option, oldvalue, newvalue){
var $self = $(this),
data = $(this).data('ajaxPager');
switch (option) {
case "page":
if (newvalue > data.totalpages && (data.rendered && data.dataloaded)) {
settings.page = oldvalue;
$('form[name="jump"] input[name="page"]', data.pagers).val(oldvalue);
$.error( 'You have tried to set a \"page\" beyond the number of available pages' );
} else {
$self.trigger('pagechange', newvalue);
}
break;
case "classes":
var pagers = data.pagers;
if (!pagers.hasClass(newvalue)) {
pagers.addClass(newvalue);
}
break;
case "searchtext":
$self.trigger('pagechange', 1);
break;
}
},
jumpFormHandler: function(event){
event.preventDefault();
var $pager = $('.pagingContent', $(this).closest('.pagingbar').parent());
var val = $('input[name="page"]', $(this)).val();
$pager.ajaxPager('option', 'page', val);
return false;
},
pageChangeHandler: function(event, page){
var $self = $(this),
data = $(this).data('ajaxPager');
var newpage = page;
switch(page){
case 1:
newpage = 1;
break;
case data.totalpages:
newpage = data.totalpages;
break;
default:
break;
}
//console.log('in page change to page ', page)
$.ajaxPager._makeRequest.call($(this), newpage);
},
filterLinkHandler: function(event){
event.preventDefault();
var $pager = event.data.el,
action = $(this).attr('rel'),
icon = $('i', $('a[rel="' + action + '"]')),
diricon = icon.attr('class'),
data = $pager.data('ajaxPager'),
sortby = $('.paging-filter', data.pagers),
newicon = 'icon-arrow-down';
$('i',sortby).removeClass('icon-arrow-up').removeClass('icon-arrow-down').removeClass('icon-').addClass('icon-');
settings.sortcolumn = action;
if (diricon === 'icon-arrow-up') {
settings.sortdir = 'desc';
newicon = 'icon-arrow-down';
} else if (diricon === 'icon-arrow-down') {
settings.sortdir = 'asc';
newicon = 'icon-arrow-up';
} else {
settings.sortdir = 'desc';
}
icon.removeClass('icon-').addClass(newicon);
$('li.dropdown.open').removeClass('open');
//console.log(settings.sortcolumn, settings.sortdir);
$.ajaxPager._makeRequest.call($pager, settings.page);
return false;
},
limitLinkHandler: function(event) {
event.preventDefault();
var $pager = event.data.el,
action = $(this).attr('rel'),
newlimit = $(this).text(),
icon = $('i', $('a[rel="' + action + '"]')),
diricon = icon.attr('class'),
data = $pager.data('ajaxPager'),
limitby = $('.paging-limit', data.pagers);
settings.limit = newlimit;
$('i',limitby).removeClass('icon-chevron-right').removeClass('icon-').addClass('icon-');
icon.removeClass('icon-').addClass('icon-chevron-right');
$('li.dropdown.open').removeClass('open');
//console.log(settings.sortcolumn, settings.sortdir);
$.ajaxPager._makeRequest.call($pager, settings.page);
return false;
},
navLinkHandler: function(event) {
event.preventDefault();
var $pager = event.data.el,
action = $(this).attr('rel');
if (!$(this).hasClass('disabled')){
$pager.trigger(action + 'page');
}
return false;
},
firstPageHandler: function(event){
$(this).trigger('optionchange',['page', settings.page, 1]);
},
previousPageHandler: function(event){
$(this).trigger('optionchange',['page', settings.page, settings.page-1]);
},
lastPageHandler: function(event){
var $self = $(this),
data = $(this).data('ajaxPager');
$(this).trigger('optionchange',['page', settings.page, data.totalpages]);
},
nextPageHandler: function(event){
$(this).trigger('optionchange',['page', settings.page, settings.page+1]);
},
initHandler: function () {
var $self = $(this);
if (settings.listeners.init && typeof settings.listeners.init === 'function'){
settings.listeners.init.call($self, 'init');
}
},
renderHandler: function(event){
var $self = $(this),
data = $(this).data('ajaxPager');
if (settings.listeners.render && typeof settings.listeners.render === 'function'){
settings.listeners.render.call($self, 'render');
}
// setup UI bindings
$('a.paging-nav', data.pagers).bind('click', {el: $self}, handlers.navLinkHandler);
$('.navbar-form', data.pagers).bind('submit', handlers.jumpFormHandler);
$('.navbar-form input', data.pagers).bind('keypress',function(e){
c = e.which ? e.which : e.keyCode;
if(c === 13) {
e.preventDefault();
var form = $(this).parent();
form.trigger('submit');
return false;
}
return true;
});
// if there are sortby, we setup bindings
if (!$.isEmptyObject(settings.sortby)) {
$('a.paging-filter', data.pagers).bind('click', {el: $self}, handlers.filterLinkHandler);
}
if (settings.limitdd) {
$('a.paging-limit', data.pagers).bind('click', {el: $self}, handlers.limitLinkHandler);
}
$self.data('ajaxPager', $.extend(data,{rendered: true}));
//console.log('in render ', $self.data('ajaxPager'));
$self.trigger('pagechange', settings.page);
},
beforeLoadHandler: function(event) {
var $self = $(this);
if (settings.listeners.beforeload && typeof settings.listeners.beforeload === 'function'){
settings.listeners.beforeload.call($self, 'beforeload');
}
},
loadHandler: function(event) {
var $self = $(this);
if (settings.listeners.load && typeof settings.listeners.load === 'function'){
settings.listeners.load.call($self, 'load');
}
}
},
_buildPagerBar: function(settings){
var ui = '<div class="pagingbar ajaxPager' + ((settings.classes.length > 0) ? (' ' + settings.classes) : '') + '">'
+ '<div class="pagingbar-inner">'
+ '<div class="container">'
+ '<div class="nav-collapse">'
+ '<ul class="nav nav-pills">'
+ '<li><a href="#first" class="paging-nav" rel="first">|&#171;</a></li>'
+ '<li class="divider-vertical"></li>'
+ '<li><a href="#previous" class="paging-nav" rel="previous">&#171;</a></li>'
+ '<li class="divider-vertical"></li>'
+ '</ul>'
+ '<form name="jump" class="navbar-form pull-left">'
+ '<strong>Page</strong> <input type="text" name="page" value="0" style="width:25px;" /> <strong>of <span class="total-pages">0</span></strong>'
+ '</form>'
+ '<ul class="nav nav-pills">'
+ '<li class="divider-vertical"></li>'
+ '<li><a href="#next" class="paging-nav" rel="next">&#187;</a></li>'
+ '<li class="divider-vertical"></li>'
+ '<li><a href="#last" class="paging-nav" rel="last">&#187;|</a></li>'
+ '<li class="divider-vertical"></li>';
if (settings.limitdd) {
ui += '<li class="dropdown">'
+ '<a class="dropdown-toggle" data-toggle="dropdown" href="#">Limit<b class="caret"></b></a>'
+ '<ul class="dropdown-menu">';
for (var i = 0; i < settings.limitoptions.length; i++) {
ui += '<li><a href="#limit-' + settings.limitoptions[i] + '" class="paging-limit" rel="' + settings.limitoptions[i] + '"><i class="icon-' + ((settings.limitoptions[i] === settings.limit) ? 'chevron-right' : '') + '"></i>' + settings.limitoptions[i] + '</a></li>';
}
ui += '</ul>'
+ '</li>'
+ '<li class="divider-vertical"></li>';
}
if (!$.isEmptyObject(settings.sortby)) {
ui += '<li class="dropdown">'
+ '<a class="dropdown-toggle" data-toggle="dropdown" href="#">Sort By<b class="caret"></b></a>'
+ '<ul class="dropdown-menu">';
for (var i in settings.sortby){
ui += '<li><a href="#filter-' + i + '" class="paging-filter" rel="' + i + '">';
if (settings.sortcolumn && i === settings.sortcolumn) {
if (settings.sortdir === 'asc') {
ui += '<i class="icon-arrow-up"></i> ';
} else if (settings.sortcolumn && settings.sortdir === 'desc') {
ui += '<i class="icon-arrow-down"></i> ';
}
} else {
ui += '<i class="icon-"></i> ';
}
ui += settings.sortby[i] + '</a>';
}
ui += '</ul>'
+ '</li>'
+ '<li class="divider-vertical"></li>';
}
ui += '</ul>'
+'<span class="pull-right navbar-text pagingbar-counts" style="margin-right:20px;">'
+ '<strong>View <span class="first-record">0</span> - <span class="last-record">0</span> of <span class="record-count">0</span></strong>'
+ '</span>'
+ '</div>'
+ '</div>'
+ '</div>'
+ '</div>';
return ui;
},
_maskContent: function (label) {
var $self = $(this);
$self.append('<div class="component-backdrop fade in" />').addClass('masked');
if(label !== undefined) {
var maskMsgDiv = $('<div class="mask-msg alert alert-info" style="display:none;"></div>');
maskMsgDiv.append('<div>' + label + '</div>');
$self.append(maskMsgDiv);
//calculate center position
maskMsgDiv.css("top", Math.round($self.height() / 2 - (maskMsgDiv.height() - parseInt(maskMsgDiv.css("padding-top")) - parseInt(maskMsgDiv.css("padding-bottom"))) / 2)+"px");
maskMsgDiv.css("left", Math.round($self.width() / 2 - (maskMsgDiv.width() - parseInt(maskMsgDiv.css("padding-left")) - parseInt(maskMsgDiv.css("padding-right"))) / 2)+"px");
maskMsgDiv.show();
}
},
_unmaskContent: function () {
var $self = $(this);
$('div.component-backdrop,div.mask-msg', $self).remove();
$self.removeClass('masked');
//console.log('let\'s unmask this thing',$('div.component-backdrop', $self));
},
_changePage: function (page, totalpages, totalrecords) {
var $self = $(this),
data = $(this).data('ajaxPager');
data = $.extend(data, {totalpages: totalpages, totalrecords: totalrecords});
switch(page){
case 1:
$('a.paging-nav[rel="first"], a.paging-nav[rel="previous"]', data.pagers).addClass('disabled');
if (data.totalpages !== 1){
$('a.paging-nav[rel="next"], a.paging-nav[rel="last"]', data.pagers).removeClass('disabled');
} else {
$('a.paging-nav[rel="next"], a.paging-nav[rel="last"]', data.pagers).addClass('disabled');
}
break;
case data.totalpages:
$('a.paging-nav[rel="first"], a.paging-nav[rel="previous"]', data.pagers).removeClass('disabled');
$('a.paging-nav[rel="next"], a.paging-nav[rel="last"]', data.pagers).addClass('disabled');
break;
default:
$('a.paging-nav[rel="first"], a.paging-nav[rel="previous"]', data.pagers).removeClass('disabled');
$('a.paging-nav[rel="next"], a.paging-nav[rel="last"]', data.pagers).removeClass('disabled');
break;
}
settings.page = page;
var count = (page*settings.limit);
data = $.extend(data, {
firstrecord: ((settings.limit*(page-1))+1),
lastrecord: (count > data.totalrecords) ? data.totalrecords : count
});
$self.data('ajaxPager', data);
//console.log('after some sets ', $self.data('ajaxPager'));
$('.pagingbar-counts .first-record', data.pagers).html(data.firstrecord);
$('.pagingbar-counts .last-record', data.pagers).html(data.lastrecord);
$('.pagingbar-counts .record-count', data.pagers).html(data.totalrecords);
$('.navbar-form .total-pages', data.pagers).html(data.totalpages);
$('form[name="jump"] input[name="page"]', data.pagers).val(page);
},
_makeRequest: function (page) {
var $self = $(this),
req = $.extend({}, settings.ajaxoptions),
tmp = {},
opts = settings,
acc = getAccessor
cp = changePage,
u = unmask,
data = $self.data('ajaxPager'),
target = data.target;
tmp[settings.params.start] = (page-1) * settings.limit;
tmp[settings.params.page] = page;
tmp[settings.params.limit] = settings.limit;
if (settings.sortcolumn) {
tmp[settings.params.sort] = settings.sortcolumn;
tmp[settings.params.dir] = settings.sortdir;
}
if (settings.searchtext) {
tmp[settings.params.search] = settings.searchtext;
}
for(var i in req){
if (req[i] === null) {
delete req[i];
}
}
req.data = $.extend({}, req.data, tmp);
mask.call($self, opts.loadtext);
$.ajax($.extend(req,{
success: function (d, s, o) {
var output = null,
dataset = null,
totalpages = null,
totalrecords = null;
// Preprocess the return, if necessary
d = (opts.listeners.preprocess && typeof opts.listeners.preprocess === 'function') ? opts.listeners.preprocess.call($self, d) : d;
// Adjust our internal data to reflect values returned from the server
// Valuable to change the display if a search is conducted
dataset = acc(d, opts.reader.root);
totalpages = parseInt(acc(d, opts.reader.totalpages));
totalpages = parseInt((totalpages !== 'undefined') ? totalpages : 1);
totalrecords = parseInt(acc(d,opts.reader.totalrecords));
totalrecords = parseInt((totalrecords !== undefined) ? totalrecords : dataset.length);
cp.call($self, page, totalpages, totalrecords);
output = (opts.renderoutput && typeof opts.renderoutput === 'function') ? opts.renderoutput.call($self, d) : d;
$self.trigger('beforeload');
u.call($self,[]);
target.html(output);
if (opts.stripedrows) {
$self.children(':even').addClass('striped-row')
}
data = $.extend(data, {dataloaded: true});
$self.data('ajaxPager', data);
$self.trigger('load');
},
error: function (o, s, err){
u.call($self,[]);
$.error('There was an error in making your request. Please notify your developer.');
}
}));
},
_getAccessor : function(obj, expr) {
var ret,p,prm = [], i;
if( typeof expr === 'function') { return expr(obj); }
ret = obj[expr];
if(ret===undefined) {
try {
if ( typeof expr === 'string' ) {
prm = expr.split('.');
}
i = prm.length;
if( i ) {
ret = obj;
while (ret && i--) {
p = prm.shift();
ret = ret[p];
}
}
} catch (e) {}
}
return ret;
}
};
})(jQuery);