oxjs/source/Ox.UI/js/Form/Ox.Spreadsheet.js
2011-11-30 17:35:50 +01:00

244 lines
No EOL
9.5 KiB
JavaScript

'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, '');
Ox.print('sv', JSON.stringify(self.values))
self.values.forEach(function(columns) {
columns.splice(index, 0, 0);
});
Ox.print('sv', JSON.stringify(self.values))
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.forEach(function(columns) {
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;
};