|
|
|
แจก Table Editor plugin สำหรับแก้ไขเซลล์ตารางให้ไปลองเทสกันครับ |
|
|
|
|
|
|
|
เป็นปลักอินแก้ไขเซลตารางทั่วไป แต่ผมปรับปรุงเรื่องเพิ่ม feature การปรับแต่งการ validation เข้าไปให้เลือกได้ว่าคอลัมน์ไหนบังคับใส่ค่ายังไง
ส่วนชนิดข้อมูลทำการ validate ได้แค่ตัวเลขกับตัวหนังสือ ถ้าเป็นพวกวันที่ที่ฟอร์แมตมันดิ้นได้หลายๆ อย่าง เขียนเพิ่มคงจะยาว เลยไม่ใส่เข้าไป แล้วก็เลือกสามารถปิด column ให้ไม่สามารถแก้ไขได้
ปรับปรุงมาจากเว็บนี้ครับ https://github.com/mindmup/editable-table/blob/master/mindmup-editabletable.js
ก่อนโพสมีพบปัญหาเลือกการที่ cell ไม่สามารถใส่ค่าเป็น blank ได้ แล้วไม่สามารถใช้งานปุ่ม del เพื่อลบข้อมูลเซลล์ได้ เดี๋ยวจะกลับมาอัพเดทให้อีกทีครับ
Code (JavaScript)
/*global $, window*/
$.fn.editableTableWidget = function (options) {
'use strict';
return $(this).each(function () {
var buildDefaultOptions = function () {
var opts = $.extend({}, $.fn.editableTableWidget.defaultOptions);
opts.editor = opts.editor.clone();
return opts;
},editMode = false, onedit = false, activeOptions = $.extend(buildDefaultOptions(), options), ddigits = null,
slstyle = function () {if (activeOptions.PreventDatatable) {return $(this).DataTable().select.style();}},
ARROW_LEFT = 37, ARROW_UP = 38, ARROW_RIGHT = 39, ARROW_DOWN = 40, ENTER = 13, ESC = 27, TAB = 9,
element = $(this),
editor = activeOptions.editor.css('position', 'absolute').hide().appendTo(element.parent()),
active,
showEditor = function (select) {
if (activeOptions.PreventDatatable) {
onedit = false;
element.DataTable().select.style('api');
}
active = element.find('td:focus').filter(function(){
return !(activeOptions.disableColumnNumbers.indexOf(findColIndex(this)) > -1);
});
if (active.length) {
if (activeOptions.PreventDatatable) {onedit = true;}
editor.val(active.text())
.removeClass('error')
.show()
.offset(active.offset())
.css(active.css(activeOptions.cloneProperties))
.width(active.width())
.height(active.height())
.focus();
if (select) {
editor.select();
} else { editor.select().get(0).setSelectionRange(editor.val().length, editor.val().length) }
}
if (activeOptions.PreventDatatable) {if (!onedit) {element.DataTable().select.style(slstyle);}}
},
setActiveText = function () {
var text = function () {
if (isNumeric(ddigits, true) && isNumeric(editor.val(), true)) {
return fixDec(editor.val(), ddigits);
} else {
return editor.val();
}
},
evt = $.Event('change'),
originalContent;
if (active.text() === text || editor.hasClass('error')) {
return true;
}
originalContent = active.html();
active.text(text).trigger(evt, text);
if (evt.result === false) {
active.html(originalContent);
}
},
movement = function (element, keycode) {
if (keycode === ARROW_RIGHT) {
return element.next('td');
} else if (keycode === ARROW_LEFT) {
return element.prev('td');
} else if (keycode === ARROW_UP) {
editMode = false; return element.parent().prev().children().eq(element.index());
} else if (keycode === ARROW_DOWN || keycode === ENTER) {
editMode = false; return element.parent().next().children().eq(element.index());
}
return [];
};
editor.blur(function () {
setActiveText();
editor.hide();
}).keydown(function (e) {
//if (e.which === ENTER) {
// setActiveText();
// editor.hide();
// active.focus();
// e.preventDefault();
// e.stopPropagation();} else
if (e.which === ESC) {
editMode = false;
editor.val(active.text());
e.preventDefault();
e.stopPropagation();
editor.hide();
active.focus();
//} else if (e.which === TAB) {
// active.focus();
} else { //if (this.selectionEnd - this.selectionStart === this.value.length) {
var possibleMove = movement(active, e.which);
if (possibleMove.length > 0 && !editMode) {
possibleMove.focus();
e.preventDefault();
e.stopPropagation();
}
}
})
.on('input paste', function () {
var evt = $.Event('validate');
active.trigger(evt, editor.val());
if (evt.result === false) {
editor.addClass('error');
} else {
editor.removeClass('error');
}
});
element.on('click keypress dblclick', showEditor)
.css('cursor', 'pointer')
.keydown(function (e) {
var prevent = true, possibleMove = movement($(e.target), e.which);
if (possibleMove.length > 0) {
possibleMove.focus();
} else if (e.which === 17 || e.which === 91 || e.which === 93 || e.which === 113) {
editMode = true;
showEditor(false);
prevent = false;
} else {
prevent = false;
}
if (prevent) {
e.stopPropagation();
e.preventDefault();
}
});
element.find('td').prop('tabindex', 1);
$(window).on('resize', function () {
if (editor.is(':visible')) {
editor.offset(active.offset())
.width(active.width())
.height(active.height());
}
});
element.on('validate', function (evt, value) {
activeOptions.validateCols.forEach(function(vcl) {
if (vcl.columnNumbers.indexOf(findColIndex(active[0])) > -1) {
if (!(vcl.fixDec === undefined)) {ddigits = vcl.fixDec;} else {ddigits = null;};
evt.result = [
notEqual(value, vcl.notEqual),
equal(value, vcl.equal),
lessThan(value, vcl.lessThan),
greaterThan(value, vcl.greaterThan),
isNumeric(value, vcl.isNumeric),
isText(value, vcl.isText),
minChrLength(value, vcl.minChrLength),
maxChrLength(value, vcl.maxChrLength)
].every(function (valid) {return valid == true;});
return;
}
});
});
});
};
var findColIndex = function(td){
var i = -1;
var elem = td;
do {++i;} while((elem=elem.previousSibling)!=null);
return i;
};
var notEqual = function(val, com){if (!(com === undefined)) {return val != com;} else {return true;}},
equal = function(val, com){if (!(com === undefined)) {return val == com;} else {return true;}},
lessThan = function(val, com){if (!(com === undefined)){return val < com;} else {return true;}},
greaterThan = function(val, com){if (!(com === undefined)) {return val > com;} else {return true;}},
isNumeric = function(val, com){if (!(com === undefined)) {return (!isNaN(parseFloat(val)) && isFinite(val)) == com;} else {return true;}},
isText = function(val, com){if (!(com === undefined)) {return (isNaN(val)) == com;} else {return true;}},
minChrLength = function(val, com){if (!(com === undefined)) {return val.length >= com;} else {return true;}},
maxChrLength = function(val, com){if (!(com === undefined)) {return val.length <= com;} else {return true;}},
fixDec = function(val, decnum){return Number(val).toFixed(decnum);};
$.fn.editableTableWidget.defaultOptions = {
cloneProperties: ['padding', 'padding-top', 'padding-bottom', 'padding-left', 'padding-right',
'text-align', 'font', 'font-size', 'font-family', 'font-weight',
'border', 'border-top', 'border-bottom', 'border-left', 'border-right'],
editor: $('<input>')
};
ตัวอย่างวิธีการประกาศใช้งาน
Code (JavaScript)
$("#pckitm").editableTableWidget({
disableColumnNumbers: [5,6,7], //ปิดไม่ให้ Column อันดับที่ 5, 6, 7 สามารถไขแก้ไข่ได้
validateCols:[{ //validateCols เป็น option สำหรับการ validation ข้อมูลในเซลล์ของ column ที่กำหนด โดยระบุค่าเป็น array โดย แต่ละelements จะเป็นการกำหนดรูปแบบการ validation
columnNumbers: [0,1,12], // element ที่ 1 กำหนดให้ column 0, 1, 12 เป็นตัวหนังสือ
isText: true
},
{
columnNumbers: [2,3,4,8], // element ที่ 2 กำหนดให้ column 2, 3, 4, 8 เป็นตัวตัวเลข และมีทศนิยท 3 หลัก และต้องมีค่ามากกว่า 100
greaterThan: 100,
isNumeric: true,
fixDec: 3
},
{
columnNumbers: [9,10,11], //element ที่ 3 กำหนดให้ column 9, 10, 11 เป็นตัวตัวเลข และมีทศนิยท 2 หลัก และต้องมีค่าน้อยกว่า 50
lessThan: 50,
isNumeric: true,
fixDec: 2
}
],
PreventDatatable: true //PreventDatatable เป็น option สำหรับ feature การปิดการเลือกรายการแถว (row) ชั่วคราว ขณะแก้ไขเซล ของตารางที่เป็น Datatable ที่ประการด้วยการใช้ปลั๊ก jquery.dataTables.min.js
});
อย่างลืมใส่สไตล์เวลาเซลล์มีค่าที่ error ด้วยนะครับ
Code (JavaScript)
input.error {
box-shadow: inset 0px 0px 5px red,inset -2px 2px 2px #CD6155;
background-image: linear-gradient(#F5B7B1, #F5B7B1);
}
editor plugin ของ Datatable ก็มีนะครับ https://editor.datatables.net/
ที่ผมไม่ใช้ editor plugin ของ Datatable เพราะมันใช้งานร่วมกับ ajax แล้วทำงานกับฝั่ง server ด้วย และมันก็ไม่ฟรี
Tag : HTML, CSS, HTML5, JavaScript, jQuery
|
ประวัติการแก้ไข 2022-01-21 14:46:11
|
|
|
|
|
Date :
2022-01-21 14:31:41 |
By :
nk4ever |
View :
667 |
Reply :
0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Load balance : Server 03
|