kempo 2.7.4 → 2.9.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.
@@ -6,6 +6,45 @@
6
6
  <title>Table - Components - Kempo Docs - A Web Components Solution</title>
7
7
  <link rel="stylesheet" href="../kempo/kempo-vars.css" /><link rel="stylesheet" href="../kempo/kempo-styles.css" />
8
8
  <link rel="stylesheet" href="../kempo/kempo-hljs.css" />
9
+ <script type="module" src="../kempo/components/Table.js"></script>
10
+ <script>
11
+
12
+ window.contacts = [];
13
+ function generateContact(){
14
+ const maleNames = [
15
+ "Liam", "Noah", "Oliver", "Elijah", "William", "James", "Benjamin",
16
+ "Lucas", "Henry", "Alexander", "Mason", "Michael", "Ethan", "Daniel",
17
+ "Jacob", "Logan", "Jackson", "Levi", "Sebastian", "Mateo", "Jack",
18
+ "Owen", "Theodore", "Aiden", "Samuel", "Joseph", "John", "David",
19
+ "Wyatt", "Matthew"
20
+ ];
21
+ const femaleNames = [
22
+ "Olivia", "Emma", "Ava", "Sophia", "Isabella", "Mia", "Amelia",
23
+ "Harper", "Evelyn", "Abigail", "Emily", "Ella", "Elizabeth",
24
+ "Camila", "Luna", "Sofia", "Avery", "Mila", "Aria", "Scarlett",
25
+ "Penelope", "Layla", "Chloe", "Victoria", "Madison", "Eleanor",
26
+ "Grace", "Nora", "Riley", "Zoey"
27
+ ];
28
+ const lastNames = [
29
+ "Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller",
30
+ "Davis", "Rodriguez", "Martinez", "Hernandez", "Lopez", "Gonzalez",
31
+ "Wilson", "Anderson", "Thomas", "Taylor", "Moore", "Jackson", "Martin",
32
+ "Lee", "Perez", "Thompson", "White", "Harris", "Sanchez", "Clark",
33
+ "Ramirez", "Lewis", "Robinson"
34
+ ];
35
+ const gender = Math.random() > 0.5 ? 'm' : 'f';
36
+ const firstName = gender === 'm' ? maleNames[Math.floor(Math.random() * maleNames.length)] : femaleNames[Math.floor(Math.random() * femaleNames.length)];
37
+ const lastName = lastNames[Math.floor(Math.random() * lastNames.length)];
38
+ const name = `${firstName} ${lastName}`;
39
+ const email = `${firstName.toLowerCase()}.${lastName.toLowerCase()}@mailserver.com`;
40
+ const birthday = `${Math.floor(Math.random() * 100) + 1920}-${String(Math.floor(Math.random() * 12) + 1).padStart(2, '0')}-${String(Math.floor(Math.random() * 28) + 1).padStart(2, '0')}`;
41
+ const phoneNumber = `(${Math.floor(Math.random() * 900) + 100}) ${Math.floor(Math.random() * 900) + 100}-${Math.floor(Math.random() * 9000) + 1000}`;
42
+ return { name, email, birthday, phoneNumber, gender };
43
+ }
44
+ for (let i = 0; i < 100; i++) {
45
+ contacts.push(generateContact());
46
+ };
47
+ </script>
9
48
  </head>
10
49
  <body>
11
50
  <k-import src="../nav-1.inc.html"></k-import>
@@ -16,13 +55,17 @@
16
55
  >
17
56
  <summary class="p">Table of Contents</summary>
18
57
  <div class="m mt0 pl">
58
+ <h6>Examples</h6>
19
59
  <a href="#basicUsage">Basic Usage</a><br />
20
60
  <a href="#customFields">Custom Fields</a><br />
61
+ <a href="#topBottomControls">Top and Bottom Controls</a><br />
62
+ <a href="#rowControls">Row Controls</a><br />
63
+ <a href="#pagination">Pagination</a><br />
64
+ <h6 class="mt">JavaScript Reference</h6>
21
65
  <a href="#constructor">Constructor</a><br />
22
66
  <a href="#requirements">Requirements</a><br />
23
67
  <a href="#properties">Properties</a><br />
24
68
  <a href="#methods">Methods</a><br />
25
- <a href="#controls">Row Controls</a><br />
26
69
  </div>
27
70
  </details>
28
71
 
@@ -30,151 +73,230 @@
30
73
  <p>The <code>&lt;k-table></code> component is used to render data into a <code>&lt;table></code> using JavaScript.</p>
31
74
 
32
75
  <h3 id="basicUsage"><a href="#basicUsage" class="no-link">Basic Usage</a></h3>
33
- <p>In HTML create a <code>&lt;k-table></code>, and then in JavaScript call the <code>setData</code> method passing in an array of objects containing your data.</p>
76
+ <p>In HTML create a <code>&lt;k-table></code>, and then in JavaScript call the <code>setData</code> method passing in an options object containing your data.</p>
34
77
 
