kempo 2.10.0 → 2.10.1
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/dist/components/Sortable.js +1 -0
- package/dist/components/Table.js +1 -1
- package/dist/components/tableControls/DeleteRecord.js +1 -0
- package/dist/components/tableControls/DeleteSelected.js +1 -1
- package/dist/components/tableControls/Edit.js +1 -1
- package/dist/components/tableControls/ExportCSV.js +1 -0
- package/dist/components/tableControls/ExportJson.js +1 -0
- package/dist/components/tableControls/FieldSortHide.js +1 -0
- package/dist/components/tableControls/Filters.js +1 -1
- package/dist/components/tableControls/FirstPage.js +1 -0
- package/dist/components/tableControls/HiddenCount.js +1 -1
- package/dist/components/tableControls/Hide.js +1 -1
- package/dist/components/tableControls/LastPage.js +1 -0
- package/dist/components/tableControls/NextPage.js +1 -0
- package/dist/components/tableControls/PageSelect.js +1 -1
- package/dist/components/tableControls/PageSize.js +1 -1
- package/dist/components/tableControls/PrevPage.js +1 -0
- package/dist/components/tableControls/Search.js +1 -0
- package/dist/components/tableControls/SelectCount.js +1 -1
- package/dist/components/tableControls/ShowAll.js +1 -1
- package/dist/components/tableControls/ShowHideFields.js +1 -0
- package/dist/components/tableControls/TableControl.js +1 -0
- package/dist/index.js +1 -1
- package/docs/components/sortable.html +96 -0
- package/docs/components/table.html +32 -7
- package/docs/components/tableControls.html +10 -24
- package/docs/components/tableFetchRecords.html +114 -0
- package/docs/components/tableFieldSortHide.html +75 -0
- package/docs/components/tablePagination.html +33 -25
- package/docs/components/tableRecordEditing.html +8 -8
- package/docs/components/tableRecordFiltering.html +6 -13
- package/docs/components/tableRecordHiding.html +10 -14
- package/docs/components/tableRecordSearching.html +75 -0
- package/docs/components/tableRecordSelection.html +8 -19
- package/docs/components/tableRowControls.html +10 -35
- package/docs/components/tableSorting.html +73 -0
- package/docs/icons/arrow-down.svg +1 -0
- package/docs/icons/arrow-up.svg +1 -0
- package/docs/icons/drag-handle.svg +1 -0
- package/docs/icons/export-file.svg +1 -0
- package/docs/icons/first.svg +1 -0
- package/docs/icons/last.svg +1 -0
- package/docs/icons/table-visibility.svg +1 -0
- package/docs/kempo/components/Sortable.js +1 -0
- package/docs/kempo/components/Table.js +1 -1
- package/docs/kempo/components/tableControls/DeleteRecord.js +1 -0
- package/docs/kempo/components/tableControls/DeleteSelected.js +1 -1
- package/docs/kempo/components/tableControls/Edit.js +1 -1
- package/docs/kempo/components/tableControls/ExportCSV.js +1 -0
- package/docs/kempo/components/tableControls/ExportJson.js +1 -0
- package/docs/kempo/components/tableControls/FieldSortHide.js +1 -0
- package/docs/kempo/components/tableControls/Filters.js +1 -1
- package/docs/kempo/components/tableControls/FirstPage.js +1 -0
- package/docs/kempo/components/tableControls/HiddenCount.js +1 -1
- package/docs/kempo/components/tableControls/Hide.js +1 -1
- package/docs/kempo/components/tableControls/LastPage.js +1 -0
- package/docs/kempo/components/tableControls/NextPage.js +1 -0
- package/docs/kempo/components/tableControls/PageSelect.js +1 -1
- package/docs/kempo/components/tableControls/PageSize.js +1 -1
- package/docs/kempo/components/tableControls/PrevPage.js +1 -0
- package/docs/kempo/components/tableControls/Search.js +1 -0
- package/docs/kempo/components/tableControls/SelectCount.js +1 -1
- package/docs/kempo/components/tableControls/ShowAll.js +1 -1
- package/docs/kempo/components/tableControls/ShowHideFields.js +1 -0
- package/docs/kempo/components/tableControls/TableControl.js +1 -0
- package/docs/kempo/index.js +1 -1
- package/icons/arrow-down.svg +1 -0
- package/icons/arrow-up.svg +1 -0
- package/icons/drag-handle.svg +1 -0
- package/icons/export-file.svg +1 -0
- package/icons/first.svg +1 -0
- package/icons/last.svg +1 -0
- package/icons/table-visibility.svg +1 -0
- package/package.json +1 -1
- package/src/components/Sortable.js +169 -0
- package/src/components/Table.js +421 -295
- package/src/components/tableControls/DeleteRecord.js +43 -0
- package/src/components/tableControls/DeleteSelected.js +11 -13
- package/src/components/tableControls/Edit.js +22 -26
- package/src/components/tableControls/ExportCSV.js +91 -0
- package/src/components/tableControls/ExportJson.js +62 -0
- package/src/components/tableControls/FieldSortHide.js +77 -0
- package/src/components/tableControls/Filters.js +18 -17
- package/src/components/tableControls/FirstPage.js +69 -0
- package/src/components/tableControls/HiddenCount.js +10 -15
- package/src/components/tableControls/Hide.js +12 -15
- package/src/components/tableControls/LastPage.js +67 -0
- package/src/components/tableControls/NextPage.js +69 -0
- package/src/components/tableControls/PageSelect.js +20 -23
- package/src/components/tableControls/PageSize.js +12 -15
- package/src/components/tableControls/PrevPage.js +69 -0
- package/src/components/tableControls/Search.js +49 -0
- package/src/components/tableControls/SelectCount.js +5 -10
- package/src/components/tableControls/ShowAll.js +9 -12
- package/src/components/tableControls/TableControl.js +51 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import Component from"./Component.js";import{onEvent,offEvent,dispatchEvent}from"../utils/element.js";import drag from"../utils/drag.js";const dragStartHandler=Symbol("dragStartHandler"),dragMoveHandler=Symbol("dragMoveHandler"),dragEndHandler=Symbol("dragEndHandler"),cleanup=Symbol("cleanup");export class Sortable extends Component{constructor(){super(),this.registerAttributes({sorting:!1})}async render(t){return await super.render(t),!1}disconnectedCallback(){super.disconnectedCallback(),this.cleanupFuncs.forEach((t=>t()))}getCursorElement(){const t=Array.from(this.children).filter((t=>"K-SORTABLE-ITEM"===t.tagName&&!t.hasAttribute("sorting")));if(0===t.length)return null;const e=event.clientY;if(e<t[0].getBoundingClientRect().top)return[t[0],"before"];if(e>t[t.length-1].getBoundingClientRect().bottom)return[t[t.length-1],"after"];for(const r of t){const t=r.getBoundingClientRect();if(e<t.top+t.height/2)return[r,"before"];if(e<t.bottom)return[r,"after"]}return null}}window.customElements.define("k-sortable",Sortable);export class SortableItem extends Component{constructor(){super(),this[dragStartHandler]=()=>{this.sorting=!0},this[dragMoveHandler]=({y:t})=>{this.style.transform=`translateY(${t}px)`,this.style.zIndex=9999;const[e,r]=this.sortable.getCursorElement();Array.from(this.sortable.children).forEach((t=>{t.classList.remove("target-before","target-after")})),e&&e.classList.add(`target-${r}`)},this[dragEndHandler]=({y:t})=>{this.sorting=!1,this.style.transform="",this.style.zIndex="";const[e,r]=this.sortable.getCursorElement();Array.from(this.sortable.children).forEach((t=>{t.classList.remove("target-before","target-after")})),e&&("before"===r?this.sortable.insertBefore(this,e):"after"===r&&this.sortable.insertBefore(this,e.nextSibling),dispatchEvent(this.sortable,"sort"))},this.registerAttributes({sorting:!1})}async render(t=!1){if(await super.render(t)){const t=this.shadowRoot.getElementById("handle");return this[cleanup]=drag({element:t,startCallback:this[dragStartHandler],moveCallback:this[dragMoveHandler],endCallback:this[dragEndHandler]}),!0}return!1}get sortable(){return this.closest("k-sortable")}get shadowTemplate(){return`\n <div id="handle">\n <k-icon name="drag-handle"></k-icon>\n </div>\n <div id="content" class="p pl0">\n ${super.shadowTemplate}\n </div>\n `}get shadowStyles(){return`\n ${super.shadowStyles}\n :host {\n display: block;\n border: 1px solid var(--c_border);\n user-select: none;\n position: relative;\n }\n :host([sorting]){\n opacity: 0.8;\n }\n #handle {\n display: inline-block;\n cursor: pointer;\n padding: var(--spacer);\n }\n #content {\n display: inline-block;\n }\n :host(.target-before)::before,\n :host(.target-after)::after {\n content: '';\n position: absolute;\n left: 0;\n right: 0;\n height: 4px;\n background-color: var(--c_primary);\n }\n :host(.target-before)::before {\n top: -2px;\n }\n :host(.target-after)::after {\n bottom: -2px;\n }\n `}}window.customElements.define("k-sortable-item",SortableItem);
|
package/dist/components/Table.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import Component from"./Component.js";import Icon from"./Icon.js";import SelectCount from"./tableControls/SelectCount.js";import PageSelect from"./tableControls/PageSelect.js";import PageSize from"./tableControls/PageSize.js";import DeleteSelected from"./tableControls/DeleteSelected.js";import Edit from"./tableControls/Edit.js";import Hide from"./tableControls/Hide.js";import HiddenCount from"./tableControls/HiddenCount.js";import ShowAll from"./tableControls/ShowAll.js";import Filters from"./tableControls/Filters.js";import{toTitleCase}from"../utils/string.js";import{onEvent,offEvent,dispatchEvent}from"../utils/element.js";const selected=Symbol("selected"),hidden=Symbol("hidden"),index=Symbol("index"),editing=Symbol("editing");export default class Table extends Component{constructor({records:e=[],fields:t=[],filters:n=[],controls:r={before:[],after:[],top:[],bottom:[]},enablePages:s=!1,pageSize:i=100,pageSizeOptions:d=[10,25,50,100,500],currentPage:o=1,enableSelection:a=!1}={}){super(),this.registerProps({fields:t,records:e,controls:r,filters:n,pageSize:i,pageSizeOptions:d,currentPage:o,enableSelection:a,enablePages:s,sort:[]})}async render(e){return!!await super.render(e)&&(this.setData({records:this.records,fields:this.fields,controls:this.controls,filters:this.filters,pageSize:this.pageSize,pageSizeOptions:this.pageSizeOptions,currentPage:this.currentPage}),!0)}renderFields(){if(!this.rendered)return;const e=this.controls?.before?.length?"<th></th>":"",t=this.controls?.after?.length?"<th></th>":"",n=this.enableSelection?'<th class="selection"><input type="checkbox" id="select-all"></th>':"";if(this.shadowRoot.getElementById("fields").innerHTML=`${n}${e}${this.fields.map((({label:e})=>`<th>${e}</th>`)).join("")}${t}`,this.enableSelection){const e=this.shadowRoot.getElementById("select-all");e.addEventListener("change",(()=>{e.checked?this.selectAllOnPage():this.deselectAllOnPage()})),onEvent(this,"selectionChange pageChange",(()=>{this.allOnPageSelected()?e.checked=!0:e.checked=!1}))}}renderRecords(){if(!this.rendered)return;const e=this.shadowRoot.getElementById("records");e.innerHTML="";const t=(this.currentPage-1)*this.pageSize,n=t+this.pageSize;this.getDisplayedRecords().slice(t,n).forEach((t=>{e.appendChild(this.renderRecord(t))}))}renderRecord(e){const t=document.createElement("tr");if(t.dataset.index=e[index],this.enableSelection){const n=document.createElement("td");n.classList.add("selection");const r=document.createElement("input");r.type="checkbox",r.checked=e[selected],r.addEventListener("change",(t=>{e[selected]=!!t.target.checked,dispatchEvent(this,"selectionChange")})),n.appendChild(r),t.appendChild(n)}if(this.controls?.before?.length&&t.appendChild(this.renderRowControls(this.controls.before,e)),null===e){const e=document.createElement("td");e.colSpan=this.fields.length,e.innerHTML="<i>Loading...</i>",fetchRecords=!0,t.appendChild(e)}else this.fields.forEach((({name:n,formatter:r,calculator:s,type:i,editor:d})=>{const o=document.createElement("td");o.dataset.field=n;let a=e[n]||"";if(e[editing])if(t.setAttribute("editing",!0),s)o.appendChild(Table.editors.calculated(s(e,this)));else if(d)o.appendChild(d(a));else{let e=Table.editors[i||typeof a];e||(e=Table.editors.string),o.appendChild(e(a))}else o.innerHTML=s?s(e,this):r?r(a):a;t.appendChild(o)}));return this.controls?.after?.length&&t.appendChild(this.renderRowControls(this.controls.after,e)),t}editRecord(e){e[editing]=!0;const t=this.shadowRoot.querySelector(`tr[data-index="${e[index]}"]`),n=this.renderRecord(e);t.replaceWith(n),dispatchEvent(this,"editingChange")}saveEditedRecord(e){e[editing]=!1;const t=this.shadowRoot.querySelector(`tr[data-index="${e[index]}"]`);t.querySelectorAll("td").forEach((t=>{const n=t.dataset.field,r=this.fields.find((e=>e.name===n));if(r&&!r.calculator){const r=1===t.children.length?t.firstChild:t.querySelector("input, select");r&&(e[n]=r.value)}}));const n=this.renderRecord(e);t.replaceWith(n)}cancelEditedRecord(e){e[editing]=!1;const t=this.shadowRoot.querySelector(`tr[data-index="${e[index]}"]`),n=this.renderRecord(e);t.replaceWith(n)}recordIsEditing(e){return e[editing]}renderRowControls(e=[],t){if(!this.rendered)return;const n=document.createElement("td");return e.filter((e=>!!e)).forEach((({html:e,icon:r,action:s,render:i})=>{if(e)n.appendChild(document.createRange().createContextualFragment(e));else if(i&&"function"==typeof i){const e=i(this,t);e instanceof HTMLElement?n.appendChild(e):"string"==typeof e&&n.appendChild(document.createRange().createContextualFragment(e))}else if(r){const e=document.createElement("button");e.classList.add("pq","no-btn"),e.appendChild(new Icon(r)),s&&onEvent(e,"click",(()=>s(this,t))),n.appendChild(e)}})),n}renderControls(e=[],t){if(!this.rendered)return;const n=this.shadowRoot.getElementById(t);n.innerHTML="",e.filter((e=>!!e)).forEach((({html:e,icon:t,action:r,render:s})=>{if(e)n.appendChild(document.createRange().createContextualFragment(e));else if(s&&"function"==typeof s){const e=s(this);e instanceof HTMLElement?n.appendChild(e):"string"==typeof e&&n.appendChild(document.createRange().createContextualFragment(e))}else if(t){const e=document.createElement("button");e.classList.add("pq","no-btn"),e.appendChild(new Icon(t)),r&&onEvent(e,"click",(()=>r(this))),n.appendChild(e)}}))}getCurrentPage(){return this.currentPage}getTotalPages(){return Math.ceil(this.getDisplayedRecords().length/this.pageSize)}setPage(e){e<1||e>this.getTotalPages()||(this.currentPage=e,this.renderRecords(),dispatchEvent(this,"pageChange"))}nextPage(){this.currentPage<this.getTotalPages()&&this.setPage(this.currentPage+1)}prevPage(){this.currentPage>1&&this.setPage(this.currentPage-1)}setPageSize(e){this.pageSize=e,this.currentPage=1,this.renderRecords(),dispatchEvent(this,"pageSizeChange")}setData({records:e=!1,fields:t=!1,controls:n=!1,pageSize:r=!1,pageSizeOptions:s=!1,currentPage:i=!1,enableSelection:d=!1}={}){let o=!1,a=!1,c=this.getTotalPages(),l=this.currentPage;e&&(this.records=e.map((e=>({...e}))),this.records.forEach(((e,t)=>{e[index]=t,e[selected]=!1,e[hidden]=!1,e[editing]=!1})),this.fields=t||Table.extractFieldsFromRecords(this.records),o=!0),r&&(this.pageSize=r,o=!0),s&&(this.pageSizeOptions=s),n&&(this.controls=n,a=!0),i&&(this.currentPage=i,o=!0),void 0!==d&&(this.enableSelection=d,o=!0),o&&(this.renderFields(),this.renderRecords()),a&&(this.renderControls(this.controls.top,"top"),this.renderControls(this.controls.bottom,"bottom"));const h=this.getTotalPages();h!==c&&dispatchEvent(this,"pageCountChanged",{totalPages:this.getTotalPages()}),l>h&&this.setPage(h)}setRecords(e){let t=this.getTotalPages(),n=this.currentPage;this.records=e.map((e=>({...e}))),this.records.forEach(((e,t)=>{e[index]=t,e[selected]=!1,e[hidden]=!1,e[editing]=!1})),this.renderRecords(),dispatchEvent(this,"recordsSet",{records:e});const r=this.getTotalPages();r!==t&&dispatchEvent(this,"pageCountChanged",{totalPages:this.getTotalPages()}),n>r&&this.setPage(r)}setupFetchRecords(e,t){const n=this.records.length;n<e&&(this.records.length=e,this.records.fill(null,n)),onEvent(this,"fetchRecords",(async e=>{const{start:n,end:r}=e.detail,s=await t(n,r-n);this.records.splice(n,s.length,...s),this.renderRecords()}))}addRecord(e){e[selected]=!1,e[hidden]=!1,e[index]=this.records.length,this.records.push(e),this.renderRecords(),dispatchEvent(this,"recordAdded",{record:e})}updateRecord(e,t){let n=!1,r=this.records.find((t=>t===e));if(r||void 0===e[index]||(r=this.records[e[index]]),Object.keys(t).forEach((e=>{r.hasOwnProperty(e)&&(r[e]=t[e],n=!0)})),n){const e=(this.currentPage-1)*this.pageSize,t=e+this.pageSize;(!this.enablePages||r[index]>=e&&r[index]<t)&&this.renderRecords()}}deleteRecord(e){let t=this.records.find((t=>t===e)),n=this.getTotalPages();if(t||void 0===e[index]||(t=this.records[e[index]]),t){const e=this.records.indexOf(t);this.records.splice(e,1),this.records.forEach(((e,t)=>{e[index]=t})),this.renderRecords(),dispatchEvent(this,"selectionChange"),dispatchEvent(this,"recordDeleted",{index:e});const r=this.getTotalPages();this.currentPage>r&&this.setPage(r),r!==n&&dispatchEvent(this,"pageCountChanged",{totalPages:r})}}deleteSelected(){let e=this.getTotalPages();this.getSelectedRecords().forEach((e=>{let t=this.records.find((t=>t===e));if(t||void 0===e[index]||(t=this.records[e[index]]),t){const e=this.records.indexOf(t);this.records.splice(e,1)}})),this.records.forEach(((e,t)=>{e[index]=t})),this.renderRecords();const t=this.getTotalPages();this.currentPage>t&&this.setPage(t),t!==e&&dispatchEvent(this,"pageCountChanged",{totalPages:t}),dispatchEvent(this,"selectionChange")}getSelectedRecords(){return this.records.filter((e=>e[selected]))}selectAllOnPage(){const e=(this.currentPage-1)*this.pageSize,t=Math.min(e+this.pageSize,this.records.length);for(let n=e;n<t;n++)this.records[n][selected]=!0;this.renderRecords(),setTimeout((()=>{dispatchEvent(this,"selectionChange")}),0)}deselectAllOnPage(){const e=(this.currentPage-1)*this.pageSize,t=Math.min(e+this.pageSize,this.records.length);for(let n=e;n<t;n++)this.records[n][selected]=!1;this.renderRecords(),setTimeout((()=>{dispatchEvent(this,"selectionChange")}),0)}allOnPageSelected(){const e=(this.currentPage-1)*this.pageSize,t=Math.min(e+this.pageSize,this.records.length);for(let n=e;n<t;n++)if(!this.records[n][selected])return!1;return!0}sortBy(e,t=!0){this.sort=this.sort.filter((t=>t.name!==e)),this.sort.push({name:e,asc:t}),this.renderRecords()}hideRecord(e){let t=this.records.find((t=>t===e));t||void 0===e[index]||(t=this.records[e[index]]),t&&(t[hidden]=!0,this.renderRecords(),dispatchEvent(this,"recordHidden"))}showRecord(e){let t=this.records.find((t=>t===e));t||void 0===e[index]||(t=this.records[e[index]]),t&&(t[hidden]=!1,this.renderRecords(),dispatchEvent(this,"recordShown"))}showAllRecords(){this.records.forEach((e=>{e[hidden]=!1})),this.renderRecords(),dispatchEvent(this,"recordShown allRecordsShown")}addFilter(e,t,n){this.filters.push({field:e,condition:t,value:n}),dispatchEvent(this,"filterAdded filterChange"),this.renderRecords()}removeFilter(e,t,n){this.filters=this.filters.filter((r=>r.field!==e||r.condition!==t||r.value!==n)),dispatchEvent(this,"filterRemoved filterChange"),this.renderRecords()}getDisplayedRecords(){let e=this.records.filter((e=>!e[hidden]));return this.filters.forEach((({field:t,condition:n,value:r})=>{e=e.filter((e=>"eq"===n?e[t]===r:"neq"===n?e[t]!==r:"gt"===n?e[t]>r:"lt"===n?e[t]<r:"gte"===n?e[t]>=r:"lte"===n?e[t]<=r:"contains"===n?e[t].includes(r):"ncontains"!==n||!e[t].includes(r)))})),this.sort.forEach((({name:t,asc:n})=>{e.sort(((e,r)=>e[t]<r[t]?n?-1:1:e[t]>r[t]?n?1:-1:0))})),e}getHiddenRecords(){return this.records.filter((e=>e[hidden]))}get shadowTemplate(){return`\n ${super.shadowTemplate}\n <div class="responsive-table">\n <div id="top"></div>\n <table class="b0">\n <thead id="fields"></thead>\n <tbody id="records"></tbody>\n </table>\n <div id="bottom"></div>\n </div>\n `}get shadowStyles(){return`\n ${super.shadowStyles}\n :host {\n display: block;\n margin-bottom: var(--spacer);\n border: 1px solid var(--c_border);\n border-radius: var(--radius);\n }\n #top, #bottom {\n display: flex;\n }\n th {\n border-top: none;\n }\n tr:last-child td:first-child {\n border-bottom-left-radius: 0;\n }\n tr:last-child td:last-child {\n border-bottom-right-radius: 0;\n }\n tr:last-child td {\n border-bottom: none;\n }\n th:first-child, td:first-child {\n border-left: none;\n }\n th:last-child, td:last-child {\n border-right: none;\n }\n #top:not(:empty) {\n border-bottom: 1px solid var(--c_border);\n }\n #bottom:not(:empty) {\n border-top: 1px solid var(--c_border);\n }\n th.selection, td.selection {\n width: 50px;\n }\n th.selection input,\n td.selection input {\n margin: 0;\n width: 1.35rem;\n height: 1.35rem;\n }\n tr[editing] td {\n padding: 0;\n }\n tr[editing] input,\n tr[editing] select,\n tr[editing] .input {\n padding: calc(0.75 * var(--spacer)) var(--spacer) !important;\n width: 100%;\n }\n `}static extractFieldsFromRecords(e,t=100){const n=new Set;return e.slice(0,t).forEach((e=>{Object.keys(e).forEach((e=>n.add(e)))})),[...n].map((e=>({name:e,label:toTitleCase(e)})))}static controls={prevPage:{render:e=>{const t=document.createElement("button");return t.classList.add("pq","no-btn"),t.appendChild(new Icon("chevron-left")),onEvent(t,"click",(()=>e.prevPage())),onEvent(e,"pageChange",(()=>{t.disabled=1===e.getCurrentPage()})),t}},nextPage:{render:e=>{const t=document.createElement("button");return t.classList.add("pq","no-btn"),t.appendChild(new Icon("chevron-right")),onEvent(t,"click",(()=>e.nextPage())),onEvent(e,"pageChange",(()=>{t.disabled=e.getCurrentPage()===e.getTotalPages()})),t}},pageSelect:{render:e=>new PageSelect(e)},pageSize:{render:e=>new PageSize(e)},selectCount:{render:e=>new SelectCount(e)},deleteSelected:{render:e=>new DeleteSelected(e)},spacer:{html:'<div class="flex"></div>'},edit:{render:(e,t)=>new Edit(e,t)},hide:{render:(e,t)=>new Hide(e,t)},hiddenCount:{render:e=>new HiddenCount(e)},showAll:{render:e=>new ShowAll(e)},filters:{render:e=>new Filters(e)}};static format(e){return(Array.isArray(e)?Table.formatters.array:Table.formatters[typeof e])(e)}static formatters={string:e=>e,number:e=>`${e}`,date:e=>e.toLocaleDateString(),boolean:e=>e?"True":"False",array:e=>e.map((e=>Table.format(e))).join(", "),undefined:e=>"",null:e=>"<code>null</code>"};static editors={string:e=>{const t=document.createElement("input");return t.value=e,t},number:e=>{const t=document.createElement("input");return t.type="number",t.value=e,t},date:e=>{const t=document.createElement("input");return t.type="date",t.value=e,t},boolean:e=>{const t=document.createElement("select");return t.innerHTML=`\n <option value="true" ${e?"selected":""}>True</option>\n <option value="false" ${e?"":"selected"}>False</option>\n `,t.value=e,t},calculated:e=>{const t=document.createElement("input");return t.disabled=!0,t.value=e,t}}}window.customElements.define("k-table",Table);
|
|
1
|
+
import Component from"./Component.js";import{toTitleCase}from"../utils/string.js";import{onEvent,offEvent,dispatchEvent}from"../utils/element.js";const selected=Symbol("selected"),hidden=Symbol("hidden"),index=Symbol("index"),editing=Symbol("editing");export default class Table extends Component{constructor({records:e=[],fields:t=[],filters:s=[],enablePages:i=!1,pageSize:r=50,pageSizeOptions:n=[10,25,50,100,500],currentPage:o=1,enableSelection:d=!1,enableSorting:l=!1}={}){super(),this.registerAttributes({enablePages:i,pageSize:r,currentPage:o,pageSizeOptions:n,enableSelection:d,enableSorting:l}),this.registerProps({fields:t,records:e,filters:s,sort:[],columnSizes:{},fetchPending:!1})}async render(e){return!!await super.render(e)&&(this.setData({records:this.records,fields:this.fields,filters:this.filters}),!0)}renderFields(){if(!this.rendered)return;this.calculateColumnSizes(),this.hasTopControls()?this.setAttribute("top-controls","true"):this.removeAttribute("top-controls"),this.hasBottomControls()?this.setAttribute("bottom-controls","true"):this.removeAttribute("bottom-controls");const e=this.shadowRoot.getElementById("fields");if(e.innerHTML="",this.enableSelection){const t=document.createElement("div");t.classList.add("field","controls","cell","field-select"),t.style.width="40px",t.innerHTML='<input type="checkbox" id="select-all" />',e.appendChild(t)}if(this.hasBeforeControls()){const t=document.createElement("div");t.classList.add("field","cell","field-before-controls"),t.style.width=this.columnSizes.beforeControls+"px",e.appendChild(t)}if(this.fields.forEach((({name:t,label:s,hidden:i})=>{if(i)return;const r=document.createElement("div");if(r.classList.add("field","cell"),r.style.width=this.columnSizes[t]+"px",r.innerHTML=s,this.enableSorting){r.style.cursor="pointer";const e=this.sort.find((e=>e.name===t));if(e){r.classList.add(e.asc?"sort-asc":"sort-desc");const t=document.createElement("k-icon");t.classList.add("icon-sort"),t.setAttribute("name",e.asc?"arrow-down":"arrow-up"),r.appendChild(t)}r.addEventListener("click",(()=>{const e=this.sort.find((e=>e.name===t)),s=!e||!e.asc;this.sortBy(t,s)}))}e.appendChild(r)})),this.hasAfterControls()){const t=document.createElement("div");t.classList.add("field","cell","field-after-controls"),t.style.width=this.columnSizes.afterControls+"px",e.appendChild(t)}if(e.style.width=this.shadowRoot.getElementById("top").style.width=this.shadowRoot.getElementById("bottom").style.width=this.shadowRoot.getElementById("records").style.width=this.columnSizes.total+"px",this.enableSelection){const e=this.shadowRoot.getElementById("select-all");e.addEventListener("change",(()=>{e.checked?this.selectAllOnPage():this.deselectAllOnPage()})),onEvent(this,"selectionChange pageChange",(()=>{this.allOnPageSelected()?e.checked=!0:e.checked=!1}))}}renderRecords(){if(!this.rendered)return;const e=this.shadowRoot.getElementById("records");e.innerHTML="";let t=this.getDisplayedRecords(),s=0,i=this.pageSize;this.enablePages&&(s=(this.currentPage-1)*this.pageSize,i=s+this.pageSize,t=t.slice(s,i));let r,n=0;t.forEach(((t,i)=>{if(null!==t)e.appendChild(this.renderRecord(t));else{r||(r=s+i),n++;const t=document.createElement("div");t.classList.add("record","fetching"),t.innerHTML='<div class="cell">Loading...</div>',e.appendChild(t)}})),r&&!this.fetchPending&&dispatchEvent(this,"fetchRecords",{start:r,count:n})}renderRecord(e){const t=document.createElement("div");if(t.classList.add("record"),t.dataset.index=e[index],this.enableSelection){const s=document.createElement("div");s.style.width="40px",s.classList.add("cell","selection","controls");const i=document.createElement("input");i.type="checkbox",i.checked=e[selected],i.addEventListener("change",(t=>{e[selected]=!!t.target.checked,dispatchEvent(this,"selectionChange")})),s.appendChild(i),t.appendChild(s)}return this.hasBeforeControls()&&t.appendChild(this.renderBeforeControls()),this.fields.forEach((({name:s,formatter:i,calculator:r,type:n,editor:o,hidden:d})=>{if(d)return;const l=document.createElement("div");l.classList.add("cell"),l.dataset.field=s,l.style.width=this.columnSizes[s]+"px";let a=e[s]||"";if(e[editing])if(t.setAttribute("editing",!0),r)l.appendChild(Table.editors.calculated(r(e,this)));else if(o)l.appendChild(o(a));else{let e=Table.editors[n||typeof a];e||(e=Table.editors.string),l.appendChild(e(a))}else l.innerHTML=r?r(e,this):i?i(a):a;t.appendChild(l)})),this.hasAfterControls()&&t.appendChild(this.renderAfterControls()),t}renderBeforeControls(){const e=document.createElement("div");return e.style.width=this.columnSizes.beforeControls+"px",e.classList.add("cell","controls","controls-before"),this.querySelectorAll('[slot="before"]').forEach((t=>{e.appendChild(t.cloneNode(!0))})),e}renderAfterControls(){const e=document.createElement("div");return e.style.width=this.columnSizes.afterControls+"px",e.classList.add("cell","controls","controls-after"),this.querySelectorAll('[slot="after"]').forEach((t=>{e.appendChild(t.cloneNode(!0))})),e}hasBeforeControls(){return!!this.querySelector('[slot="before"]')}hasAfterControls(){return!!this.querySelector('[slot="after"]')}hasTopControls(){return!!this.querySelector('[slot="top"]')}hasBottomControls(){return!!this.querySelector(":scope > :not([slot])")}editRecord(e){e[editing]=!0;const t=this.shadowRoot.querySelector(`.record[data-index="${e[index]}"]`),s=this.renderRecord(e);t.replaceWith(s),dispatchEvent(this,"editingChange")}saveEditedRecord(e){e[editing]=!1;const t=this.shadowRoot.querySelector(`.record[data-index="${e[index]}"]`);t.querySelectorAll(".cell").forEach((t=>{const s=t.dataset.field,i=this.fields.find((e=>e.name===s));if(i&&!i.calculator){const i=1===t.children.length?t.firstChild:t.querySelector("input, select");i&&(e[s]=i.value)}})),t.replaceWith(this.renderRecord(e))}cancelEditedRecord(e){e[editing]=!1,this.shadowRoot.querySelector(`.record[data-index="${e[index]}"]`).replaceWith(this.renderRecord(e))}recordIsEditing(e){return e[editing]}getCurrentPage(){return this.currentPage}getTotalPages(){return Math.ceil(this.getDisplayedRecords().length/this.pageSize)}setPage(e){e<1||e>this.getTotalPages()||(this.currentPage=e,this.renderRecords(),dispatchEvent(this,"pageChange"))}firstPage(){1!==this.currentPage&&this.setPage(1)}nextPage(){this.currentPage<this.getTotalPages()&&this.setPage(this.currentPage+1)}prevPage(){this.currentPage>1&&this.setPage(this.currentPage-1)}lastPage(){this.currentPage!==this.getTotalPages()&&this.setPage(this.getTotalPages())}setPageSize(e){this.pageSize=e,this.currentPage=1,this.renderRecords(),dispatchEvent(this,"pageSizeChange")}setData({records:e=!1,fields:t=!1,pageSize:s=!1,pageSizeOptions:i=!1,currentPage:r=!1,enableSelection:n}={}){let o=!1,d=this.getTotalPages(),l=this.currentPage;e&&(this.records=e.map((e=>({...e}))),this.records.forEach(((e,t)=>{e[index]=t,e[selected]=!1,e[hidden]=!1,e[editing]=!1})),this.fields=t||Table.extractFieldsFromRecords(this.records),o=!0),s&&(this.pageSize=s,o=!0),i&&(this.pageSizeOptions=i),r&&(this.currentPage=r,o=!0),void 0!==n&&(this.enableSelection=n,o=!0),o&&(this.renderFields(),this.renderRecords());const a=this.getTotalPages();a!==d&&dispatchEvent(this,"pageCountChanged",{totalPages:this.getTotalPages()}),l>a&&this.setPage(a)}setRecords(e,t){let s=this.getTotalPages(),i=this.currentPage;this.records=e.map((e=>({...e}))),this.records.forEach(((e,t)=>{e[index]=t,e[selected]=!1,e[hidden]=!1,e[editing]=!1})),this.fields=t||Table.extractFieldsFromRecords(this.records),this.renderFields(),this.renderRecords(),dispatchEvent(this,"recordsSet",{records:e});const r=this.getTotalPages();r!==s&&dispatchEvent(this,"pageCountChanged",{totalPages:this.getTotalPages()}),i>r&&this.setPage(r)}setupFetchRecords(e,t){const s=this.records.length;s<e&&(this.records.length=e,this.records.fill(null,s)),onEvent(this,"fetchRecords",(async e=>{if(this.fetchPending)return;this.fetchPending=!0;const{start:s,count:i}=e.detail,r=await t(s,i);this.records.splice(s,r.length,...r),this.fetchPending=!1,this.renderRecords()}))}addRecord(e){e[selected]=!1,e[hidden]=!1,e[index]=this.records.length,this.records.push(e),this.renderRecords(),dispatchEvent(this,"recordAdded",{record:e})}updateRecord(e,t){let s=!1,i=this.records.find((t=>t===e));if(i||void 0===e[index]||(i=this.records[e[index]]),Object.keys(t).forEach((e=>{i.hasOwnProperty(e)&&(i[e]=t[e],s=!0)})),s){const e=(this.currentPage-1)*this.pageSize,t=e+this.pageSize;(!this.enablePages||i[index]>=e&&i[index]<t)&&this.renderRecords()}}deleteRecord(e){let t=this.records.find((t=>t===e)),s=this.getTotalPages();if(t||void 0===e[index]||(t=this.records[e[index]]),t){const e=this.records.indexOf(t);this.records.splice(e,1),this.records.forEach(((e,t)=>{e[index]=t})),this.renderRecords(),dispatchEvent(this,"selectionChange"),dispatchEvent(this,"recordDeleted",{index:e});const i=this.getTotalPages();this.currentPage>i&&this.setPage(i),i!==s&&dispatchEvent(this,"pageCountChanged",{totalPages:i})}}deleteSelected(){let e=this.getTotalPages();this.getSelectedRecords().forEach((e=>{let t=this.records.find((t=>t===e));if(t||void 0===e[index]||(t=this.records[e[index]]),t){const e=this.records.indexOf(t);this.records.splice(e,1)}})),this.records.forEach(((e,t)=>{e[index]=t})),this.renderRecords();const t=this.getTotalPages();this.currentPage>t&&this.setPage(t),t!==e&&dispatchEvent(this,"pageCountChanged",{totalPages:t}),dispatchEvent(this,"selectionChange")}getSelectedRecords(){return this.records.filter((e=>e[selected]))}selectAllOnPage(){const e=(this.currentPage-1)*this.pageSize,t=Math.min(e+this.pageSize,this.records.length);for(let s=e;s<t;s++)this.records[s][selected]=!0;this.renderRecords(),setTimeout((()=>{dispatchEvent(this,"selectionChange")}),0)}deselectAllOnPage(){const e=(this.currentPage-1)*this.pageSize,t=Math.min(e+this.pageSize,this.records.length);for(let s=e;s<t;s++)this.records[s][selected]=!1;this.renderRecords(),setTimeout((()=>{dispatchEvent(this,"selectionChange")}),0)}allOnPageSelected(){const e=(this.currentPage-1)*this.pageSize,t=Math.min(e+this.pageSize,this.records.length);for(let s=e;s<t;s++)if(!this.records[s][selected])return!1;return!0}sortBy(e,t=!0){this.sort=this.sort.filter((t=>t.name!==e)),this.sort.push({name:e,asc:t}),this.renderFields(),this.renderRecords()}hideRecord(e){let t=this.records.find((t=>t===e));t||void 0===e[index]||(t=this.records[e[index]]),t&&(t[hidden]=!0,this.renderRecords(),dispatchEvent(this,"recordHidden"))}showRecord(e){let t=this.records.find((t=>t===e));t||void 0===e[index]||(t=this.records[e[index]]),t&&(t[hidden]=!1,this.renderRecords(),dispatchEvent(this,"recordShown"))}showAllRecords(){this.records.forEach((e=>{e[hidden]=!1})),this.filters.length&&(this.filters=[],dispatchEvent(this,"filterRemoved filterChange")),this.renderRecords(),dispatchEvent(this,"recordShown allRecordsShown")}addFilter(e,t,s){this.filters.push({field:e,condition:t,value:s}),dispatchEvent(this,"filterAdded filterChange"),this.renderRecords()}removeFilter(e,t,s,i=!0){const r=this.filters.findIndex((i=>i.field===e&&i.condition===t&&i.value===s));-1!==r&&(this.records.forEach((i=>{this.testFilter(i,e,t,s)||(i[hidden]=!1)})),this.filters.splice(r,1),dispatchEvent(this,"filterRemoved filterChange"),i&&this.renderRecords())}testFilter(e,t,s,i){const r=e[t];switch(s){case"equals":return r===i;case"not-equals":return r!==i;case"contains":return r.includes(i);case"not-contains":return!r.includes(i);case"greater-than":return r>i;case"less-than":return r<i;case"greater-than-or-equal":return r>=i;case"less-than-or-equal":return r<=i;default:return!0}}removeAllFilters(){this.filters.length&&(this.filters.forEach((({field:e,condition:t,value:s})=>{this.removeFilter(e,t,s,!1)})),this.renderRecords())}search(e){const t=e.trim().toLowerCase();let s=!1;this.records.forEach((e=>{if(e[hidden])return;let i=!1;this.fields.forEach((({name:s})=>{(e[s]?.toString().toLowerCase()||"").includes(t)&&(i=!0)})),e[hidden]!==!i&&(e[hidden]=!i,s=!0)})),s&&(dispatchEvent(this,"recordHidden"),this.renderRecords()),dispatchEvent(this,"search",{term:e})}getDisplayedRecords(){this.filters.forEach((({field:e,condition:t,value:s})=>{this.records.forEach((i=>{this.testFilter(i,e,t,s)||(i[hidden]=!0)}))}));let e=this.records.filter((e=>null===e||!e[hidden]));return this.sort.forEach((({name:t,asc:s})=>{e.sort(((e,i)=>e[t]<i[t]?s?-1:1:e[t]>i[t]?s?1:-1:0))})),e}getHiddenRecords(){return this.records.filter((e=>e[hidden]))}calculateColumnSizes(){return this.columnSizes={},this.columnSizes.total=0,this.enableSelection&&(this.columnSizes.total+=40),this.columnSizes.beforeControls=Array.from(this.querySelectorAll('[slot="before"]')).reduce(((e,t)=>e+(t.maxWidth||40)),0),this.columnSizes.afterControls=Array.from(this.querySelectorAll('[slot="after"]')).reduce(((e,t)=>e+(t.maxWidth||40)),0),this.hasBeforeControls()&&(this.columnSizes.total+=this.columnSizes.beforeControls),this.hasAfterControls()&&(this.columnSizes.total+=this.columnSizes.afterControls),this.fields.forEach((e=>{if(e.size)this.columnSizes[e.name]=e.size;else{let t=0;this.records.slice(0,100).forEach((s=>{let i=s[e.name];e.calculator&&(i=e.calculator(s,this)),e.formatter&&(i=e.formatter(i)),i&&i.toString().length>t&&(t=i.toString().length)})),this.columnSizes[e.name]=Math.max(10*t+32,128),e.hidden||(this.columnSizes.total+=this.columnSizes[e.name])}})),this.columnSizes}setFieldHiddenState(e,t){const s=this.fields.find((t=>t.name===e));s&&(s.hidden=t,this.calculateColumnSizes(),this.renderFields(),this.renderRecords(),dispatchEvent(this,"fieldVisibilityChanged "+(t?"fieldHidden":"fieldShown"),{field:s}))}hideField(e){this.setFieldHiddenState(e,!0)}showField(e){this.setFieldHiddenState(e,!1)}reorderFields(e){const t=[];e.forEach((e=>{const s=this.fields.find((t=>t.name===e));s&&t.push(s)})),this.fields=t,this.renderFields(),this.renderRecords()}get shadowTemplate(){return`\n <div id="wrapper">\n <div id="top"><slot name="top"></slot></div>\n <div id="table">\n <div id="fields"></div>\n <div id="records"></div>\n </div>\n <div id="bottom">${super.shadowTemplate}</div>\n </div>\n <div style="display: none">\n <slot name="before"></slot>\n <slot name="after"></slot>\n </div>\n `}get shadowStyles(){return`\n ${super.shadowStyles}\n :host {\n display: block;\n width: 100%;\n overflow: auto;\n margin-bottom: var(--spacer);\n }\n #wrapper {\n width: min-content;\n border: 1px solid var(--c_border);\n border-radius: var(--radius);\n }\n #table {\n width: min-content;\n }\n #fields,\n .record {\n display: flex;\n }\n #fields {\n background-color: var(--c_bg__alt);\n border-bottom: 1px solid var(--c_border);\n }\n .record:not([editing="true"]) .cell:not(.controls),\n #fields .cell:not(.controls) {\n padding: calc(0.5 * var(--spacer)) var(--spacer);\n }\n .cell:not(:first-child) {\n border-left: 1px solid var(--c_border);\n }\n .record:not(:last-child) .cell {\n border-bottom: 1px solid var(--c_border);\n }\n #top, #bottom {\n display: flex;\n width: 100%;\n }\n #top slot {\n display: block;\n width: 100%;\n border-bottom: 1px solid var(--c_border);\n }\n #bottom slot {\n display: block;\n width: 100%;\n border-top: 1px solid var(--c_border);\n }\n :host(:not([top-controls])) #top,\n :host(:not([bottom-controls])) #bottom {\n display: none;\n }\n .field-select,\n .selection {\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .field-select input,\n .selection input {\n width: 1.25rem;\n height: 1.25rem;\n }\n .icon-sort {\n float: right;\n opacity: 0.5;\n }\n `}static extractFieldsFromRecords(e,t=100){const s=new Set;return e.slice(0,t).forEach((e=>{Object.keys(e).forEach((e=>s.add(e)))})),[...s].map((e=>({name:e,label:toTitleCase(e)})))}static format(e){return(Array.isArray(e)?Table.formatters.array:Table.formatters[typeof e])(e)}static formatters={string:e=>e,number:e=>`${e}`,date:e=>e.toLocaleDateString(),boolean:e=>e?"True":"False",array:e=>e.map((e=>Table.format(e))).join(", "),undefined:e=>"",null:e=>"<code>null</code>"};static editors={string:e=>{const t=document.createElement("input");return t.value=e,t},number:e=>{const t=document.createElement("input");return t.type="number",t.value=e,t},date:e=>{const t=document.createElement("input");return t.type="date",t.value=e,t},boolean:e=>{const t=document.createElement("select");return t.innerHTML=`\n <option value="true" ${e?"selected":""}>True</option>\n <option value="false" ${e?"":"selected"}>False</option>\n `,t.value=e,t},calculated:e=>{const t=document.createElement("input");return t.disabled=!0,t.value=e,t}}}window.customElements.define("k-table",Table);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import TableControl from"./TableControl.js";import"../Icon.js";import{onEvent,offEvent}from"../../utils/element.js";const clickHandler=Symbol("clickHandler");export default class DeleteRecord extends TableControl{constructor(){super(),this[clickHandler]=this.delete.bind(this)}async render(e=!1){return!!await super.render(e)&&(onEvent(this.shadowRoot.getElementById("delete"),"click",this[clickHandler]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("delete"),"click",this[clickHandler])}delete(){this.record&&this.table.deleteRecord(this.record)}get shadowTemplate(){return'\n <button id="delete" class="no-btn icon-btn">\n <slot><k-icon name="delete"></k-icon></slot>\n </button>\n '}}window.customElements.define("k-tc-delete-record",DeleteRecord);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import TableControl from"./TableControl.js";import{onEvent,offEvent}from"../../utils/element.js";const deleteSelected=Symbol("deleteSelected"),updateButtonState=Symbol("updateButtonState");export default class DeleteSelected extends TableControl{constructor(){super(),this[deleteSelected]=this.deleteSelected.bind(this),this[updateButtonState]=(()=>{this.shadowRoot.getElementById("deleteSelectedButton").disabled=0===this.table.getSelectedRecords().length}).bind(this)}async render(e=!1){return!!await super.render(e)&&(this[updateButtonState](),onEvent(this.shadowRoot.getElementById("deleteSelectedButton"),"click",this[deleteSelected]),onEvent(this.table,"selectionChange",this[updateButtonState]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("deleteSelectedButton"),"click",this[deleteSelected]),offEvent(this.table,"selectionChange",this[updateButtonState])}deleteSelected(){this.table.deleteSelected(),this[updateButtonState]()}get shadowTemplate(){return'\n <button id="deleteSelectedButton" class="pq no-btn">\n <k-icon name="delete"></k-icon>\n </button>\n '}get shadowStyles(){return"\n :host {\n display: inline-flex;\n width: max-content;\n align-items: baseline;\n }\n #deleteSelectedButton {\n display: flex;\n align-items: center;\n }\n #deleteSelectedButton:disabled,\n #deleteSelectedButton[disabled] {\n cursor: not-allowed;\n opacity: 0.5;\n }\n "}}window.customElements.define("k-table-delete-selected",DeleteSelected);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import TableControl from"./TableControl.js";import{offEvent,onEvent}from"../../utils/element.js";const editRecord=Symbol("editRecord"),saveRecord=Symbol("saveRecord"),cancelEdit=Symbol("cancelEdit");export default class Edit extends TableControl{constructor(){super(),this[editRecord]=this.editRecord.bind(this),this[saveRecord]=this.saveRecord.bind(this),this[cancelEdit]=this.cancelEdit.bind(this),this.registerAttributes({editing:!1}),this.maxWidth=80}async render(t=!1){if(await super.render(t)){const t=this.record;return t&&(this.editing=this.table.recordIsEditing(t)),onEvent(this.shadowRoot.getElementById("editButton"),"click",this[editRecord]),onEvent(this.shadowRoot.getElementById("saveButton"),"click",this[saveRecord]),onEvent(this.shadowRoot.getElementById("cancelButton"),"click",this[cancelEdit]),!0}return!1}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("editButton"),"click",this[editRecord]),offEvent(this.shadowRoot.getElementById("saveButton"),"click",this[saveRecord]),offEvent(this.shadowRoot.getElementById("cancelButton"),"click",this[cancelEdit])}editRecord(){this.table.editRecord(this.record)}saveRecord(){this.table.saveEditedRecord(this.record)}cancelEdit(){this.table.cancelEditedRecord(this.record)}get shadowTemplate(){return'\n <button id="editButton" class="icon-btn no-btn">\n <k-icon name="edit"></k-icon>\n </button>\n <button id="saveButton" class="icon-btn no-btn bg-success">\n <k-icon name="check"></k-icon>\n </button>\n <button id="cancelButton" class="icon-btn no-btn bg-danger">\n <k-icon name="close"></k-icon>\n </button>\n '}get shadowStyles(){return`\n ${super.shadowStyles}\n :host {\n display: inline-flex;\n width: max-content;\n align-items: baseline;\n }\n :host([editing]) #editButton,\n :host(:not([editing])) #cancelButton,\n :host(:not([editing])) #saveButton {\n display: none !important;\n }\n `}}window.customElements.define("k-tc-edit",Edit);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import TableControl from"./TableControl.js";import"../Icon.js";import{onEvent,offEvent}from"../../utils/element.js";const clickHandler=Symbol("clickHandler");export default class ExportCsv extends TableControl{constructor(){super({maxWidth:136}),this[clickHandler]=this.export.bind(this)}async render(e=!1){return!!await super.render(e)&&(onEvent(this.shadowRoot.getElementById("export"),"click",this[clickHandler]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("export"),"click",this[clickHandler])}getCSV(){const e=this.table;let t="";if(e){const o=[];if(e.fields.forEach((({name:e,calculator:t})=>{t||o.push(e)})),t+=o.join(",")+"\n",this.record){const e=this.record,n=[];o.forEach((t=>{n.push(e[t])})),t+=n.join(",")+"\n"}else e.records.forEach((e=>{const n=[];o.forEach((t=>{n.push(e[t])})),t+=n.join(",")+"\n"}))}return t}export(){const e=this.getCSV();if(this.record){const t=new Blob([e],{type:"application/json"}),o=URL.createObjectURL(t),n=document.createElement("a");n.href=o,n.download="data.json",n.click(),URL.revokeObjectURL(o)}else{const t=new Blob([e],{type:"application/json"}),o=URL.createObjectURL(t),n=document.createElement("a");n.href=o,n.download="data.json",n.click(),URL.revokeObjectURL(o)}}get shadowTemplate(){return'\n <button id="export" class="no-btn ph">\n <slot><k-icon name="export-file"></k-icon> Export CSV</slot>\n </button>\n '}}window.customElements.define("k-tc-export-csv",ExportCsv);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import TableControl from"./TableControl.js";import"../Icon.js";import{onEvent,offEvent}from"../../utils/element.js";const clickHandler=Symbol("clickHandler");export default class ExportJson extends TableControl{constructor(){super({maxWidth:136}),this[clickHandler]=this.export.bind(this)}async render(e=!1){return!!await super.render(e)&&(onEvent(this.shadowRoot.getElementById("export"),"click",this[clickHandler]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("export"),"click",this[clickHandler])}export(){const e=this.record;if(e){const t=JSON.stringify(e),o=new Blob([t],{type:"application/json"}),n=URL.createObjectURL(o),c=document.createElement("a");c.href=n,c.download="data.json",c.click(),URL.revokeObjectURL(n)}else{const e=JSON.stringify(this.table.records),t=new Blob([e],{type:"application/json"}),o=URL.createObjectURL(t),n=document.createElement("a");n.href=o,n.download="data.json",n.click(),URL.revokeObjectURL(o)}}get shadowTemplate(){return'\n <button id="export" class="no-btn ph">\n <slot><k-icon name="export-file"></k-icon> Export JSON</slot>\n </button>\n '}}window.customElements.define("k-tc-export-json",ExportJson);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import TableControl from"./TableControl.js";import{onEvent,offEvent}from"../../utils/element.js";import Dialog from"../Dialog.js";const clickHandler=Symbol("clickHandler");export default class FieldSortHide extends TableControl{constructor(){super(),this[clickHandler]=this.openDialog.bind(this)}async render(e=!1){return!!await super.render(e)&&(onEvent(this.shadowRoot.getElementById("sort"),"click",this[clickHandler]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("sort"),"click",this[clickHandler])}openDialog(){import("../Sortable.js");const e=Dialog.create(`\n <h3 class="m0 ph" slot="title">Show / Hide Fields</h3>\n <div class="m">\n <k-sortable id="sorting">\n ${this.table.fields.map((e=>`\n <k-sortable-item data-field="${e.name}">\n <label class="field pb0">\n <input\n class="field-visibility"\n data-field="${e.name}"\n type="checkbox"\n ${e.hidden?"":"checked"}\n style="height: 1.25rem; width: 1.25rem"\n />\n ${e.label}\n </label>\n </k-sortable-item>\n `)).join("")}\n </k-sortable>\n </div>\n `,{width:"400px",cancelText:"Close"});onEvent(e,"click",(e=>{if(!e.target.closest(".field"))return;const t=e.target.closest(".field-visibility");if(t){const e=t.getAttribute("data-field");this.table.setFieldHiddenState(e,!t.checked)}}));const t=e.querySelector("#sorting");onEvent(t,"sort",(()=>{const e=Array.from(t.querySelectorAll("k-sortable-item")).map((e=>e.getAttribute("data-field")));this.table.reorderFields(e)}))}get shadowTemplate(){return'\n <button\n id="sort"\n class="no-btn icon-btn"\n >\n <k-icon name="table-visibility"></k-icon>\n </button>\n '}}window.customElements.define("k-tc-field-sort-hide",FieldSortHide);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import TableControl from"./TableControl.js";import Dialog from"../Dialog.js";import{offEvent,onEvent}from"../../utils/element.js";const table=Symbol("table"),clickHandler=Symbol("clickHandler");export default class Filters extends TableControl{constructor(){super(),this[clickHandler]=this.revealFilters.bind(this)}async render(t=!1){return!!await super.render(t)&&(onEvent(this.shadowRoot.getElementById("filterBtn"),"click",this[clickHandler]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("filterBtn"),"click",this[clickHandler])}revealFilters(){const t=Dialog.create(`\n <h3 slot="title" class="m0 pyh px">Filters</h3>\n <div class="p">\n ${0===this.table.filters.length?"\n <p>No Current Filters.</p>\n ":`\n <h5>Current Filters</h5>\n <ul id="currentFilters">${this.table.filters.map((function({field:t,condition:e,value:n}){return`<li\n data-field="${t}"\n data-condition="${e}"\n data-value="${n}"\n >\n ${t} ${{eq:"equals",ne:"does not equal",gt:"is greater than",gte:"is greater than or equal to",lt:"is less than",lte:"is less than or equal to",contains:"contains",starts:"starts with",ends:"ends with"}[e]} ${n}\n <button class="remove-filter no-btn pq">\n <k-icon name="close"></k-icon>\n </button>\n </li>`})).join("")}</ul>\n `}\n <hr />\n <h5>Add A Filter</h5>\n <form id="addFilter">\n <select id="filterField" class="mb">${this.table.fields.map((({name:t,label:e})=>`<option value="${t}">${e}</option>`)).join("")}</select>\n <select id="filterCondition" class="mb">${Object.entries({eq:"equals",ne:"does not equal",gt:"is greater than",gte:"is greater than or equal to",lt:"is less than",lte:"is less than or equal to",contains:"contains",starts:"starts with",ends:"ends with"}).map((([t,e])=>`<option value="${t}" ${"contains"===t?"selected":""}>${e}</option>`)).join("")}</select>\n <input id="filterValue" type="text" class="mb" />\n <button type="submit" class="btn primary mb mr">Add Filter</button>\n ${0===this.table.filters.length?"":'\n <button type="button" id="clearFilters" class="btn danger mb mr">Clear All Filters</button>\n '}\n </form>\n </div>\n `,{width:"600px"}),e=t.querySelector("#addFilter");onEvent(e,"submit",(n=>{n.preventDefault(),this.table.addFilter(e.filterField.value,e.filterCondition.value,e.filterValue.value),t.close(),this.revealFilters()})),onEvent(t,"click",(e=>{if(e.target.closest("button")?.classList.contains("remove-filter")){const n=e.target.closest("li");if(n){const{field:e,condition:l,value:i}=n.dataset;this.table.removeFilter(e,l,i),t.close(),this.revealFilters()}}"clearFilters"===e.target.id&&(this.table.removeAllFilters(),t.close())}))}get shadowTemplate(){return'\n <button id="filterBtn" class="no-btn icon-btn">\n <k-icon name="filter"></k-icon>\n </button>\n '}}window.customElements.define("k-tc-filters",Filters);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import TableControl from"./TableControl.js";import{onEvent,offEvent}from"../../utils/element.js";const clickHandler=Symbol("clickHandler"),handlePageChange=Symbol("handlePageChange");export default class FirstPage extends TableControl{constructor(){super(),this[clickHandler]=this.goToFirstPage.bind(this),this[handlePageChange]=(()=>{const e=this.table;e&&1!==e.getCurrentPage()?this.shadowRoot.getElementById("firstPage").disabled=!1:this.shadowRoot.getElementById("firstPage").disabled=!0}).bind(this)}async render(e=!1){return!!await super.render(e)&&(onEvent(this.shadowRoot.getElementById("firstPage"),"click",this[clickHandler]),this[handlePageChange](),onEvent(this.table,"pageChange",this[handlePageChange]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("firstPage"),"click",this[clickHandler]),offEvent(this.table,"pageChange",this[handlePageChange])}goToFirstPage(){const e=this.table;e&&e.firstPage()}get shadowTemplate(){return'\n <button\n id="firstPage"\n class="no-btn icon-btn"\n >\n <slot><k-icon name="first"></k-icon></slot>\n </button>\n '}get shadowStyles(){return`\n ${super.shadowStyles}\n #firstPage[disabled] {\n cursor: inherit;\n opacity: 0.5;\n }\n `}}window.customElements.define("k-tc-first-page",FirstPage);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import TableControl from"./TableControl.js";import{offEvent,onEvent}from"../../utils/element.js";const hiddenChangeHandler=Symbol("hiddenChangeHandler");export default class HiddenCount extends TableControl{constructor(){super(),this[hiddenChangeHandler]=(()=>{this.shadowRoot.getElementById("hiddenCount").textContent=this.table.getHiddenRecords().length}).bind(this),this.classList.add("mq")}async render(e=!1){return!!await super.render(e)&&(this[hiddenChangeHandler](),onEvent(this.table,"recordHidden recordShown",this[hiddenChangeHandler]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.table,"recordHidden recordShown",this[hiddenChangeHandler])}get shadowTemplate(){return'\n <span id="hiddenCount"></span> Hidden Records\n '}}window.customElements.define("k-tc-hidden-count",HiddenCount);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import TableControl from"./TableControl.js";import{offEvent,onEvent}from"../../utils/element.js";const clickHandler=Symbol("clickHandler");export default class Hide extends TableControl{constructor(){super(),this[clickHandler]=(()=>{const e=this.table,t=this.record;e&&t&&e.hideRecord(t)}).bind(this)}async render(e=!1){return!!await super.render(e)&&(onEvent(this.shadowRoot.getElementById("hideButton"),"click",this[clickHandler]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("hideButton"),"click",this[clickHandler])}get shadowTemplate(){return'\n <button id="hideButton" class="no-btn icon-btn">\n <k-icon name="hide"></k-icon>\n </button>\n '}}window.customElements.define("k-tc-hide",Hide);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import TableControl from"./TableControl.js";import{onEvent,offEvent}from"../../utils/element.js";const clickHandler=Symbol("clickHandler"),handlePageChange=Symbol("handlePageChange");export default class LastPage extends TableControl{constructor(){super(),this[clickHandler]=this.lastPage.bind(this),this[handlePageChange]=(()=>{const e=this.table;e&&e.getCurrentPage()!==e.getTotalPages()?this.shadowRoot.getElementById("lastPage").disabled=!1:this.shadowRoot.getElementById("lastPage").disabled=!0}).bind(this)}async render(e=!1){return!!await super.render(e)&&(onEvent(this.shadowRoot.getElementById("lastPage"),"click",this[clickHandler]),this[handlePageChange](),onEvent(this.table,"pageChange",this[handlePageChange]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("lastPage"),"click",this[clickHandler]),offEvent(this.table,"pageChange",this[handlePageChange])}lastPage(){const e=this.table;e&&e.lastPage()}get shadowTemplate(){return'\n <button\n id="lastPage"\n class="no-btn icon-btn"\n >\n <slot><k-icon name="last"></k-icon></slot>\n </button>\n '}get shadowStyles(){return`\n ${super.shadowStyles}\n #lastPage[disabled] {\n cursor: inherit;\n opacity: 0.5;\n }\n `}}window.customElements.define("k-tc-last-page",LastPage);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import TableControl from"./TableControl.js";import{onEvent,offEvent}from"../../utils/element.js";const clickHandler=Symbol("clickHandler"),handlePageChange=Symbol("handlePageChange");export default class NextPage extends TableControl{constructor(){super(),this[clickHandler]=this.nextPage.bind(this),this[handlePageChange]=(()=>{const e=this.table;e&&e.getCurrentPage()!==e.getTotalPages()?this.shadowRoot.getElementById("nextPage").disabled=!1:this.shadowRoot.getElementById("nextPage").disabled=!0}).bind(this)}async render(e=!1){return!!await super.render(e)&&(onEvent(this.shadowRoot.getElementById("nextPage"),"click",this[clickHandler]),this[handlePageChange](),onEvent(this.table,"pageChange",this[handlePageChange]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("nextPage"),"click",this[clickHandler]),offEvent(this.table,"pageChange",this[handlePageChange])}nextPage(){const e=this.table;e&&e.nextPage()}get shadowTemplate(){return'\n <button\n id="nextPage"\n class="no-btn icon-btn"\n >\n <slot><k-icon name="chevron-right"></k-icon></slot>\n </button>\n '}get shadowStyles(){return`\n ${super.shadowStyles}\n #nextPage[disabled] {\n cursor: inherit;\n opacity: 0.5;\n }\n `}}window.customElements.define("k-tc-next-page",NextPage);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import TableControl from"./TableControl.js";import{onEvent}from"../../utils/element.js";const updateOptions=Symbol("updateOptions"),handleSelectChange=Symbol("handleSelectChange"),handlePageSizeChange=Symbol("handlePageSizeChange"),handlePageChange=Symbol("handlePageChange"),handlePageCountChange=Symbol("handlePageCountChange");export default class PageSelect extends TableControl{constructor(){super(),this[updateOptions]=(()=>{const e=this.shadowRoot.getElementById("pageSelect");e.innerHTML="";for(let t=1;t<=this.table.getTotalPages();t++){const a=document.createElement("option");a.value=t,a.textContent=t,e.appendChild(a)}e.value=this.table.getCurrentPage(),this.shadowRoot.getElementById("totalPages").textContent=this.table.getTotalPages()}).bind(this),this[handleSelectChange]=(()=>{this.table.setPage(parseInt(this.shadowRoot.getElementById("pageSelect").value))}).bind(this),this[handlePageSizeChange]=(()=>{this[updateOptions](),this.shadowRoot.getElementById("pageSelect").value=this.table.getCurrentPage()}).bind(this),this[handlePageChange]=(()=>{this.shadowRoot.getElementById("pageSelect").value=this.table.getCurrentPage()}).bind(this),this[handlePageCountChange]=(()=>{this.shadowRoot.getElementById("totalPages").textContent=this.table.getTotalPages(),this[updateOptions]()}).bind(this)}async render(e=!1){if(await super.render(e)){const e=this.shadowRoot.getElementById("pageSelect");return onEvent(e,"change",this[handleSelectChange]),onEvent(this.table,"pageSizeChange",this[handlePageSizeChange]),onEvent(this.table,"pageChange pageCountChanged",this[handlePageChange]),onEvent(this.table,"pageCountChanged",this[handlePageCountChange]),this[updateOptions](),!0}return!1}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("pageSelect"),"change",this[handleSelectChange]),offEvent(this.table,"pageSizeChange",this[handlePageSizeChange]),offEvent(this.table,"pageChange pageCountChanged",this[handlePageChange]),offEvent(this.table,"pageCountChanged",this[handlePageCountChange])}get shadowTemplate(){return'\n <select id="pageSelect" class="mxq"></select>\n <label> out of <span id="totalPages"></span></label>\n '}get shadowStyles(){return"\n :host {\n display: inline-flex;\n width: max-content;\n align-items: baseline;\n }\n #pageSelect, label {\n display: inline;\n }\n label {\n white-space: nowrap;\n }\n "}}window.customElements.define("k-tc-page-select",PageSelect);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import TableControl from"./TableControl.js";import{onEvent,offEvent}from"../../utils/element.js";const updateOptions=Symbol("updateOptions"),changeHandler=Symbol("changeHandler"),pageSizeChangeHandler=Symbol("pageSizeChangeHandler");export default class PageSize extends TableControl{constructor(e){super(),this[updateOptions]=(()=>{const e=this.shadowRoot.getElementById("pageSizeSelect");this.table.pageSizeOptions.forEach((t=>{const a=document.createElement("option");a.value=t,a.textContent=t,e.appendChild(a)})),e.value=this.table.pageSize}).bind(this),this[changeHandler]=(()=>{this.table.setPageSize(parseInt(this.shadowRoot.getElementById("pageSizeSelect").value))}).bind(this),this[pageSizeChangeHandler]=(()=>{this.shadowRoot.getElementById("pageSizeSelect").value=this.table.pageSize}).bind(this)}async render(e=!1){return!!await super.render(e)&&(onEvent(this.shadowRoot.getElementById("pageSizeSelect"),"change",this[changeHandler]),onEvent(this.table,"pageSizeChange",this[pageSizeChangeHandler]),this[updateOptions](),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("pageSizeSelect"),"change",this[changeHandler]),offEvent(this.table,"pageSizeChange",this[pageSizeChangeHandler])}get shadowTemplate(){return'\n <label for="pageSizeSelect">Page Size: </label>\n <select id="pageSizeSelect" class="mxq"></select>\n '}get shadowStyles(){return"\n :host {\n display: inline-flex;\n width: max-content;\n align-items: baseline;\n }\n label {\n white-space: nowrap;\n }\n "}}window.customElements.define("k-tc-page-size",PageSize);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import TableControl from"./TableControl.js";import{onEvent,offEvent}from"../../utils/element.js";const clickHandler=Symbol("clickHandler"),handlePageChange=Symbol("handlePageChange");export default class PrevPage extends TableControl{constructor(){super(),this[clickHandler]=this.prevPage.bind(this),this[handlePageChange]=(()=>{const e=this.table;e&&1!==e.getCurrentPage()?this.shadowRoot.getElementById("prevPage").disabled=!1:this.shadowRoot.getElementById("prevPage").disabled=!0}).bind(this)}async render(e=!1){return!!await super.render(e)&&(onEvent(this.shadowRoot.getElementById("prevPage"),"click",this[clickHandler]),this[handlePageChange](),onEvent(this.table,"pageChange",this[handlePageChange]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("prevPage"),"click",this[clickHandler]),offEvent(this.table,"pageChange",this[handlePageChange])}prevPage(){const e=this.table;e&&e.prevPage()}get shadowTemplate(){return'\n <button\n id="prevPage"\n class="no-btn icon-btn"\n >\n <slot><k-icon name="chevron-left"></k-icon></slot>\n </button>\n '}get shadowStyles(){return`\n ${super.shadowStyles}\n #prevPage[disabled] {\n cursor: inherit;\n opacity: 0.5;\n }\n `}}window.customElements.define("k-tc-prev-page",PrevPage);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import TableControl from"./TableControl.js";import{offEvent,onEvent}from"../../utils/element.js";import debounce from"../../utils/debounce.js";const changeHandler=Symbol("changeHandler");export default class Search extends TableControl{constructor(){super(),this[changeHandler]=debounce(this.search.bind(this),200)}async render(e=!1){return!!await super.render(e)&&(onEvent(this.shadowRoot.getElementById("search"),"input",this[changeHandler]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("search"),"input",this[changeHandler])}search(){const e=this.shadowRoot.getElementById("search").value;e.length<3?this.table.showAllRecords():this.table.search(e)}get shadowTemplate(){return`\n <input\n id="search"\n type="search"\n placeholder="Search"\n class="px pyh"\n />\n ${super.shadowTemplate}\n `}}window.customElements.define("k-tc-search",Search);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import TableControl from"./TableControl.js";import{onEvent}from"../../utils/element.js";export default class SelectCount extends TableControl{async render(e=!1){return!!await super.render(e)&&(this.updateCount(),onEvent(this.table,"selectionChange",(()=>{this.updateCount()})),!0)}updateCount(){this.shadowRoot.getElementById("selectCount").textContent=this.table.getSelectedRecords().length}get shadowTemplate(){return'\n Selected: <span id="selectCount"></span>\n '}get shadowStyles(){return"\n :host {\n display: inline-flex;\n width: max-content;\n align-items: baseline;\n align-self: center;\n }\n label {\n white-space: nowrap;\n }\n "}}window.customElements.define("k-table-select-count",SelectCount);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import TableControl from"./TableControl.js";import{offEvent,onEvent}from"../../utils/element.js";const clickHandler=Symbol("clickHandler");export default class HiddenCount extends TableControl{constructor(){super(),this[clickHandler]=(()=>{this.table.showAllRecords()}).bind(this)}async render(t=!1){return!!await super.render(t)&&(onEvent(this.shadowRoot.getElementById("showAllButton"),"click",this[clickHandler]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("showAllButton"),"click",this[clickHandler])}get shadowTemplate(){return'\n <button id="showAllButton" class="no-btn icon-btn">\n <k-icon name="show"></k-icon>\n </button>\n '}}window.customElements.define("k-tc-show-all",HiddenCount);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import TableControl from"./TableControl.js";import{onEvent,offEvent}from"../../utils/element.js";import Dialog from"../Dialog.js";const clickHandler=Symbol("clickHandler");export default class ShowHideFields extends TableControl{constructor(){super(),this[clickHandler]=this.openDialog.bind(this)}async render(e=!1){return!!await super.render(e)&&(onEvent(this.shadowRoot.getElementById("sort"),"click",this[clickHandler]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("sort"),"click",this[clickHandler])}openDialog(){const e=Dialog.create(`\n <h3 class="m0 ph" slot="title">Show / Hide Fields</h3>\n <div class="p">\n ${this.table.fields.map((e=>`\n <div class="mb">\n <label class="field">\n <input\n class="field-visibility"\n data-field="${e.name}"\n type="checkbox"\n ${e.hidden?"":"checked"}\n style="height: 1.25rem; width: 1.25rem"\n />\n ${e.label}\n </label>\n </div>\n `)).join("")}\n </div>\n `,{width:"400px",cancelText:"Close"});onEvent(e,"click",(e=>{if(!e.target.closest(".field"))return;const t=e.target.closest(".field-visibility");if(t){const e=t.getAttribute("data-field");this.table.setFieldHiddenState(e,!t.checked)}}))}get shadowTemplate(){return'\n <button\n id="sort"\n class="no-btn icon-btn"\n >\n <k-icon name="table-visibility"></k-icon>\n </button>\n '}}window.customElements.define("k-tc-show-hide-fields",ShowHideFields);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import Component from"../Component.js";export default class TableControl extends Component{constructor({maxWidth:t=40}={}){super(),this.registerAttributes({maxWidth:t})}get table(){return this.getRootNode()instanceof ShadowRoot?this.getRootNode().host.closest("k-table"):this.closest("k-table")}get record(){if(this.getRootNode()instanceof ShadowRoot){const t=this.closest(".record");if(t){const e=t.dataset.index;if(e)return this.table.records[e]}}return!1}get shadowStyles(){return`\n ${super.shadowStyles}\n :host {\n display: inline-flex;\n }\n .icon-btn {\n display: inline-flex !important;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n }\n `}}
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import Accordion from"./components/Accordion.js";import Card from"./components/Card.js";import Component from"./components/Component.js";import ContentSlider from"./components/ContentSlider.js";import Dialog from"./components/Dialog.js";import DirectoryViewer from"./components/DirectoryViewer.js";import FocusCapture from"./components/FocusCapture.js";import Icon from"./components/Icon.js";import Import from"./components/Import.js";import LazyComponent from"./components/LazyComponent.js";import ReactiveComponent from"./components/ReactiveComponent.js";import ReactiveLazyComponent from"./components/ReactiveLazyComponent.js";import Resize from"./components/Resize.js";import Search from"./components/Search.js";import ShowMore from"./components/ShowMore.js";import SideMenu from"./components/SideMenu.js";import Split from"./components/Split.js";import Table from"./components/Table.js";import DeleteSelected from"./components/tableControlsDeleteSelected.js";import Edit from"./components/tableControlsEdit.js";import Filters from"./components/tableControlsFilters.js";import HiddenCount from"./components/tableControlsHiddenCount.js";import Hide from"./components/tableControlsHide.js";import PageSelect from"./components/tableControlsPageSelect.js";import PageSize from"./components/tableControlsPageSize.js";import SelectCount from"./components/tableControlsSelectCount.js";import ShowAll from"./components/tableControlsShowAll.js";import Tabs from"./components/Tabs.js";import Tags from"./components/Tags.js";import ThemeSwitcher from"./components/ThemeSwitcher.js";import Timestamp from"./components/Timestamp.js";import Toggle from"./components/Toggle.js";import cli from"./utils/cli.js";import cookie from"./utils/cookie.js";import debounce from"./utils/debounce.js";import drag from"./utils/drag.js";import element from"./utils/element.js";import formatTimestamp from"./utils/formatTimestamp.js";import fuzzyMatch from"./utils/fuzzyMatch.js";import getPreferredTheme from"./utils/getPreferredTheme.js";import loadCss from"./utils/loadCss.js";import loadScript from"./utils/loadScript.js";import object from"./utils/object.js";import raf from"./utils/raf.js";import string from"./utils/string.js";import toFunction from"./utils/toFunction.js";import type from"./utils/type.js";import waitFrames from"./utils/waitFrames.js";import watchDirectoryHandle from"./utils/watchDirectoryHandle.js";export default{Accordion:Accordion,Card:Card,Component:Component,ContentSlider:ContentSlider,Dialog:Dialog,DirectoryViewer:DirectoryViewer,FocusCapture:FocusCapture,Icon:Icon,Import:Import,LazyComponent:LazyComponent,ReactiveComponent:ReactiveComponent,ReactiveLazyComponent:ReactiveLazyComponent,Resize:Resize,Search:Search,ShowMore:ShowMore,SideMenu:SideMenu,Split:Split,Table:Table,DeleteSelected:DeleteSelected,Edit:Edit,Filters:Filters,HiddenCount:HiddenCount,Hide:Hide,PageSelect:PageSelect,PageSize:PageSize,SelectCount:SelectCount,ShowAll:ShowAll,Tabs:Tabs,Tags:Tags,ThemeSwitcher:ThemeSwitcher,Timestamp:Timestamp,Toggle:Toggle,cli:cli,cookie:cookie,debounce:debounce,drag:drag,element:element,formatTimestamp:formatTimestamp,fuzzyMatch:fuzzyMatch,getPreferredTheme:getPreferredTheme,loadCss:loadCss,loadScript:loadScript,object:object,raf:raf,string:string,toFunction:toFunction,type:type,waitFrames:waitFrames,watchDirectoryHandle:watchDirectoryHandle};
|
|
1
|
+
import Accordion from"./components/Accordion.js";import Card from"./components/Card.js";import Component from"./components/Component.js";import ContentSlider from"./components/ContentSlider.js";import Dialog from"./components/Dialog.js";import DirectoryViewer from"./components/DirectoryViewer.js";import FocusCapture from"./components/FocusCapture.js";import Icon from"./components/Icon.js";import Import from"./components/Import.js";import LazyComponent from"./components/LazyComponent.js";import ReactiveComponent from"./components/ReactiveComponent.js";import ReactiveLazyComponent from"./components/ReactiveLazyComponent.js";import Resize from"./components/Resize.js";import Search from"./components/Search.js";import ShowMore from"./components/ShowMore.js";import SideMenu from"./components/SideMenu.js";import Sortable from"./components/Sortable.js";import Split from"./components/Split.js";import Table from"./components/Table.js";import DeleteRecord from"./components/tableControlsDeleteRecord.js";import DeleteSelected from"./components/tableControlsDeleteSelected.js";import Edit from"./components/tableControlsEdit.js";import ExportCSV from"./components/tableControlsExportCSV.js";import ExportJson from"./components/tableControlsExportJson.js";import FieldSortHide from"./components/tableControlsFieldSortHide.js";import Filters from"./components/tableControlsFilters.js";import FirstPage from"./components/tableControlsFirstPage.js";import HiddenCount from"./components/tableControlsHiddenCount.js";import Hide from"./components/tableControlsHide.js";import LastPage from"./components/tableControlsLastPage.js";import NextPage from"./components/tableControlsNextPage.js";import PageSelect from"./components/tableControlsPageSelect.js";import PageSize from"./components/tableControlsPageSize.js";import PrevPage from"./components/tableControlsPrevPage.js";import Search from"./components/tableControlsSearch.js";import SelectCount from"./components/tableControlsSelectCount.js";import ShowAll from"./components/tableControlsShowAll.js";import TableControl from"./components/tableControlsTableControl.js";import Tabs from"./components/Tabs.js";import Tags from"./components/Tags.js";import ThemeSwitcher from"./components/ThemeSwitcher.js";import Timestamp from"./components/Timestamp.js";import Toggle from"./components/Toggle.js";import cli from"./utils/cli.js";import cookie from"./utils/cookie.js";import debounce from"./utils/debounce.js";import drag from"./utils/drag.js";import element from"./utils/element.js";import formatTimestamp from"./utils/formatTimestamp.js";import fuzzyMatch from"./utils/fuzzyMatch.js";import getPreferredTheme from"./utils/getPreferredTheme.js";import loadCss from"./utils/loadCss.js";import loadScript from"./utils/loadScript.js";import object from"./utils/object.js";import raf from"./utils/raf.js";import string from"./utils/string.js";import toFunction from"./utils/toFunction.js";import type from"./utils/type.js";import waitFrames from"./utils/waitFrames.js";import watchDirectoryHandle from"./utils/watchDirectoryHandle.js";export default{Accordion:Accordion,Card:Card,Component:Component,ContentSlider:ContentSlider,Dialog:Dialog,DirectoryViewer:DirectoryViewer,FocusCapture:FocusCapture,Icon:Icon,Import:Import,LazyComponent:LazyComponent,ReactiveComponent:ReactiveComponent,ReactiveLazyComponent:ReactiveLazyComponent,Resize:Resize,Search:Search,ShowMore:ShowMore,SideMenu:SideMenu,Sortable:Sortable,Split:Split,Table:Table,DeleteRecord:DeleteRecord,DeleteSelected:DeleteSelected,Edit:Edit,ExportCSV:ExportCSV,ExportJson:ExportJson,FieldSortHide:FieldSortHide,Filters:Filters,FirstPage:FirstPage,HiddenCount:HiddenCount,Hide:Hide,LastPage:LastPage,NextPage:NextPage,PageSelect:PageSelect,PageSize:PageSize,PrevPage:PrevPage,Search:Search,SelectCount:SelectCount,ShowAll:ShowAll,TableControl:TableControl,Tabs:Tabs,Tags:Tags,ThemeSwitcher:ThemeSwitcher,Timestamp:Timestamp,Toggle:Toggle,cli:cli,cookie:cookie,debounce:debounce,drag:drag,element:element,formatTimestamp:formatTimestamp,fuzzyMatch:fuzzyMatch,getPreferredTheme:getPreferredTheme,loadCss:loadCss,loadScript:loadScript,object:object,raf:raf,string:string,toFunction:toFunction,type:type,waitFrames:waitFrames,watchDirectoryHandle:watchDirectoryHandle};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Sortable - Components - Kempo Docs - A Web Components Solution</title>
|
|
7
|
+
<link rel="stylesheet" href="../kempo/kempo-vars.css" /><link rel="stylesheet" href="../kempo/kempo-styles.css" />
|
|
8
|
+
<link rel="stylesheet" href="../kempo/kempo-hljs.css" />
|
|
9
|
+
<script type="module">
|
|
10
|
+
import Icon from '../kempo/components/Icon.js';
|
|
11
|
+
import Search from '../kempo/components/Search.js';
|
|
12
|
+
Icon.pathToIcons = ['../icons'];
|
|
13
|
+
Search.searchDataUrl = '../search.json';
|
|
14
|
+
</script>
|
|
15
|
+
</head>
|
|
16
|
+
<body>
|
|
17
|
+
<k-import src="../nav-1.inc.html"></k-import>
|
|
18
|
+
<h1 class="ta-center">Sortable</h1>
|
|
19
|
+
<main>
|
|
20
|
+
<details
|
|
21
|
+
class="b r mb"
|
|
22
|
+
>
|
|
23
|
+
<summary class="p">Table of Contents</summary>
|
|
24
|
+
<div class="m mt0 pl">
|
|
25
|
+
<h6>Examples</h6>
|
|
26
|
+
<a href="#basicUsage">Basic Usage</a><br />
|
|
27
|
+
|
|
28
|
+
<h6 class="mt">
|
|
29
|
+
<a href="#sortable">Sortable JavaScript Reference</a>
|
|
30
|
+
</h6>
|
|
31
|
+
<a href="#sortableConstructor">Constructor</a><br />
|
|
32
|
+
<a href="#sortableRequirements">Requirements</a><br />
|
|
33
|
+
<a href="#sortableAttributes">Attributes</a>
|
|
34
|
+
|
|
35
|
+
<h6 class="mt">
|
|
36
|
+
<a href="#sortableItem">SortableItem JavaScript Reference</a>
|
|
37
|
+
</h6>
|
|
38
|
+
<a href="#sortableItemConstructor">Constructor</a><br />
|
|
39
|
+
<a href="#sortableItemAttributes">Attributes</a>
|
|
40
|
+
</div>
|
|
41
|
+
</details>
|
|
42
|
+
|
|
43
|
+
<h3>Description</h3>
|
|
44
|
+
<p>A component that allows the user to sort items in a list.</p>
|
|
45
|
+
|
|
46
|
+
<h3 id="basicUsage"><a href="#basicUsage" class="no-link">Basic Usage</a></h3>
|
|
47
|
+
|
|
48
|
+
<pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">k-sortable</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">k-sortable-item</span>></span>Item 1<span class="hljs-tag"></<span class="hljs-name">k-sortable-item</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">k-sortable-item</span>></span>Item 2<span class="hljs-tag"></<span class="hljs-name">k-sortable-item</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">k-sortable-item</span>></span>Item 3<span class="hljs-tag"></<span class="hljs-name">k-sortable-item</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">k-sortable-item</span>></span>Item 4<span class="hljs-tag"></<span class="hljs-name">k-sortable-item</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">k-sortable-item</span>></span>Item 5<span class="hljs-tag"></<span class="hljs-name">k-sortable-item</span>></span><br /><span class="hljs-tag"></<span class="hljs-name">k-sortable</span>></span></code></pre>
|
|
49
|
+
<k-sortable>
|
|
50
|
+
<k-sortable-item>Item 1</k-sortable-item>
|
|
51
|
+
<k-sortable-item>Item 2</k-sortable-item>
|
|
52
|
+
<k-sortable-item>Item 3</k-sortable-item>
|
|
53
|
+
<k-sortable-item>Item 4</k-sortable-item>
|
|
54
|
+
<k-sortable-item>Item 5</k-sortable-item>
|
|
55
|
+
</k-sortable>
|
|
56
|
+
|
|
57
|
+
<br />
|
|
58
|
+
<hr />
|
|
59
|
+
|
|
60
|
+
<h2 id="sortable">Sortable JavaScript Reference</h2>
|
|
61
|
+
|
|
62
|
+
<h3 id="sortableConstructor"><a href="#sortableConstructor" class="no-link">Constructor</a></h3>
|
|
63
|
+
<h6>Extends <a href="./component.html">Component</a></h6>
|
|
64
|
+
<h5>
|
|
65
|
+
<code>new Sortable()</code>
|
|
66
|
+
</h5>
|
|
67
|
+
|
|
68
|
+
<h3 id="sortableRequirements"><a href="#sortableRequirements" class="no-link">Requirements</a></h3>
|
|
69
|
+
<ul>
|
|
70
|
+
<li>Sortable items must be direct children of the Sortable component.</li>
|
|
71
|
+
</ul>
|
|
72
|
+
|
|
73
|
+
<h3 id="sortableAttributes"><a href="#sortableAttributes" class="no-link">Attributes</a></h3>
|
|
74
|
+
<h5><code>sorting: boolean</code></h5>
|
|
75
|
+
<p>Indicates whether the item is currently being sorted.</p>
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
<br />
|
|
79
|
+
<hr />
|
|
80
|
+
<h2 id="sortableItem">SortableItem JavaScript Reference</h2>
|
|
81
|
+
|
|
82
|
+
<h3 id="sortableItemConstructor"><a href="#sortableItemConstructor" class="no-link">Constructor</a></h3>
|
|
83
|
+
<h6>Extends <a href="./component.html">Component</a></h6>
|
|
84
|
+
<h5>
|
|
85
|
+
<code>new SortableItem()</code>
|
|
86
|
+
</h5>
|
|
87
|
+
|
|
88
|
+
<h3 id="sortableItemAttributes"><a href="#sortableItemAttributes" class="no-link">Attributes</a></h3>
|
|
89
|
+
<h5><code>sorting: boolean</code></h5>
|
|
90
|
+
<p>Indicates whether the item is currently being sorted.</p>
|
|
91
|
+
|
|
92
|
+
</main>
|
|
93
|
+
<script type="module" src="../kempo/components/Import.js"></script>
|
|
94
|
+
<script type="module" src="../kempo/components/Sortable.js"></script>
|
|
95
|
+
</body>
|
|
96
|
+
</html>
|
|
@@ -72,6 +72,10 @@
|
|
|
72
72
|
<a href="tableRecordEditing.html">Record Editing</a><br />
|
|
73
73
|
<a href="tableRecordHiding.html">Record Hiding</a><br />
|
|
74
74
|
<a href="tableRecordFiltering.html">Record Filtering</a><br />
|
|
75
|
+
<a href="tableRecordSearching.html">Record Searching</a><br />
|
|
76
|
+
<a href="tableSorting.html">Sorting</a><br />
|
|
77
|
+
<a href="tableFieldSortHide.html">Field Sorting and Hiding</a><br />
|
|
78
|
+
<a href="tableFetchRecords.html">Fetching Records</a><br />
|
|
75
79
|
<h6 class="mt">JavaScript Reference</h6>
|
|
76
80
|
<a href="#constructor">Constructor</a><br />
|
|
77
81
|
<a href="#requirements">Requirements</a><br />
|
|
@@ -129,6 +133,10 @@
|
|
|
129
133
|
<li><a href="tableRecordEditing.html">Record Editing</a></li>
|
|
130
134
|
<li><a href="tableRecordHiding.html">Record Hiding</a></li>
|
|
131
135
|
<li><a href="tableRecordFiltering.html">Record Filtering</a></li>
|
|
136
|
+
<li><a href="tableRecordSearching.html">Record Searching</a></li>
|
|
137
|
+
<li><a href="tableSorting.html">Sorting</a></li>
|
|
138
|
+
<li><a href="tableFieldSortHide.html">Field Sorting and Hiding</a></li>
|
|
139
|
+
<li><a href="tableFetchRecords.html">Fetching Records</a></li>
|
|
132
140
|
</ul>
|
|
133
141
|
|
|
134
142
|
<br />
|
|
@@ -181,13 +189,12 @@
|
|
|
181
189
|
<ul>
|
|
182
190
|
<li><code>records</code>: An array of objects representing the records to be shown in the table.</li>
|
|
183
191
|
<li><code>fields</code>: An array of objects representing the fields of the table, each object must contain a <code>name</code> and a <code>label</code>. If this property is omitted, the fields will be automatically generated from the first 100 records.</li>
|
|
184
|
-
<li><code>
|
|
192
|
+
<li><code>filters</code>: An array of filter objects to apply to the records.</li>
|
|
185
193
|
<li><code>pageSize</code>: The number of records to display per page.</li>
|
|
186
194
|
<li><code>pageSizeOptions</code>: An array of numbers representing the available page size options.</li>
|
|
187
195
|
<li><code>currentPage</code>: The current page to display.</li>
|
|
188
196
|
<li><code>enableSelection</code>: A boolean to enable or disable record selection.</li>
|
|
189
197
|
<li><code>enablePages</code>: A boolean to enable or disable pagination.</li>
|
|
190
|
-
<li><code>filters</code>: An array of filter objects to apply to the records.</li>
|
|
191
198
|
</ul>
|
|
192
199
|
|
|
193
200
|
<h5><code>renderFields()<i>: undefined</i></code></h5>
|
|
@@ -217,7 +224,7 @@
|
|
|
217
224
|
<h5><code>nextPage()<i>: undefined</i></code></h5>
|
|
218
225
|
<p>Moves to the next page.</p>
|
|
219
226
|
|
|
220
|
-
<h5><code>prevPage()<i>: undefined</i></h5>
|
|
227
|
+
<h5><code>prevPage()<i>: undefined</i></code></h5>
|
|
221
228
|
<p>Moves to the previous page.</p>
|
|
222
229
|
|
|
223
230
|
<h5><code>getCurrentPage()<i>: number</i></code></h5>
|
|
@@ -262,24 +269,42 @@
|
|
|
262
269
|
<h5><code>showAllRecords()<i>: undefined</i></code></h5>
|
|
263
270
|
<p>Shows all hidden records in the table.</p>
|
|
264
271
|
|
|
265
|
-
<h5><code>addFilter(<i>string</i> field, <i>string</i> condition, <i>any</i> value)<i>: undefined</i></h5>
|
|
272
|
+
<h5><code>addFilter(<i>string</i> field, <i>string</i> condition, <i>any</i> value)<i>: undefined</i></code></h5>
|
|
266
273
|
<p>Adds a filter to the table.</p>
|
|
267
274
|
|
|
268
|
-
<h5><code>removeFilter(<i>string</i> field, <i>string</i> condition, <i>any</i> value)<i>: undefined</i></h5>
|
|
275
|
+
<h5><code>removeFilter(<i>string</i> field, <i>string</i> condition, <i>any</i> value)<i>: undefined</i></code></h5>
|
|
269
276
|
<p>Removes a filter from the table.</p>
|
|
270
277
|
|
|
278
|
+
<h5><code>removeAllFilters()<i>: undefined</i></code></h5>
|
|
279
|
+
<p>Removes all filters from the table.</p>
|
|
280
|
+
|
|
281
|
+
<h5><code>search(<i>string</i> term)<i>: undefined</i></code></h5>
|
|
282
|
+
<p>Searches the records for the specified term.</p>
|
|
283
|
+
|
|
271
284
|
<h5><code>getDisplayedRecords()<i>: Array</i></code></h5>
|
|
272
285
|
<p>Returns an array of the records currently displayed in the table.</p>
|
|
273
286
|
|
|
274
287
|
<h5><code>getHiddenRecords()<i>: Array</i></code></h5>
|
|
275
288
|
<p>Returns an array of the hidden records in the table.</p>
|
|
276
289
|
|
|
277
|
-
<h5><code>setupFetchRecords(<i>number</i> totalRecords, <i>function</i> callback)<i>: undefined</i></h5>
|
|
290
|
+
<h5><code>setupFetchRecords(<i>number</i> totalRecords, <i>function</i> callback)<i>: undefined</i></code></h5>
|
|
278
291
|
<p>Sets up the table to fetch records dynamically.</p>
|
|
279
292
|
|
|
280
|
-
<h5><code>sortBy(<i>string</i> field, <i>boolean</i> asc)<i>: undefined</i></h5>
|
|
293
|
+
<h5><code>sortBy(<i>string</i> field, <i>boolean</i> asc)<i>: undefined</i></code></h5>
|
|
281
294
|
<p>Sorts the records by the specified field in ascending or descending order.</p>
|
|
282
295
|
|
|
296
|
+
<h5><code>setFieldHiddenState(<i>string</i> fieldName, <i>boolean</i> hidden)<i>: undefined</i></code></h5>
|
|
297
|
+
<p>Sets the hidden state of a field.</p>
|
|
298
|
+
|
|
299
|
+
<h5><code>hideField(<i>string</i> fieldName)<i>: undefined</i></code></h5>
|
|
300
|
+
<p>Hides a field in the table.</p>
|
|
301
|
+
|
|
302
|
+
<h5><code>showField(<i>string</i> fieldName)<i>: undefined</i></code></h5>
|
|
303
|
+
<p>Shows a hidden field in the table.</p>
|
|
304
|
+
|
|
305
|
+
<h5><code>reorderFields(<i>Array</i> newOrder)<i>: undefined</i></code></h5>
|
|
306
|
+
<p>Reorders the fields in the table based on the new order array.</p>
|
|
307
|
+
|
|
283
308
|
</main>
|
|
284
309
|
<div style="height: 33.333vh"></div>
|
|
285
310
|
<script type="module" src="../kempo/components/Import.js"></script>
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
const phoneNumber = `(${Math.floor(Math.random() * 900) + 100}) ${Math.floor(Math.random() * 900) + 100}-${Math.floor(Math.random() * 9000) + 1000}`;
|
|
48
48
|
return { name, email, birthday, phoneNumber, gender };
|
|
49
49
|
}
|
|
50
|
-
for (let i = 0; i <
|
|
50
|
+
for (let i = 0; i < 10; i++) {
|
|
51
51
|
contacts.push(generateContact());
|
|
52
52
|
};
|
|
53
53
|
</script>
|
|
@@ -59,30 +59,16 @@
|
|
|
59
59
|
|
|
60
60
|
<a href="./table.html"><h5>Back to Table Component Documentation</h5></a>
|
|
61
61
|
|
|
62
|
-
<p>The table component
|
|
63
|
-
<pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">k-table</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"topBottomControlsExample"</span>></span><span class="hljs-tag"><
|
|
64
|
-
<k-table id="topBottomControlsExample"
|
|
62
|
+
<p>The table component supports controls at both the top and bottom. These controls can handle pagination, adding new records, or other actions. They are web components that interact with their parent <code>k-table</code> by accessing its methods and listening for its events.</p>
|
|
63
|
+
<pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">k-table</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"topBottomControlsExample"</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">k-tc-export-json</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"top"</span>></span><span class="hljs-tag"></<span class="hljs-name">k-tc-export-json</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">k-tc-export-csv</span>></span><span class="hljs-tag"></<span class="hljs-name">k-tc-export-csv</span>></span><br /><span class="hljs-tag"></<span class="hljs-name">k-table</span>></span><br /><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"../kempo/components/tableControls/ExportJson.js"</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br /><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"../kempo/components/tableControls/ExportCsv.js"</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span><br /><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span>></span><span class="javascript"><br /> <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'topBottomControlsExample'</span>).setRecords(contacts);<br /></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span></code></pre>
|
|
64
|
+
<k-table id="topBottomControlsExample">
|
|
65
|
+
<k-tc-export-json slot="top"></k-tc-export-json>
|
|
66
|
+
<k-tc-export-csv></k-tc-export-csv>
|
|
67
|
+
</k-table>
|
|
68
|
+
<script type="module" src="../kempo/components/tableControls/ExportJson.js"></script>
|
|
69
|
+
<script type="module" src="../kempo/components/tableControls/ExportCsv.js"></script>
|
|
65
70
|
<script type="module">
|
|
66
|
-
document.getElementById('topBottomControlsExample').
|
|
67
|
-
records: contacts.slice(0, 10),
|
|
68
|
-
controls: {
|
|
69
|
-
top: [
|
|
70
|
-
{
|
|
71
|
-
icon: 'add',
|
|
72
|
-
action: (table) => table.addRecord(generateContact())
|
|
73
|
-
}
|
|
74
|
-
],
|
|
75
|
-
bottom: [
|
|
76
|
-
{
|
|
77
|
-
icon: 'refresh',
|
|
78
|
-
action: (table) => {
|
|
79
|
-
contacts = contacts.sort(() => Math.random() - 0.5);
|
|
80
|
-
table.setRecords(contacts.slice(0, 10));
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
]
|
|
84
|
-
}
|
|
85
|
-
});
|
|
71
|
+
document.getElementById('topBottomControlsExample').setRecords(contacts);
|
|
86
72
|
</script>
|
|
87
73
|
</main>
|
|
88
74
|
<div style="height: 33.333vh"></div>
|