From 0c4a30ecc567aa0cb1802caf4a0a9f3a89534ce1 Mon Sep 17 00:00:00 2001 From: rolux Date: Wed, 30 Nov 2011 15:54:11 +0100 Subject: [PATCH] add Spreadsheet --- source/Ox.UI/js/Form/Ox.Spreadsheet.js | 242 +++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 source/Ox.UI/js/Form/Ox.Spreadsheet.js diff --git a/source/Ox.UI/js/Form/Ox.Spreadsheet.js b/source/Ox.UI/js/Form/Ox.Spreadsheet.js new file mode 100644 index 00000000..2a7fef3d --- /dev/null +++ b/source/Ox.UI/js/Form/Ox.Spreadsheet.js @@ -0,0 +1,242 @@ +'use strict'; + +Ox.Spreadsheet = function(options, self) { + + self = self || {}; + var that = Ox.Element({}, self) + .defaults({ + columnPlaceholder: '', + columns: [], + columnTitleType: 'str', + columnWidth: 64, + rowPlaceholder: '', + rows: [], + rowTitleType: 'str', + rowTitleWidth: 128, + title: '', + value: [] + }) + .options(options || {}) + .addClass('OxSpreadsheet'); + + self.values = []; + self.options.rows.forEach(function(row, r) { + self.values.push([]); + self.options.columns.forEach(function(column, c) { + self.values[r].push(0); + }); + }); + self.sums = getSums(); + + renderSpreadsheet(); + + function addColumn(index) { + self.options.columns.splice(index, 0, ''); + self.values = self.values.map(function(columns) { + return columns.splice(index, 0, 0); + }); + renderSpreadsheet(); + } + + function addRow(index) { + self.options.rows.splice(index, 0, ''); + self.values.splice(index, 0, Ox.repeat([0], self.columns)); + renderSpreadsheet(); + } + + function getSums() { + var sums = { + column: Ox.repeat([0], self.columns), + row: Ox.repeat([0], self.rows), + sheet: 0 + }; + Ox.print('sv', self.values); + self.values.forEach(function(columns, r) { + columns.forEach(function(value, c) { + sums.column[c] += value; + sums.row[r] += value; + sums.sheet += value; + }); + }); + return sums; + } + + function removeColumn(index) { + self.options.columns.splice(index, 1); + self.values = self.values.map(function(columns) { + return columns.splice(index, 1); + }); + renderSpreadsheet(); + } + + function removeRow(index) { + self.options.rows.splice(index, 1); + self.values.splice(index, 1); + renderSpreadsheet(); + } + + function renderSpreadsheet() { + + self.columns = self.options.columns.length; + self.rows = self.options.rows.length; + self.sums = getSums(); + self.$input = {}; + + that.empty() + .css({ + width: self.options.rowTitleWidth + + self.options.columnWidth * (self.columns + 1) + 'px', + height: 16 * (self.rows + 2) + 'px' + }); + + Ox.merge([self.options.title], Ox.clone(self.options.rows), ['Total']).forEach(function(row, r) { + r--; + Ox.print('ROW', row); + Ox.merge([''], Ox.clone(self.options.columns), ['Total']).forEach(function(column, c) { + c--; + if (r == -1) { + if (c == -1 || c == self.columns) { + Ox.print('c', c, 'row', row) + Ox.Label({ + style: 'square', + textAlign: c == -1 ? 'left' : 'right', + title: c == -1 ? self.options.title : 'Total', + width: c == -1 ? self.options.rowTitleWidth : self.options.columnWidth + }) + .appendTo(that); + } else { + Ox.Select({ + selectable: false, + style: 'square', + type: 'image', + items: [ + {id: 'before', title: 'Add column before'}, + {id: 'after', title: 'Add column after'}, + {id: 'remove', title: 'Remove this column', disabled: self.columns == 1} + ] + }) + .bindEvent({ + click: function(data) { + if (data.id == 'remove') { + removeColumn(c); + } else { + addColumn(c + (data.id == 'after')); + } + triggerChangeEvent(); + } + }) + .appendTo(that); + Ox.Input({ + placeholder: self.options.columnPlaceholder, + style: 'square', + type: self.options.columnTitleType, + value: column, + width: self.options.columnWidth - 16 + }) + .bindEvent({ + change: function(data) { + self.options.columns[c] = data.value; + triggerChangeEvent(); + } + }) + .appendTo(that); + } + } else { + if (c == -1) { + if (r < self.rows) { + Ox.Select({ + selectable: false, + style: 'square', + type: 'image', + items: [ + {id: 'before', title: 'Add row above'}, + {id: 'after', title: 'Add row below'}, + {id: 'remove', title: 'Remove this row', disabled: self.rows == 1} + ] + }) + .bindEvent({ + click: function(data) { + if (data.id == 'remove') { + removeRow(r); + } else { + addRow(r + (data.id == 'after')); + } + triggerChangeEvent(); + } + }) + .appendTo(that); + Ox.Input({ + placeholder: self.options.rowPlaceholder, + style: 'square', + type: self.options.rowTitleType, + value: row, + width: self.options.rowTitleWidth - 16 + }) + .bindEvent({ + change: function(data) { + self.options.rows[r] = data.value; + triggerChangeEvent(); + } + }) + .appendTo(that); + } else { + Ox.Label({ + style: 'square', + textAlign: 'right', + title: row, + width: self.options.rowTitleWidth + }) + .appendTo(that); + } + } else { + var id = c + ',' + r, + isColumnSum = r == self.rows, + isRowSum = c == self.columns, + isSheetSum = isColumnSum && isRowSum, + isSum = isColumnSum || isRowSum; + self.$input[id] = Ox.Input({ + //changeOnKeypress: true, + disabled: isSum, + style: 'square', + type: 'int', + value: isSheetSum ? self.sums.sheet + : isColumnSum ? self.sums.column[c] + : isRowSum ? self.sums.row[r] + : self.values[r][c], + width: self.options.columnWidth + }) + .appendTo(that); + !isSum && self.$input[id].bindEvent({ + change: function(data) { + self.values[r][c] = parseInt(data.value); + self.sums = getSums(); + self.$input[c + ',' + self.rows].options({value: self.sums.column[c]}); + self.$input[self.columns + ',' + r].options({value: self.sums.row[r]}); + self.$input[self.columns + ',' + self.rows].options({value: self.sums.sheet}); + triggerChangeEvent(); + } + }); + } + } + }); + }); + + } + + function triggerChangeEvent() { + that.triggerEvent('change', { + value: that.value() + }); + } + + that.value = function() { + return { + columns: self.options.columns, + rows: self.options.rows, + values: self.values + }; + }; + + return that; + +}; \ No newline at end of file