35
- <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-table</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"contacts"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-table</span>&gt;</span><br /><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span>&gt;</span><span class="javascript"><br /> <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'contacts'</span>).setData([<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">"Dustin"</span>,<br /> <span class="hljs-attr">phoneNumber</span>: <span class="hljs-string">"(111) 111-1111"</span>,<br /> <span class="hljs-attr">emailAddress</span>: <span class="hljs-string">"dustin@mailserver.com"</span>,<br /> <span class="hljs-attr">gender</span>: <span class="hljs-string">"Male"</span><br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">"Kayla"</span>,<br /> <span class="hljs-attr">phoneNumber</span>: <span class="hljs-string">"(222) 222-2222"</span>,<br /> <span class="hljs-attr">emailAddress</span>: <span class="hljs-string">"kayla@mailserver.com"</span>,<br /> <span class="hljs-attr">gender</span>: <span class="hljs-string">"Female"</span><br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">"Alexander"</span>,<br /> <span class="hljs-attr">phoneNumber</span>: <span class="hljs-string">"(333) 333-33333"</span>,<br /> <span class="hljs-attr">emailAddress</span>: <span class="hljs-string">"alex@mailserver.com"</span>,<br /> <span class="hljs-attr">gender</span>: <span class="hljs-string">"Male"</span><br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">"Amelia"</span>,<br /> <span class="hljs-attr">phoneNumber</span>: <span class="hljs-string">"(444) 444-44444"</span>,<br /> <span class="hljs-attr">emailAddress</span>: <span class="hljs-string">"amelia@mailserver.com"</span>,<br /> <span class="hljs-attr">gender</span>: <span class="hljs-string">"Female"</span><br /> },<br /> ]);<br /></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
36
- <script type="module" src="../kempo/components/Table.js"></script>
37
- <k-table id="contacts"></k-table>
78
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-table</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"basicUsageExample"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-table</span>&gt;</span><br /><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span>&gt;</span><span class="javascript"><br /> <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'basicUsageExample'</span>).setData({<br /> records: [<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">"Dustin"</span>,<br /> <span class="hljs-attr">phoneNumber</span>: <span class="hljs-string">"(111) 111-1111"</span>,<br /> <span class="hljs-attr">emailAddress</span>: <span class="hljs-string">"dustin@mailserver.com"</span>,<br /> <span class="hljs-attr">gender</span>: <span class="hljs-string">"Male"</span><br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">"Kayla"</span>,<br /> <span class="hljs-attr">phoneNumber</span>: <span class="hljs-string">"(222) 222-2222"</span>,<br /> <span class="hljs-attr">emailAddress</span>: <span class="hljs-string">"kayla@mailserver.com"</span>,<br /> <span class="hljs-attr">gender</span>: <span class="hljs-string">"Female"</span><br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">"Alexander"</span>,<br /> <span class="hljs-attr">phoneNumber</span>: <span class="hljs-string">"(333) 333-33333"</span>,<br /> <span class="hljs-attr">emailAddress</span>: <span class="hljs-string">"alex@mailserver.com"</span>,<br /> <span class="hljs-attr">gender</span>: <span class="hljs-string">"Male"</span><br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">"Amelia"</span>,<br /> <span class="hljs-attr">phoneNumber</span>: <span class="hljs-string">"(444) 444-44444"</span>,<br /> <span class="hljs-attr">emailAddress</span>: <span class="hljs-string">"amelia@mailserver.com"</span>,<br /> <span class="hljs-attr">gender</span>: <span class="hljs-string">"Female"</span><br /> },<br /> ]<br /> });<br /></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
79
+ <k-table id="basicUsageExample"></k-table>
38
80
  <script type="module">
39
- document.getElementById('contacts').setData([
40
- {
41
- name: "Dustin",
42
- phoneNumber: "(111) 111-1111",
43
- emailAddress: "dustin@mailserver.com",
44
- gender: "Male"
45
- },
46
- {
47
- name: "Kayla",
48
- phoneNumber: "(222) 222-2222",
49
- emailAddress: "kayla@mailserver.com",
50
- gender: "Female"
51
- },
52
- {
53
- name: "Alexander",
54
- phoneNumber: "(333) 333-33333",
55
- emailAddress: "alex@mailserver.com",
56
- gender: "Male"
57
- },
58
- {
59
- name: "Amelia",
60
- phoneNumber: "(444) 444-44444",
61
- emailAddress: "amelia@mailserver.com",
62
- gender: "Female"
63
- },
64
- ]);
81
+ document.getElementById('basicUsageExample').setData({
82
+ records: [
83
+ {
84
+ name: "Dustin",
85
+ phoneNumber: "(111) 111-1111",
86
+ emailAddress: "dustin@mailserver.com",
87
+ gender: "Male"
88
+ },
89
+ {
90
+ name: "Kayla",
91
+ phoneNumber: "(222) 222-2222",
92
+ emailAddress: "kayla@mailserver.com",
93
+ gender: "Female"
94
+ },
95
+ {
96
+ name: "Alexander",
97
+ phoneNumber: "(333) 333-33333",
98
+ emailAddress: "alex@mailserver.com",
99
+ gender: "Male"
100
+ },
101
+ {
102
+ name: "Amelia",
103
+ phoneNumber: "(444) 444-44444",
104
+ emailAddress: "amelia@mailserver.com",
105
+ gender: "Female"
106
+ },
107
+ ]
108
+ });
65
109
  </script>
