//vim: et:ts=4:sw=4:sts=4:ft=js Ox.TextList = function(options, self) { // fixme: rename to TableList var self = self || {}, that = new Ox.Element({}, self) .defaults({ columns: [], columnsMovable: false, columnsRemovable: false, columnsResizable: false, columnsVisible: false, columnWidth: [40, 800], id: '', items: null, // function() {} {sort, range, keys, callback} or array max: -1, min: 0, pageLength: 100, scrollbarVisible: false, selected: [], sort: [] }) .options(options || {}) .addClass('OxTextList'); Ox.print('Ox.TextList self.options', self.options) self.options.columns.forEach(function(v) { // fixme: can this go into a generic ox.js function? // fixme: and can't these just remain undefined? if (Ox.isUndefined(v.align)) { v.align = 'left'; } if (Ox.isUndefined(v.clickable)) { v.clickable = false; } if (Ox.isUndefined(v.editable)) { v.editable = false; } if (Ox.isUndefined(v.unique)) { v.unique = false; } if (Ox.isUndefined(v.visible)) { v.visible = false; } if (v.unique) { self.unique = v.id; } }); $.extend(self, { columnPositions: [], defaultColumnWidths: $.map(self.options.columns, function(v) { return v.defaultWidth || v.width; }), itemHeight: 16, page: 0, pageLength: 100, scrollLeft: 0, selectedColumn: getColumnIndexById(self.options.sort[0].key), visibleColumns: $.map(self.options.columns, function(v) { return v.visible ? v : null; }) }); // fixme: there might be a better way than passing both visible and position self.options.columns.forEach(function(v) { if (!Ox.isUndefined(v.position)) { self.visibleColumns[v.position] = v; } }) $.extend(self, { columnWidths: $.map(self.visibleColumns, function(v, i) { return v.width; }), pageHeight: self.options.pageLength * self.itemHeight }); self.format = {}; self.options.columns.forEach(function(v, i) { if (v.format) { self.format[v.id] = v.format; } }); // Head if (self.options.columnsVisible) { that.$bar = new Ox.Bar({ orientation: 'horizontal', size: 16 }).appendTo(that); that.$head = new Ox.Container() .addClass('OxHead') .css({ right: self.options.scrollbarVisible ? Ox.UI.SCROLLBAR_SIZE + 'px' : 0 }) .appendTo(that.$bar); that.$head.$content.addClass('OxTitles'); constructHead(); if (self.options.columnsRemovable) { that.$select = new Ox.Select({ id: self.options.id + 'SelectColumns', items: $.map(self.options.columns, function(v, i) { return { checked: v.visible, disabled: v.removable === false, id: v.id, title: v.title } }), max: -1, min: 1, type: 'image' }) .bindEvent('change', changeColumns) .appendTo(that.$bar.$element); } } // Body that.$body = new Ox.List({ construct: constructItem, id: self.options.id, items: self.options.items, itemHeight: 16, items: self.options.items, itemWidth: getItemWidth(), format: self.format, // fixme: not needed, happens in TextList keys: $.map(self.visibleColumns, function(v) { return v.id; }), max: self.options.max, min: self.options.min, pageLength: self.options.pageLength, paste: self.options.paste, orientation: 'vertical', selected: self.options.selected, sort: self.options.sort, sortable: self.options.sortable, type: 'text', unique: self.unique }, $.extend({}, self)) // pass event handler .addClass('OxBody') .css({ top: (self.options.columnsVisible ? 16 : 0) + 'px', overflowY: (self.options.scrollbarVisible ? 'scroll' : 'hidden') }) .scroll(function() { var scrollLeft = $(this).scrollLeft(); if (scrollLeft != self.scrollLeft) { self.scrollLeft = scrollLeft; that.$head && that.$head.scrollLeft(scrollLeft); } }) .bindEvent({ edit: function(event, data) { that.editCell(data.id, data.key); }, select: function(event, data) { self.options.selected = data.ids; } }) .appendTo(that); that.$body.$content.css({ width: getItemWidth() + 'px' }); //Ox.print('s.vC', self.visibleColumns) function addColumn(id) { //Ox.print('addColumn', id); var column, ids, index = 0; Ox.forEach(self.options.columns, function(v) { if (v.visible) { index++; } else if (v.id == id) { column = v; return false; } }); column.visible = true; self.visibleColumns.splice(index, 0, column); self.columnWidths.splice(index, 0, column.width); that.$head.$content.empty(); constructHead(); that.$body.options({ keys: $.map(self.visibleColumns, function(v, i) { return v.id; }) }); that.$body.reloadPages(); } function changeColumns(event, data) { var add, ids = []; Ox.forEach(data.selected, function(column) { var index = getColumnIndexById(column.id); if (!self.options.columns[index].visible) { addColumn(column.id); add = true; return false; } ids.push(column.id); }); if (!add) { Ox.forEach(self.visibleColumns, function(column) { if (ids.indexOf(column.id) == -1) { removeColumn(column.id); return false; } }); } triggerColumnChangeEvent(); } function clickColumn(id) { Ox.print('clickColumn', id); var i = getColumnIndexById(id), isSelected = self.options.sort[0].key == self.options.columns[i].id; that.sortList( self.options.columns[i].id, isSelected ? (self.options.sort[0].operator == '+' ? '-' : '+') : self.options.columns[i].operator ); } function constructHead() { var offset = 0; that.$titles = []; self.columnOffsets = []; self.visibleColumns.forEach(function(v, i) { var $order, $resize, $left, $center, $right; offset += self.columnWidths[i]; self.columnOffsets[i] = offset - self.columnWidths[i] / 2; that.$titles[i] = new Ox.Element() .addClass('OxTitle OxColumn' + Ox.toTitleCase(v.id)) .css({ width: (self.columnWidths[i] - 9) + 'px', textAlign: v.align }) .html(v.title) .bindEvent({ anyclick: function(event, e) { clickColumn(v.id); }, dragstart: function(event, e) { dragstartColumn(v.id, e); }, drag: function(event, e) { dragColumn(v.id, e); }, dragend: function(event, e) { dragendColumn(v.id, e); } }) .appendTo(that.$head.$content.$element); $order = $('