appendgrid 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013-2019 Albert L.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
19
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21
+ OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # AppendGrid
2
+
3
+ **AppendGrid** allow you to input structured data row by row such like filling spreadsheets. It allows you to add/remove/insert/delete row in the grid. The generated input/select/textarea controls are well named for submitting to server side applications such as ASP.NET/PHP/JSP. Multiple options and callback events are available to fit different situations.
4
+
5
+
6
+ ## About versions
7
+ The project was originally named "jquery.appendGrid" because [version 1](../../tree/v1-dev) required jQuery, but jQuery is no longer required since [version 2](../../tree/v2-dev). The GitHub repository will be renamed to "appendgrid" to better reflect the current state of the project. GitHub will automatically redirect the old URL, so existing links and clones will continue to work.
8
+
9
+ Starting from [version 3](../../tree/v3-dev), the source code has been migrated to TypeScript for improved type safety and developer experience.
10
+
11
+
12
+ ## Prerequisite
13
+ - Nope, just need a modern web browser that can run JavaScript!
14
+
15
+
16
+ ## Demo
17
+ Lots of demo cases are available on [Demo section](https://appendgrid.azurewebsites.net/Demo) of **AppendGrid** website.
18
+
19
+
20
+ ## Documentation
21
+ The full list of options / methods / callback events are available on the [Documentation section](https://appendgrid.azurewebsites.net/Documentation) of **AppendGrid** website.
22
+
23
+
24
+ ## Instructions
25
+ - Execute command `npm install` to install development dependencies
26
+ - Execute command `npm run start` for running development server and preview
27
+ - Execute command `npm test` for running the test suite
28
+ - Execute command `npm run build` for creating distribution files
29
+
30
+
31
+ ## Others
32
+ - The project website was hosted by AppHarbor but it is [closed on Dec 2022](https://twitter.com/appharbor/status/1590544012481826816) and the website was moved to [freeasphosting.net](https://freeasphosting.net)
33
+ - Due to some compatibility issues and the project website is moved to [Azure Web Apps](https://azure.microsoft.com/en-us/products/app-service/web) with a [new project website URL](https://appendgrid.azurewebsites.net) (wish it won't change again)
34
+
35
+ ## License
36
+ Licensed under the [MIT](http://www.opensource.org/licenses/mit-license.php) license.
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):(e="undefined"!=typeof globalThis?globalThis:e||self).AppendGrid=t()}(this,function(){var e=class{constructor(e,t=!1){this.name=e,this.icons={append:null,removeLast:null,insert:null,remove:null,moveUp:null,moveDown:null},this.isTextBased=t}},t=class extends e{constructor(e){super("icon-default",!0),Object.assign(this.icons,{append:"+",removeLast:"-",insert:"↜",remove:"✕",moveUp:"▲",moveDown:"▼"}),e&&Object.assign(this.icons,e)}generateIcon(e,t){const n=document.createTextNode(this.icons[t]||"");return e.appendChild(n),n}};function n(e,...t){t&&t.length&&t.forEach(function(t){if(t){const n=t.split(/\s+/gi);n&&n.length&&n.forEach(function(t){t&&e.classList.add(t)})}})}function o(e){return null==e}function s(e){return!isNaN(parseFloat(e))&&isFinite(e)}function r(e){return"[object Object]"===Object.prototype.toString.call(e)}function l(e,t=null,o=null,s=null,r=null){const l=document.createElement(e);return t&&(l.id=t),o&&(l.name=o),s&&n(l,s),r&&(l.type=r),l}var i=class extends e{constructor(e){super("icon-bootstrapicons");const t={baseUrl:"",icons:null};Object.assign(t,e);const n={append:"plus",removeLast:"dash",insert:"arrow-90deg-left",remove:"trash",moveUp:"chevron-up",moveDown:"chevron-down"};t.icons&&Object.assign(n,t.icons),this.icons=n,this.baseUrl=t.baseUrl}generateIcon(e,t){const o=document.createElement("img");return o.src=this.baseUrl+this.icons[t]+".svg",n(o,this.icons[t]),e.appendChild(o),o}},a=class extends e{constructor(e){super("icon-fontawesome6");const t={icons:null};Object.assign(t,e);const n={append:"fa-solid fa-plus",removeLast:"fa-solid fa-minus",insert:"fa-solid fa-reply",remove:"fa-solid fa-times",moveUp:"fa-solid fa-angle-up",moveDown:"fa-solid fa-angle-down"};t.icons&&Object.assign(n,t.icons),this.icons=n}generateIcon(e,t){const o=document.createElement("i");return n(o,this.icons[t]),e.appendChild(o),o}},c=class extends e{constructor(e){super("icon-fontawesome5");const t={icons:null};Object.assign(t,e);const n={append:"fas fa-plus",removeLast:"fas fa-minus",insert:"fas fa-reply",remove:"fas fa-times",moveUp:"fas fa-angle-up",moveDown:"fas fa-angle-down"};t.icons&&Object.assign(n,t.icons),this.icons=n}generateIcon(e,t){const o=document.createElement("i");return n(o,this.icons[t]),e.appendChild(o),o}},u=class extends e{constructor(e){super("icon-materialdesignicons3");const t={icons:null};Object.assign(t,e);const n={append:"mdi mdi-plus",removeLast:"mdi mdi-minus",insert:"mdi mdi-reply",remove:"mdi mdi-close",moveUp:"mdi mdi-chevron-up",moveDown:"mdi mdi-chevron-down"};t.icons&&Object.assign(n,t.icons),this.icons=n}generateIcon(e,t){const o=document.createElement("span");return n(o,this.icons[t]),e.appendChild(o),o}},d=class extends e{constructor(e){super("icon-ionicon4");const t={icons:null};Object.assign(t,e);const n={append:"icon ion-md-add",removeLast:"icon ion-md-remove",insert:"icon ion-md-undo",remove:"icon ion-md-close",moveUp:"icon ion-md-arrow-dropup",moveDown:"icon ion-md-arrow-dropdown"};t.icons&&Object.assign(n,t.icons),this.icons=n}generateIcon(e,t){const o=document.createElement("i");return n(o,this.icons[t]),e.appendChild(o),o}},m=class extends e{constructor(e){super("icon-typicons2");const t={icons:null};Object.assign(t,e);const n={append:"typcn typcn-plus",removeLast:"typcn typcn-minus",insert:"typcn typcn-arrow-back",remove:"typcn typcn-times",moveUp:"typcn typcn-arrow-sorted-up",moveDown:"typcn typcn-arrow-sorted-down"};t.icons&&Object.assign(n,t.icons),this.icons=n}generateIcon(e,t){const o=document.createElement("span");return n(o,this.icons[t]),e.appendChild(o),o}},p=class extends e{constructor(e){super("icon-openiconic");const t={icons:null};Object.assign(t,e);const n={append:"plus",removeLast:"minus",insert:"share",remove:"x",moveUp:"chevron-top",moveDown:"chevron-bottom"};t.icons&&Object.assign(n,t.icons),this.icons=n}generateIcon(e,t){const n=document.createElement("span");return n.className="oi",n.dataset.glyph=this.icons[t]??void 0,n.setAttribute("aria-hidden","true"),e.appendChild(n),n}},h=class{constructor(e,t){this.i18n=e,this.iconFramework=t,this.sectionClasses={table:null,thead:null,theadRow:null,theadCell:null,tbody:null,tbodyRow:null,tbodyCell:null,tfoot:null,tfootRow:null,tfootCell:null,first:null,last:null,control:null,button:null,buttonGroup:null,append:null,removeLast:null,insert:null,remove:null,moveUp:null,moveDown:null,empty:null}}applySectionClasses(e){for(const t in this.sectionClasses){const n=t;e[n]&&(this.sectionClasses[n]?this.sectionClasses[n]+=" "+e[n]:this.sectionClasses[n]=e[n])}}getSectionClasses(e){return this.sectionClasses[e]??null}createButtonGroup(){return null}generateButton(e,t,o){const s=l("button",o??null,null,null,"button");return s.title=this.i18n[t],n(s,this.getSectionClasses("button"),this.getSectionClasses(t)),e.appendChild(s),this.iconFramework.generateIcon(s,t),s}generateControl(e,t,s,i){let a;if("select"===t.type){const e=document.createElement("select");if(e.id=s,e.name=i,a=e,Array.isArray(t.ctrlOptions)){if(t.ctrlOptions.length>0)if(r(t.ctrlOptions[0])){let n=null,s=null;for(let r=0;r<t.ctrlOptions.length;r++){const l=t.ctrlOptions[r];o(l.group)?s=null:n!==l.group&&(n=l.group,s=document.createElement("optgroup"),s.label=n,e.appendChild(s));const i=document.createElement("option");i.value=l.value,i.innerText=l.label,o(l.title)||i.setAttribute("title",l.title),(s??e).appendChild(i)}}else for(let n=0;n<t.ctrlOptions.length;n++){const o=t.ctrlOptions[n];e.options[e.options.length]=new Option(o,o)}}else if(r(t.ctrlOptions)){const n=t.ctrlOptions;for(const t in n)e.options[e.options.length]=new Option(n[t],t)}else if("string"==typeof t.ctrlOptions){const n=t.ctrlOptions.split(";");for(let t=0;t<n.length;t++){const o=n[t].indexOf(":");e.options[e.options.length]=-1===o?new Option(n[t],n[t]):new Option(n[t].substring(o+1),n[t].substring(0,o))}}else"function"==typeof t.ctrlOptions&&t.ctrlOptions(e)}else if("checkbox"===t.type)a=l("input",s,i,null,"checkbox"),a.value="1";else if("textarea"===t.type)a=l("textarea",s,i);else if(/^(color|date|datetime|datetime-local|email|month|number|range|search|tel|time|url|week)$/.test(t.type)){a=l("input",s,i);try{a.type=t.type}catch(c){}}else a=l("input",s,i),a.type="text";return n(a,this.getSectionClasses("control"),t.ctrlClass),e&&e.appendChild(a),a}},f=class extends h{constructor(e,t,n){super(t,n),this.name="ui-default"}},w=class extends h{constructor(e,t,n){super(t,n),this.name="ui-bootstrap4";const o={useButtonGroup:!0,sectionClasses:null,sizing:"normal"};Object.assign(o,e);const s={table:"table",thead:"thead-light",control:"form-control",button:"btn",buttonGroup:"btn-group",append:"btn-outline-secondary",removeLast:"btn-outline-secondary",insert:"btn-outline-secondary",remove:"btn-outline-secondary",moveUp:"btn-outline-secondary",moveDown:"btn-outline-secondary",empty:"text-center"};"small"===o.sizing?(s.table+=" table-sm",s.buttonGroup+=" btn-group-sm",s.control+=" form-control-sm"):"large"===o.sizing&&(s.buttonGroup+=" btn-group-lg",s.control+=" form-control-lg"),o.sectionClasses&&Object.assign(s,o.sectionClasses),this.applySectionClasses(s),this.uiParams=o}createButtonGroup(){if(this.uiParams.useButtonGroup){const e=document.createElement("div");return n(e,this.getSectionClasses("buttonGroup")),e}return super.createButtonGroup()}generateControl(e,t,o,s){let r;if("checkbox"===t.type){const i=l("div",null,null,"form-check");e?.appendChild(i),r=l("input",o,s,"form-check-input position-static"),r.type="checkbox",r.value="1",n(r,t.ctrlClass),i.appendChild(r)}else"readonly"===t.type?(r=l("input",o,s,null,"text"),n(r,this.getSectionClasses("control"),t.ctrlClass),r.classList.remove("form-control"),r.classList.add("form-control-plaintext"),r.readOnly=!0,e?.appendChild(r)):r=super.generateControl(e,t,o,s);return r}},g=class extends h{constructor(e,t,n){super(t,n),this.name="ui-bootstrap5";const o={useButtonGroup:!0,sectionClasses:null,sizing:"normal"};Object.assign(o,e);const s={table:"table",thead:"table-light",control:"form-control",button:"btn",buttonGroup:"btn-group",append:"btn-outline-secondary",removeLast:"btn-outline-secondary",insert:"btn-outline-secondary",remove:"btn-outline-secondary",moveUp:"btn-outline-secondary",moveDown:"btn-outline-secondary",empty:"text-center"};"small"===o.sizing?(s.table+=" table-sm",s.buttonGroup+=" btn-group-sm",s.control+=" form-control-sm"):"large"===o.sizing&&(s.buttonGroup+=" btn-group-lg",s.control+=" form-control-lg"),o.sectionClasses&&Object.assign(s,o.sectionClasses),this.applySectionClasses(s),this.uiParams=o}createButtonGroup(){if(this.uiParams.useButtonGroup){const e=document.createElement("div");return n(e,this.getSectionClasses("buttonGroup")),e}return super.createButtonGroup()}generateControl(e,t,o,s){let r;return"checkbox"===t.type?(r=l("input",o,s,"form-check-input"),r.type="checkbox",r.value="1",n(r,t.ctrlClass),e?.appendChild(r)):"readonly"===t.type?(r=l("input",o,s,null,"text"),n(r,this.getSectionClasses("control"),t.ctrlClass),r.classList.remove("form-control"),r.classList.add("form-control-plaintext"),r.readOnly=!0,e?.appendChild(r)):r=super.generateControl(e,t,o,s),r}},C=class extends h{constructor(e,t,n){super(t,n),this.name="ui-bulma";const o={useButtonGroup:!0,sectionClasses:null,sizing:"normal"};Object.assign(o,e);const s={table:"table",control:"input",button:"button",buttonGroup:"field has-addons",append:"",removeLast:"",insert:"",remove:"",moveUp:"",moveDown:"",empty:"has-text-centered"};"small"===o.sizing?(s.table+=" is-narrow",s.control+=" is-small",s.button+=" is-small"):"medium"===o.sizing?(s.control+=" is-medium",s.button+=" is-medium"):"large"===o.sizing&&(s.control+=" is-large",s.button+=" is-large"),o.sectionClasses&&Object.assign(s,o.sectionClasses),this.applySectionClasses(s),this.uiParams=o}generateButton(e,t,o){const s=l("button",o??null,null,null,"button");let r;if(s.title=this.i18n[t],n(s,this.getSectionClasses("button"),this.getSectionClasses(t)),this.iconFramework.isTextBased?r=s:(r=document.createElement("span"),r.classList.add("icon"),s.appendChild(r)),this.iconFramework.generateIcon(r,t),this.uiParams.useButtonGroup){const t=document.createElement("p");t.classList.add("control"),t.appendChild(s),e.appendChild(t)}else e.appendChild(s);return s}createButtonGroup(){if(this.uiParams.useButtonGroup){const e=document.createElement("div");return n(e,this.getSectionClasses("buttonGroup")),e}return super.createButtonGroup()}generateControl(e,t,o,s){let r;if("select"===t.type){const i=l("div",null,null,"select");"small"===this.uiParams.sizing?i.classList.add("is-small"):"medium"===this.uiParams.sizing?i.classList.add("is-medium"):"large"===this.uiParams.sizing&&i.classList.add("is-large"),e?.appendChild(i),r=super.generateControl(null,t,o,s),n(r,t.ctrlClass),i.appendChild(r)}else if("checkbox"===t.type){const i=l("label",null,null,"checkbox");e?.appendChild(i),r=l("input",o,s,null,"checkbox"),r.value="1",n(r,t.ctrlClass),i.appendChild(r)}else"readonly"===t.type?(r=l("input",o,s,null,"text"),n(r,this.getSectionClasses("control"),t.ctrlClass),r.classList.add("is-static"),r.readOnly=!0,e?.appendChild(r)):r=super.generateControl(e,t,o,s);return r}},b=class extends h{constructor(e,t,n){super(t,n),this.name="ui-foundation6";const o={useButtonGroup:!0,sectionClasses:null};Object.assign(o,e);const s={button:"button",buttonGroup:"button-group"};o.sectionClasses&&Object.assign(s,o.sectionClasses),this.applySectionClasses(s),this.uiParams=o}createButtonGroup(){if(this.uiParams.useButtonGroup){const e=document.createElement("div");return n(e,this.getSectionClasses("buttonGroup")),e}return super.createButtonGroup()}},y=class{constructor(e){this.rowOrder=[],this.uniqueIndex=0,this.visibleCount=0,this.finalColSpan=0,this.hideLastColumn=!1;const s=this,r=Object.assign({},e);s.settings=r;let h=null;if(h="string"==typeof r.element?document.getElementById(r.element):r.element,!h||!h.tagName||"TABLE"!==h.tagName)throw"*element* is not defined or is not a table DOM element.";if(s.tbWhole=h,h.innerHTML="","bootstrapicons"===r.iconFramework)s.iconFramework=new i(r.iconParams);else if("fontawesome6"===r.iconFramework)s.iconFramework=new a(r.iconParams);else if("fontawesome5"===r.iconFramework)s.iconFramework=new c(r.iconParams);else if("ionicon4"===r.iconFramework)s.iconFramework=new d(r.iconParams);else if("materialdesignicons3"===r.iconFramework)s.iconFramework=new u(r.iconParams);else if("openiconic"===r.iconFramework)s.iconFramework=new p(r.iconParams);else if("typicons2"===r.iconFramework)s.iconFramework=new m(r.iconParams);else{if(r.iconFramework&&"default"!==r.iconFramework)throw`Unknown Icon framework *${r.iconFramework}*.`;s.iconFramework=new t(r.iconParams)}if("bootstrap4"===r.uiFramework)s.uiFramework=new w(r.uiParams,r.i18n,s.iconFramework);else if("bootstrap5"===r.uiFramework)s.uiFramework=new g(r.uiParams,r.i18n,s.iconFramework);else if("bulma"===r.uiFramework)s.uiFramework=new C(r.uiParams,r.i18n,s.iconFramework);else if("foundation6"===r.uiFramework)s.uiFramework=new b(r.uiParams,r.i18n,s.iconFramework);else{if(r.uiFramework&&"default"!==r.uiFramework)throw`Unknown UI framework *${r.uiFramework}*.`;s.uiFramework=new f(r.uiParams,r.i18n,s.iconFramework)}o(r.idPrefix)&&(h.id?r.idPrefix=h.id:r.idPrefix="ag"+(new Date).getTime()),r.sectionClasses&&s.uiFramework.applySectionClasses(r.sectionClasses),n(h,s.uiFramework.getSectionClasses("table"));const y=s.createElement("thead");h.appendChild(y);let v,x=s.createElement("tr","theadRow");y.appendChild(x);let R=0;r.hideRowNumColumn||(v=s.createElement("th","theadCell"),x.appendChild(v),R++);let O=0;for(let t=0;t<r.columns.length;t++)if("hidden"!==r.columns[t].type){if(0===O){if(v=s.createElement("th","theadCell"),x.appendChild(v),n(v,r.columns[t].displayClass),!o(r.columns[t].displayCss)){const e=r.columns[t].displayCss;for(const t in e)v.style[t]=e[t]}r.columns[t].headerSpan>1&&(v.setAttribute("colSpan",String(r.columns[t].headerSpan)),O=r.columns[t].headerSpan-1),"function"==typeof r.columns[t].display?r.columns[t].display(v):r.columns[t].display&&(v.innerText=r.columns[t].display)}else O--;R++}v=s.createElement("th","theadCell"),r.hideButtons.insert&&r.hideButtons.remove&&r.hideButtons.moveUp&&r.hideButtons.moveDown?(s.hideLastColumn=!0,v.style.display="none"):R++,!s.hideLastColumn&&r.rowButtonsInFront?r.hideRowNumColumn?x.insertBefore(v,x.firstChild):x.insertBefore(v,x.childNodes[1]):x.appendChild(v),s.finalColSpan=R;const B=s.createElement("tbody");h.appendChild(B),s.tbBody=B;const k=s.createElement("tfoot");h.appendChild(k),x=s.createElement("tr","tfootRow"),k.appendChild(x),v=s.createElement("td","tfootCell"),v.colSpan=s.finalColSpan,x.appendChild(v);const E=r.idPrefix+"_rowOrder",I=l("input",E,E,null,"hidden");if(v.appendChild(I),r.hideButtons.append&&r.hideButtons.removeLast)x.style.display="none";else{let e=s.uiFramework.createButtonGroup();e?v.appendChild(e):e=v,r.hideButtons.append||s.uiFramework.generateButton(e,"append").addEventListener("click",function(){s.insertRow(1)}),r.hideButtons.removeLast||s.uiFramework.generateButton(e,"removeLast").addEventListener("click",function(){s.removeRow()})}this.showEmptyMessage()}createElement(e,t,n){return l(e,n??null,null,this.uiFramework.getSectionClasses(t||e))}loadData(e,t=!1){if(!Array.isArray(e)||!e.length)throw"*records* should be in array format!";const n=this,o=n.settings;n.tbBody.innerHTML="",n.rowOrder.length=0,n.uniqueIndex=0;const s=n.insertRow(e.length);for(let r=0;r<s.addedRows.length;r++){for(let t=0;t<o.columns.length;t++)n.setCtrlValue(t,n.rowOrder[r],e[r][o.columns[t].name]);"function"==typeof o.rowDataLoaded&&o.rowDataLoaded(n.tbWhole,e[r],r,n.rowOrder[r])}t&&(n.settings.initData=null),"function"==typeof o.dataLoaded&&o.dataLoaded(n.tbWhole,e)}insertRow(e,t,r){const i=this,a=i.settings,c=i.uiFramework,u=i.tbBody;let d,m;const p=[];let h,f=null,w=!1,g=!1;Array.isArray(e)?(h=e.length,g=!0):h=e;let C=t??null;if(s(r)){for(let n=0;n<i.rowOrder.length;n++)if(i.rowOrder[n]===r){C=n,0!==n&&(f=n-1);break}}else s(C)?C>=i.rowOrder.length?C=null:f=C-1:0!==i.rowOrder.length&&(C=null,f=i.rowOrder.length-1);0===i.rowOrder.length&&(u.innerHTML="");for(let b=0;b<h;b++){if(0<a.maxRowsAllowed&&i.rowOrder.length>=a.maxRowsAllowed){w=!0;break}const t=++i.uniqueIndex,r=[];if(d=i.createElement("tr","tbodyRow",a.idPrefix+"_$row_"+t),d.dataset.uniqueIndex=String(t),s(C)){const e=C+b;i.rowOrder.splice(e,0,t),u.insertBefore(d,u.childNodes[e])}else i.rowOrder.push(t),u.appendChild(d);p.push(t),a.hideRowNumColumn||(m=i.createElement("td","tbodyCell",a.idPrefix+"_$rowNum_"+t),m.innerText=String(i.rowOrder.length),n(m,c.getSectionClasses("first")),d.appendChild(m));for(let s=0;s<a.columns.length;s++){if("hidden"===a.columns[s].type){r.push(s);continue}if(m=i.createElement("td","tbodyCell"),d.appendChild(m),n(m,a.columns[s].cellClass),!o(a.columns[s].cellCss)){const e=a.columns[s].cellCss;for(const t in e)m.style[t]=e[t]}const l=a.idPrefix+"_"+a.columns[s].name+"_"+t;let c;c="function"==typeof a.nameFormatter?a.nameFormatter(a.idPrefix,a.columns[s].name,t):l;let u=null;const p="custom"===a.columns[s].type;if(p)"function"==typeof a.columns[s].customBuilder&&(u=a.columns[s].customBuilder(m,a.idPrefix,a.columns[s].name,t));else{if(u=i.uiFramework.generateControl(m,a.columns[s],l,c),!o(a.columns[s].ctrlAttr)){const e=a.columns[s].ctrlAttr;for(const t in e)u.setAttribute(t,e[t])}if(!o(a.columns[s].ctrlCss)){const e=a.columns[s].ctrlCss;for(const t in e)u.style[t]=e[t]}if(a.columns[s].events){u.dataset.columnName=a.columns[s].name,u.dataset.uniqueIndex=String(t);for(const e in a.columns[s].events){const t=a.columns[s].events[e];u.addEventListener(e,function(e){const n=e.currentTarget;e.columnName=n.dataset.columnName,e.uniqueIndex=parseInt(n.dataset.uniqueIndex),t(e)})}}}g?i.setCtrlValue(s,t,e[b][a.columns[s].name]):o(a.columns[s].value)||i.setCtrlValue(s,t,a.columns[s].value),p||"function"!=typeof a.columns[s].ctrlAdded||a.columns[s].ctrlAdded(u,m,t)}if(m=i.createElement("td","tbodyCell",a.idPrefix+"_$rowButton_"+t),i.hideLastColumn||!a.rowButtonsInFront?d.appendChild(m):a.hideRowNumColumn?d.insertBefore(m,d.firstChild):d.insertBefore(m,d.childNodes[1]),r.forEach(function(n){const s=a.columns[n].name,r=a.idPrefix+"_"+s+"_"+t;let c;c="function"==typeof a.nameFormatter?a.nameFormatter(a.idPrefix,s,t):r,m.appendChild(l("input",r,c,null,"hidden")),g?i.setCtrlValue(n,t,e[b][s]):o(a.columns[n].value)||i.setCtrlValue(n,t,a.columns[n].value)}),i.hideLastColumn)m.style.display="none";else if(a.columns.length>i.visibleCount){n(m,c.getSectionClasses("last"));let e=c.createButtonGroup();e?m.appendChild(e):e=m,["insert","remove","moveUp","moveDown"].forEach(function(n){if(!a.hideButtons[n]){const o=a.idPrefix+"_$"+n+"_"+t,s=c.generateButton(e,n,o);s.dataset.uniqueIndex=String(t),s.addEventListener("click",function(e){const t=parseInt(e.currentTarget.dataset.uniqueIndex);i.rowButtonActions(n,t)})}})}}return i.saveSetting(),a.hideRowNumColumn||o(C)||i.sortSequence(C),s(C)?"function"==typeof a.afterRowInserted&&a.afterRowInserted(i.tbWhole,f,p):"function"==typeof a.afterRowAppended&&a.afterRowAppended(i.tbWhole,f,p),w&&"function"==typeof a.maxNumRowsReached&&a.maxNumRowsReached(i.tbWhole),{addedRows:p,parentIndex:f,rowIndex:C}}removeRow(e,t,n){const o=this,r=o.settings,l=o.tbBody;let i=e??null;if(s(t))for(let s=0;s<o.rowOrder.length;s++)if(o.rowOrder[s]===t){i=s;break}s(i)?(n||"function"!=typeof r.beforeRowRemove||r.beforeRowRemove(o.tbWhole,i))&&(o.rowOrder.splice(i,1),l.removeChild(l.childNodes[i]),o.saveSetting(),r.hideRowNumColumn||o.sortSequence(i),"function"==typeof r.afterRowRemoved&&r.afterRowRemoved(o.tbWhole,i)):(n||"function"!=typeof r.beforeRowRemove||r.beforeRowRemove(o.tbWhole,o.rowOrder.length-1))&&(o.rowOrder.pop(),l.removeChild(l.lastChild),o.saveSetting(),"function"==typeof r.afterRowRemoved&&r.afterRowRemoved(o.tbWhole,null)),0===o.rowOrder.length&&o.showEmptyMessage()}moveUpRow(e,t){const n=this,r=n.settings,l=n.tbBody;let i=null,a=t??null;if(s(e)&&e>0&&e<n.rowOrder.length?(i=e,a=n.rowOrder[e]):s(a)&&(i=n.findRowIndex(a)),!o(i)&&i>0){const e=n.rowOrder[i-1],t=document.getElementById(r.idPrefix+"_$row_"+a),o=document.getElementById(r.idPrefix+"_$row_"+e);if(l.removeChild(t),l.insertBefore(t,o),n.rowOrder[i]=e,n.rowOrder[i-1]=a,!r.hideRowNumColumn){const t=document.getElementById(r.idPrefix+"_$rowNum_"+a),n=document.getElementById(r.idPrefix+"_$rowNum_"+e),o=n.innerHTML;n.innerHTML=t.innerHTML,t.innerHTML=o}n.saveSetting(),document.getElementById(r.idPrefix+"_$moveUp_"+a)?.blur(),document.getElementById(r.idPrefix+"_$moveUp_"+e)?.focus(),"function"==typeof r.afterRowSwapped&&r.afterRowSwapped(n.tbWhole,i,i-1)}}moveDownRow(e,t){const n=this,r=n.settings,l=n.tbBody;let i=null,a=t??null;if(s(e)&&e>=0&&e<n.rowOrder.length-1?(i=e,a=n.rowOrder[e]):s(a)&&(i=n.findRowIndex(a)),!o(i)&&i!==n.rowOrder.length-1){const e=n.rowOrder[i+1],t=document.getElementById(r.idPrefix+"_$row_"+a),o=document.getElementById(r.idPrefix+"_$row_"+e);if(l.removeChild(o),l.insertBefore(o,t),n.rowOrder[i]=e,n.rowOrder[i+1]=a,!r.hideRowNumColumn){const t=document.getElementById(r.idPrefix+"_$rowNum_"+a),n=document.getElementById(r.idPrefix+"_$rowNum_"+e),o=n.innerHTML;n.innerHTML=t.innerHTML,t.innerHTML=o}n.saveSetting(),document.getElementById(r.idPrefix+"_$moveDown_"+a)?.blur(),document.getElementById(r.idPrefix+"_$moveDown_"+e)?.focus(),"function"==typeof r.afterRowSwapped&&r.afterRowSwapped(n.tbWhole,i,i+1)}}setCtrlValue(e,t,n){const r=this,l=r.settings,i=l.columns[e].type,a=l.columns[e].name;if("custom"===i)"function"==typeof l.columns[e].customSetter&&l.columns[e].customSetter(l.idPrefix,a,t,n);else{const e=r.getCellCtrl(l.idPrefix,a,t);e&&("checkbox"===i?"boolean"==typeof n?e.checked=n:s(n)?e.checked=0!==n:e.checked=!o(n):e.value=o(n)?"":String(n))}}getCellCtrl(e,t,n){return document.getElementById(e+"_"+t+"_"+n)}getCtrlValue(e,t){const n=this,o=n.settings,s=o.columns[e];if("custom"===s.type){if("function"==typeof s.customGetter)return s.customGetter(o.idPrefix,s.name,t);throw`*customGetter* of column *${s.name}* is not defined.`}{const e=n.getCellCtrl(o.idPrefix,s.name,t);return null===e?null:"checkbox"===s.type?e.checked?1:0:e.value}}getRowValue(e,t){const n=this,s={},r=o(t)?"":"_"+t;return n.settings.columns.forEach(function(t,o){const l=t.name+r;s[l]=n.getCtrlValue(o,e)}),s}getColumnIndex(e){const t=this.settings.columns;for(let n=0;n<t.length;n++)if(t[n].name===e)return n;return null}isRowEmpty(e){const t=this,n=t.settings.columns;for(let s=0;s<n.length;s++){const r=n[s].emptyCriteria,l=t.getCtrlValue(s,e);if("function"==typeof r){if(!r(l))return!1}else{let i=null;if(o(r)){const o=n[s].type;if("checkbox"===o)i=0;else if("select"===o){const o=t.getCellCtrl(t.settings.idPrefix,n[s].name,e);i=o&&o.options.length>0?o.options[0].value:""}else i=""}else i=r;if(l!==i)return!1}}return!0}findRowIndex(e){for(let t=0;t<this.rowOrder.length;t++)if(this.rowOrder[t]===e)return t;return null}saveSetting(){document.getElementById(this.settings.idPrefix+"_rowOrder").value=this.rowOrder.join()}showEmptyMessage(){const e=this;e.tbBody.innerHTML="";const t=e.createElement("tr","tbodyRow");e.tbBody.appendChild(t);const o=e.createElement("td","tbodyCell");o.setAttribute("colspan",String(e.finalColSpan)),n(o,e.uiFramework.getSectionClasses("empty")),o.innerText=e.settings.i18n.rowEmpty,t.appendChild(o)}sortSequence(e){const t=this;for(let n=e||0;n<t.rowOrder.length;n++)document.getElementById(t.settings.idPrefix+"_$rowNum_"+t.rowOrder[n]).innerText=String(n+1)}rowButtonActions(e,t){const n=this;"insert"===e?n.insertRow(1,null,t):"remove"===e?n.removeRow(null,t):"moveUp"===e?n.moveUpRow(null,t):"moveDown"===e&&n.moveDownRow(null,t)}},v={uiFramework:null,uiParams:null,iconFramework:null,iconParams:null,initRows:3,idPrefix:null,initData:null,columns:[],i18n:null,hideButtons:null,hideRowNumColumn:!1,rowButtonsInFront:!1,rowCountName:"_RowCount",sectionClasses:null,maxRowsAllowed:0},x={nameFormatter:null,dataLoaded:null,rowDataLoaded:null,afterRowAppended:null,afterRowInserted:null,afterRowSwapped:null,beforeRowRemove:null,afterRowRemoved:null,maxNumRowsReached:null},R={type:"text",name:void 0,value:null,display:null,displayCss:null,displayClass:null,displayTooltip:null,headerSpan:1,cellCss:null,cellClass:null,ctrlAttr:null,ctrlProp:null,ctrlCss:null,ctrlClass:null,ctrlOptions:null,invisible:!1,emptyCriteria:null,customBuilder:null,customGetter:null,customSetter:null,events:null,ctrlAdded:null};return class{#e;constructor(e){const t=Object.assign({},v,x,e),n={append:"Append Row",removeLast:"Remove Last Row",insert:"Insert Row Above",remove:"Remove Current Row",moveUp:"Move Up",moveDown:"Move Down",rowEmpty:"This Grid Is Empty"};t.i18n&&Object.assign(n,t.i18n),t.i18n=n;const o={append:!1,removeLast:!1,insert:!1,remove:!1,moveUp:!1,moveDown:!1};t.hideButtons&&Object.assign(o,t.hideButtons),t.hideButtons=o;for(let r=0;r<t.columns.length;r++)t.columns[r]=Object.assign({},R,t.columns[r]);const s=new y(t);this.#e=s,Array.isArray(t.initData)?s.loadData(t.initData):(t.initRows??0)>0&&s.insertRow(t.initRows)}appendRow(e){return this.#e.insertRow(e??1).addedRows}insertRow(e,t){return this.#e.insertRow(e,t).addedRows}removeRow(e){this.#e.removeRow(e)}moveUpRow(e){this.#e.moveUpRow(e)}moveDownRow(e){this.#e.moveDownRow(e)}load(e){this.#e.loadData(e)}getAllValue(e){const t=this.#e,n=e?{}:[];return t.rowOrder.forEach(function(o,s){e?Object.assign(n,t.getRowValue(o,s)):n.push(t.getRowValue(o))}),e&&(n[t.settings.rowCountName]=t.rowOrder.length),n}getUniqueIndex(e){const t=this.#e.rowOrder;return e>=0&&e<t.length?t[e]:null}getRowIndex(e){const t=this.#e.rowOrder;for(let n=0;n<t.length;n++)if(t[n]===e)return n;return null}getRowCount(){return this.#e.rowOrder.length}getRowOrder(){return this.#e.rowOrder.slice()}getRowValue(e){const t=this.getUniqueIndex(e);return null!==t?this.#e.getRowValue(t):null}getCtrlValue(e,t){const n=this.#e.getColumnIndex(e),o=this.getUniqueIndex(t);return null!==n&&null!==o?this.#e.getCtrlValue(n,o):null}setCtrlValue(e,t,n){const o=this.#e.getColumnIndex(e),s=this.getUniqueIndex(t);null!==o&&null!==s&&this.#e.setCtrlValue(o,s,n)}getColumns(){return this.#e.settings.columns.slice()}getCellCtrl(e,t){const n=this.getUniqueIndex(t);return this.getCellCtrlByUniqueIndex(e,n)}getCellCtrlByUniqueIndex(e,t){const n=this.#e;return null!==n.getColumnIndex(e)&&s(t)?n.getCellCtrl(n.settings.idPrefix,e,t):null}isRowEmpty(e){const t=this.getUniqueIndex(e);return null===t||this.#e.isRowEmpty(t)}removeEmptyRows(){const e=this.#e,t=this.getRowOrder();for(let n=0;n<t.length;n++)e.isRowEmpty(t[n])&&e.removeRow(null,t[n],!0)}}});
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "appendgrid",
3
+ "version": "3.0.0",
4
+ "description": "AppendGrid - The dynamic table input JavaScript plugin",
5
+ "main": "dist/AppendGrid.js",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "scripts": {
10
+ "build": "vite build",
11
+ "start": "vite",
12
+ "test": "vitest run",
13
+ "test:watch": "vitest"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/hkalbertl/appendgrid"
18
+ },
19
+ "keywords": [
20
+ "ui",
21
+ "header-detail",
22
+ "master-detail",
23
+ "edit",
24
+ "table",
25
+ "input",
26
+ "grid"
27
+ ],
28
+ "author": "Albert L. <hkalbertl@outlook.com>",
29
+ "license": "MIT",
30
+ "bugs": {
31
+ "url": "https://github.com/hkalbertl/appendgrid/issues"
32
+ },
33
+ "homepage": "https://github.com/hkalbertl/appendgrid",
34
+ "devDependencies": {
35
+ "chai": "^6.2.2",
36
+ "jsdom": "^27.0.1",
37
+ "terser": "^5.48.0",
38
+ "typescript": "^6.0.3",
39
+ "vite": "^8.0.16",
40
+ "vitest": "^3.2.6"
41
+ }
42
+ }