66
110
 
67
111
  <h3 id="customFields"><a href="#customFields" class="no-link">Custom Fields</a></h3>
68
- <p>Use the second paramter of <code>setData</code> to define custom fields.</p>
69
- <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-table</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"movies"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-table</span>&gt;</span><br /><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span>&gt;</span><span class="javascript"><br /> <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'movies'</span>).setData([<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">'Good Will Hunting'</span>,<br /> <span class="hljs-attr">year</span>: <span class="hljs-number">1997</span>,<br /> <span class="hljs-attr">lead</span>: <span class="hljs-string">'Matt Damon'</span>,<br /> <span class="hljs-attr">budget</span>: <span class="hljs-number">10000000</span><br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">'A Few Good Men'</span>,<br /> <span class="hljs-attr">year</span>: <span class="hljs-number">1992</span>,<br /> <span class="hljs-attr">lead</span>: <span class="hljs-string">'Tom Cruise'</span>,<br /> <span class="hljs-attr">prod</span>: <span class="hljs-string">'Castle Rock Entertainment'</span><br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">'The Silence of the Lambs'</span>,<br /> <span class="hljs-attr">year</span>: <span class="hljs-number">1991</span>,<br /> <span class="hljs-attr">lead</span>: <span class="hljs-string">'Jodie Foster'</span>,<br /> <span class="hljs-attr">prequel</span>: <span class="hljs-string">'Red Dragon'</span><br /> }<br /> ],[<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">"name"</span>,<br /> <span class="hljs-attr">label</span>: <span class="hljs-string">"Name"</span><br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">'year'</span>,<br /> <span class="hljs-attr">label</span>: <span class="hljs-string">'Year'</span><br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">'prod'</span>,<br /> <span class="hljs-attr">label</span>: <span class="hljs-string">'Production Company'</span><br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">'lead'</span>,<br /> <span class="hljs-attr">label</span>: <span class="hljs-string">'Lead Actor / Actress'</span><br /> }<br /> ]);<br /></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
70
- <k-table id="movies"></k-table>
112
+ <p>Use the <code>fields</code> property of the options object in <code>setData</code> to define custom fields. This is useful for hiding fields, reordering fields, changing the labels, formatting the output, or creating a calculated field.</p>
113
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-table</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"customFieldsExample"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-table</span>&gt;</span><br /><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span>&gt;</span><span class="javascript"><br /> <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'customFieldsExample'</span>).setData({<br /> records: contacts.slice(<span class="hljs-number">0</span>,<span class="hljs-number">10</span>),<br /> fields: [<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">"name"</span>,<br /> <span class="hljs-attr">label</span>: <span class="hljs-string">"Name"</span><br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">'phoneNumber'</span>,<br /> <span class="hljs-attr">label</span>: <span class="hljs-string">'Phone Number'</span><br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">'email'</span>,<br /> <span class="hljs-attr">label</span>: <span class="hljs-string">'Email Address'</span><br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">'birthday'</span>,<br /> <span class="hljs-attr">label</span>: <span class="hljs-string">'Birthday'</span><br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">'age'</span>,<br /> <span class="hljs-attr">label</span>: <span class="hljs-string">'Age'</span>,<br /> <span class="hljs-attr">calculator</span>: <span class="hljs-function">(<span class="hljs-params">record</span>) =&gt;</span> {<br /> <span class="hljs-comment">// record.birthday is a string in the format "YYYY-MM-DD"</span><br /> <span class="hljs-keyword">const</span> today = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();<br /> <span class="hljs-keyword">const</span> birthDate = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(record.birthday);<br /> <span class="hljs-keyword">let</span> age = today.getFullYear() - birthDate.getFullYear();<br /> <span class="hljs-keyword">const</span> monthDifference = today.getMonth() - birthDate.getMonth();<br /> <span class="hljs-keyword">if</span> (monthDifference &lt; <span class="hljs-number">0</span> || (monthDifference === <span class="hljs-number">0</span> &amp;&amp; today.getDate() &lt; birthDate.getDate())) {<br /> age--;<br /> }<br /> <span class="hljs-keyword">return</span> age;<br /> }<br /> },<br /> {<br /> <span class="hljs-attr">name</span>: <span class="hljs-string">'gender'</span>,<br /> <span class="hljs-attr">label</span>: <span class="hljs-string">'Gender'</span>,<br /> <span class="hljs-attr">formatter</span>: <span class="hljs-function">(<span class="hljs-params">v</span>) =&gt;</span> v===<span class="hljs-string">'m'</span>?<span class="hljs-string">'Male'</span>:<span class="hljs-string">'Female'</span> <span class="hljs-comment">// original value is "m" or "f"</span><br /> }<br /> ]<br /> });<br /></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
114
+ <k-table id="customFieldsExample"></k-table>
71
115
  <script type="module">
72
- document.getElementById('movies').setData([
73
- {
74
- name: 'Good Will Hunting',
75
- year: 1997,
76
- lead: 'Matt Damon',
77
- budget: 10000000
78
- },
79
- {
80
- name: 'A Few Good Men',
81
- year: 1992,
82
- lead: 'Tom Cruise',
83
- prod: 'Castle Rock Entertainment'
84
- },
85
- {
86
- name: 'The Silence of the Lambs',
87
- year: 1991,
88
- lead: 'Jodie Foster',
89
- prequel: 'Red Dragon'
90
- }
91
- ],[
92
- {
93
- name: "name",
94
- label: "Name"
95
- },
96
- {
97
- name: 'year',
98
- label: 'Year'
99
- },
100
- {
101
- name: 'prod',
102
- label: 'Production Company'
103
- },
104
- {
105
- name: 'lead',
106
- label: 'Lead Actor / Actress'
107
- }
108
- ]);
109
- </script>
110
-
111
- <h3 id="controls"><a href="#controls" class="no-link">Row Controls</a></h3>
112
- <p>The table component can display controls before or after each row. Each control is defined by an icon name, a callback function, and optionally an HTML string or a render function. All controls are combined into a single <code>&lt;td&gt;</code> with each control being a button.</p>
113
-
114
-
115
- <k-table id="contacts2"></k-table>
116
- <script type="module">
117
- document.getElementById('contacts2').setData([
118
- {
119
- name: "Dustin",
120
- phoneNumber: "(111) 111-1111",
121
- emailAddress: "dustin@mailserver.com",
122
- gender: "Male"
123
- },
124
- {
125
- name: "Kayla",
126
- phoneNumber: "(222) 222-2222",
127
- emailAddress: "kayla@mailserver.com",
128
- gender: "Female"
129
- }
130
- ], false, {
131
- before: [
116
+ document.getElementById('customFieldsExample').setData({
117
+ records: contacts.slice(0,10),
118
+ fields: [
132
119
  {
133
- icon: 'edit',
134
- action: (table, record) => console.log('Edit', table, record)
135
- }
136
- ],
137
- after: [
120
+ name: "name",
121
+ label: "Name"
122
+ },
138
123
  {
139
- icon: 'delete',
140
- action: (table, record) => console.log('Delete', table, record)
124
+ name: 'phoneNumber',
125
+ label: 'Phone Number'
141
126
  },
142
127
  {
143
- html: '<span>Custom HTML</span>'
128
+ name: 'email',
129
+ label: 'Email Address'
144
130
  },
145
131
  {
146
- render: (table, record) => `<a href="mailto:${record.emailAddress}">Email</a>`
147
- }
148
- ],
149
- top: [
132
+ name: 'birthday',
133
+ label: 'Birthday'
134
+ },
150
135
  {
151
- icon: 'add',
152
- action: (table) => console.log('Add', table)
153
- }
154
- ],
155
- bottom: [
136
+ name: 'age',
137
+ label: 'Age',
138
+ calculator: (record) => {
139
+ // record.birthday is a string in the format "YYYY-MM-DD"
140
+ const today = new Date();
141
+ const birthDate = new Date(record.birthday);
142
+ let age = today.getFullYear() - birthDate.getFullYear();
143
+ const monthDifference = today.getMonth() - birthDate.getMonth();
144
+ if (monthDifference < 0 || (monthDifference === 0 && today.getDate() < birthDate.getDate())) {
145
+ age--;
146
+ }
147
+ return age;
148
+ }
149
+ },
156
150
  {
157
- icon: 'refresh',
158
- action: (table) => console.log('Refresh', table)
151
+ name: 'gender',
152
+ label: 'Gender',
153
+ formatter: (v) => v==='m'?'Male':'Female' // original value is "m" or "f"
159
154
  }
160
155
  ]
161
156
  });
162
157
  </script>
163
158
 
164
- <h3 id="constructor"><a href="#consttructor" class="no-link">Constructor</a></h3>
159
+ <h3 id="topBottomControls"><a href="#topBottomControls" class="no-link">Top and Bottom Controls</a></h3>
160
+ <p>The table component can display controls at the top and bottom of the table. These controls can be used for pagination, adding new records, or any other actions. Each control is defined by an icon name, a callback function, and optionally an HTML string or a render function.</p>
161
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-table</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"topBottomControlsExample"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-table</span>&gt;</span><br /><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span>&gt;</span><span class="javascript"><br /> <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'topBottomControlsExample'</span>).setData({<br /> records: contacts.slice(<span class="hljs-number">10</span>, <span class="hljs-number">20</span>),<br /> controls: {<br /> <span class="hljs-attr">top</span>: [<br /> {<br /> <span class="hljs-attr">icon</span>: <span class="hljs-string">'add'</span>,<br /> <span class="hljs-attr">action</span>: <span class="hljs-function">(<span class="hljs-params">table</span>) =&gt;</span> table.addRecord(generateContact())<br /> }<br /> ],<br /> <span class="hljs-attr">bottom</span>: [<br /> {<br /> <span class="hljs-attr">icon</span>: <span class="hljs-string">'refresh'</span>,<br /> <span class="hljs-attr">action</span>: <span class="hljs-function">(<span class="hljs-params">table</span>) =&gt;</span> {<br /> contacts = contacts.sort(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-built_in">Math</span>.random() - <span class="hljs-number">0.5</span>);<br /> table.setRecords(contacts.slice(<span class="hljs-number">0</span>, <span class="hljs-number">10</span>));<br /> }<br /> }<br /> ]<br /> }<br /> });<br /></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
162
+ <k-table id="topBottomControlsExample"></k-table>
163
+ <script type="module">
164
+ document.getElementById('topBottomControlsExample').setData({
165
+ records: contacts.slice(10, 20),
166
+ controls: {
167
+ top: [
168
+ {
169
+ icon: 'add',
170
+ action: (table) => table.addRecord(generateContact())
171
+ }
172
+ ],
173
+ bottom: [
174
+ {
175
+ icon: 'refresh',
176
+ action: (table) => {
177
+ contacts = contacts.sort(() => Math.random() - 0.5);
178
+ table.setRecords(contacts.slice(0, 10));
179
+ }
180
+ }
181
+ ]
182
+ }
183
+ });
184
+ </script>
185
+
186
+ <h3 id="rowControls"><a href="#rowControls" class="no-link">Row Controls</a></h3>
187
+ <p>The table component can display controls before or after each row. Each control is defined by an icon name, a callback function, and optionally an HTML string or a render function.</p>
188
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-table</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"rowControlsExample"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-table</span>&gt;</span><br /><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span>&gt;</span><span class="javascript"><br /> <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'rowControlsExample'</span>).setData({<br /> records: contacts.slice(20, 25),<br /> controls: {<br /> <span class="hljs-attr">before</span>: [<br /> {<br /> <span class="hljs-attr">html</span>: <span class="hljs-string">'&lt;span&gt;Custom HTML&lt;/span&gt; '</span><br /> },<br /> {<br /> <span class="hljs-attr">render</span>: <span class="hljs-function">(<span class="hljs-params">table, record</span>) =&gt;</span> {<br /> <span class="hljs-keyword">return</span> <span class="hljs-string">`&lt;button onclick="alert('<span class="hljs-subst">${record.name}</span>')"&gt;Alert&lt;/button&gt;`</span>;<br /> }<br /> }<br /> ],<br /> <span class="hljs-attr">after</span>: [<br /> {<br /> <span class="hljs-attr">icon</span>: <span class="hljs-string">'edit'</span>,<br /> <span class="hljs-attr">action</span>: <span class="hljs-function">(<span class="hljs-params">table, record, index</span>) =&gt;</span> {<br /> <span class="hljs-keyword">const</span> newName = prompt(<span class="hljs-string">"Enter a new name:"</span>, record.name);<br /> <span class="hljs-keyword">if</span> (newName) {<br /> record.name = newName;<br /> table.updateRecord(index, record);<br /> }<br /> }<br /> },<br /> {<br /> <span class="hljs-attr">icon</span>: <span class="hljs-string">'delete'</span>,<br /> <span class="hljs-attr">action</span>: <span class="hljs-function">(<span class="hljs-params">table, record, index</span>) =&gt;</span> {<br /> table.deleteRecord(index);<br /> }<br /> }<br /> ]<br /> }<br /> });<br /></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
189
+ <k-table id="rowControlsExample"></k-table>
190
+ <script type="module">
191
+ document.getElementById('rowControlsExample').setData({
192
+ records: contacts.slice(20, 25),
193
+ controls: {
194
+ before: [
195
+ {
196
+ html: '<span>Custom HTML</span> '
197
+ },
198
+ {
199
+ render: (table, record) => {
200
+ return `<button onclick="alert('${record.name}')">Alert</button>`;
201
+ }
202
+ }
203
+ ],
204
+ after: [
205
+ {
206
+ icon: 'edit',
207
+ action: (table, record, index) => {
208
+ const newName = prompt("Enter a new name:", record.name);
209
+ if (newName) {
210
+ record.name = newName;
211
+ table.updateRecord(index, record);
212
+ }
213
+ }
214
+ },
215
+ {
216
+ icon: 'delete',
217
+ action: (table, record, index) => {
218
+ table.deleteRecord(index);
219
+ }
220
+ }
221
+ ]
222
+ }
223
+ });
224
+ </script>
225
+
226
+
227
+ <h3 id="pagination"><a href="#pagination" class="no-link">Pagination</a></h3>
228
+ <p>The table component supports pagination. You can set the page size and navigate through pages using the provided methods.</p>
229
+ <p>There are some predefined controls that you can use directly from <code>Table.controls</code>. These controls include:</p>
230
+ <ul>
231
+ <li><code>prevPage</code>: A control to navigate to the previous page.</li>
232
+ <li><code>nextPage</code>: A control to navigate to the next page.</li>
233
+ <li><code>pageSelect</code>: A control to select a specific page.</li>
234
+ <li><code>spacer</code>: A spacer that flexes to separate the other controls to before it to the left, and after it to the far right.</li>
235
+ <li><code>pageSize</code>: A control to select the number of records per page.</li>
236
+ </ul>
237
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-table</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"paginationExample"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-table</span>&gt;</span><br /><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span>&gt;</span><span class="javascript"><br /> <span class="hljs-keyword">import</span> Table <span class="hljs-keyword">from</span> <span class="hljs-string">'../kempo/components/Table.js'</span>;<br /> <span class="hljs-keyword">const</span> $paginationExample = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'paginationExample'</span>);<br /> $paginationExample.setData({<br /> <span class="hljs-attr">records</span>: contacts,<br /> <span class="hljs-attr">controls</span>: {<br /> <span class="hljs-attr">bottom</span>: [<br /> Table.controls.prevPage,<br /> Table.controls.nextPage,<br /> Table.controls.pageSelect,<br /> Table.controls.spacer,<br /> Table.controls.pageSize<br /> ]<br /> },<br /> <span class="hljs-attr">pageSize</span>: <span class="hljs-number">10</span>,<br /> <span class="hljs-attr">pageSizeOptions</span>: [<span class="hljs-number">5</span>, <span class="hljs-number">10</span>, <span class="hljs-number">20</span>]<br /> });<br /></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
238
+ <k-table id="paginationExample"></k-table>
239
+ <script type="module">
240
+ import Table from '../kempo/components/Table.js';
241
+ const $paginationExample = document.getElementById('paginationExample');
242
+ $paginationExample.setData({
243
+ records: contacts,
244
+ controls: {
245
+ bottom: [
246
+ Table.controls.prevPage,
247
+ Table.controls.nextPage,
248
+ Table.controls.pageSelect,
249
+ Table.controls.spacer,
250
+ Table.controls.pageSize
251
+ ]
252
+ },
253
+ pageSize: 10,
254
+ pageSizeOptions: [5, 10, 20]
255
+ });
256
+ </script>
257
+
258
+ <h3 id="recordSelection"><a href="#recordSelection" class="no-link">Record Selection</a></h3>
259
+ <p>The table component supports record selection. You can enable record selection by setting the <code>enableSelection</code> property to <code>true</code>.</p>
260
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-table</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"recordSelectionExample"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">k-table</span>&gt;</span><br /><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span>&gt;</span><span class="javascript"><br /> <span class="hljs-keyword">import</span> Table <span class="hljs-keyword">from</span> <span class="hljs-string">'../kempo/components/Table.js'</span>;<br /><br /> <span class="hljs-keyword">const</span> $recordSelectionExample = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'recordSelectionExample'</span>);<br /> $recordSelectionExample.setData({<br /> <span class="hljs-attr">records</span>: contacts,<br /> <span class="hljs-attr">enableSelection</span>: <span class="hljs-literal">true</span>,<br /> <span class="hljs-attr">controls</span>: {<br /> <span class="hljs-attr">bottom</span>: [<br /> Table.controls.prevPage,<br /> Table.controls.nextPage,<br /> Table.controls.spacer,<br /> Table.controls.selectCount,<br /> Table.controls.deleteSelected<br /> ]<br /> },<br /> <span class="hljs-attr">pageSize</span>: <span class="hljs-number">10</span><br /> });<br /></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
261
+ <k-table id="recordSelectionExample"></k-table>
262
+ <script type="module">
263
+ import Table from '../kempo/components/Table.js';
264
+
265
+ const $recordSelectionExample = document.getElementById('recordSelectionExample');
266
+ $recordSelectionExample.setData({
267
+ records: contacts,
268
+ enableSelection: true,
269
+ controls: {
270
+ bottom: [
271
+ Table.controls.prevPage,
272
+ Table.controls.nextPage,
273
+ Table.controls.spacer,
274
+ Table.controls.selectCount,
275
+ Table.controls.deleteSelected
276
+ ]
277
+ },
278
+ pageSize: 10
279
+ });
280
+ </script>
281
+
282
+ <h2>JavaScript Reference</h2>
283
+ <h3 id="constructor"><a href="#constructor" class="no-link">Constructor</a></h3>
165
284
  <h6>Extends <a href="./component.html">Component</a></h6>
166
285
  <h5>
167
286
  <code>new Table()</code><br />
168
- <code>new Table(<i>&lt;Array>object</i> records)</code><br />
169
- <code>new Table(<i>&lt;Array>object</i> records, <i>&lt;Array>object</i> fields)</code>
287
+ <code>new Table(<i>&lt;Array>object</i> options)</code>
170
288
  </h5>
171
289
 
172
- <h4>Paramters</h4>
173
- <h5><code><i>&lt;Array>object</i> records</code></h5>
174
- <p>An array of objects that represent the records to be shown in the table.</p>
175
-
176
- <h5><code><i>&lt;Array>object</i> fields</code></h5>
177
- <p>An array of objects that represents the feilds of the table, each object must contain a <code>name</code> and a <code>label</code>. If this parameter is ommitted the fields will be automatically generated from the first 100 records.</p>
290
+ <h4>Parameters</h4>
291
+ <h5><code><i>object</i> options</code></h5>
292
+ <p>An object containing the initial configuration for the table. The options object can contain the following properties:</p>
293
+ <ul>
294
+ <li><code>records</code>: An array of objects representing the records to be shown in the table.</li>
295
+ <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>
296
+ <li><code>controls</code>: An object containing optional arrays of controls to be displayed before and/or after each row. Each control is defined by an icon name, a callback function, and optionally an HTML string or a render function. The <code>controls</code> object can contain the optional <code>before</code> and <code>after</code> properties, which are arrays of objects containing the <code>icon</code> (string), <code>action</code> (function), <code>html</code> (string), and <code>render</code> (function). If <code>html</code> is present, it overrides the icon and is rendered in its place. If <code>render</code> is present, it is used to render the control.</li>
297
+ <li><code>pageSize</code>: The number of records to display per page.</li>
298
+ <li><code>pageSizeOptions</code>: An array of numbers representing the available page size options.</li>
299
+ </ul>
178
300
 
179
301
  <h3 id="requirements"><a href="#requirements" class="no-link">Requirements</a></h3>
180
302
  <ul>
@@ -183,49 +305,74 @@
183
305
 
184
306
  <h3 id="properties"><a href="#properties" class="no-link">Properties</a></h3>
185
307
  <h5><code>fields<i>: &lt;Array>object</i></code></h5>
186
- <p>An array of objects containing a <code>name</code> and <code>label</code> that represent the fields to be displayed.</p>
308
+ <p>An array of objects containing a <code>name</code>, <code>label</code>, <code>renderer</code> function, and <code>calculator</code> function that represent the fields to be displayed. The <code>renderer</code> function can be used to customize the display of the field, and the <code>calculator</code> function can be used to calculate the value of the field based on other fields in the record.</p>
187
309
 
188
310
  <h5><code>records<i>: &lt;Array>object</i></code></h5>
189
311
  <p>An array of objects containing the data that will be the records of the table, where the object keys match the field names.</p>
190
312
 
191
- <h5><code><i>object</i> controls</code></h5>
192
- <p>An object containing optional arrays of controls to be displayed before and/or after each row. Each control is defined by an icon name, a callback function, and optionally an HTML string or a render function. The <code>controls</code> object can contain the optional <code>before</code> and <code>after</code> properties, which are arrays of objects containing the <code>icon</code> (string), <code>action</code> (function), <code>html</code> (string), and <code>render</code> (function). If <code>html</code> is present, it overrides the icon and is rendered in its place. If <code>render</code> is present, it is used to render the control.</p>
193
- <p>Example:</p>
194
- <pre><code class="hljs javascript">{
195
- before: [
196
- {
197
- icon: 'edit',
198
- action: (record, table) => console.log('Edit', record, table)
199
- }
200
- ],
201
- after: [
202
- {
203
- icon: 'delete',
204
- action: (record, table) => console.log('Delete', record, table)
205
- },
206
- {
207
- html: '<span>Custom HTML</span>'
208
- },
209
- {
210
- render: (record, table) => `&lt;button onclick="console.log('Rendered Action', ${record}, ${table})">Rendered Button&lt;/button>`
211
- }
212
- ]
213
- }</code></pre>
313
+ <h5><code>controls<i>: object</i></code></h5>
314
+ <p>An object containing optional arrays of controls to be displayed before and/or after each row, or above and below the table. Each control is defined by an icon name, a callback function, and optionally an HTML string or a render function. The <code>controls</code> object can contain the optional <code>before</code>, <code>after</code>, <code>top</code>, and <code>bottom</code> properties, which are arrays of objects containing the <code>icon</code> (string), <code>action</code> (function), <code>html</code> (string), and <code>render</code> (function). If <code>html</code> is present, it overrides the icon and is rendered in its place. If <code>render</code> is present, it is used to render the control. Controls in the <code>before</code> or <code>after</code> arrays receive the record and index as the 2nd and 3rd parameters in the action function and the renderer function.</p>
315
+
316
+ <h5><code>pageSize<i>: number</i></code></h5>
317
+ <p>The number of records to display per page.</p>
318
+
319
+ <h5><code>pageSizeOptions<i>: &lt;Array>number</i></code></h5>
320
+ <p>An array of numbers representing the available page size options.</p>
214
321
 
215
322
  <h3 id="methods"><a href="#methods" class="no-link">Methods</a></h3>
216
323
 
217
- <h5><code>setData(<i>&lt;Array>object</i> records, <i>&lt;Array>object</i> fields)<i>: undefined</i></code></h5>
218
- <p>Sets the records and the fields and renders the table, if no fields are provided then they will be automatically generated from the keys of the first 100 records.</p>
324
+ <h5><code>setData(<i>object</i> options)<i>: undefined</i></code></h5>
325
+ <p>Sets the records and the fields and renders the table. If no fields are provided, they will be automatically generated from the keys of the first 100 records. The options object can contain the following properties:</p>
326
+ <ul>
327
+ <li><code>records</code>: An array of objects representing the records to be shown in the table.</li>
328
+ <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>
329
+ <li><code>controls</code>: An object containing optional arrays of controls to be displayed before and/or after each row. Each control is defined by an icon name, a callback function, and optionally an HTML string or a render function. The <code>controls</code> object can contain the optional <code>before</code> and <code>after</code> properties, which are arrays of objects containing the <code>icon</code> (string), <code>action</code> (function), <code>html</code> (string), and <code>render</code> (function). If <code>html</code> is present, it overrides the icon and is rendered in its place. If <code>render</code> is present, it is used to render the control.</li>
330
+ <li><code>pageSize</code>: The number of records to display per page.</li>
331
+ <li><code>pageSizeOptions</code>: An array of numbers representing the available page size options.</li>
332
+ </ul>
219
333
 
220
334
  <h5><code>renderFields()<i>: undefined</i></code></h5>
221
- <p>Renders the fields as table headers, this is called automatically by setData, you should never have to call it.</p>
335
+ <p>Renders the fields as table headers. This is called automatically by setData, you should never have to call it.</p>
222
336
 
223
337
  <h5><code>renderRecords()<i>: undefined</i></code></h5>
224
- <p>Renders the records as table row, this is called automatically by setData, you should never have to call it.</p>
338
+ <p>Renders the records as table rows. This is called automatically by setData, you should never have to call it.</p>
339
+
340
+ <h5><code>addRecord(<i>object</i> record)<i>: undefined</i></code></h5>
341
+ <p>Adds a new record to the table.</p>
342
+
343
+ <h5><code>updateRecord(<i>number</i> index, <i>object</i> record)<i>: undefined</i></code></h5>
344
+ <p>Updates an existing record at the specified index.</p>
345
+
346
+ <h5><code>deleteRecord(<i>number</i> index)<i>: undefined</i></code></h5>
347
+ <p>Deletes a record at the specified index.</p>
348
+
349
+ <h5><code>setRecords(<i>Array</i> records)<i>: undefined</i></code></h5>
350
+ <p>Sets the records for the table and re-renders the rows.</p>
351
+
352
+ <h5><code>setPageSize(<i>number</i> pageSize)<i>: undefined</i></code></h5>
353
+ <p>Sets the number of records to display per page.</p>
354
+
355
+ <h5><code>goToPage(<i>number</i> pageNumber)<i>: undefined</i></code></h5>
356
+ <p>Navigates to the specified page number.</p>
357
+
358
+ <h5><code>getSelectedRecords()<i>: Array</i></code></h5>
359
+ <p>Returns an array of the currently selected records.</p>
360
+
361
+ <h5><code>deleteSelectedRecords()<i>: undefined</i></code></h5>
362
+ <p>Deletes all currently selected records from the table.</p>
363
+
364
+ <h5><code>selectAllOnPage()<i>: undefined</i></code></h5>
365
+ <p>Selects all the records on the current page.</p>
366
+
367
+ <h5><code>deselectAllOnPage()<i>: undefined</i></code></h5>
368
+ <p>Deselects all the records on the current page.</p>
369
+
370
+ <h5><code>allOnPageSelected()<i>: undefined</i></code></h5>
371
+ <p>Returns <code>true</code> if all the records on the current page are selected, and <code>false</code> if they are not.</p>
372
+
225
373
 
226
374
  </main>
227
375
  <div style="height: 33.333vh"></div>
228
376
  <script type="module" src="../kempo/components/Import.js"></script>
229
-
230
377
  </body>
231
378
  </html>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M440-440H200v-80h240v-240h80v240h240v80H520v240h-80v-240Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M480-160q-134 0-227-93t-93-227q0-134 93-227t227-93q69 0 132 28.5T720-690v-110h80v280H520v-80h168q-32-56-87.5-88T480-720q-100 0-170 70t-70 170q0 100 70 170t170 70q77 0 139-44t87-116h84q-28 106-114 173t-196 67Z"/></svg>