mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
Customizable tables implementation...
SVN:trunk[2128]
This commit is contained in:
230
js/datatable.js
Normal file
230
js/datatable.js
Normal file
@@ -0,0 +1,230 @@
|
||||
// jQuery UI style "widget" for selecting and sorting "fields"
|
||||
$(function()
|
||||
{
|
||||
// the widget definition, where "itop" is the namespace,
|
||||
// "datatable" the widget name
|
||||
$.widget( "itop.datatable",
|
||||
{
|
||||
// default options
|
||||
options:
|
||||
{
|
||||
sPersistentId: '',
|
||||
sFilter: '',
|
||||
oColumns: {},
|
||||
sSelectMode: '',
|
||||
sViewLink: 'true',
|
||||
iNbObjects: 0,
|
||||
iDefaultPageSize: -1,
|
||||
iPageSize: -1,
|
||||
iPageIndex: 0,
|
||||
oClassAliases: {},
|
||||
sTableId : null,
|
||||
oExtraParams: {},
|
||||
sRenderUrl: 'index.php',
|
||||
oRenderParameters: {},
|
||||
oDefaultSettings: {},
|
||||
oLabels: { moveup: 'Move Up', movedown: 'Move Down' }
|
||||
},
|
||||
|
||||
// the constructor
|
||||
_create: function()
|
||||
{
|
||||
this.aDlgStateParams = ['iDefaultPageSize', 'oColumns'];
|
||||
|
||||
this.element
|
||||
.addClass('itop-datatable');
|
||||
|
||||
var me = this;
|
||||
var sId = new String(this.element.attr('id'));
|
||||
var sListId = sId.replace('datatable_', '');
|
||||
var bViewLink = (this.options.sViewLink == 'true');
|
||||
$('#sfl_'+sListId).fieldsorter({hasKeyColumn: bViewLink, labels: this.options.oLabels, fields: this.options.oColumns, onChange: function() { me._onSpecificSettings(); } });
|
||||
$('#datatable_dlg_'+sListId).find('input[name=page_size]').click(function() { me._onSpecificSettings(); });
|
||||
$('#datatable_dlg_'+sListId).find('input[name=save_settings]').click(function() { me._updateSaveScope(); });
|
||||
this.element.find('.itop_popup > ul li').popupmenu();
|
||||
this._updateSaveScope();
|
||||
this._saveDlgState();
|
||||
},
|
||||
|
||||
// called when created, and later when changing options
|
||||
_refresh: function()
|
||||
{
|
||||
oParams = this.options.oRenderParameters;
|
||||
oParams.operation = 'datatable';
|
||||
|
||||
oParams.filter = this.options.sFilter;
|
||||
oParams.extra_param = this.options.oExtraParams;
|
||||
oParams.start = 0;
|
||||
oParams.end = this.options.iPageSize;
|
||||
oParams.select_mode = this.options.sSelectMode;
|
||||
oParams.display_key = this.options.sViewLink;
|
||||
oParams.class_aliases = this.options.oClassAliases;
|
||||
oParams.columns = this.options.oColumns;
|
||||
|
||||
var sId = new String(this.element.attr('id'));
|
||||
var sListId = sId.replace('datatable_', '');
|
||||
oParams.list_id = sListId;
|
||||
var me = this;
|
||||
$.post(this.options.sRenderUrl, oParams, function(data) {
|
||||
// Nasty workaround to clear the pager's state for paginated lists !!!
|
||||
// See jquery.tablesorter.pager.js / saveParams / restoreParams
|
||||
if (window.pager_params)
|
||||
{
|
||||
window.pager_params['pager'+sListId] = undefined;
|
||||
}
|
||||
// End of workaround
|
||||
|
||||
me.element.find('.datacontents').html(data);
|
||||
}, 'html' );
|
||||
|
||||
},
|
||||
_useDefaultSettings: function(bResetAll)
|
||||
{
|
||||
var oParams = this.options.oRenderParameters;
|
||||
oParams.operation = 'datatable_reset_settings';
|
||||
|
||||
oParams.table_id = this.options.sTableId;
|
||||
oParams.defaults = bResetAll;
|
||||
oParams.class_aliases = this.options.oClassAliases;
|
||||
|
||||
var me = this;
|
||||
$.post(this.options.sRenderUrl, oParams, function(data) {
|
||||
// Do nothing...
|
||||
}, 'html' );
|
||||
},
|
||||
_saveSettings: function(bSaveAsDefaults)
|
||||
{
|
||||
var oParams = this.options.oRenderParameters;
|
||||
oParams.operation = 'datatable_save_settings';
|
||||
|
||||
oParams.page_size = this.options.iPageSize;
|
||||
oParams.table_id = this.options.sTableId;
|
||||
oParams.defaults = bSaveAsDefaults;
|
||||
oParams.class_aliases = this.options.oClassAliases;
|
||||
oParams.columns = this.options.oColumns;
|
||||
|
||||
var me = this;
|
||||
$.post(this.options.sRenderUrl, oParams, function(data) {
|
||||
// Do nothing...
|
||||
}, 'html' );
|
||||
},
|
||||
onDlgOk: function()
|
||||
{
|
||||
var oOptions = {};
|
||||
var sId = new String(this.element.attr('id'));
|
||||
var sListId = sId.replace('datatable_', '');
|
||||
oSettings = $('#datatable_dlg_'+sListId).find('input[name=settings]:checked');
|
||||
if (oSettings.val() == 'defaults')
|
||||
{
|
||||
oOptions = { iPageSize: this.options.oDefaultSettings.iDefaultPageSize,
|
||||
oColumns: this.options.oDefaultSettings.oColumns,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var oDisplayColumns = {};
|
||||
var iColIdx = 0;
|
||||
var iSortIdx = 0;
|
||||
var sSortDirection = 'asc';
|
||||
var oColumns = $('#datatable_dlg_'+sListId).find(':itop-fieldsorter').fieldsorter('get_params');
|
||||
var iPageSize = $('#datatable_dlg_'+sListId+' input[name=page_size]').val();
|
||||
|
||||
oOptions = {oColumns: oColumns, iPageSize: iPageSize };
|
||||
}
|
||||
this._setOptions(oOptions);
|
||||
|
||||
// Check if we need to save the settings or not...
|
||||
var oSaveCheck = $('#datatable_dlg_'+sListId).find('input[name=save_settings]');
|
||||
var oSaveScope = $('#datatable_dlg_'+sListId).find('input[name=scope]:checked');
|
||||
if (oSaveCheck.attr('checked'))
|
||||
{
|
||||
if (oSettings.val() == 'defaults')
|
||||
{
|
||||
this._useDefaultSettings((oSaveScope.val() == 'defaults'));
|
||||
}
|
||||
else
|
||||
{
|
||||
this._saveSettings((oSaveScope.val() == 'defaults'));
|
||||
}
|
||||
}
|
||||
this._saveDlgState();
|
||||
},
|
||||
onDlgCancel: function()
|
||||
{
|
||||
this._restoreDlgState();
|
||||
},
|
||||
_onSpecificSettings: function()
|
||||
{
|
||||
var sId = new String(this.element.attr('id'));
|
||||
var sListId = sId.replace('datatable_', '');
|
||||
$('#datatable_dlg_'+sListId).find('input.specific_settings').attr('checked', 'checked');
|
||||
},
|
||||
_updateSaveScope: function()
|
||||
{
|
||||
var sId = new String(this.element.attr('id'));
|
||||
var sListId = sId.replace('datatable_', '');
|
||||
var oSaveCheck = $('#datatable_dlg_'+sListId).find('input[name=save_settings]');
|
||||
if (oSaveCheck.attr('checked'))
|
||||
{
|
||||
$('#datatable_dlg_'+sListId).find('input[name=scope]').removeAttr('disabled');
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#datatable_dlg_'+sListId).find('input[name=scope]').attr('disabled', 'disabled');
|
||||
}
|
||||
},
|
||||
// events bound via _bind are removed automatically
|
||||
// revert other modifications here
|
||||
destroy: function()
|
||||
{
|
||||
this.element
|
||||
.removeClass('itop-datatable');
|
||||
|
||||
var sId = new String(this.element.attr('id'));
|
||||
var sListId = sId.replace('datatable_', '');
|
||||
$('#sfl_'+sListId).remove();
|
||||
|
||||
// call the original destroy method since we overwrote it
|
||||
$.Widget.prototype.destroy.call( this );
|
||||
},
|
||||
// _setOptions is called with a hash of all options that are changing
|
||||
_setOptions: function()
|
||||
{
|
||||
// in 1.9 would use _superApply
|
||||
$.Widget.prototype._setOptions.apply( this, arguments );
|
||||
this._refresh();
|
||||
},
|
||||
// _setOption is called for each individual option that is changing
|
||||
_setOption: function( key, value )
|
||||
{
|
||||
// in 1.9 would use _super
|
||||
$.Widget.prototype._setOption.call( this, key, value );
|
||||
},
|
||||
_saveDlgState: function()
|
||||
{
|
||||
this.originalState = {};
|
||||
for(k in this.aDlgStateParams)
|
||||
{
|
||||
this.originalState[this.aDlgStateParams[k]] = this.options[this.aDlgStateParams[k]];
|
||||
}
|
||||
var sId = new String(this.element.attr('id'));
|
||||
var sListId = sId.replace('datatable_', '');
|
||||
this.originalState.oFields = $('#datatable_dlg_'+sListId).find(':itop-fieldsorter').fieldsorter('get_params');
|
||||
},
|
||||
_restoreDlgState: function()
|
||||
{
|
||||
var sId = new String(this.element.attr('id'));
|
||||
var sListId = sId.replace('datatable_', '');
|
||||
var dlgElement = $('#datatable_dlg_'+sListId);
|
||||
|
||||
for(k in this.aDlgStateParams)
|
||||
{
|
||||
this._setOption(this.aDlgStateParams[k], this.originalState[this.aDlgStateParams[k]]);
|
||||
}
|
||||
|
||||
dlgElement.find('input[name=page_size]').val(this.originalState.iDefaultPageSize);
|
||||
|
||||
dlgElement.find(':itop-fieldsorter').fieldsorter('option', { fields: this.originalState.oFields });
|
||||
}
|
||||
});
|
||||
});
|
||||
277
js/field_sorter.js
Normal file
277
js/field_sorter.js
Normal file
@@ -0,0 +1,277 @@
|
||||
// jQuery UI style "widget" for selecting and sorting "fields"
|
||||
$(function()
|
||||
{
|
||||
// the widget definition, where "itop" is the namespace,
|
||||
// "fieldsorter" the widget name
|
||||
$.widget( "itop.fieldsorter",
|
||||
{
|
||||
// default options
|
||||
options:
|
||||
{
|
||||
fields: {},
|
||||
labels: { moveup: 'Move Up', movedown: 'Move Down' },
|
||||
onChange: null
|
||||
},
|
||||
|
||||
// the constructor
|
||||
_create: function()
|
||||
{
|
||||
var me = this;
|
||||
|
||||
this.element
|
||||
.addClass('itop-fieldsorter');
|
||||
|
||||
var me = this;
|
||||
this._initFields();
|
||||
|
||||
var width = 10+this.element.width();
|
||||
this.moveup_btn = $('<button type="button" disabled style="position: absolute; top: 0; left: '+width+'px;">'+this.options.labels.moveup+'</button>');
|
||||
this.movedown_btn = $('<button type="button" disabled style="position: absolute; top: 30px; left: '+width+'px;">'+this.options.labels.movedown+'</button>');
|
||||
this.element.wrap('<div style="position:relative;"></div>');
|
||||
this.element.parent().append(this.moveup_btn).append(this.movedown_btn);
|
||||
this.moveup_btn.click(function() { me._moveUp(); });
|
||||
this.movedown_btn.click(function() { me._moveDown(); });
|
||||
},
|
||||
|
||||
// called when created, and later when changing options
|
||||
_refresh: function()
|
||||
{
|
||||
this.element.find('li').remove();
|
||||
this._initFields();
|
||||
},
|
||||
_initFields: function()
|
||||
{
|
||||
var me = this;
|
||||
for(alias in this.options.fields)
|
||||
{
|
||||
for(k in this.options.fields[alias])
|
||||
{
|
||||
var f = this.options.fields[alias][k];
|
||||
if (f.label != '')
|
||||
{
|
||||
var sChecked = '';
|
||||
if (f.checked) sChecked = ' checked';
|
||||
var sDisabled = '';
|
||||
if (f.disabled) sDisabled = ' disabled';
|
||||
var sSortOrder = '';
|
||||
|
||||
if (f.sort)
|
||||
{
|
||||
var sHidden = ' sort_hidden';
|
||||
|
||||
if (f.checked) sHidden = '';
|
||||
|
||||
if (f.sort == 'none')
|
||||
{
|
||||
sSortOrder = ' <span sort="none" class="sort_order sort_none' + sHidden + '"/> </span>';
|
||||
}
|
||||
else if (f.sort == 'asc')
|
||||
{
|
||||
sSortOrder = ' <span sort="none" class="sort_order sort_asc' + sHidden + '"/> </span>';
|
||||
}
|
||||
else if (f.sort == 'desc')
|
||||
{
|
||||
sSortOrder = ' <span sort="none" class="sort_order sort_desc' + sHidden + '"> </span>';
|
||||
}
|
||||
}
|
||||
var field = $('<li name="' + k + '" alias="' + f.alias + '" code="' + f.code + '"><input type="checkbox"' + sChecked + sDisabled + '/> ' + f.label + sSortOrder + '</li>');
|
||||
field.click(function() { me._selectItem(this); });
|
||||
field.find('input').click(function() { me._checkboxClicked(this); } );
|
||||
field.find('span').click(function() { me._sortOrderClicked(this); } );
|
||||
this.element.append(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.element.sortable({items: 'li:not(.ui-state-disabled)', start: function(event, ui) { me._selectItem(ui.item.get(0)); }, stop: function(event, ui) { me._onSortStop(event, ui); } });
|
||||
},
|
||||
// events bound via _bind are removed automatically
|
||||
// revert other modifications here
|
||||
destroy: function()
|
||||
{
|
||||
this.element
|
||||
.removeClass('itop-fieldsorter');
|
||||
|
||||
this.moveup_btn.remove();
|
||||
this.movedown_btn.remove();
|
||||
this.element.sortable('destroy').html('');
|
||||
|
||||
// call the original destroy method since we overwrote it
|
||||
$.Widget.prototype.destroy.call( this );
|
||||
},
|
||||
// _setOptions is called with a hash of all options that are changing
|
||||
_setOptions: function()
|
||||
{
|
||||
// in 1.9 would use _superApply
|
||||
$.Widget.prototype._setOptions.apply( this, arguments );
|
||||
},
|
||||
// _setOption is called for each individual option that is changing
|
||||
_setOption: function( key, value )
|
||||
{
|
||||
// in 1.9 would use _super
|
||||
$.Widget.prototype._setOption.call( this, key, value );
|
||||
|
||||
if (key == 'fields') this._refresh();
|
||||
},
|
||||
_selectItem: function(item)
|
||||
{
|
||||
this.element.find('li').each(function() {
|
||||
if (this == item)
|
||||
{
|
||||
$(this).addClass('selected');
|
||||
}
|
||||
else
|
||||
{
|
||||
$(this).removeClass('selected');
|
||||
}
|
||||
});
|
||||
this.moveup_btn.removeAttr('disabled');
|
||||
this.movedown_btn.removeAttr('disabled');
|
||||
},
|
||||
_moveUp: function()
|
||||
{
|
||||
var oSelected = this.element.find('li.selected');
|
||||
if (oSelected.length == 0) return;
|
||||
|
||||
var oPrev = oSelected.prev();
|
||||
if (oPrev.length != 0)
|
||||
{
|
||||
if (!oPrev.hasClass('ui-state-disabled'))
|
||||
{
|
||||
// Not at the top, let's move up
|
||||
var oNew = oSelected.clone(true);
|
||||
oPrev.before(oNew);
|
||||
oSelected.remove();
|
||||
this._scrollIntoView(oNew);
|
||||
this._notifyChange();
|
||||
}
|
||||
}
|
||||
this._notifyChange();
|
||||
},
|
||||
_moveDown: function()
|
||||
{
|
||||
var oSelected = this.element.find('li.selected');
|
||||
if (oSelected.length == 0) return;
|
||||
if (oSelected.hasClass('ui-state-disabled')) return; // not moveable
|
||||
|
||||
var oNext = oSelected.next();
|
||||
if (oNext.length != 0)
|
||||
{
|
||||
// Not at the top, let's move up
|
||||
var oNew = oSelected.clone(true);
|
||||
oNext.after(oNew);
|
||||
oSelected.remove();
|
||||
this._scrollIntoView(oNew);
|
||||
}
|
||||
this._notifyChange();
|
||||
},
|
||||
_scrollIntoView: function(item)
|
||||
{
|
||||
var containerTop = this.element.scrollTop();
|
||||
var containerHeight = this.element.height();
|
||||
var itemTop = item.position().top;
|
||||
var itemBottom = itemTop + item.height();
|
||||
|
||||
if (itemTop < 0)
|
||||
{
|
||||
this.element.scrollTop(containerTop + itemTop);
|
||||
}
|
||||
else if (itemBottom > containerHeight)
|
||||
{
|
||||
this.element.scrollTop(containerTop + itemBottom - this.element.height());
|
||||
}
|
||||
},
|
||||
_onSortStop: function(event, ui)
|
||||
{
|
||||
this._notifyChange();
|
||||
},
|
||||
_checkboxClicked: function(elt)
|
||||
{
|
||||
if (elt.checked)
|
||||
{
|
||||
$(elt).parent().find('span.sort_order').removeClass('sort_hidden');
|
||||
}
|
||||
else
|
||||
{
|
||||
$(elt).parent().find('span.sort_order').addClass('sort_hidden');
|
||||
}
|
||||
this._notifyChange();
|
||||
},
|
||||
_sortOrderClicked: function(elt)
|
||||
{
|
||||
// Reset all other sort orders
|
||||
var oElt = $(elt);
|
||||
this.element.find('span.sort_order').each(function(){
|
||||
if (this != elt)
|
||||
{
|
||||
$(this).attr('sort', 'none').removeClass('sort_asc').removeClass('sort_desc').addClass('sort_none');
|
||||
}
|
||||
});
|
||||
var sSortOrder = oElt.attr('sort');
|
||||
if (sSortOrder == 'none')
|
||||
{
|
||||
oElt.attr('sort', 'asc').removeClass('sort_none').addClass('sort_asc');
|
||||
}
|
||||
else if (sSortOrder == 'asc')
|
||||
{
|
||||
oElt.attr('sort', 'desc').removeClass('sort_asc').addClass('sort_desc');
|
||||
}
|
||||
else if (sSortOrder == 'desc')
|
||||
{
|
||||
oElt.attr('sort', 'none').removeClass('sort_desc').addClass('sort_none');
|
||||
}
|
||||
this._notifyChange();
|
||||
},
|
||||
_notifyChange: function()
|
||||
{
|
||||
if (this.options.onChange)
|
||||
{
|
||||
this.options.onChange();
|
||||
}
|
||||
},
|
||||
get_params: function()
|
||||
{
|
||||
var oParams = {};
|
||||
var me = this;
|
||||
this.element.find('li').each(function() {
|
||||
var oItem = $(this);
|
||||
var sName = oItem.attr('name');
|
||||
var sCode, sAlias;
|
||||
if (sName == undefined)
|
||||
{
|
||||
sName = '_key_'; // By convention the unnamed first column is the key
|
||||
sCode = 'id';
|
||||
sAlias = '';
|
||||
sLabel = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
sCode = oItem.attr('code');
|
||||
sAlias = oItem.attr('alias');
|
||||
sLabel = me.options.fields[sAlias][sCode].label;
|
||||
}
|
||||
|
||||
var oCheckbox = oItem.find('input[type=checkbox]');
|
||||
var bChecked = false;
|
||||
if (oCheckbox.attr('checked'))
|
||||
{
|
||||
bChecked = true;
|
||||
}
|
||||
var bDisabled = false;
|
||||
if (oCheckbox.attr('disabled'))
|
||||
{
|
||||
bDisabled = true;
|
||||
}
|
||||
var sSort = undefined;
|
||||
var oSort = oItem.find('span.sort_order');
|
||||
if (oSort.length > 0)
|
||||
{
|
||||
sSort = oSort.attr('sort');
|
||||
}
|
||||
var oData = { checked: bChecked, disabled: bDisabled, sort: sSort, code:sCode, alias: sAlias, label: sLabel };
|
||||
if (oParams[sAlias] == undefined) oParams[sAlias] = {};
|
||||
oParams[sAlias][sCode] = oData;
|
||||
});
|
||||
return oParams;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -151,7 +151,7 @@ function sprintf(format, etc) {
|
||||
{
|
||||
s = table.config.totalRows - ex;
|
||||
}
|
||||
$('.selectedCount',pager).text(s);
|
||||
pager.closest('table').find('.selectedCount').text(s);
|
||||
if (table.config.cssCount != '')
|
||||
{
|
||||
$(table.config.cssCount).val(s);
|
||||
@@ -187,7 +187,8 @@ function sprintf(format, etc) {
|
||||
sort_order: s_order,
|
||||
select_mode: c.select_mode,
|
||||
display_key: c.displayKey,
|
||||
display_list: c.displayList
|
||||
columns: c.columns,
|
||||
class_aliases: c.class_aliases
|
||||
},
|
||||
function(data)
|
||||
{
|
||||
@@ -431,7 +432,8 @@ function sprintf(format, etc) {
|
||||
totalSelected: 0,
|
||||
selectionMode: 'positive',
|
||||
displayKey: true,
|
||||
displayList: []
|
||||
columns: {},
|
||||
class_aliases: {}
|
||||
};
|
||||
|
||||
this.construct = function(settings) {
|
||||
@@ -481,11 +483,14 @@ function sprintf(format, etc) {
|
||||
$(table).find(':checkbox.checkAll').removeAttr('onclick').click(function() {
|
||||
return checkAll(table, pager, this.checked);
|
||||
});
|
||||
|
||||
|
||||
$(table).bind('load_selection', function() {
|
||||
loadSelection(table, pager);
|
||||
applySelection(table);
|
||||
});
|
||||
$(table).bind('check_all', function() {
|
||||
checkAll(table, pager, true);
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user