Skip to content

Instantly share code, notes, and snippets.

@juareznjunior
Created March 24, 2011 17:53
Show Gist options
  • Save juareznjunior/885521 to your computer and use it in GitHub Desktop.
Save juareznjunior/885521 to your computer and use it in GitHub Desktop.
jQuery UI DataGrid - beta version - create by @juareznjunior
(function($){
$.widget('ui.datagrid',{
// plugin options
options: {
limit:5
,mapper:[]
,height:200
,jsonStore:{
// ajax params
params: {}
// is ajax
,url: ''
// json
,data:{}
}
,pagination: true
,toolBarButtons:false
,refresh: false
,onSelectRow: false
,rowHover: true
,rowClick: true
,rowNumber: false
,ajaxMethod: 'POST'
,autoRender: true
,autoLoad: false
,title: ''
,classThead: 'ui-state-default'
,containerBorder: true
,fit: false
}
,_create: function() {
// plugin params elements
this.uiDataGrid = $(this._getMarkup());
this.uiDataGridChilds = this.uiDataGrid.children();
this.uiDataGridTables = this.uiDataGridChilds.find('table');
this.uiDataGridThead = $(this.uiDataGridTables[0].tHead);
this.uiDataGridTbody = $(this.uiDataGridTables[1].tBodies[0]);
this.uiDataGridTfoot = (this.options.pagination || $.isArray(this.options.toolBarButtons))
? $(this.uiDataGridTables[2].tBodies[0])
: $([]);
this.uiDataGridScroll = this.uiDataGridTables.eq(0).parent().next();
// plugin params
this._offset = 0;
this._totalPages = 0;
this._selectedRows = [];
this._tbodyEvents();
delete this.uiDataGridTables;
delete this.uiDataGridChilds
}
,_init: function() {
(this.options.autoRender && this.render())
}
,_setOption: function(option,value) {
$.Widget.prototype._setOption.apply(this,arguments);
}
,_getMarkup: function() {
var _div = document.createElement('div'),markup = '';
_div.className = 'ui-data-grid-container ui-widget'+((this.options.containerBorder) ? ' ui-widget-content ui-corner-all' : '');
_div.style.cssText = 'padding:1px';
if (this.options.title != '') {
markup += '<div style="text-align: center; padding: 0.4em 0pt" class="ui-widget-header ui-corner-all">'
+this.options.title
+'</div>'
+'<div>'
}
markup += '<div>'
+'<table cellspacing="0" cellpadding="0" class="ui-datagrid" role="grid">'
+'<thead>'
+'<tr role="rowheader"></tr>'
+'</thead>'
+'</table>'
+'</div>'
+'<div class="ui-widget-content" style="height:'+this.options.height+'px;overflow-y:scroll;overflow-x:hidden;border:0 !important">'
+'<table cellspacing="0" cellpadding="0" class="ui-datagrid ui-datagrid-tbody" role="grid">'
+'<tbody></tbody>'
+'</table>'
+'</div>';
if (this.options.pagination || $.isArray(this.options.toolBarButtons)) {
markup += '<div class="ui-widget ui-state-default ui-corner-all" style="margin-top:1px">'
+'<table cellspacing="0" cellpadding="0" style="width:100%">'
+'<tbody>'
+'<tr>'
+'<td style="padding:2px;text-align:left">&nbsp;</td>';
if (this.options.pagination) {
markup += '<td style="text-align:right;padding:2px">'
+'<span style="margin-right:5px"></span>'
+'</td>';
}
markup += '</tr>'
+'</tbody>'
+'</table>'
+'</div>';
}
if (this.options.title != '') {
markup += '</div>'
}
markup += '</div>';
_div.innerHTML = markup;
markup = null;
return _div
}
,_createToolButtons: function() {
for(var btns = [],t = ['first','prev','next','end'],b,c,k = 0;c=t[k++];) {
_b = document.createElement('button');
_b.name = 'data-grid-button-'+c;
_b.innerHTML = c;
$(_b).button({
icons: {
primary: 'ui-icon-seek-'+c
}
,text:false
});
btns[btns.length] = _b
}
$(btns).appendTo($(this.uiDataGridTfoot[0].rows[0].cells).eq(-1)[0]);
btns = t = b = c = null;
return this
}
,_disableToolButtons: function() {
$(this.uiDataGridTfoot[0].rows[0].cells).eq(-1)
.children(':button')
.removeClass('ui-state-hover ui-state-focus')
.button('disable');
return this
}
,_createColumns: function() {
for(var cls = 'ui-widget '+this.options.classThead,aux,row = [],_th,i=0;_th = this.options.mapper[i++];) {
aux = document.createElement('th');
aux.className = cls;
if (i > 1) {
aux.style.borderLeftWidth = '0';
}
undefined !== _th.css && $(aux).css(_th.css);
$(aux).attr('role','gridcell')[0].innerHTML = undefined !== _th.alias ? _th.alias : _th.name;
row[row.length] = aux
}
aux = document.createElement('th');
aux.innerHtml = '&nbsp';
aux.className = cls;
aux.style.cssText = 'border-left-width:0;width:10px';
row[row.length] = aux;
if (this.options.rowNumber) {
aux = document.createElement('th');
aux.innerHTML = '&nbsp';
aux.className = cls+' ui-datagrid-cell-rownumber';
aux.style.cssText = 'width:20px;border-right-width:0';
row.splice(0,0,aux)
}
var r = this.uiDataGridThead[0].rows[0];
for(i=0;_th = row[i++];) {
r.appendChild(_th)
}
row = aux = r = null
}
,_createRows: function(json) {
var theadThs = this.getThead()[0].rows[0].cells;
this.uiDataGridTbody.empty();
this.uiDataGridScroll.scrollTop(0);
for(var cls = 'ui-widget ui-widget-content',row,cell,item,td,i=0,j=0;item = json.rows[i++];) {
row = document.createElement('tr');
row.style.cssText = 'cursor:default';
row.className = 'ui-datagrid-row-'+((i%2) ? 'odd' : 'even');
if (this.options.rowNumber) {
cell = document.createElement('td');
cell.className = this.options.classThead;
cell.style.cssText = 'width:20px;text-align:center;vertical-align:middle;border-width:0 0 0 1px';
cell.innerHTML = parseInt(this._offset) + i;
row.appendChild(cell)
}
while (_td = this.options.mapper[j++]) {
cell = document.createElement('td');
cell.className = cls;
// default
cell.style.cssText = 'border-width:0 1px 0 1px;color:inherit;background:0;text-align:'+theadThs[j].style.textAlign;
if (j > 1) {
cell.style.borderLeftWidth = '0';
}
// apply the css conditions
((undefined != _td.css) && $(cell).css(_td.css));
// cell content
cell.innerHTML = $.isFunction(_td.map)
? _td.map(item[_td.name]) // aplica uma função no valor do campo
: item[_td.name]; // mapper.row.fieldName
row.appendChild(cell)
}
this.uiDataGridTbody[0].appendChild(row);
// reset
j = 0;
row = null
}
$(this.uiDataGridTbody[0].rows).last().children().css('border-bottom-width','1px');
row = cell = theadThs = null;
i = y = 0
}
,_ajax: function() {
var self = this;
// ajax
if (self.options.jsonStore.url != '') {
// serialize
// literal object (isPlainObject (json))
if ('string' === typeof self.options.jsonStore.params) {
self.options.jsonStore.params = (0 === self._offset)
? self.options.jsonStore.params+'&limit='+self.options.limit+'&offset='+self._offset
: self.options.jsonStore.params.replace(/(&offset=)(.+)/,'&offset='+self._offset)
} else {
self.options.jsonStore.params.limit = self.options.limit;
self.options.jsonStore.params.offset = self._offset
}
// disable button toolbar
if (self.options.pagination) {
self._disableToolButtons();
}
$.ajax({
type: self.options.ajaxMethod.toLowerCase()
,url: self.options.jsonStore.url.replace(/\?.*/,'')
,data: self.options.jsonStore.params
,success: function(json) {
try {
json = $.parseJSON(json);
} catch (e) {
alert(json.split('#').join("\n"));
return
}
if (undefined != json.error) {
alert(json.error);
return;
}
if (json.numRows == 0) {
return false;
}
if (self.options.pagination) {
self._totalPages = Math.ceil(json.numRows / self.options.limit);
var currentPage = (self._offset == 0 ) ? 1 : ((self._offset / self.options.limit) + 1)
,infoPages = currentPage+' de '+self._totalPages+' ('+json.numRows+')';
// ultimo td
$.each($(self.uiDataGridTfoot[0].rows[0].cells).eq(-1).children(),function(){
if (/span/i.test(this.tagName)) {
this.innerHTML = infoPages
} else {
(/data-grid-button-(first|prev)/.test(this.name))
? (self._offset > 0 && this.disabled && $(this).button('enable'))
: (self._totalPages > currentPage && this.disabled && $(this).button('enable'))
}
})
}
self._createRows(json)
}
})
} else {
self._createRows(self.options.jsonStore.data)
}
}
,render: function() {
var self = this;
if (self.element.children().eq(0).hasClass('ui-data-grid-container')) {
self.resetOffset();
self.load()
} else {
self._createColumns();
if ($.isArray(self.options.toolBarButtons)) {
$.each(self.options.toolBarButtons,function(i,b){
$(document.createElement('button')).html(b.label).each(function(){
if ($.isFunction(b.fn)) {
$(this).click(function(e){
b.fn.call(this,self.element);
$(this).blur()
})
}
$(this).button({icons:{primary:(undefined === b.icon) ? null : 'ui-icon-'+b.icon}});
self.uiDataGridTfoot[0].rows[0].cells[0].appendChild(this);
})
})
}
// create ui-datagrid
self.element.html(self.uiDataGrid[0]);
if (self.options.pagination) {
// create and disable buttons
self._createToolButtons()._disableToolButtons();
// prev next event
$(self.uiDataGridTfoot[0].rows[0].cells).eq(-1).delegate('button','click',function(){
if (!this.disabled) {
self[this.name.replace(/data-grid-button-/,'')+'Page']();
self._selectedRows = [];
self.load()
}
});
}
self.resize();
// load
(self.options.autoLoad && self.load());
// onComplete callback
($.isFunction(self.options.onComplete) && self.options.onComplete.call(self.uiDataGridTbody[0]));
}
return this
}
,nextPage: function() {
this._offset += this.options.limit
}
,prevPage: function() {
this._offset -= this.options.limit
}
,endPage: function() {
this._offset = (this._totalPages * this.options.limit) - this.options.limit
}
,firstPage: function() {
this._offset = 0
}
,_tbodyEvents: function() {
var self = this,ev = [];
if (this.options.rowHover) {
ev[ev.length] = 'mouseover';
ev[ev.length] = 'mouseout'
}
if (this.options.rowClick) {
ev[ev.length] = 'click'
}
if (ev.length > 0) {
self.uiDataGridTbody.undelegate().delegate('tr',ev.join(' '),function(event){
('click' === event.type)
? self._clickRow(this,event)
: $(this)[(('mouseover' === event.type) ? 'addClass' : 'removeClass')]('ui-state-hover')
})
}
ev = null
}
,_clickRow: function(tr,event) {
var self = this;
if ($(tr).hasClass('ui-state-highlight')) {
$(tr).removeClass('ui-state-highlight');
for(var i=0,row;row=self._selectedRows[i++];) {
if (tr === row) {
self._selectedRows.splice(--i,1);
break
}
}
} else {
$(tr).addClass('ui-state-highlight');
self._selectedRows[self._selectedRows.length] = tr;
($.isFunction(self.options.onSelectRow) && self.options.onSelectRow.call(tr,[self.element[0]]))
}
}
,resize: function() {
var self = this;
// fit to parent
if (self.options.fit) {
self.uiDataGridScroll.each(function(){
var h = self.uiDataGrid.outerHeight() - self.element.height();
this.style.height = $(this).height() - h +'px';
})
}
return this
}
,getSelectedRows: function() {
return this._selectedRows
}
,clearSelectedRows: function() {
for(var i=0,row;row=this._selectedRows[i++];) {
$(row).removeClass('ui-state-highlight');
}
this._selectedRows = []
}
,load: function() {
this._ajax()
return this
}
,widget: function() {
return this.uiDataGrid
}
,destroy: function() {
$.Widget.prototype.destroy.call(this);
this.element.empty()
}
,getOffset: function() {
return this._offset
}
,resetOffset: function() {
this._offset = 0
}
,getThead: function(callback) {
return ($.isFunction(callback))
? callback.call(this.uiDataGridThead[0])
: this.uiDataGridThead
}
,getTbody: function(callback) {
return ($.isFunction(callback))
? callback.call(this.uiDataGridTbody[0])
: this.uiDataGridTbody
}
,getTFoot: function(callback) {
return ($.isFunction(callback))
? callback.call(this.uiDataGridTfoot[0])
: this.uiDataGridTfoot
}
})
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment