ColumnSetting = Object.subClass({
|
init: function(config) {
|
if (prototyping) {
|
return;
|
}
|
|
this.owner = config.owner;
|
Object.init.call(this, config);
|
this.option = this.createEmptyValue();
|
},
|
|
createEmptyValue: function(option) {
|
var result = {
|
id: null,
|
code: null,
|
name: null,
|
formatter: null,
|
align: null,
|
width: 1
|
}
|
|
if (option) {
|
$.extend(result, option);
|
}
|
|
return result;
|
},
|
|
set: function(parent, column, setting) {
|
if (!setting) {
|
return;
|
}
|
|
if (column == null) {
|
column = this.config.getActiveColumn();
|
}
|
|
if (column) {
|
var option = column.option;
|
option.align = option.align || "center";
|
option.width = option.width || "1";
|
option.formatter = option.formatter || "text";
|
|
for (var prop in setting) {
|
if (setting[prop]) {
|
option[prop] = setting[prop];
|
}
|
}
|
|
column.option = option;
|
}
|
|
try {
|
if (this.config.onBeginSetting) {
|
this.config.onBeginSetting.call(this, column);
|
}
|
|
if (this.config.onSetCode) {
|
this.config.onSetCode.call(this, column, setting.code);
|
}
|
if (this.config.onSetName) {
|
this.config.onSetName.call(this, column, setting.name);
|
}
|
if (this.config.onSetExpression) {
|
this.config.onSetExpression.call(this, column, setting.expression);
|
}
|
if (this.config.onSetFormatter) {
|
this.config.onSetFormatter.call(this, column, setting.formatter);
|
}
|
if (this.config.onSetAlign) {
|
this.config.onSetAlign.call(this, column, setting.align);
|
}
|
if (this.config.onSetWidth) {
|
this.config.onSetWidth.call(this, column, setting.width);
|
}
|
}
|
finally {
|
if (this.config.onEndSetting) {
|
this.config.onEndSetting.call(this, parent, column);
|
}
|
}
|
}
|
|
})
|
|
|
Sheet = Control.subClass({
|
|
items: true,
|
|
init: function(config) {
|
config.css = util.combine(config.css, {
|
container: null
|
});
|
|
this.columns = {
|
length: 0
|
};
|
this.addOneColumn = null;
|
this.holderColumn = null;
|
this.selectedColum;
|
this.nameSequence = {};
|
this.onAddColumnByBand = null;
|
this.onDeleteColumn = null;
|
this.onChangeColumn = null;
|
|
Control.call(this, config);
|
|
this.columnSetting = this.createColumnSetting();
|
this.settingListener = null;
|
},
|
|
getContainerTemplate: function() {
|
return $(Sheet_Template.container.join(""));
|
},
|
|
createContent: function() {
|
this.nameSequence = this.createNameSequence();
|
this.body = $("#sheet_body", this.container);
|
|
var columnOptions = this.config.columns;
|
|
//1. create indicator column
|
this.createIndicatorColumn();
|
|
//2. create index column
|
this.createIndexColumn();
|
|
//2. create columns
|
var max = columnOptions.length;
|
for (var i = 0; i < max; i++) {
|
var columnOption = columnOptions[i];
|
this.createDataColumn(columnOption);
|
}
|
|
this.createAddOneColumn();
|
this.createHolderColumn();
|
},
|
removeOneColumn: function (option) {
|
if(!option.id) {
|
return;
|
}
|
if(this.columns[option.code]) {
|
var column = this.columns[option.code];
|
column.el.remove();
|
this.columns[option.code] = null;
|
// this.reloadData();
|
}
|
},
|
clearColumns: function() {
|
for (var name in this.columns) {
|
if ("length" == name) {
|
continue;
|
}
|
|
var column = this.columns[name];
|
column.el.remove();
|
}
|
|
this.columns = {
|
length: 0
|
};
|
},
|
|
loadColumns: function(columnOptions) {
|
//1. clear
|
this.clearColumns();
|
|
//2. create columns
|
var beforeIndicator = this.addOneColumn ? this.addOneColumn.el : null;
|
var max = columnOptions.length;
|
|
this.columnSetting.loading = true;
|
try {
|
for (var i = 0; i < max; i++) {
|
var columnOption = columnOptions[i];
|
this.createDataColumn(columnOption, beforeIndicator);
|
}
|
}
|
finally {
|
this.columnSetting.loading = false;
|
}
|
},
|
|
createIndicatorColumn: function() {
|
//1. column
|
var column = $(Sheet_Template.indicatorColumn.join(""));
|
|
//2. root indicator
|
var indicator = $(Sheet_Template.top.join(""));
|
column.append(indicator);
|
|
//3. left indicator
|
var lineNum = this.config.lineNum;
|
for (var i = 0; i < lineNum; i++) {
|
var indicator = $(Sheet_Template.indicator.join(""));
|
column.append(indicator);
|
}
|
|
//4. append to container
|
this.container.append(column);
|
},
|
|
createIndexColumn: function() {
|
//1. column
|
var column = {
|
cells: []
|
};
|
var el = $(Sheet_Template.indexColumn.join(""));
|
|
//1. indicator
|
var indicator = $(Sheet_Template.top.join(""));
|
el.append(indicator);
|
|
//2. title
|
var title = el.title = $(Sheet_Template.title.join(""));
|
title.html("序号");
|
el.append(title);
|
|
//4. cell
|
var lineNum = this.config.lineNum; var cells = column.cells;
|
|
for (var i = 1; i <= lineNum; i++) {
|
var cell = $(Sheet_Template.cell.join(""));
|
cell.html(i);
|
cell.addClass("align-center");
|
|
cells.push({
|
parent: column,
|
el: cell
|
});
|
|
el.append(cell);
|
}
|
|
this.container.append(el);
|
},
|
|
createAddOneColumn: function() {
|
var column = {
|
type: "addOne"
|
};
|
|
var el = column.el = $(Sheet_Template.addOneColumn.join(""));
|
|
//1. indicator
|
var indicator = $(Sheet_Template.top.join(""));
|
el.append(indicator);
|
|
//2. title
|
var me = this;
|
var title = el.title = $(Sheet_Template.title.join(""));
|
title.html("+");
|
title.click(function(e){
|
me.createOneColumn.call(me);
|
e.preventDefault();
|
});
|
|
el.append(title);
|
|
//3. append to parent
|
this.body.append(el);
|
this.addOneColumn = column;
|
},
|
|
createHolderColumn: function() {
|
var el = $(Sheet_Template.holderColumn.join(""));
|
this.holder = el;
|
|
//1. indicator
|
var indicator = $(Sheet_Template.top.join(""));
|
el.append(indicator);
|
|
//2. title
|
var title = el.title = $(Sheet_Template.title.join(""));
|
el.append(title);
|
},
|
|
createDataColumn: function(columnOption, beforeIndicator) {
|
//1. column
|
var column = {
|
option: {},
|
cells: []
|
};
|
|
var el = columnOption.el;
|
|
if (!el) {
|
el = $(Sheet_Template.dataColumn.join(""));
|
}
|
column.el = el;
|
this.columns[columnOption.code] = column;
|
this.columns.length++;
|
|
columnOption.planId = this.config.planId;
|
columnOption.bookId = this.config.bookId;
|
columnOption.orderNo = this.columns.length;
|
|
var me = this;
|
var onClick = function() {
|
me.selectColum.call(me, column);
|
};
|
|
//2. indicator
|
var indicator = null;
|
if (!columnOption.el) {
|
indicator = $(Sheet_Template.top.join(""));
|
el.append(indicator);
|
}
|
else {
|
indicator = $(".cell-indicator", el);
|
}
|
indicator.click(onClick);
|
|
//3. title
|
var name = null;
|
if (!columnOption.el) {
|
title = $(Sheet_Template.title.join(""));
|
title.html(columnOption.name);
|
el.append(title);
|
}
|
else {
|
title = $(".cell-title", el);
|
}
|
el.title = title;
|
title.click(onClick);
|
|
//4. cell
|
var lineNum = this.config.lineNum; var cells = column.cells;
|
|
for (var i = 0; i < lineNum; i++) {
|
var cell = $(Sheet_Template.cell.join(""));
|
|
cells.push({
|
parent: column,
|
el: cell
|
});
|
|
el.append(cell);
|
}
|
|
//5. layout
|
column.setDirty = this.setDirty;
|
this.columnSetting.set(this, column, columnOption);
|
|
//6. append to container
|
if (!columnOption.el) {
|
if (beforeIndicator) {
|
el.insertBefore(beforeIndicator);
|
}
|
else {
|
this.body.append(el);
|
}
|
}
|
else {
|
el.addClass("column-data");
|
el.removeClass("column-holder");
|
}
|
|
this.refreshColumnOrderNo(column);
|
|
if(this.onChangeColumn) {
|
this.onChangeColumn(column.option, 1);
|
}
|
return column;
|
},
|
|
createOneColumn: function(option) {
|
if (!option) {
|
var name = this.getNextName();
|
option = {
|
id: randomString(20),
|
code: name,
|
name: name,
|
expression: "",
|
};
|
}
|
|
option = this.columnSetting.createEmptyValue(option);
|
var beforeIndicator = this.addOneColumn.el;
|
var column = this.createDataColumn(option, beforeIndicator);
|
|
this.selectColum(column);
|
|
if(this.onAddColumnByBand) {
|
this.onAddColumnByBand(column.option);
|
}
|
|
|
|
},
|
reloadData:function (dataList) {
|
if(!dataList) {
|
dataList = this.dataList;
|
}
|
this.loadData(dataList);
|
},
|
loadData: function(dataList) {
|
//1. clear
|
this.clearCells();
|
|
//2. load
|
this.dataList = dataList;
|
|
if (!dataList) {
|
return;
|
}
|
|
var columns = this.columns;
|
|
for (var prop in columns) {
|
var column = columns[prop];
|
var array = dataList[prop] == null ? dataList[prop.toLowerCase()] : dataList[prop];
|
this.loadOneColumnData(column, array);
|
}
|
},
|
|
loadOneColumnData: function(column, array) {
|
if (!column || !array || !column.cells || !column.cells.length) {
|
return;
|
}
|
|
var formatter = column.formatter ? column.formatter : this.getColumnFormatter();
|
var cells = column.cells;
|
var max = Math.min(array.length, cells.length);
|
|
for (var i = 0; i < max; i++) {
|
var value = array[i];
|
var cell = cells[i];
|
cell.el.html(formatter(value));
|
}
|
},
|
|
refreshNewColumnData: function(holderOption) {
|
var columnEl = $(".column-holder", this.body);
|
if (!columnEl.size()) {
|
return;
|
}
|
|
var columnOption = {
|
code: "test",
|
name: "test",
|
width: 1,
|
formatter:"text",
|
el: columnEl,
|
lineNum: 10
|
}
|
let option = columnOption;
|
if(holderOption) {
|
//属性覆盖
|
option = {...columnOption, ...holderOption};
|
}
|
option.code = randomString(12);
|
var column = this.createDataColumn(option);
|
|
if(this.onAddColumnByBand) {
|
this.onAddColumnByBand(column.option);
|
}
|
if(this.onChangeColumn) {
|
this.onChangeColumn(column.option, 1);
|
}
|
},
|
|
refreshColumnOrderNo: function(column) {
|
if(!column || !column.el || !column.option) {
|
return;
|
}
|
let el = column.el;
|
|
column.option.orderNo = $(el).index();
|
},
|
|
getChangedColumns: function() {
|
var result = [];
|
let me = this;
|
var columns = this.columns;
|
|
for (var code in columns) {
|
if ("length" == code) {
|
continue;
|
}
|
|
var column = columns[code];
|
if (!column) {
|
continue;
|
}
|
me.refreshColumnOrderNo(column);
|
var option = column.option;
|
|
if (!column.dirty) {
|
result.push({
|
id: option.id,
|
code: option.code,
|
name: option.name,
|
dirty: false
|
});
|
|
continue;
|
};
|
|
let one = {...option};
|
|
one.dirty = true;
|
result.push(one);
|
}
|
|
return result;
|
},
|
|
setDirty: function(dirty) {
|
this.dirty = dirty;
|
if (dirty) {
|
this.el.title.addClass("title-dirty");
|
}
|
else {
|
this.el.title.removeClass("title-dirty");
|
}
|
},
|
|
createColumnSetting: function(setting, column) {
|
var me = this;
|
var result = new ColumnSetting({
|
owner: "sheet",
|
getActiveColumn: function() {
|
return me.selectedColumn;
|
},
|
onSetCode: function(column, code) {
|
if(!code) {
|
return;
|
}
|
if (!this.loading) {
|
column.setDirty.call(column, true);
|
}
|
},
|
onSetName: function(column, name) {
|
if(!name) {
|
return;
|
}
|
column.el.title.html(name);
|
if (!this.loading) {
|
column.setDirty.call(column, true);
|
}
|
},
|
onSetExpression: function(column, expression) {
|
if(!expression) {
|
return;
|
}
|
if (!this.loading) {
|
column.setDirty.call(column, true);
|
}
|
},
|
onSetFormatter: function(column, formatter) {
|
if(!formatter) {
|
return;
|
}
|
var el = column.el;
|
var formatter = me.getColumnFormatter(formatter);
|
|
if (column.formatter != formatter) {
|
column.formatter = formatter;
|
if (!this.loading) {
|
column.setDirty.call(column, true);
|
}
|
if(me.dataList && column.option && column.option.code) {
|
me.loadOneColumnData(column, me.dataList[column.option.code.toLowerCase()]);
|
}else {
|
me.loadOneColumnData(me.dataList, column, column.code);
|
}
|
|
}
|
},
|
onSetAlign: function(column, align) {
|
if(!align) {
|
return;
|
}
|
var el = column.el;
|
var alignClass = me.getColumnAlignClass(align);
|
|
if (el.alignClass != alignClass) {
|
el.addClass(alignClass);
|
if (el.alignClass) {el.removeClass(el.alignClass)};
|
el.alignClass = alignClass;
|
}
|
|
if (!this.loading) {
|
column.setDirty.call(column, true);
|
}
|
},
|
onSetWidth: function(column, width) {
|
if (!width) {
|
return;
|
}
|
var el = column.el;
|
var widthClass = me.getColumnWidthClass(width);
|
|
if (el.widthClass != widthClass) {
|
el.addClass(widthClass);
|
if (el.widthClass) {el.removeClass(el.widthClass)};
|
el.widthClass = widthClass;
|
}
|
|
if (!this.loading) {
|
column.setDirty.call(column, true);
|
}
|
},
|
onBeginSetting: function(column) {
|
if (this.expressionChanged) {
|
me.onSaveExpression(this.column);
|
}
|
this.column = column;
|
this.expressionChanged = false;
|
|
},
|
onEndSetting: function(parent, column) {
|
// var settingListener = me.config.settingListener;
|
|
// if (settingListener && (parent != settingListener)) {
|
// settingListener.setColumnSetting(me, column, column.option);
|
// }
|
}
|
});
|
|
return result;
|
},
|
|
setColumnSetting: function(sender, column, option) {
|
column = column || this.selectedColumn;
|
this.columnSetting.set(sender, column, option);
|
},
|
|
selectColum: function(column) {
|
if (!column || column == this.selectedColumn) {
|
return;
|
}
|
|
//1. class
|
if (this.selectedColumn) {
|
this.selectedColumn.el.title.removeClass("title-selected");
|
this.selectedColumn.el.title.addClass("title-unselected");
|
}
|
|
column.el.title.removeClass("title-unselected");
|
column.el.title.addClass("title-selected");
|
|
this.selectedColumn = column;
|
this.columnSetting.column = column;
|
|
//2. fire event
|
if (this.config.settingListener) {
|
this.config.settingListener.setColumnSetting(this, column, column.option);
|
}
|
},
|
|
clearCells: function() {
|
for (var prop in this.columns) {
|
var column = this.columns[prop];
|
var cells = column.cells;
|
|
if (!cells || !cells.length) {
|
return;
|
}
|
|
var max = cells.length;
|
for (var i = 0; i < cells; i++) {
|
cells[i].empty();
|
}
|
}
|
},
|
|
textFormatter: function(value) {
|
return value;
|
},
|
|
boolFormatter: function(value) {
|
if (!value) {
|
return ;
|
}
|
if("T" == value || "1" == value || 1 == value || "true" == value || "yes" == value) {
|
return "是";
|
}
|
return "否";
|
},
|
|
moneyFormatter: function(value) {
|
if (!value || isNaN(value)) {
|
return "¥0";
|
}
|
|
var num = typeof value == 'string' ? parseFloat(value) : value;
|
num = num.toFixed(3);
|
num = '¥' + num;
|
|
return num;
|
},
|
|
percentFormatter: function(value) {
|
if (value) {
|
var num = typeof value == 'string' ? parseFloat(value) : value;
|
num = num.toFixed(0);
|
return num + '%';
|
}
|
return "0%";
|
},
|
|
getColumnFormatter: function(formatter) {
|
if (!formatter) {
|
return this.textFormatter;
|
}
|
else if ("money" == formatter) {
|
return this.moneyFormatter;
|
}else if ("bool" == formatter) {
|
return this.boolFormatter;
|
}
|
else if ("percent" == formatter) {
|
return this.percentFormatter;
|
}
|
else {
|
return this.textFormatter;
|
}
|
},
|
|
getColumnAlignClass: function(align) {
|
if ("left" == align) {
|
return "column-left";
|
}
|
else if ("right" == align) {
|
return "column-right";
|
}
|
else {
|
return "column-center";
|
}
|
},
|
|
getColumnWidthClass: function(width) {
|
width = "" + width;
|
|
if ("0.6" == width) {
|
return "column-width-06";
|
}
|
else if ("0.8" == width) {
|
return "column-width-08";
|
}
|
else if ("1" == width) {
|
return "column-width-10";
|
}
|
else if ("1.5" == width) {
|
return "column-width-15";
|
}
|
else if ("2.5" == width) {
|
return "column-width-25";
|
}
|
else {
|
return "column-width-10";
|
}
|
},
|
|
getHolder: function(title) {
|
this.holder.title.html(title);
|
this.holder.height(220);
|
var holder = this.holder.get(0);
|
return holder.cloneNode(true);
|
},
|
|
setSelectedLayout: function(layout) {
|
if (!layout) {
|
return;
|
}
|
|
var selected = this.selectedColumn;
|
this.setColumnLayout(selected, layout);
|
},
|
|
createNameSequence: function() {
|
var nameSequence = [];
|
|
for (var i = 0; i <= 25; i++) {
|
var char = String.fromCharCode(i + 65);
|
nameSequence[i] = { "code": char, "used": false};
|
}
|
|
for (var i = 26; i <= 51; i++) {
|
var char = "A" + String.fromCharCode(i + 39);
|
nameSequence[i] = { "code": char, "used": false};
|
}
|
|
return nameSequence;
|
},
|
|
getNextName: function() {
|
return randomString(12)
|
}
|
|
});
|
|
|
//*************************************
|
Sheet_Template = {};
|
|
Sheet_Template.container = [
|
'<div class="sheet">',
|
'<div class="sheet-body">',
|
'<div id="sheet_body" class="sheet-body-inner"></div>',
|
'</div>',
|
'</div>'
|
];
|
|
Sheet_Template.indicatorColumn = [
|
'<div class="column-indicator">',
|
'</div>'
|
];
|
|
Sheet_Template.indexColumn = [
|
'<div class="column-index">',
|
'</div>'
|
];
|
|
Sheet_Template.dataColumn = [
|
'<div class="column-data">',
|
'</div>'
|
];
|
|
Sheet_Template.addOneColumn = [
|
'<div class="column-addOne">',
|
'</div>'
|
];
|
|
Sheet_Template.holderColumn = [
|
'<div class="column-holder">',
|
'</div>'
|
];
|
|
Sheet_Template.indicator = [
|
'<div class="cell-indicator">',
|
'</div>'
|
];
|
|
Sheet_Template.top = [
|
'<div class="cell-top">',
|
'</div>'
|
];
|
|
Sheet_Template.title = [
|
'<div class="cell-title title-unselected">',
|
'</div>'
|
];
|
|
Sheet_Template.cell = [
|
'<div class="cell-data">',
|
'</div>'
|
];
|
|
function randomString(len, charSet) {
|
charSet = charSet || 'abcdefghijklmnopqrstuvwxyz0123456789';
|
var randomString = '';
|
for (var i = 0; i < len; i++) {
|
var randomPoz = Math.floor(Math.random() * charSet.length);
|
let subStr = charSet.substring(randomPoz,randomPoz+1);
|
if (randomString.length == 0 && !isNaN(parseFloat(subStr)) && isFinite(subStr)) {
|
//首字母是数字
|
i--;
|
continue;
|
}
|
randomString += subStr;
|
}
|
return randomString;
|
}
|