官方网站:https://valor-software.com/ng2-handsontable/
html
<div class="row col-md-10" *ngIf="datas && datas.length > 0">
<div id="hot" class="hot handsontable dataTable table-striped center-block">
<hot-table [data]="datas"
[columns]="columns"
[colHeaders]="colHeaders"
[colWidths]="colHeaders"
[options]="options">
</hot-table>
<input type="hidden" id="showTotal" value="yes">
</div>
</div>
test.module.ts
import { HotTableModule } from 'ng2-handsontable';
@NgModule({
imports: [
HotTableModule
],
declarations: [
....
],
exports: [
.....
]
})
export class TestModule {
}
test.component.ts
import {HandsontableNumberEditor} from 'handsontable-number-editor';
private datas: any[];
private backUpDatasLength: number = 0;
private options: any;
private colHeaders: string[];
private columns: any[];
ngDoCheck() {
if (this.datas && this.datas.length > this.backUpDatasLength) {
this.options = {
readOnly: false,
mergeCells: this.merge()
}
this.backUpDatasLength = this.datas.length;
}
}
private initInfo(): void{
this.colHeaders = [
'date',
'',
'Country',
'Level',
'Units'
];
this.columns = [
{data: 'date', type: 'text', editor: HandsontableNumberEditor, width: 100},
{data: 'cellOneNull', type: 'text', editor: HandsontableNumberEditor, width: 100},
{data: 'Country', type: 'text', editor: HandsontableNumberEditor, width: 120},
{data: 'Level', type: 'text', editor: HandsontableNumberEditor, width: 120},
{data: 'Units', type: 'text', editor: HandsontableNumberEditor, width: 120},
];
this.options = {
rowHeaders: false,
columnSorting: false,
contextMenu: false,
mergeCells: true
}
}
merge():any{
var mergeCells=[]
for (var row=0;row<this.datas.length;row++){
mergeCells.push({row: row, col: 0, rowspan: 1, colspan: 2})
}
return mergeCells;
}
private getDataInfo(): void{
this.initInfo();
this.modifyFlag = null;
let param = {"no": this.no};
let height = 580;
this.remote.getDataInfo(param).subscribe((res) => {
if (res.formList.length > 0) {
jQuery("#showTotal").val('yes');
this.datas = [];
res.formList.forEach((table) => {
this.datas.push(table);
});
if (res.formList.length < 15) {
height = 450
};
this.options = {
height: height,
readOnly: true,
stretchH: 'all',
className: 'htCenter htMiddle',
beforeRender: function() {
jQuery('#hot').find('.handsontable-container').css("border-top","1px solid #CDCDCD");
jQuery('#hot').find('.ht_master').find('thead').find('tr:first').hide();
jQuery('#hot').find('.ht_clone_top').find('thead').find('tr:first').hide();
},
afterRender: function () {
jQuery("#hot").find('thead').append(
'<tr><th rowspan="2" colspan="2" style="vertical-align:middle;">日期</th><th colspan="3">aaa</th><th colspan="5">bbb</th><th rowspan="2" colspan="2" style="vertical-align:middle;">ccc</th></tr>' +
'<tr><th>Country</th><th>Level</th><th style="vertical-align:middle;">Units</th></tr>');
if ( jQuery("#total").length > 0 ) {
} else {
if (jQuery("#showTotal").val() == "yes") {
jQuery("#hot").find('tbody:first').after(
'<tr id="total"><th rowspan="2" colspan="2" style="vertical-align:middle;">total</th><th>'+res.aaa+'</th><th>'+res.bbb+'</th><th>'+res.cfSurplusTotal+'</th><th>'+res.ccc+'</th></tr>');
}
}
},
mergeCells: this.merge(),
}
this.backUpDatasLength = this.datas.length;
} else {
this.datas = [{},{},{},{},{},{},{},{},{},{},{}];
this.options = {
height: height,
readOnly: false,
stretchH: 'all',
className: 'htCenter htMiddle',
beforeRender: function() {
jQuery('#hot').find('.handsontable-container').css("border-top","1px solid #CDCDCD");
jQuery('#hot').find('.ht_master').find('thead').find('tr:first').hide();
jQuery('#hot').find('.ht_clone_top').find('thead').find('tr:first').hide();
},
afterRender: function () {
jQuery("#hot").find('thead').append(
'<tr><th rowspan="2" colspan="2" style="vertical-align:middle;">日期</th><th colspan="3">aaa</th><th colspan="5">bbb</th><th rowspan="2" colspan="2" style="vertical-align:middle;">ccc</th></tr>' +
'<tr><th>Country</th><th>Level</th><th style="vertical-align:middle;">Units</th></tr>');
},
mergeCells: this.merge()
}
this.backUpDatasLength = this.datas.length;
}
}, (error) => {
});
}
public inputCheck(datas: AForm[]): boolean {
let reg1 = /^$/;
let reg2 = /^$/;
for(let data of this.datas){
let date = data.date;
if(date && !reg1.test(date.replace(/\s*/g, ''))){
this.dialog.warning("waring", "aaaa。");
return false;
}
let Country = data.Country;
if(Country && !reg2.test(this.replaceSpecial(Country.replace(/\s*/g, '')))){
this.dialog.warning("waring", "ccc。");
return false;
}
}
return true;
}
private replaceSpecial(str: string): string {
let replaceStrMap: any = {'▲': '-', '¥':'', ',':'', '%': ''};
let reg = new RegExp('(' + Object.keys(replaceStrMap).join('|') + ')', 'g');
return str.replace(reg, function(match) {
return replaceStrMap[match];
}).replace(/\\/g, '');
}
IME控制,只能输入tel类型
handsontable-number-editor.ts
import * as Handsontable from 'handsontable';
export class HandsontableNumberEditor extends Handsontable.editors.TextEditor {
createElements() {
// Call the original createElements method
super.createElements.apply(this, arguments);
// Create number input and update relevant properties
this.TEXTAREA = document.createElement('input');
this.TEXTAREA.setAttribute('type', 'tel');
this.TEXTAREA.className = 'handsontableInput';
this.textareaStyle = this.TEXTAREA.style;
this.textareaStyle.width = '0';
this.textareaStyle.height = '0';
//replace textarea with number input
Handsontable.dom.empty(this.TEXTAREA_PARENT);
this.TEXTAREA_PARENT.appendChild(this.TEXTAREA);
}
}