2011-05-01 22:33:19 +04:00
|
|
|
/*!
|
|
|
|
* jquery.fixedHeaderTable. The jQuery fixedHeaderTable plugin
|
|
|
|
*
|
|
|
|
* Copyright (c) 2011 Mark Malek
|
|
|
|
* http://fixedheadertable.com
|
|
|
|
*
|
|
|
|
* Licensed under MIT
|
|
|
|
* http://www.opensource.org/licenses/mit-license.php
|
|
|
|
*
|
|
|
|
* http://docs.jquery.com/Plugins/Authoring
|
|
|
|
* jQuery authoring guidelines
|
|
|
|
*
|
|
|
|
* Launch : October 2009
|
|
|
|
* Version : 1.2
|
|
|
|
* Released: May 2nd, 2011
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* all CSS sizing (width,height) is done in pixels (px)
|
|
|
|
*/
|
2011-05-01 01:06:58 +04:00
|
|
|
|
|
|
|
(function($) {
|
|
|
|
|
2011-05-01 22:33:19 +04:00
|
|
|
$.fn.fixedHeaderTable = function( method ) {
|
2011-05-01 01:06:58 +04:00
|
|
|
|
|
|
|
// plugin's default options
|
|
|
|
var defaults = {
|
2011-05-01 04:44:30 +04:00
|
|
|
|
2011-05-01 04:45:15 +04:00
|
|
|
width: '100%',
|
|
|
|
height: '100%',
|
|
|
|
borderCollapse: true,
|
2011-05-01 22:33:19 +04:00
|
|
|
themeClass: 'fht-default',
|
2011-05-01 04:45:15 +04:00
|
|
|
|
2011-05-01 22:33:19 +04:00
|
|
|
autoShow: true, // hide table after its created
|
2011-05-01 01:06:58 +04:00
|
|
|
loader: false,
|
2011-05-01 22:33:19 +04:00
|
|
|
footer: false, // show footer
|
|
|
|
cloneHeadToFoot: false, // clone head and use as footer
|
2011-05-01 04:45:15 +04:00
|
|
|
cloneHeaderToFooter: false, // deprecated option
|
2011-05-01 22:33:19 +04:00
|
|
|
autoResize: false, // resize table if its parent wrapper changes size
|
2011-05-07 11:33:04 +04:00
|
|
|
create: null // callback after plugin completes
|
2011-05-01 01:06:58 +04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
var settings = {}
|
|
|
|
|
|
|
|
// public methods
|
|
|
|
var methods = {
|
|
|
|
|
|
|
|
init : function(options) {
|
|
|
|
|
|
|
|
settings = $.extend({}, defaults, options);
|
|
|
|
|
|
|
|
// iterate through all the DOM elements we are attaching the plugin to
|
|
|
|
return this.each(function() {
|
|
|
|
|
|
|
|
var $self = $(this), // reference the jQuery version of the current DOM element
|
|
|
|
self = this; // reference to the actual DOM element
|
|
|
|
|
|
|
|
if ( helpers._isTable($self) ) {
|
|
|
|
methods.setup.apply(this, Array.prototype.slice.call(arguments, 1));
|
2011-05-01 04:45:15 +04:00
|
|
|
|
2011-05-07 11:33:04 +04:00
|
|
|
$.isFunction(settings.create) && settings.create.call(this);
|
2011-05-01 04:45:15 +04:00
|
|
|
} else {
|
|
|
|
$.error('Invalid table mark-up');
|
2011-05-01 01:06:58 +04:00
|
|
|
}
|
2011-05-01 04:45:15 +04:00
|
|
|
|
2011-05-01 01:06:58 +04:00
|
|
|
});
|
|
|
|
|
|
|
|
},
|
2011-05-01 22:33:19 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Setup table structure for fixed headers and optional footer
|
|
|
|
*/
|
2011-05-01 04:45:15 +04:00
|
|
|
setup: function( options ) {
|
2011-05-01 01:06:58 +04:00
|
|
|
var $self = $(this),
|
|
|
|
self = this,
|
|
|
|
$thead = $self.find('thead'),
|
|
|
|
$tfoot = $self.find('tfoot'),
|
|
|
|
$tbody = $self.find('tbody'),
|
|
|
|
$wrapper,
|
|
|
|
$divHead,
|
|
|
|
$divFoot,
|
|
|
|
$divBody,
|
|
|
|
$fixedHeadRow,
|
|
|
|
$temp;
|
2011-05-01 04:45:15 +04:00
|
|
|
|
|
|
|
settings.scrollbarOffset = helpers._getScrollbarWidth();
|
2011-05-01 22:33:19 +04:00
|
|
|
settings.themeClassName = settings.themeClass;
|
2011-05-02 04:30:01 +04:00
|
|
|
|
|
|
|
if ( settings.width.search('%') > -1 ) {
|
2011-05-07 09:36:20 +04:00
|
|
|
var widthMinusScrollbar = $self.parent().width() - settings.scrollbarOffset;
|
2011-05-02 04:30:01 +04:00
|
|
|
} else {
|
|
|
|
var widthMinusScrollbar = settings.width - settings.scrollbarOffset;
|
|
|
|
}
|
|
|
|
|
2011-05-01 04:45:15 +04:00
|
|
|
$self.css({
|
2011-05-02 04:30:01 +04:00
|
|
|
width: widthMinusScrollbar
|
|
|
|
});
|
|
|
|
|
2011-05-01 22:33:19 +04:00
|
|
|
|
2011-05-01 01:06:58 +04:00
|
|
|
if ( !$self.closest('.fht-table-wrapper').length ) {
|
|
|
|
$self.addClass('fht-table');
|
|
|
|
$self.wrap('<div class="fht-table-wrapper"></div>');
|
|
|
|
}
|
2011-05-01 22:33:19 +04:00
|
|
|
|
2011-05-01 01:06:58 +04:00
|
|
|
$wrapper = $self.closest('.fht-table-wrapper');
|
|
|
|
|
|
|
|
$wrapper.css({
|
2011-05-02 04:30:01 +04:00
|
|
|
width: settings.width,
|
|
|
|
height: settings.height
|
|
|
|
})
|
|
|
|
.addClass(settings.themeClassName);
|
2011-05-01 22:33:19 +04:00
|
|
|
|
2011-05-01 01:06:58 +04:00
|
|
|
if ( !$self.hasClass('fht-table-init') ) {
|
|
|
|
|
|
|
|
$self.wrap('<div class="fht-tbody"></div>');
|
2011-05-01 04:45:15 +04:00
|
|
|
|
|
|
|
}
|
2011-05-01 22:33:19 +04:00
|
|
|
$divBody = $self.closest('.fht-tbody');
|
|
|
|
|
2011-05-01 04:45:15 +04:00
|
|
|
var tableProps = helpers._getTableProps($self);
|
|
|
|
|
2011-05-01 22:33:19 +04:00
|
|
|
helpers._setupClone( $divBody, tableProps.tbody );
|
|
|
|
|
2011-05-01 04:45:15 +04:00
|
|
|
if ( !$self.hasClass('fht-table-init') ) {
|
2011-05-02 09:18:18 +04:00
|
|
|
$divHead = $('<div class="fht-thead"><table class="fht-table"></table></div>').prependTo($wrapper);
|
2011-05-01 01:06:58 +04:00
|
|
|
|
|
|
|
$thead.clone().appendTo($divHead.find('table'));
|
2011-05-01 04:45:15 +04:00
|
|
|
} else {
|
2011-05-02 09:18:18 +04:00
|
|
|
$divHead = $wrapper.find('div.fht-thead');
|
2011-05-01 04:45:15 +04:00
|
|
|
}
|
2011-05-02 04:30:01 +04:00
|
|
|
|
2011-05-01 04:45:15 +04:00
|
|
|
helpers._setupClone( $divHead, tableProps.thead );
|
|
|
|
|
|
|
|
$self.css({
|
|
|
|
'margin-top': -$thead.outerHeight(true) - tableProps.border
|
|
|
|
});
|
2011-05-01 22:33:19 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Check for footer
|
|
|
|
* Setup footer if present
|
|
|
|
*/
|
2011-05-01 04:45:15 +04:00
|
|
|
if ( settings.footer ) {
|
|
|
|
|
2011-05-02 09:18:18 +04:00
|
|
|
helpers._setupTableFooter( $self, self, tableProps );
|
2011-05-01 04:45:15 +04:00
|
|
|
|
2011-05-02 09:18:18 +04:00
|
|
|
if ( !$tfoot.length ) {
|
|
|
|
$tfoot = $wrapper.find('div.fht-tfoot table');
|
|
|
|
}
|
|
|
|
|
2011-05-01 01:06:58 +04:00
|
|
|
}
|
2011-05-02 09:18:18 +04:00
|
|
|
|
2011-05-01 04:45:15 +04:00
|
|
|
var tbodyHeight = $wrapper.height() - $thead.outerHeight(true) - $tfoot.outerHeight(true) - tableProps.border;
|
|
|
|
$divBody.css({
|
|
|
|
'height': tbodyHeight
|
|
|
|
});
|
|
|
|
|
|
|
|
if ( !settings.autoShow ) {
|
|
|
|
$wrapper.hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
$self.addClass('fht-table-init');
|
|
|
|
|
2011-05-01 22:33:19 +04:00
|
|
|
if ( typeof(settings.altClass) !== 'undefined' ) {
|
|
|
|
$self.find('tbody tr:odd')
|
|
|
|
.addClass(settings.altClass);
|
|
|
|
}
|
|
|
|
|
2011-05-01 04:44:30 +04:00
|
|
|
return self;
|
2011-05-01 01:06:58 +04:00
|
|
|
},
|
|
|
|
|
2011-05-02 04:30:01 +04:00
|
|
|
/*
|
|
|
|
* Resize the table
|
2011-05-02 09:18:18 +04:00
|
|
|
* Incomplete - not implemented yet
|
2011-05-02 04:30:01 +04:00
|
|
|
*/
|
|
|
|
resize: function( options ) {
|
|
|
|
var $self = $(this),
|
|
|
|
self = this;
|
|
|
|
|
|
|
|
return self;
|
|
|
|
},
|
|
|
|
|
2011-05-01 22:33:19 +04:00
|
|
|
/*
|
|
|
|
* Show a hidden fixedHeaderTable table
|
|
|
|
*/
|
2011-05-02 09:18:18 +04:00
|
|
|
show: function( arg1, arg2, arg3 ) {
|
|
|
|
var $self = $(this),
|
|
|
|
self = this,
|
|
|
|
$wrapper = $self.closest('.fht-table-wrapper');
|
|
|
|
|
|
|
|
// User provided show duration without a specific effect
|
|
|
|
if ( typeof(arg1) !== 'undefined' && typeof(arg1) === 'number' ) {
|
|
|
|
|
|
|
|
$wrapper.show(arg1, function() {
|
|
|
|
$.isFunction(arg3) && arg3.call(this);
|
|
|
|
});
|
|
|
|
|
|
|
|
return self;
|
2011-05-01 04:44:30 +04:00
|
|
|
|
2011-05-02 09:18:18 +04:00
|
|
|
} else if ( typeof(arg1) !== 'undefined' && typeof(arg1) === 'string'
|
|
|
|
&& typeof(arg2) !== 'undefined' && typeof(arg2) === 'number' ) {
|
2011-05-02 18:52:24 +04:00
|
|
|
|
|
|
|
// User provided show duration with an effect
|
|
|
|
|
2011-05-02 09:18:18 +04:00
|
|
|
$wrapper.show(arg1, arg2, function() {
|
|
|
|
$.isFunction(arg3) && arg3.call(this);
|
|
|
|
});
|
|
|
|
|
|
|
|
return self;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
$self.closest('.fht-table-wrapper')
|
|
|
|
.show();
|
|
|
|
$.isFunction(arg3) && arg3.call(this);
|
|
|
|
|
|
|
|
return self;
|
2011-05-01 01:06:58 +04:00
|
|
|
},
|
|
|
|
|
2011-05-01 22:33:19 +04:00
|
|
|
/*
|
|
|
|
* Hide a fixedHeaderTable table
|
|
|
|
*/
|
2011-05-02 09:18:18 +04:00
|
|
|
hide: function( arg1, arg2, arg3 ) {
|
|
|
|
var $self = $(this),
|
2011-05-07 11:33:04 +04:00
|
|
|
self = this,
|
2011-05-02 09:18:18 +04:00
|
|
|
$wrapper = $self.closest('.fht-table-wrapper');
|
|
|
|
|
|
|
|
// User provided show duration without a specific effect
|
|
|
|
if ( typeof(arg1) !== 'undefined' && typeof(arg1) === 'number' ) {
|
|
|
|
$wrapper.hide(arg1, function() {
|
|
|
|
$.isFunction(arg3) && arg3.call(this);
|
|
|
|
});
|
|
|
|
|
|
|
|
return self;
|
|
|
|
} else if ( typeof(arg1) !== 'undefined' && typeof(arg1) === 'string'
|
|
|
|
&& typeof(arg2) !== 'undefined' && typeof(arg2) === 'number' ) {
|
|
|
|
|
|
|
|
$wrapper.hide(arg1, arg2, function() {
|
|
|
|
$.isFunction(arg3) && arg3.call(this);
|
|
|
|
});
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
2011-05-01 04:44:30 +04:00
|
|
|
|
|
|
|
$self.closest('.fht-table-wrapper')
|
2011-05-02 09:18:18 +04:00
|
|
|
.hide();
|
|
|
|
|
|
|
|
$.isFunction(arg3) && arg3.call(this);
|
|
|
|
|
2011-05-01 04:44:30 +04:00
|
|
|
|
2011-05-02 09:18:18 +04:00
|
|
|
|
2011-05-02 04:30:01 +04:00
|
|
|
return self;
|
2011-05-01 01:06:58 +04:00
|
|
|
},
|
|
|
|
|
2011-05-01 22:33:19 +04:00
|
|
|
/*
|
|
|
|
* Destory fixedHeaderTable and return table to original state
|
|
|
|
*/
|
2011-05-01 01:06:58 +04:00
|
|
|
destroy: function() {
|
2011-05-01 04:44:30 +04:00
|
|
|
var $self = $(this),
|
|
|
|
self = this,
|
|
|
|
$wrapper = $self.closest('.fht-table-wrapper');
|
|
|
|
|
|
|
|
$self.insertBefore($wrapper)
|
|
|
|
.removeAttr('style')
|
|
|
|
.append($wrapper.find('tfoot'))
|
2011-05-01 04:45:15 +04:00
|
|
|
.removeClass('fht-table fht-table-init')
|
|
|
|
.find('.fht-cell')
|
|
|
|
.remove();
|
2011-05-01 04:44:30 +04:00
|
|
|
|
|
|
|
$wrapper.remove();
|
|
|
|
|
2011-05-02 04:30:01 +04:00
|
|
|
return self;
|
2011-05-01 01:06:58 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// private methods
|
|
|
|
var helpers = {
|
|
|
|
|
2011-05-01 22:33:19 +04:00
|
|
|
/*
|
|
|
|
* return boolean
|
|
|
|
* True if a thead and tbody exist.
|
|
|
|
*/
|
2011-05-01 01:06:58 +04:00
|
|
|
_isTable: function( $obj ) {
|
|
|
|
var $self = $obj,
|
|
|
|
hasTable = $self.is('table'),
|
|
|
|
hasThead = $self.find('thead').length > 0,
|
|
|
|
hasTbody = $self.find('tbody').length > 0;
|
|
|
|
|
|
|
|
if ( hasTable && hasThead && hasTbody ) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2011-05-02 09:18:18 +04:00
|
|
|
/*
|
|
|
|
* return void
|
|
|
|
*/
|
|
|
|
_setupTableFooter: function ( $obj, obj, tableProps ) {
|
|
|
|
|
|
|
|
var $self = $obj,
|
|
|
|
self = obj,
|
|
|
|
$wrapper = $self.closest('.fht-table-wrapper'),
|
|
|
|
$tfoot = $self.find('tfoot'),
|
|
|
|
$divFoot = $wrapper.find('div.fht-tfoot');
|
|
|
|
|
|
|
|
if ( !$divFoot.length ) {
|
|
|
|
$divFoot = $('<div class="fht-tfoot"><table class="fht-table"></table></div>').appendTo($wrapper);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (true) {
|
|
|
|
case settings.cloneHeadToFoot && !$tfoot.length:
|
|
|
|
|
|
|
|
var $divHead = $wrapper.find('div.fht-thead');
|
|
|
|
|
|
|
|
$divFoot.empty();
|
|
|
|
$divHead.find('table')
|
|
|
|
.clone()
|
|
|
|
.appendTo($divFoot);
|
|
|
|
|
|
|
|
break;
|
|
|
|
case $tfoot.length && !settings.cloneHeadToFoot && !$divFoot.find('tr').length:
|
|
|
|
|
|
|
|
$divFoot.find('table')
|
|
|
|
.append($tfoot)
|
|
|
|
.css({
|
|
|
|
'margin-top': -tableProps.border
|
|
|
|
});
|
|
|
|
|
|
|
|
helpers._setupClone( $divFoot, tableProps.tfoot );
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
2011-05-01 22:33:19 +04:00
|
|
|
/*
|
|
|
|
* return object
|
|
|
|
* Widths of each thead cell and tbody cell for the first rows.
|
|
|
|
* Used in fixing widths for the fixed header and optional footer.
|
|
|
|
*/
|
2011-05-01 01:06:58 +04:00
|
|
|
_getTableProps: function( $obj ) {
|
|
|
|
var tableProp = {
|
|
|
|
thead: {},
|
2011-05-01 04:45:15 +04:00
|
|
|
tbody: {},
|
2011-05-02 09:18:18 +04:00
|
|
|
tfoot: {},
|
2011-05-01 04:45:15 +04:00
|
|
|
border: 0
|
2011-05-01 01:06:58 +04:00
|
|
|
};
|
2011-05-01 04:45:15 +04:00
|
|
|
|
|
|
|
tableProp.border = ( $obj.find('th:first-child').outerWidth() - $obj.find('th:first-child').innerWidth() ) / 2;
|
|
|
|
|
2011-05-02 09:18:18 +04:00
|
|
|
$obj.find('thead tr:first-child th').each(function(index) {
|
2011-05-01 04:45:15 +04:00
|
|
|
tableProp.thead[index] = $(this).width() + tableProp.border;
|
2011-05-01 01:06:58 +04:00
|
|
|
});
|
|
|
|
|
2011-05-02 09:18:18 +04:00
|
|
|
$obj.find('tfoot tr:first-child td').each(function(index) {
|
|
|
|
tableProp.tfoot[index] = $(this).width() + tableProp.border;
|
|
|
|
});
|
|
|
|
|
2011-05-01 01:06:58 +04:00
|
|
|
$obj.find('tbody tr:first-child td').each(function(index) {
|
2011-05-01 04:45:15 +04:00
|
|
|
tableProp.tbody[index] = $(this).width() + tableProp.border;
|
2011-05-01 01:06:58 +04:00
|
|
|
});
|
2011-05-01 04:45:15 +04:00
|
|
|
|
2011-05-01 01:06:58 +04:00
|
|
|
return tableProp;
|
2011-05-01 04:45:15 +04:00
|
|
|
},
|
|
|
|
|
2011-05-01 22:33:19 +04:00
|
|
|
/*
|
|
|
|
* return void
|
|
|
|
* Fix widths of each cell in the first row of obj.
|
|
|
|
*/
|
|
|
|
_setupClone: function( $obj, cellArray ) {
|
|
|
|
var $self = $obj,
|
2011-05-01 04:45:15 +04:00
|
|
|
selector = ( $self.find('thead').length ) ?
|
|
|
|
'thead th' :
|
|
|
|
( $self.find('tfoot').length ) ?
|
|
|
|
'tfoot td' :
|
|
|
|
'tbody td',
|
|
|
|
$cell;
|
2011-05-02 09:18:18 +04:00
|
|
|
|
2011-05-01 04:45:15 +04:00
|
|
|
$self.find(selector).each(function(index) {
|
|
|
|
$cell = ( $(this).find('div.fht-cell').length ) ? $(this).find('div.fht-cell') : $('<div class="fht-cell"></div>').appendTo($(this));
|
2011-05-02 09:18:18 +04:00
|
|
|
|
2011-05-01 04:45:15 +04:00
|
|
|
$cell.css({
|
2011-05-01 22:33:19 +04:00
|
|
|
'width': parseInt(cellArray[index])
|
2011-05-01 04:45:15 +04:00
|
|
|
});
|
2011-05-02 09:18:18 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Fixed Header and Footer should extend the full width
|
|
|
|
* to align with the scrollbar of the body
|
|
|
|
*/
|
|
|
|
if ( !$(this).closest('.fht-tbody').length && $(this).is(':last-child') ) {
|
|
|
|
var padding = ( ( $(this).innerWidth() - $(this).width() ) / 2 ) + settings.scrollbarOffset;
|
|
|
|
$(this).css({
|
|
|
|
'padding-right': padding + 'px'
|
|
|
|
});
|
|
|
|
}
|
2011-05-01 04:45:15 +04:00
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2011-05-01 22:33:19 +04:00
|
|
|
/*
|
|
|
|
* return int
|
|
|
|
* get the width of the browsers scroll bar
|
|
|
|
*/
|
2011-05-01 04:45:15 +04:00
|
|
|
_getScrollbarWidth: function() {
|
|
|
|
var scrollbarWidth = 0;
|
|
|
|
|
|
|
|
if ( !scrollbarWidth ) {
|
|
|
|
if ( $.browser.msie ) {
|
|
|
|
var $textarea1 = $('<textarea cols="10" rows="2"></textarea>')
|
|
|
|
.css({ position: 'absolute', top: -1000, left: -1000 }).appendTo('body'),
|
|
|
|
$textarea2 = $('<textarea cols="10" rows="2" style="overflow: hidden;"></textarea>')
|
|
|
|
.css({ position: 'absolute', top: -1000, left: -1000 }).appendTo('body');
|
|
|
|
scrollbarWidth = $textarea1.width() - $textarea2.width();
|
|
|
|
$textarea1.add($textarea2).remove();
|
|
|
|
} else {
|
|
|
|
var $div = $('<div />')
|
|
|
|
.css({ width: 100, height: 100, overflow: 'auto', position: 'absolute', top: -1000, left: -1000 })
|
|
|
|
.prependTo('body').append('<div />').find('div')
|
|
|
|
.css({ width: '100%', height: 200 });
|
|
|
|
scrollbarWidth = 100 - $div.width();
|
|
|
|
$div.parent().remove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return scrollbarWidth;
|
2011-05-01 01:06:58 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-05-02 09:18:18 +04:00
|
|
|
|
2011-05-01 01:06:58 +04:00
|
|
|
// if a method as the given argument exists
|
2011-05-01 22:33:19 +04:00
|
|
|
if ( methods[method] ) {
|
2011-05-01 01:06:58 +04:00
|
|
|
|
|
|
|
// call the respective method
|
|
|
|
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
|
|
|
|
|
|
|
// if an object is given as method OR nothing is given as argument
|
2011-05-01 22:33:19 +04:00
|
|
|
} else if ( typeof method === 'object' || !method ) {
|
2011-05-01 01:06:58 +04:00
|
|
|
|
|
|
|
// call the initialization method
|
|
|
|
return methods.init.apply(this, arguments);
|
|
|
|
|
|
|
|
// otherwise
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// trigger an error
|
|
|
|
$.error( 'Method "' + method + '" does not exist in fixedHeaderTable plugin!');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})(jQuery);
|