@liedekef/ftable 1.1.43 → 1.1.45

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/ftable.esm.js CHANGED
@@ -199,7 +199,7 @@ class FTableDOMHelper {
199
199
 
200
200
  if (options.attributes) {
201
201
  Object.entries(options.attributes).forEach(([key, value]) => {
202
- if (value !== '')
202
+ if (value !== null)
203
203
  element.setAttribute(key, value);
204
204
  });
205
205
  }
@@ -1064,7 +1064,10 @@ class FTableFormBuilder {
1064
1064
 
1065
1065
  let input;
1066
1066
 
1067
- if (value == null || value == undefined ) {
1067
+ if (value == undefined) {
1068
+ value = null;
1069
+ }
1070
+ if (value == null && field.defaultValue ) {
1068
1071
  value = field.defaultValue;
1069
1072
  }
1070
1073
  // Auto-detect select type if options are provided
@@ -1126,10 +1129,16 @@ class FTableFormBuilder {
1126
1129
  // Otherwise, fallback to default
1127
1130
  else {
1128
1131
  container.appendChild(input);
1132
+ if (input.datalistElement && input.datalistElement instanceof Node) {
1133
+ container.appendChild(input.datalistElement);
1134
+ }
1129
1135
  }
1130
1136
  } else {
1131
1137
  // No custom input function — just add the default input
1132
1138
  container.appendChild(input);
1139
+ if (input.datalistElement && input.datalistElement instanceof Node) {
1140
+ container.appendChild(input.datalistElement);
1141
+ }
1133
1142
  }
1134
1143
 
1135
1144
  // Add explanation if provided
@@ -1155,7 +1164,7 @@ class FTableFormBuilder {
1155
1164
  attributes: {
1156
1165
  id: 'real-' + fieldName,
1157
1166
  type: 'hidden',
1158
- value: value || '',
1167
+ value: value,
1159
1168
  name: fieldName
1160
1169
  }
1161
1170
  });
@@ -1165,7 +1174,7 @@ class FTableFormBuilder {
1165
1174
  id: `Edit-${fieldName}`,
1166
1175
  type: 'text',
1167
1176
  'data-date': value,
1168
- placeholder: field.placeholder || '',
1177
+ placeholder: field.placeholder || null,
1169
1178
  readOnly: true
1170
1179
  };
1171
1180
  // Set any additional attributes
@@ -1219,8 +1228,8 @@ class FTableFormBuilder {
1219
1228
  const attributes = {
1220
1229
  type: inputType,
1221
1230
  id: `Edit-${fieldName}`,
1222
- placeholder: field.placeholder || '',
1223
- value: value || ''
1231
+ placeholder: field.placeholder || null,
1232
+ value: value
1224
1233
  };
1225
1234
 
1226
1235
  // extra check for name and multiple
@@ -1241,7 +1250,7 @@ class FTableFormBuilder {
1241
1250
  attributes.name = name;
1242
1251
 
1243
1252
  const input = FTableDOMHelper.create('input', {
1244
- className: field.inputClass || '',
1253
+ className: field.inputClass || null,
1245
1254
  attributes: attributes
1246
1255
  });
1247
1256
 
@@ -1263,8 +1272,8 @@ class FTableFormBuilder {
1263
1272
  type: 'text',
1264
1273
  name: fieldName,
1265
1274
  id: `Edit-${fieldName}`,
1266
- placeholder: field.placeholder || '',
1267
- value: value || '',
1275
+ placeholder: field.placeholder || null,
1276
+ value: value,
1268
1277
  list: `${fieldName}-datalist`
1269
1278
  };
1270
1279
 
@@ -1275,7 +1284,7 @@ class FTableFormBuilder {
1275
1284
  }
1276
1285
 
1277
1286
  const input = FTableDOMHelper.create('input', {
1278
- className: field.inputClass || '',
1287
+ className: field.inputClass || null,
1279
1288
  attributes: attributes
1280
1289
  });
1281
1290
 
@@ -1291,10 +1300,7 @@ class FTableFormBuilder {
1291
1300
  this.populateDatalistOptions(datalist, field.options);
1292
1301
  }
1293
1302
 
1294
- // Append datalist to the document body or form
1295
- document.body.appendChild(datalist);
1296
-
1297
- // Store reference for cleanup
1303
+ // Store reference
1298
1304
  input.datalistElement = datalist;
1299
1305
 
1300
1306
  return input;
@@ -1329,7 +1335,7 @@ class FTableFormBuilder {
1329
1335
  type: 'hidden',
1330
1336
  name: fieldName,
1331
1337
  id: `Edit-${fieldName}`,
1332
- value: value || ''
1338
+ value: value
1333
1339
  };
1334
1340
 
1335
1341
  // Apply inputAttributes
@@ -1345,7 +1351,7 @@ class FTableFormBuilder {
1345
1351
  const attributes = {
1346
1352
  name: fieldName,
1347
1353
  id: `Edit-${fieldName}`,
1348
- placeholder: field.placeholder || ''
1354
+ placeholder: field.placeholder || null
1349
1355
  };
1350
1356
 
1351
1357
  // Apply inputAttributes
@@ -1355,9 +1361,9 @@ class FTableFormBuilder {
1355
1361
  }
1356
1362
 
1357
1363
  const textarea = FTableDOMHelper.create('textarea', {
1358
- className: field.inputClass || '',
1364
+ className: field.inputClass || null,
1359
1365
  attributes: attributes,
1360
- value: value || ''
1366
+ value: value
1361
1367
  });
1362
1368
  return textarea;
1363
1369
  }
@@ -1386,7 +1392,7 @@ class FTableFormBuilder {
1386
1392
  attributes.name = name;
1387
1393
 
1388
1394
  const select = FTableDOMHelper.create('select', {
1389
- className: field.inputClass || '',
1395
+ className: field.inputClass || null,
1390
1396
  attributes: attributes
1391
1397
  });
1392
1398
 
@@ -1431,7 +1437,7 @@ class FTableFormBuilder {
1431
1437
 
1432
1438
  const radio = FTableDOMHelper.create('input', {
1433
1439
  attributes: radioAttributes,
1434
- className: field.inputClass || '',
1440
+ className: field.inputClass || null,
1435
1441
  parent: radioWrapper
1436
1442
  });
1437
1443
 
@@ -1565,11 +1571,10 @@ class FTableFormBuilder {
1565
1571
  }
1566
1572
  attributes.name = name;
1567
1573
 
1568
- const input = FTableDOMHelper.create('input', {
1569
- className: field.inputClass || '',
1574
+ return FTableDOMHelper.create('input', {
1575
+ className: field.inputClass || null,
1570
1576
  attributes: attributes
1571
1577
  });
1572
- return input;
1573
1578
  }
1574
1579
  }
1575
1580
 
package/ftable.js CHANGED
@@ -200,7 +200,7 @@ class FTableDOMHelper {
200
200
 
201
201
  if (options.attributes) {
202
202
  Object.entries(options.attributes).forEach(([key, value]) => {
203
- if (value !== '')
203
+ if (value !== null)
204
204
  element.setAttribute(key, value);
205
205
  });
206
206
  }
@@ -1065,7 +1065,10 @@ class FTableFormBuilder {
1065
1065
 
1066
1066
  let input;
1067
1067
 
1068
- if (value == null || value == undefined ) {
1068
+ if (value == undefined) {
1069
+ value = null;
1070
+ }
1071
+ if (value == null && field.defaultValue ) {
1069
1072
  value = field.defaultValue;
1070
1073
  }
1071
1074
  // Auto-detect select type if options are provided
@@ -1127,10 +1130,16 @@ class FTableFormBuilder {
1127
1130
  // Otherwise, fallback to default
1128
1131
  else {
1129
1132
  container.appendChild(input);
1133
+ if (input.datalistElement && input.datalistElement instanceof Node) {
1134
+ container.appendChild(input.datalistElement);
1135
+ }
1130
1136
  }
1131
1137
  } else {
1132
1138
  // No custom input function — just add the default input
1133
1139
  container.appendChild(input);
1140
+ if (input.datalistElement && input.datalistElement instanceof Node) {
1141
+ container.appendChild(input.datalistElement);
1142
+ }
1134
1143
  }
1135
1144
 
1136
1145
  // Add explanation if provided
@@ -1156,7 +1165,7 @@ class FTableFormBuilder {
1156
1165
  attributes: {
1157
1166
  id: 'real-' + fieldName,
1158
1167
  type: 'hidden',
1159
- value: value || '',
1168
+ value: value,
1160
1169
  name: fieldName
1161
1170
  }
1162
1171
  });
@@ -1166,7 +1175,7 @@ class FTableFormBuilder {
1166
1175
  id: `Edit-${fieldName}`,
1167
1176
  type: 'text',
1168
1177
  'data-date': value,
1169
- placeholder: field.placeholder || '',
1178
+ placeholder: field.placeholder || null,
1170
1179
  readOnly: true
1171
1180
  };
1172
1181
  // Set any additional attributes
@@ -1220,8 +1229,8 @@ class FTableFormBuilder {
1220
1229
  const attributes = {
1221
1230
  type: inputType,
1222
1231
  id: `Edit-${fieldName}`,
1223
- placeholder: field.placeholder || '',
1224
- value: value || ''
1232
+ placeholder: field.placeholder || null,
1233
+ value: value
1225
1234
  };
1226
1235
 
1227
1236
  // extra check for name and multiple
@@ -1242,7 +1251,7 @@ class FTableFormBuilder {
1242
1251
  attributes.name = name;
1243
1252
 
1244
1253
  const input = FTableDOMHelper.create('input', {
1245
- className: field.inputClass || '',
1254
+ className: field.inputClass || null,
1246
1255
  attributes: attributes
1247
1256
  });
1248
1257
 
@@ -1264,8 +1273,8 @@ class FTableFormBuilder {
1264
1273
  type: 'text',
1265
1274
  name: fieldName,
1266
1275
  id: `Edit-${fieldName}`,
1267
- placeholder: field.placeholder || '',
1268
- value: value || '',
1276
+ placeholder: field.placeholder || null,
1277
+ value: value,
1269
1278
  list: `${fieldName}-datalist`
1270
1279
  };
1271
1280
 
@@ -1276,7 +1285,7 @@ class FTableFormBuilder {
1276
1285
  }
1277
1286
 
1278
1287
  const input = FTableDOMHelper.create('input', {
1279
- className: field.inputClass || '',
1288
+ className: field.inputClass || null,
1280
1289
  attributes: attributes
1281
1290
  });
1282
1291
 
@@ -1292,10 +1301,7 @@ class FTableFormBuilder {
1292
1301
  this.populateDatalistOptions(datalist, field.options);
1293
1302
  }
1294
1303
 
1295
- // Append datalist to the document body or form
1296
- document.body.appendChild(datalist);
1297
-
1298
- // Store reference for cleanup
1304
+ // Store reference
1299
1305
  input.datalistElement = datalist;
1300
1306
 
1301
1307
  return input;
@@ -1330,7 +1336,7 @@ class FTableFormBuilder {
1330
1336
  type: 'hidden',
1331
1337
  name: fieldName,
1332
1338
  id: `Edit-${fieldName}`,
1333
- value: value || ''
1339
+ value: value
1334
1340
  };
1335
1341
 
1336
1342
  // Apply inputAttributes
@@ -1346,7 +1352,7 @@ class FTableFormBuilder {
1346
1352
  const attributes = {
1347
1353
  name: fieldName,
1348
1354
  id: `Edit-${fieldName}`,
1349
- placeholder: field.placeholder || ''
1355
+ placeholder: field.placeholder || null
1350
1356
  };
1351
1357
 
1352
1358
  // Apply inputAttributes
@@ -1356,9 +1362,9 @@ class FTableFormBuilder {
1356
1362
  }
1357
1363
 
1358
1364
  const textarea = FTableDOMHelper.create('textarea', {
1359
- className: field.inputClass || '',
1365
+ className: field.inputClass || null,
1360
1366
  attributes: attributes,
1361
- value: value || ''
1367
+ value: value
1362
1368
  });
1363
1369
  return textarea;
1364
1370
  }
@@ -1387,7 +1393,7 @@ class FTableFormBuilder {
1387
1393
  attributes.name = name;
1388
1394
 
1389
1395
  const select = FTableDOMHelper.create('select', {
1390
- className: field.inputClass || '',
1396
+ className: field.inputClass || null,
1391
1397
  attributes: attributes
1392
1398
  });
1393
1399
 
@@ -1432,7 +1438,7 @@ class FTableFormBuilder {
1432
1438
 
1433
1439
  const radio = FTableDOMHelper.create('input', {
1434
1440
  attributes: radioAttributes,
1435
- className: field.inputClass || '',
1441
+ className: field.inputClass || null,
1436
1442
  parent: radioWrapper
1437
1443
  });
1438
1444
 
@@ -1566,11 +1572,10 @@ class FTableFormBuilder {
1566
1572
  }
1567
1573
  attributes.name = name;
1568
1574
 
1569
- const input = FTableDOMHelper.create('input', {
1570
- className: field.inputClass || '',
1575
+ return FTableDOMHelper.create('input', {
1576
+ className: field.inputClass || null,
1571
1577
  attributes: attributes
1572
1578
  });
1573
- return input;
1574
1579
  }
1575
1580
  }
1576
1581
 
package/ftable.min.js CHANGED
@@ -1,4 +1,4 @@
1
- (e=>{let s={serverCommunicationError:"An error occurred while communicating to the server.",loadingMessage:"Loading records...",noDataAvailable:"No data available!",addNewRecord:"Add new record",editRecord:"Edit record",areYouSure:"Are you sure?",deleteConfirmation:"This record will be deleted. Are you sure?",yes:"Yes",no:"No",save:"Save",saving:"Saving",cancel:"Cancel",deleteText:"Delete",deleting:"Deleting",error:"An error has occured",close:"Close",cannotLoadOptionsFor:"Cannot load options for field {0}!",pagingInfo:"Showing {0}-{1} of {2}",canNotDeletedRecords:"Can not delete {0} of {1} records!",deleteProgress:"Deleting {0} of {1} records, processing...",pageSizeChangeLabel:"Row count",gotoPageLabel:"Go to page",sortingInfoPrefix:"Sorting applied: ",sortingInfoSuffix:"",ascending:"Ascending",descending:"Descending",sortingInfoNone:"No sorting applied",resetSorting:"Reset sorting",csvExport:"CSV",printTable:"🖨️ Print",cloneRecord:"Clone Record",resetTable:"Reset table",resetTableConfirm:"This will reset all columns, pagesize, sorting to their defaults. Do you want to continue?",resetSearch:"Reset"};class t{constructor(){this.cache=new Map,this.pendingRequests=new Map}generateKey(e,t){return e+"?"+Object.keys(t||{}).sort().map(e=>e+"="+t[e]).join("&")}get(e,t){e=this.generateKey(e,t);return this.cache.get(e)}set(e,t,s){e=this.generateKey(e,t);this.cache.set(e,s)}clear(e=null,t=null){if(e)if(t){t=this.generateKey(e,t);this.cache.delete(t)}else{var s,a=e.split("?")[0];for([s]of this.cache)s.startsWith(a)&&this.cache.delete(s)}else this.cache.clear()}async getOrCreate(e,t,s){let a=this.generateKey(e,t);e=this.cache.get(a);return e||(this.pendingRequests.has(a)?this.pendingRequests.get(a):(t=(async()=>{try{var e=await s();return this.cache.set(a,e),e}finally{this.pendingRequests.delete(a)}})(),this.pendingRequests.set(a,t),t))}size(){return this.cache.size}}class a{static LOG_LEVELS={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};constructor(e=a.LOG_LEVELS.WARN){this.level=e}log(t,e){var s;!window.console||t<this.level||(s=Object.keys(a.LOG_LEVELS).find(e=>a.LOG_LEVELS[e]===t),console.log(`fTable ${s}: `+e))}debug(e){this.log(a.LOG_LEVELS.DEBUG,e)}info(e){this.log(a.LOG_LEVELS.INFO,e)}warn(e){this.log(a.LOG_LEVELS.WARN,e)}error(e){this.log(a.LOG_LEVELS.ERROR,e)}}class u{static create(e,t={}){let s=document.createElement(e);return t.className&&(s.className=t.className),t.style&&(s.style.cssText=t.style),t.attributes&&Object.entries(t.attributes).forEach(([e,t])=>{""!==t&&s.setAttribute(e,t)}),t.text&&(s.textContent=t.text),t.html&&(s.innerHTML=t.html),t.parent&&t.parent.appendChild(s),s}static find(e,t=document){return t.querySelector(e)}static findAll(e,t=document){return Array.from(t.querySelectorAll(e))}static addClass(e,t){e.classList.add(...t.split(" "))}static removeClass(e,t){e.classList.remove(...t.split(" "))}static toggleClass(e,t){e.classList.toggle(t)}static show(e){e.style.display=""}static hide(e){e.style.display="none"}static escapeHtml(e){if(!e)return e;let t={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#039;"};return e.replace(/[&<>"']/g,e=>t[e])}}class l{static async request(e,t={}){var s={method:"GET",headers:{}},a={...s,...t};t.headers&&(a.headers={...s.headers,...t.headers});try{var i=await fetch(e,a);if(401===i.status)throw new Error("Unauthorized");if(!i.ok)throw new Error("HTTP error! status: "+i.status);var o=i.headers.get("content-type");if(o&&o.includes("application/json"))return await i.json();var r=await i.text();try{return JSON.parse(r)}catch{return{Result:"OK",Message:r}}}catch(e){throw e}}static async get(e,t={}){let a=new URL(e,window.location.href);return Object.entries(t).forEach(([e,s])=>{if(null!=s)if(Array.isArray(s)){let t=e.replace(/\[\]$/,"")+"[]";s.forEach(e=>{null!=e&&a.searchParams.append(t,e)})}else a.searchParams.append(e,s)}),this.request(a.toString(),{method:"GET",headers:{"Content-Type":"application/x-www-form-urlencoded"}})}static async post(e,t={}){e=new URL(e,window.location.href);let a=new FormData;return Object.entries(t).forEach(([e,s])=>{if(null!=s)if(Array.isArray(s)){let t=e.replace(/\[\]$/,"")+"[]";s.forEach(e=>{null!=e&&a.append(t,e)})}else a.append(e,s)}),this.request(e.toString(),{method:"POST",body:a})}}class i{constructor(e,t="localStorage"){this.prefix=e,this.method=t}set(e,t){var s,e=""+this.prefix+e;"localStorage"===this.method?localStorage.setItem(e,t):((s=new Date).setDate(s.getDate()+30),document.cookie=e+`=${t}; expires=${s.toUTCString()}; path=/`)}get(e){e=""+this.prefix+e;if("localStorage"===this.method)return localStorage.getItem(e);var t,s=e+"=";for(t of decodeURIComponent(document.cookie).split(";")){for(;" "===t.charAt(0);)t=t.substring(1);if(0===t.indexOf(s))return t.substring(s.length,t.length)}return null}remove(e){e=""+this.prefix+e;"localStorage"===this.method?localStorage.removeItem(e):document.cookie=e+"=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"}generatePrefix(e,t){e=e?e+"#":"";return"ftable#"+(t=>{let s=0;if(0!==t.length)for(let e=0;e<t.length;e++){var a=t.charCodeAt(e);s=(s<<5)-s+a,s&=s}return s})(e+=t.join("$")+"#c"+t.length)}}class o{constructor(e={}){this.options={title:"Modal",content:"",buttons:[],className:"ftable-modal",parent:document.body,...e},this.overlay=null,this.modal=null,this.isOpen=!1}create(){this.overlay=u.create("div",{className:"ftable-modal-overlay",parent:this.options.parent}),this.modal=u.create("div",{className:"ftable-modal "+this.options.className,parent:this.overlay});u.create("h2",{className:"ftable-modal-header",text:this.options.title,parent:this.modal});u.create("span",{className:"ftable-modal-close",html:"&times;",parent:this.modal}).addEventListener("click",()=>this.close());var e=u.create("div",{className:"ftable-modal-body",parent:this.modal});if("string"==typeof this.options.content?e.innerHTML=this.options.content:e.appendChild(this.options.content),0<this.options.buttons.length){let s=u.create("div",{className:"ftable-modal-footer",parent:this.modal});this.options.buttons.forEach(e=>{var t=u.create("button",{className:"ftable-dialog-button "+(e.className||""),html:`<span>${e.text}</span>`,parent:s});e.onClick&&(t._originalOnClick=e.onClick,t.addEventListener("click",this._createWrappedClickHandler(t)))})}return this.options.closeOnOverlayClick&&this.overlay.addEventListener("click",e=>{e.target===this.overlay&&this.close()}),this.hide(),this}show(){return this.modal||this.create(),this.overlay.style.display="flex",this.isOpen=!0,this.modal.querySelectorAll(".ftable-dialog-button").forEach(e=>{e.disabled=!1}),this}hide(){return this.overlay&&(this.overlay.style.display="none"),this.isOpen=!1,this}close(){return this.hide(),this.options.onClose&&this.options.onClose(),this}destroy(){return this.overlay&&this.overlay.remove(),this.isOpen=!1,this}setContent(e){this.options.content=e;var t=this.modal.querySelector(".ftable-modal-body");t&&(t.innerHTML="","string"==typeof e?t.innerHTML=e:t.appendChild(e))}_createWrappedClickHandler(a){return async e=>{a.disabled=!0;try{var t,s=a._originalOnClick;"function"==typeof s&&(t=s.call(a,e))instanceof Promise&&await t}catch(e){console.error("Modal button action failed:",e)}finally{a.disabled=!1}}}}class r{constructor(e){this.options=e,this.dependencies=new Map,this.optionsCache=new t,this.originalFieldOptions=new Map,this.resolvedFieldOptions=new Map,Object.keys(this.options.fields||{}).forEach(e=>{this.resolvedFieldOptions.set(e,{})}),Object.entries(this.options.fields).forEach(([e,t])=>{this.originalFieldOptions.set(e,t.options)})}async getFieldOptions(t,s="table",e={}){var a=this.options.fields[t],i=this.originalFieldOptions.get(t);if(!i)return null;var o=this.shouldForceRefreshForContext(a,s,e),r=this.generateOptionsCacheKey(s,e);if(!o&&!e.forceRefresh){var n=this.resolvedFieldOptions.get(t)[r];if(n)return n}try{var l={...a,options:i},c=await this.resolveOptions(l,{...e},s,o);return this.resolvedFieldOptions.get(t)[r]=c}catch(e){return console.error(`Failed to resolve options for ${t} (${s}):`,e),i}}clearResolvedOptions(e=null,s=null){e?this.resolvedFieldOptions.has(e)&&(s?this.resolvedFieldOptions.get(e)[s]=null:this.resolvedFieldOptions.set(e,{table:null,create:null,edit:null})):s?this.resolvedFieldOptions.forEach((e,t)=>{this.resolvedFieldOptions.get(t)[s]=null}):this.resolvedFieldOptions.forEach((e,t)=>{this.resolvedFieldOptions.set(t,{table:null,create:null,edit:null})})}shouldForceRefreshForContext(e,t,s){return!!e.noCache&&("boolean"==typeof e.noCache?e.noCache:"function"==typeof e.noCache?e.noCache({context:t,...s}):"object"==typeof e.noCache&&!0===e.noCache[t])}generateOptionsCacheKey(e,t){let s=[e];return t.dependedValues&&Object.keys(t.dependedValues).sort().forEach(e=>{s.push(e+"="+t.dependedValues[e])}),s.join("|")}shouldIncludeField(e,t){return"create"===t?!1!==e.create&&!(!0===e.key&&!0!==e.create):"edit"!==t||!1!==e.edit}createFieldContainer(e,t,s,a){var i=u.create("div",{className:"hidden"!=t.type?"ftable-input-field-container":"",attributes:{id:"ftable-input-field-container-div-"+e}}),t=("hidden"!=t.type&&u.create("div",{className:"ftable-input-label",text:t.inputTitle||t.title,parent:i}),this.createInput(e,t,s[e],a));return i.appendChild(t),i}async createForm(e="create",t={}){this.currentFormRecord=t;var s,a,i,o,r=u.create("form",{className:`ftable-dialog-form ftable-${e}-form`});this.buildDependencyMap();for([s,a]of Object.entries(this.options.fields))this.shouldIncludeField(a,e)&&(i={...a},a.dependsOn?i.options=a.options:(o=await this.getFieldOptions(s,e,{record:t,source:e}),i.options=o),o=this.createFieldContainer(s,i,t,e),r.appendChild(o));return this.setupDependencyListeners(r),r}shouldResolveOptions(e){return e&&("function"==typeof e||"string"==typeof e)&&!Array.isArray(e)&&!("object"==typeof e&&!Array.isArray(e)&&0<Object.keys(e).length)}buildDependencyMap(){this.dependencies.clear(),Object.entries(this.options.fields).forEach(([t,s])=>{if(s.dependsOn){let e;"string"==typeof s.dependsOn&&(e=s.dependsOn.split(",").map(e=>e.trim()).filter(e=>e)).forEach(e=>{this.dependencies.has(e)||this.dependencies.set(e,[]),this.dependencies.get(e).push(t)})}})}setupDependencyListeners(s){Array.from(this.dependencies.keys()).forEach(e=>{var t=s.querySelector(`[name="${e}"]`);t&&t.addEventListener("change",()=>{this.handleDependencyChange(s,e)})}),this.handleDependencyChange(s)}async resolveOptions(e,t={},s="",a=!1){if(!e.options)return[];if(Array.isArray(e.options)||"object"==typeof e.options)return e.options;let i;t={...t,source:s,clearCache:()=>{a=!0,this.updateFieldCacheSetting(e,s,!0)}};if("function"==typeof e.options)i=await e.options(t);else{if("string"!=typeof e.options)return[];i=e.options}t=i&&"object"==typeof i&&i.url;let o=t?i.url:i;if(a=t&&void 0!==i.noCache?i.noCache:a,"string"!=typeof o)return[];if(!a)return this.optionsCache.getOrCreate(o,{},async()=>{try{var e=this.options.forcePost?await l.post(o):await l.get(o);return e.Options||e.options||e||[]}catch(e){return console.error(`Failed to load options from ${o}:`,e),[]}});try{var r=this.options.forcePost?await l.post(o):await l.get(o);return r.Options||r.options||r||[]}catch(e){return console.error(`Failed to load options from ${o}:`,e),[]}}updateFieldCacheSetting(e,t,s){e.noCache?"boolean"==typeof e.noCache?e.noCache={table:e.noCache,create:e.noCache,edit:e.noCache,[t]:s}:"object"==typeof e.noCache&&(e.noCache[t]=s):e.noCache={[t]:s}}clearOptionsCache(e=null,t=null){this.optionsCache.clear(e,t)}getFormValues(e){var t={},s=e.elements;for(let e=0;e<s.length;e++){var a=s[e],i=a.name;if(i&&!a.disabled)switch(a.type){case"checkbox":t[i]=a.checked?a.value||"1":"0";break;case"radio":a.checked&&(t[i]=a.value);break;case"select-multiple":t[i]=Array.from(a.selectedOptions).map(e=>e.value);break;default:t[i]=a.value}}return t}async handleDependencyChange(e,s=""){var a,i,o=this.getFormValues(e),r=e.classList.contains("ftable-create-form")?"create":"edit",n=this.currentFormRecord||{},l={record:n,source:r,form:e,dependedValues:o};for([a,i]of Object.entries(this.options.fields))if(i.dependsOn){if(""!==s)if(!i.dependsOn.split(",").map(e=>e.trim()).filter(e=>e).includes(s))continue;let t=e.querySelector(`[name="${a}"]`);if(t&&this.shouldIncludeField(i,r))try{"SELECT"===t.tagName?t.innerHTML='<option value="">Loading...</option>':"INPUT"===t.tagName&&t.list&&(c=document.getElementById(t.list.id))&&(c.innerHTML="");var c,d=t.value||n[a]||"",h={...l,dependsOnField:i.dependsOn,dependsOnValue:o[i.dependsOn]},p=await this.getFieldOptions(a,r,h);"SELECT"===t.tagName?this.populateSelectOptions(t,p,d):"INPUT"===t.tagName&&t.list&&(this.populateDatalistOptions(t.list,p),d)&&(t.value=d),setTimeout(()=>{t.dispatchEvent(new Event("change",{bubbles:!0}))},0)}catch(e){console.error(`Error loading options for ${a}:`,e),"SELECT"===t.tagName&&(t.innerHTML='<option value="">Error</option>')}}}parseInputAttributes(e){if("string"!=typeof e)return e||{};for(var t={},s=/(\w+)(?:=("[^"]*"|'[^']*'|\S+))?/g;null!==(i=s.exec(e));){var a=i[1],i=i[2]?i[2].replace(/^["']|["']$/g,""):"";t[a]=""===i?"true":i}return t}createInput(e,t,s,a){var i=u.create("div",{className:`ftable-input ftable-${t.type||"text"}-input`});let o;switch(null==s&&(s=t.defaultValue),!t.type&&t.options&&(t.type="select"),t.type){case"hidden":o=this.createHiddenInput(e,t,s);break;case"textarea":o=this.createTextarea(e,t,s);break;case"select":o=this.createSelect(e,t,s);break;case"checkbox":o=this.createCheckbox(e,t,s);break;case"radio":o=this.createRadioGroup(e,t,s);break;case"datalist":o=this.createDatalistInput(e,t,s);break;case"file":o=this.createFileInput(e,t,s);break;case"date":case"datetime":case"datetime-local":o=this.createDateInput(e,t,s);break;default:o=this.createTypedInput(e,t,s)}return"function"==typeof t.input?(a={field:t,record:this.currentFormRecord,inputField:o,formType:a},"string"==typeof(a=t.input(a))?i.innerHTML=a:a instanceof Node?i.appendChild(a):i.appendChild(o)):i.appendChild(o),t.explain&&u.create("div",{className:"ftable-field-explain",html:`<small>${t.explain}</small>`,parent:i}),i}createDateInput(s,a,i){if("undefined"==typeof FDatepicker)return createTypedInput(s,a,i);{let e=a.dateFormat||this.options.defaultDateFormat;var o,r=document.createElement("div"),n=u.create("input",{attributes:{id:"real-"+s,type:"hidden",value:i||"",name:s}}),i={id:"Edit-"+s,type:"text","data-date":i,placeholder:a.placeholder||"",readOnly:!0};a.inputAttributes&&(o=this.parseInputAttributes(a.inputAttributes),Object.assign(i,o));let t=u.create("input",{className:a.inputClass||"datepicker-input",attributes:i});switch(r.appendChild(n),r.appendChild(t),a.type){case"date":setTimeout(()=>{new FDatepicker(t,{format:e,altField:"real-"+s,altFormat:"Y-m-d"})},0);break;case"datetime":case"datetime-local":setTimeout(()=>{new FDatepicker(t,{format:e,timepicker:!0,altField:"real-"+s,altFormat:"Y-m-d H:i:00"})},0)}return r}}createTypedInput(e,t,s){var a,s={type:t.type||"text",id:"Edit-"+e,placeholder:t.placeholder||"",value:s||""};let i=e,o=(t.inputAttributes&&(a=this.parseInputAttributes(t.inputAttributes),Object.assign(s,a),void 0!==a.multiple&&!1!==a.multiple)&&(i=e+"[]"),s.name=i,u.create("input",{className:t.inputClass||"",attributes:s}));return o.addEventListener("keypress",e=>{if(13===(e.keyCode||e.which))return e.preventDefault(),o.dispatchEvent(new Event("change",{bubbles:!0})),!1}),o}createDatalistInput(e,t,s){var s={type:"text",name:e,id:"Edit-"+e,placeholder:t.placeholder||"",value:s||"",list:e+"-datalist"},a=(t.inputAttributes&&(a=this.parseInputAttributes(t.inputAttributes),Object.assign(s,a)),u.create("input",{className:t.inputClass||"",attributes:s})),s=u.create("datalist",{attributes:{id:e+"-datalist"}});return t.options&&this.populateDatalistOptions(s,t.options),document.body.appendChild(s),a.datalistElement=s,a}populateDatalistOptions(s,e){s.innerHTML="",Array.isArray(e)?e.forEach(e=>{u.create("option",{attributes:{value:e.Value||e.value||e},text:e.DisplayText||e.text||e,parent:s})}):"object"==typeof e&&Object.entries(e).forEach(([e,t])=>{u.create("option",{attributes:{value:e},text:t,parent:s})})}createHiddenInput(e,t,s){e={type:"hidden",name:e,id:"Edit-"+e,value:s||""};return t.inputAttributes&&(s=this.parseInputAttributes(t.inputAttributes),Object.assign(e,s)),u.create("input",{attributes:e})}createTextarea(e,t,s){var e={name:e,id:"Edit-"+e,placeholder:t.placeholder||""},a=(t.inputAttributes&&(a=this.parseInputAttributes(t.inputAttributes),Object.assign(e,a)),u.create("textarea",{className:t.inputClass||"",attributes:e,value:s||""}));return a}createSelect(e,t,s){var a={name:e,id:"Edit-"+e};let i=e;t.inputAttributes&&(o=this.parseInputAttributes(t.inputAttributes),Object.assign(a,o),void 0!==o.multiple&&!1!==o.multiple)&&(i=e+"[]"),a.name=i;var o=u.create("select",{className:t.inputClass||"",attributes:a});return t.options&&this.populateSelectOptions(o,t.options,s),o}createRadioGroup(o,r,n){let l=u.create("div",{className:"ftable-radio-group"});return r.options&&(Array.isArray(r.options)?r.options:"object"==typeof r.options?Object.entries(r.options).map(([e,t])=>({Value:e,DisplayText:t})):[]).forEach((e,t)=>{var s=u.create("div",{className:"ftable-radio-wrapper",parent:l}),a=o+"_"+t,i={type:"radio",name:o,id:a,value:e.Value||e.value||e},t=(r.required&&0===t&&(i.required="required"),r.disabled&&(i.disabled="disabled"),r.inputAttributes&&(t=this.parseInputAttributes(r.inputAttributes),Object.assign(i,t)),u.create("input",{attributes:i,className:r.inputClass||"",parent:s}));i.value===n&&(t.checked=!0),u.create("label",{attributes:{for:a},text:e.DisplayText||e.text||e,parent:s})}),l}createCheckbox(e,t,s){var a=u.create("div",{className:"ftable-yesno-check-wrapper"}),s=[1,"1",!0,"true"].includes(s);let i=this.options.messages.no,o=this.options.messages.yes;return t.values&&"object"==typeof t.values&&(void 0!==t.values[0]&&(i=t.values[0]),void 0!==t.values[1])&&(o=t.values[1]),u.create("input",{className:["ftable-yesno-check-input",t.inputClass||""].filter(Boolean).join(" "),attributes:{type:"checkbox",name:e,id:"Edit-"+e,value:"1"},parent:a}).checked=s,t.label?u.create("label",{className:"ftable-yesno-check-fixedlabel",attributes:{for:"Edit-"+e},text:t.label,parent:a}):u.create("label",{className:"ftable-yesno-check-text",attributes:{for:"Edit-"+e,"data-yes":o,"data-no":i},parent:a}),a}populateSelectOptions(a,e,i){a.innerHTML="",Array.isArray(e)?e.forEach(e=>{var t=void 0!==e.Value?e.Value:void 0!==e.value?e.value:e;let s=u.create("option",{attributes:{value:t},text:e.DisplayText||e.text||e,parent:a});e.Data&&"object"==typeof e.Data&&Object.entries(e.Data).forEach(([e,t])=>{s.setAttribute("data-"+e,t)}),s.value==i&&(s.selected=!0)}):"object"==typeof e&&Object.entries(e).forEach(([e,t])=>{t=u.create("option",{attributes:{value:e},text:t,parent:a});e==i&&(t.selected=!0)})}createFileInput(e,t,s){var a,i={type:"file",id:"Edit-"+e};let o=e;return t.inputAttributes&&(a=this.parseInputAttributes(t.inputAttributes),Object.assign(i,a),void 0!==a.multiple&&!1!==a.multiple)&&(o=e+"[]"),i.name=o,u.create("input",{className:t.inputClass||"",attributes:i})}}class n extends class{constructor(){this.events={}}on(e,t){return this.events[e]||(this.events[e]=[]),this.events[e].push(t),this}once(t,s){let a=(...e)=>{this.off(t,a),s.apply(this,e)};return a.fn=s,this.on(t,a),this}emit(e,t={}){return this.events[e]&&this.events[e].forEach(e=>e(t)),this}off(e,t){return this.events[e]&&(this.events[e]=this.events[e].filter(e=>e!==t)),this}}{constructor(e,t={}){if(super(),this.element="string"==typeof e?document.querySelector(e):e,this.element){if(this.element.ftableInstance)return this.element.ftableInstance;this.options=this.mergeOptions(t),this.verifyOptions(),this.logger=new a(this.options.logLevel),this.userPrefs=new i("",this.options.saveUserPreferencesMethod),this.formBuilder=new r(this.options,this),this.state={records:[],totalRecordCount:0,currentPage:1,isLoading:!1,selectedRecords:new Set,sorting:[],searchQueries:{}},this.elements={},this.modals={},this.searchTimeout=null,this.lastSortEvent=null,this._recalculatedOnce=!1,this.shiftKeyDown=!1,this.lastSelectedRow=null,(this.element.ftableInstance=this).init()}}mergeOptions(e){var t={tableId:void 0,logLevel:a.LOG_LEVELS.WARN,actions:{},fields:{},forcePost:!0,closeOnOverlayClick:!0,animationsEnabled:!0,loadingAnimationDelay:1e3,defaultDateLocale:"",defaultDateFormat:"Y-m-d",saveUserPreferences:!0,saveUserPreferencesMethod:"localStorage",defaultSorting:"",tableReset:!1,paging:!1,pageList:"normal",pageSize:10,pageSizes:[10,25,50,100,250,500],gotoPageArea:"combobox",sorting:!1,multiSorting:!1,multiSortingCtrlKey:!0,selecting:!1,multiselect:!1,openChildAsAccordion:!1,toolbarsearch:!1,toolbarreset:!0,searchDebounceMs:300,listCache:3e4,messages:{...s}};return this.deepMerge(t,e)}deepMerge(e,t){var s,a={...e};for(s in t)t[s]&&"object"==typeof t[s]&&!Array.isArray(t[s])?a[s]=this.deepMerge(a[s]||{},t[s]):a[s]=t[s];return a}verifyOptions(){this.options.pageSize&&!this.options.pageSizes.includes(this.options.pageSize)&&(this.options.pageSize=this.options.pageSizes[0])}static setMessages(e){Object.assign(s,e)}init(){this.processFieldDefinitions(),this.createMainStructure(),this.setupFTableUserPreferences(),this.createTable(),this.createModals(),this.options.paging&&this.createPagingUI(),this.resolveAsyncFieldOptions().then(()=>{setTimeout(()=>{this.refreshDisplayValues()},0)}).catch(console.error),this.bindEvents(),this.updateSortingHeaders(),this.renderSortingInfo(),this.initColumnWidths()}initColumnWidths(){var e=this.columnList.filter(e=>{e=this.options.fields[e];return"hidden"!==e.visibility&&"separator"!==e.visibility});let t=e.length;e.forEach(e=>{e=this.options.fields[e];e.width=e.width||100/t+"%"})}normalizeColumnWidths(){var e=this.elements.mainContainer,t=this.columnList.map(e=>({th:this.elements.table.querySelector(`[data-field-name="${e}"]`),field:this.options.fields[e]})).filter(e=>e.th&&"hidden"!==e.field.visibility&&"separator"!==e.field.visibility);if(0!==t.length){let s=e.offsetWidth,a=0;t.forEach(e=>{var t=e.th.offsetWidth/s*100;e.field.width=t+"%",e.th.style.width=e.field.width,a+=t})}}parseDefaultSorting(e){let o=[];return e&&"string"==typeof e&&e.split(",").forEach(s=>{s=s.trim();if(s){var a=s.toUpperCase().indexOf(" DESC"),i=s.toUpperCase().indexOf(" ASC");let e="ASC",t=s;e=0<a?(t=s.slice(0,a).trim(),"DESC"):(t=(0<i?s.slice(0,i):s).trim(),"ASC");a=this.options.fields[t];a&&!1!==a.sorting&&o.push({fieldName:t,direction:e})}}),o}addEssentialCSS(){var e;document.querySelector("#ftable-essential-css")||((e=document.createElement("style")).id="ftable-essential-css",e.textContent=`
1
+ (e=>{let s={serverCommunicationError:"An error occurred while communicating to the server.",loadingMessage:"Loading records...",noDataAvailable:"No data available!",addNewRecord:"Add new record",editRecord:"Edit record",areYouSure:"Are you sure?",deleteConfirmation:"This record will be deleted. Are you sure?",yes:"Yes",no:"No",save:"Save",saving:"Saving",cancel:"Cancel",deleteText:"Delete",deleting:"Deleting",error:"An error has occured",close:"Close",cannotLoadOptionsFor:"Cannot load options for field {0}!",pagingInfo:"Showing {0}-{1} of {2}",canNotDeletedRecords:"Can not delete {0} of {1} records!",deleteProgress:"Deleting {0} of {1} records, processing...",pageSizeChangeLabel:"Row count",gotoPageLabel:"Go to page",sortingInfoPrefix:"Sorting applied: ",sortingInfoSuffix:"",ascending:"Ascending",descending:"Descending",sortingInfoNone:"No sorting applied",resetSorting:"Reset sorting",csvExport:"CSV",printTable:"🖨️ Print",cloneRecord:"Clone Record",resetTable:"Reset table",resetTableConfirm:"This will reset all columns, pagesize, sorting to their defaults. Do you want to continue?",resetSearch:"Reset"};class t{constructor(){this.cache=new Map,this.pendingRequests=new Map}generateKey(e,t){return e+"?"+Object.keys(t||{}).sort().map(e=>e+"="+t[e]).join("&")}get(e,t){e=this.generateKey(e,t);return this.cache.get(e)}set(e,t,s){e=this.generateKey(e,t);this.cache.set(e,s)}clear(e=null,t=null){if(e)if(t){t=this.generateKey(e,t);this.cache.delete(t)}else{var s,a=e.split("?")[0];for([s]of this.cache)s.startsWith(a)&&this.cache.delete(s)}else this.cache.clear()}async getOrCreate(e,t,s){let a=this.generateKey(e,t);e=this.cache.get(a);return e||(this.pendingRequests.has(a)?this.pendingRequests.get(a):(t=(async()=>{try{var e=await s();return this.cache.set(a,e),e}finally{this.pendingRequests.delete(a)}})(),this.pendingRequests.set(a,t),t))}size(){return this.cache.size}}class a{static LOG_LEVELS={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};constructor(e=a.LOG_LEVELS.WARN){this.level=e}log(t,e){var s;!window.console||t<this.level||(s=Object.keys(a.LOG_LEVELS).find(e=>a.LOG_LEVELS[e]===t),console.log(`fTable ${s}: `+e))}debug(e){this.log(a.LOG_LEVELS.DEBUG,e)}info(e){this.log(a.LOG_LEVELS.INFO,e)}warn(e){this.log(a.LOG_LEVELS.WARN,e)}error(e){this.log(a.LOG_LEVELS.ERROR,e)}}class u{static create(e,t={}){let s=document.createElement(e);return t.className&&(s.className=t.className),t.style&&(s.style.cssText=t.style),t.attributes&&Object.entries(t.attributes).forEach(([e,t])=>{null!==t&&s.setAttribute(e,t)}),t.text&&(s.textContent=t.text),t.html&&(s.innerHTML=t.html),t.parent&&t.parent.appendChild(s),s}static find(e,t=document){return t.querySelector(e)}static findAll(e,t=document){return Array.from(t.querySelectorAll(e))}static addClass(e,t){e.classList.add(...t.split(" "))}static removeClass(e,t){e.classList.remove(...t.split(" "))}static toggleClass(e,t){e.classList.toggle(t)}static show(e){e.style.display=""}static hide(e){e.style.display="none"}static escapeHtml(e){if(!e)return e;let t={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#039;"};return e.replace(/[&<>"']/g,e=>t[e])}}class l{static async request(e,t={}){var s={method:"GET",headers:{}},a={...s,...t};t.headers&&(a.headers={...s.headers,...t.headers});try{var i=await fetch(e,a);if(401===i.status)throw new Error("Unauthorized");if(!i.ok)throw new Error("HTTP error! status: "+i.status);var o=i.headers.get("content-type");if(o&&o.includes("application/json"))return await i.json();var r=await i.text();try{return JSON.parse(r)}catch{return{Result:"OK",Message:r}}}catch(e){throw e}}static async get(e,t={}){let a=new URL(e,window.location.href);return Object.entries(t).forEach(([e,s])=>{if(null!=s)if(Array.isArray(s)){let t=e.replace(/\[\]$/,"")+"[]";s.forEach(e=>{null!=e&&a.searchParams.append(t,e)})}else a.searchParams.append(e,s)}),this.request(a.toString(),{method:"GET",headers:{"Content-Type":"application/x-www-form-urlencoded"}})}static async post(e,t={}){e=new URL(e,window.location.href);let a=new FormData;return Object.entries(t).forEach(([e,s])=>{if(null!=s)if(Array.isArray(s)){let t=e.replace(/\[\]$/,"")+"[]";s.forEach(e=>{null!=e&&a.append(t,e)})}else a.append(e,s)}),this.request(e.toString(),{method:"POST",body:a})}}class i{constructor(e,t="localStorage"){this.prefix=e,this.method=t}set(e,t){var s,e=""+this.prefix+e;"localStorage"===this.method?localStorage.setItem(e,t):((s=new Date).setDate(s.getDate()+30),document.cookie=e+`=${t}; expires=${s.toUTCString()}; path=/`)}get(e){e=""+this.prefix+e;if("localStorage"===this.method)return localStorage.getItem(e);var t,s=e+"=";for(t of decodeURIComponent(document.cookie).split(";")){for(;" "===t.charAt(0);)t=t.substring(1);if(0===t.indexOf(s))return t.substring(s.length,t.length)}return null}remove(e){e=""+this.prefix+e;"localStorage"===this.method?localStorage.removeItem(e):document.cookie=e+"=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"}generatePrefix(e,t){e=e?e+"#":"";return"ftable#"+(t=>{let s=0;if(0!==t.length)for(let e=0;e<t.length;e++){var a=t.charCodeAt(e);s=(s<<5)-s+a,s&=s}return s})(e+=t.join("$")+"#c"+t.length)}}class o{constructor(e={}){this.options={title:"Modal",content:"",buttons:[],className:"ftable-modal",parent:document.body,...e},this.overlay=null,this.modal=null,this.isOpen=!1}create(){this.overlay=u.create("div",{className:"ftable-modal-overlay",parent:this.options.parent}),this.modal=u.create("div",{className:"ftable-modal "+this.options.className,parent:this.overlay});u.create("h2",{className:"ftable-modal-header",text:this.options.title,parent:this.modal});u.create("span",{className:"ftable-modal-close",html:"&times;",parent:this.modal}).addEventListener("click",()=>this.close());var e=u.create("div",{className:"ftable-modal-body",parent:this.modal});if("string"==typeof this.options.content?e.innerHTML=this.options.content:e.appendChild(this.options.content),0<this.options.buttons.length){let s=u.create("div",{className:"ftable-modal-footer",parent:this.modal});this.options.buttons.forEach(e=>{var t=u.create("button",{className:"ftable-dialog-button "+(e.className||""),html:`<span>${e.text}</span>`,parent:s});e.onClick&&(t._originalOnClick=e.onClick,t.addEventListener("click",this._createWrappedClickHandler(t)))})}return this.options.closeOnOverlayClick&&this.overlay.addEventListener("click",e=>{e.target===this.overlay&&this.close()}),this.hide(),this}show(){return this.modal||this.create(),this.overlay.style.display="flex",this.isOpen=!0,this.modal.querySelectorAll(".ftable-dialog-button").forEach(e=>{e.disabled=!1}),this}hide(){return this.overlay&&(this.overlay.style.display="none"),this.isOpen=!1,this}close(){return this.hide(),this.options.onClose&&this.options.onClose(),this}destroy(){return this.overlay&&this.overlay.remove(),this.isOpen=!1,this}setContent(e){this.options.content=e;var t=this.modal.querySelector(".ftable-modal-body");t&&(t.innerHTML="","string"==typeof e?t.innerHTML=e:t.appendChild(e))}_createWrappedClickHandler(a){return async e=>{a.disabled=!0;try{var t,s=a._originalOnClick;"function"==typeof s&&(t=s.call(a,e))instanceof Promise&&await t}catch(e){console.error("Modal button action failed:",e)}finally{a.disabled=!1}}}}class r{constructor(e){this.options=e,this.dependencies=new Map,this.optionsCache=new t,this.originalFieldOptions=new Map,this.resolvedFieldOptions=new Map,Object.keys(this.options.fields||{}).forEach(e=>{this.resolvedFieldOptions.set(e,{})}),Object.entries(this.options.fields).forEach(([e,t])=>{this.originalFieldOptions.set(e,t.options)})}async getFieldOptions(t,s="table",e={}){var a=this.options.fields[t],i=this.originalFieldOptions.get(t);if(!i)return null;var o=this.shouldForceRefreshForContext(a,s,e),r=this.generateOptionsCacheKey(s,e);if(!o&&!e.forceRefresh){var n=this.resolvedFieldOptions.get(t)[r];if(n)return n}try{var l={...a,options:i},c=await this.resolveOptions(l,{...e},s,o);return this.resolvedFieldOptions.get(t)[r]=c}catch(e){return console.error(`Failed to resolve options for ${t} (${s}):`,e),i}}clearResolvedOptions(e=null,s=null){e?this.resolvedFieldOptions.has(e)&&(s?this.resolvedFieldOptions.get(e)[s]=null:this.resolvedFieldOptions.set(e,{table:null,create:null,edit:null})):s?this.resolvedFieldOptions.forEach((e,t)=>{this.resolvedFieldOptions.get(t)[s]=null}):this.resolvedFieldOptions.forEach((e,t)=>{this.resolvedFieldOptions.set(t,{table:null,create:null,edit:null})})}shouldForceRefreshForContext(e,t,s){return!!e.noCache&&("boolean"==typeof e.noCache?e.noCache:"function"==typeof e.noCache?e.noCache({context:t,...s}):"object"==typeof e.noCache&&!0===e.noCache[t])}generateOptionsCacheKey(e,t){let s=[e];return t.dependedValues&&Object.keys(t.dependedValues).sort().forEach(e=>{s.push(e+"="+t.dependedValues[e])}),s.join("|")}shouldIncludeField(e,t){return"create"===t?!1!==e.create&&!(!0===e.key&&!0!==e.create):"edit"!==t||!1!==e.edit}createFieldContainer(e,t,s,a){var i=u.create("div",{className:"hidden"!=t.type?"ftable-input-field-container":"",attributes:{id:"ftable-input-field-container-div-"+e}}),t=("hidden"!=t.type&&u.create("div",{className:"ftable-input-label",text:t.inputTitle||t.title,parent:i}),this.createInput(e,t,s[e],a));return i.appendChild(t),i}async createForm(e="create",t={}){this.currentFormRecord=t;var s,a,i,o,r=u.create("form",{className:`ftable-dialog-form ftable-${e}-form`});this.buildDependencyMap();for([s,a]of Object.entries(this.options.fields))this.shouldIncludeField(a,e)&&(i={...a},a.dependsOn?i.options=a.options:(o=await this.getFieldOptions(s,e,{record:t,source:e}),i.options=o),o=this.createFieldContainer(s,i,t,e),r.appendChild(o));return this.setupDependencyListeners(r),r}shouldResolveOptions(e){return e&&("function"==typeof e||"string"==typeof e)&&!Array.isArray(e)&&!("object"==typeof e&&!Array.isArray(e)&&0<Object.keys(e).length)}buildDependencyMap(){this.dependencies.clear(),Object.entries(this.options.fields).forEach(([t,s])=>{if(s.dependsOn){let e;"string"==typeof s.dependsOn&&(e=s.dependsOn.split(",").map(e=>e.trim()).filter(e=>e)).forEach(e=>{this.dependencies.has(e)||this.dependencies.set(e,[]),this.dependencies.get(e).push(t)})}})}setupDependencyListeners(s){Array.from(this.dependencies.keys()).forEach(e=>{var t=s.querySelector(`[name="${e}"]`);t&&t.addEventListener("change",()=>{this.handleDependencyChange(s,e)})}),this.handleDependencyChange(s)}async resolveOptions(e,t={},s="",a=!1){if(!e.options)return[];if(Array.isArray(e.options)||"object"==typeof e.options)return e.options;let i;t={...t,source:s,clearCache:()=>{a=!0,this.updateFieldCacheSetting(e,s,!0)}};if("function"==typeof e.options)i=await e.options(t);else{if("string"!=typeof e.options)return[];i=e.options}t=i&&"object"==typeof i&&i.url;let o=t?i.url:i;if(a=t&&void 0!==i.noCache?i.noCache:a,"string"!=typeof o)return[];if(!a)return this.optionsCache.getOrCreate(o,{},async()=>{try{var e=this.options.forcePost?await l.post(o):await l.get(o);return e.Options||e.options||e||[]}catch(e){return console.error(`Failed to load options from ${o}:`,e),[]}});try{var r=this.options.forcePost?await l.post(o):await l.get(o);return r.Options||r.options||r||[]}catch(e){return console.error(`Failed to load options from ${o}:`,e),[]}}updateFieldCacheSetting(e,t,s){e.noCache?"boolean"==typeof e.noCache?e.noCache={table:e.noCache,create:e.noCache,edit:e.noCache,[t]:s}:"object"==typeof e.noCache&&(e.noCache[t]=s):e.noCache={[t]:s}}clearOptionsCache(e=null,t=null){this.optionsCache.clear(e,t)}getFormValues(e){var t={},s=e.elements;for(let e=0;e<s.length;e++){var a=s[e],i=a.name;if(i&&!a.disabled)switch(a.type){case"checkbox":t[i]=a.checked?a.value||"1":"0";break;case"radio":a.checked&&(t[i]=a.value);break;case"select-multiple":t[i]=Array.from(a.selectedOptions).map(e=>e.value);break;default:t[i]=a.value}}return t}async handleDependencyChange(e,s=""){var a,i,o=this.getFormValues(e),r=e.classList.contains("ftable-create-form")?"create":"edit",n=this.currentFormRecord||{},l={record:n,source:r,form:e,dependedValues:o};for([a,i]of Object.entries(this.options.fields))if(i.dependsOn){if(""!==s)if(!i.dependsOn.split(",").map(e=>e.trim()).filter(e=>e).includes(s))continue;let t=e.querySelector(`[name="${a}"]`);if(t&&this.shouldIncludeField(i,r))try{"SELECT"===t.tagName?t.innerHTML='<option value="">Loading...</option>':"INPUT"===t.tagName&&t.list&&(c=document.getElementById(t.list.id))&&(c.innerHTML="");var c,d=t.value||n[a]||"",h={...l,dependsOnField:i.dependsOn,dependsOnValue:o[i.dependsOn]},p=await this.getFieldOptions(a,r,h);"SELECT"===t.tagName?this.populateSelectOptions(t,p,d):"INPUT"===t.tagName&&t.list&&(this.populateDatalistOptions(t.list,p),d)&&(t.value=d),setTimeout(()=>{t.dispatchEvent(new Event("change",{bubbles:!0}))},0)}catch(e){console.error(`Error loading options for ${a}:`,e),"SELECT"===t.tagName&&(t.innerHTML='<option value="">Error</option>')}}}parseInputAttributes(e){if("string"!=typeof e)return e||{};for(var t={},s=/(\w+)(?:=("[^"]*"|'[^']*'|\S+))?/g;null!==(i=s.exec(e));){var a=i[1],i=i[2]?i[2].replace(/^["']|["']$/g,""):"";t[a]=""===i?"true":i}return t}createInput(e,t,s,a){var i=u.create("div",{className:`ftable-input ftable-${t.type||"text"}-input`});let o;switch(null==(s=null==s?null:s)&&t.defaultValue&&(s=t.defaultValue),!t.type&&t.options&&(t.type="select"),t.type){case"hidden":o=this.createHiddenInput(e,t,s);break;case"textarea":o=this.createTextarea(e,t,s);break;case"select":o=this.createSelect(e,t,s);break;case"checkbox":o=this.createCheckbox(e,t,s);break;case"radio":o=this.createRadioGroup(e,t,s);break;case"datalist":o=this.createDatalistInput(e,t,s);break;case"file":o=this.createFileInput(e,t,s);break;case"date":case"datetime":case"datetime-local":o=this.createDateInput(e,t,s);break;default:o=this.createTypedInput(e,t,s)}return"function"==typeof t.input?(a={field:t,record:this.currentFormRecord,inputField:o,formType:a},"string"==typeof(a=t.input(a))?i.innerHTML=a:a instanceof Node?i.appendChild(a):(i.appendChild(o),o.datalistElement&&o.datalistElement instanceof Node&&i.appendChild(o.datalistElement))):(i.appendChild(o),o.datalistElement&&o.datalistElement instanceof Node&&i.appendChild(o.datalistElement)),t.explain&&u.create("div",{className:"ftable-field-explain",html:`<small>${t.explain}</small>`,parent:i}),i}createDateInput(s,a,i){if("undefined"==typeof FDatepicker)return createTypedInput(s,a,i);{let e=a.dateFormat||this.options.defaultDateFormat;var o,r=document.createElement("div"),n=u.create("input",{attributes:{id:"real-"+s,type:"hidden",value:i,name:s}}),i={id:"Edit-"+s,type:"text","data-date":i,placeholder:a.placeholder||null,readOnly:!0};a.inputAttributes&&(o=this.parseInputAttributes(a.inputAttributes),Object.assign(i,o));let t=u.create("input",{className:a.inputClass||"datepicker-input",attributes:i});switch(r.appendChild(n),r.appendChild(t),a.type){case"date":setTimeout(()=>{new FDatepicker(t,{format:e,altField:"real-"+s,altFormat:"Y-m-d"})},0);break;case"datetime":case"datetime-local":setTimeout(()=>{new FDatepicker(t,{format:e,timepicker:!0,altField:"real-"+s,altFormat:"Y-m-d H:i:00"})},0)}return r}}createTypedInput(e,t,s){var a,s={type:t.type||"text",id:"Edit-"+e,placeholder:t.placeholder||null,value:s};let i=e,o=(t.inputAttributes&&(a=this.parseInputAttributes(t.inputAttributes),Object.assign(s,a),void 0!==a.multiple&&!1!==a.multiple)&&(i=e+"[]"),s.name=i,u.create("input",{className:t.inputClass||null,attributes:s}));return o.addEventListener("keypress",e=>{if(13===(e.keyCode||e.which))return e.preventDefault(),o.dispatchEvent(new Event("change",{bubbles:!0})),!1}),o}createDatalistInput(e,t,s){var s={type:"text",name:e,id:"Edit-"+e,placeholder:t.placeholder||null,value:s,list:e+"-datalist"},a=(t.inputAttributes&&(a=this.parseInputAttributes(t.inputAttributes),Object.assign(s,a)),u.create("input",{className:t.inputClass||null,attributes:s})),s=u.create("datalist",{attributes:{id:e+"-datalist"}});return t.options&&this.populateDatalistOptions(s,t.options),a.datalistElement=s,a}populateDatalistOptions(s,e){s.innerHTML="",Array.isArray(e)?e.forEach(e=>{u.create("option",{attributes:{value:e.Value||e.value||e},text:e.DisplayText||e.text||e,parent:s})}):"object"==typeof e&&Object.entries(e).forEach(([e,t])=>{u.create("option",{attributes:{value:e},text:t,parent:s})})}createHiddenInput(e,t,s){e={type:"hidden",name:e,id:"Edit-"+e,value:s};return t.inputAttributes&&(s=this.parseInputAttributes(t.inputAttributes),Object.assign(e,s)),u.create("input",{attributes:e})}createTextarea(e,t,s){var e={name:e,id:"Edit-"+e,placeholder:t.placeholder||null},a=(t.inputAttributes&&(a=this.parseInputAttributes(t.inputAttributes),Object.assign(e,a)),u.create("textarea",{className:t.inputClass||null,attributes:e,value:s}));return a}createSelect(e,t,s){var a={name:e,id:"Edit-"+e};let i=e;t.inputAttributes&&(o=this.parseInputAttributes(t.inputAttributes),Object.assign(a,o),void 0!==o.multiple&&!1!==o.multiple)&&(i=e+"[]"),a.name=i;var o=u.create("select",{className:t.inputClass||null,attributes:a});return t.options&&this.populateSelectOptions(o,t.options,s),o}createRadioGroup(o,r,n){let l=u.create("div",{className:"ftable-radio-group"});return r.options&&(Array.isArray(r.options)?r.options:"object"==typeof r.options?Object.entries(r.options).map(([e,t])=>({Value:e,DisplayText:t})):[]).forEach((e,t)=>{var s=u.create("div",{className:"ftable-radio-wrapper",parent:l}),a=o+"_"+t,i={type:"radio",name:o,id:a,value:e.Value||e.value||e},t=(r.required&&0===t&&(i.required="required"),r.disabled&&(i.disabled="disabled"),r.inputAttributes&&(t=this.parseInputAttributes(r.inputAttributes),Object.assign(i,t)),u.create("input",{attributes:i,className:r.inputClass||null,parent:s}));i.value===n&&(t.checked=!0),u.create("label",{attributes:{for:a},text:e.DisplayText||e.text||e,parent:s})}),l}createCheckbox(e,t,s){var a=u.create("div",{className:"ftable-yesno-check-wrapper"}),s=[1,"1",!0,"true"].includes(s);let i=this.options.messages.no,o=this.options.messages.yes;return t.values&&"object"==typeof t.values&&(void 0!==t.values[0]&&(i=t.values[0]),void 0!==t.values[1])&&(o=t.values[1]),u.create("input",{className:["ftable-yesno-check-input",t.inputClass||""].filter(Boolean).join(" "),attributes:{type:"checkbox",name:e,id:"Edit-"+e,value:"1"},parent:a}).checked=s,t.label?u.create("label",{className:"ftable-yesno-check-fixedlabel",attributes:{for:"Edit-"+e},text:t.label,parent:a}):u.create("label",{className:"ftable-yesno-check-text",attributes:{for:"Edit-"+e,"data-yes":o,"data-no":i},parent:a}),a}populateSelectOptions(a,e,i){a.innerHTML="",Array.isArray(e)?e.forEach(e=>{var t=void 0!==e.Value?e.Value:void 0!==e.value?e.value:e;let s=u.create("option",{attributes:{value:t},text:e.DisplayText||e.text||e,parent:a});e.Data&&"object"==typeof e.Data&&Object.entries(e.Data).forEach(([e,t])=>{s.setAttribute("data-"+e,t)}),s.value==i&&(s.selected=!0)}):"object"==typeof e&&Object.entries(e).forEach(([e,t])=>{t=u.create("option",{attributes:{value:e},text:t,parent:a});e==i&&(t.selected=!0)})}createFileInput(e,t,s){var a,i={type:"file",id:"Edit-"+e};let o=e;return t.inputAttributes&&(a=this.parseInputAttributes(t.inputAttributes),Object.assign(i,a),void 0!==a.multiple&&!1!==a.multiple)&&(o=e+"[]"),i.name=o,u.create("input",{className:t.inputClass||null,attributes:i})}}class n extends class{constructor(){this.events={}}on(e,t){return this.events[e]||(this.events[e]=[]),this.events[e].push(t),this}once(t,s){let a=(...e)=>{this.off(t,a),s.apply(this,e)};return a.fn=s,this.on(t,a),this}emit(e,t={}){return this.events[e]&&this.events[e].forEach(e=>e(t)),this}off(e,t){return this.events[e]&&(this.events[e]=this.events[e].filter(e=>e!==t)),this}}{constructor(e,t={}){if(super(),this.element="string"==typeof e?document.querySelector(e):e,this.element){if(this.element.ftableInstance)return this.element.ftableInstance;this.options=this.mergeOptions(t),this.verifyOptions(),this.logger=new a(this.options.logLevel),this.userPrefs=new i("",this.options.saveUserPreferencesMethod),this.formBuilder=new r(this.options,this),this.state={records:[],totalRecordCount:0,currentPage:1,isLoading:!1,selectedRecords:new Set,sorting:[],searchQueries:{}},this.elements={},this.modals={},this.searchTimeout=null,this.lastSortEvent=null,this._recalculatedOnce=!1,this.shiftKeyDown=!1,this.lastSelectedRow=null,(this.element.ftableInstance=this).init()}}mergeOptions(e){var t={tableId:void 0,logLevel:a.LOG_LEVELS.WARN,actions:{},fields:{},forcePost:!0,closeOnOverlayClick:!0,animationsEnabled:!0,loadingAnimationDelay:1e3,defaultDateLocale:"",defaultDateFormat:"Y-m-d",saveUserPreferences:!0,saveUserPreferencesMethod:"localStorage",defaultSorting:"",tableReset:!1,paging:!1,pageList:"normal",pageSize:10,pageSizes:[10,25,50,100,250,500],gotoPageArea:"combobox",sorting:!1,multiSorting:!1,multiSortingCtrlKey:!0,selecting:!1,multiselect:!1,openChildAsAccordion:!1,toolbarsearch:!1,toolbarreset:!0,searchDebounceMs:300,listCache:3e4,messages:{...s}};return this.deepMerge(t,e)}deepMerge(e,t){var s,a={...e};for(s in t)t[s]&&"object"==typeof t[s]&&!Array.isArray(t[s])?a[s]=this.deepMerge(a[s]||{},t[s]):a[s]=t[s];return a}verifyOptions(){this.options.pageSize&&!this.options.pageSizes.includes(this.options.pageSize)&&(this.options.pageSize=this.options.pageSizes[0])}static setMessages(e){Object.assign(s,e)}init(){this.processFieldDefinitions(),this.createMainStructure(),this.setupFTableUserPreferences(),this.createTable(),this.createModals(),this.options.paging&&this.createPagingUI(),this.resolveAsyncFieldOptions().then(()=>{setTimeout(()=>{this.refreshDisplayValues()},0)}).catch(console.error),this.bindEvents(),this.updateSortingHeaders(),this.renderSortingInfo(),this.initColumnWidths()}initColumnWidths(){var e=this.columnList.filter(e=>{e=this.options.fields[e];return"hidden"!==e.visibility&&"separator"!==e.visibility});let t=e.length;e.forEach(e=>{e=this.options.fields[e];e.width=e.width||100/t+"%"})}normalizeColumnWidths(){var e=this.elements.mainContainer,t=this.columnList.map(e=>({th:this.elements.table.querySelector(`[data-field-name="${e}"]`),field:this.options.fields[e]})).filter(e=>e.th&&"hidden"!==e.field.visibility&&"separator"!==e.field.visibility);if(0!==t.length){let s=e.offsetWidth,a=0;t.forEach(e=>{var t=e.th.offsetWidth/s*100;e.field.width=t+"%",e.th.style.width=e.field.width,a+=t})}}parseDefaultSorting(e){let o=[];return e&&"string"==typeof e&&e.split(",").forEach(s=>{s=s.trim();if(s){var a=s.toUpperCase().indexOf(" DESC"),i=s.toUpperCase().indexOf(" ASC");let e="ASC",t=s;e=0<a?(t=s.slice(0,a).trim(),"DESC"):(t=(0<i?s.slice(0,i):s).trim(),"ASC");a=this.options.fields[t];a&&!1!==a.sorting&&o.push({fieldName:t,direction:e})}}),o}addEssentialCSS(){var e;document.querySelector("#ftable-essential-css")||((e=document.createElement("style")).id="ftable-essential-css",e.textContent=`
2
2
  .ftable-row-animation {
3
3
  transition: background-color 0.3s ease;
4
4
  }
package/ftable.umd.js CHANGED
@@ -200,7 +200,7 @@ class FTableDOMHelper {
200
200
 
201
201
  if (options.attributes) {
202
202
  Object.entries(options.attributes).forEach(([key, value]) => {
203
- if (value !== '')
203
+ if (value !== null)
204
204
  element.setAttribute(key, value);
205
205
  });
206
206
  }
@@ -1065,7 +1065,10 @@ class FTableFormBuilder {
1065
1065
 
1066
1066
  let input;
1067
1067
 
1068
- if (value == null || value == undefined ) {
1068
+ if (value == undefined) {
1069
+ value = null;
1070
+ }
1071
+ if (value == null && field.defaultValue ) {
1069
1072
  value = field.defaultValue;
1070
1073
  }
1071
1074
  // Auto-detect select type if options are provided
@@ -1127,10 +1130,16 @@ class FTableFormBuilder {
1127
1130
  // Otherwise, fallback to default
1128
1131
  else {
1129
1132
  container.appendChild(input);
1133
+ if (input.datalistElement && input.datalistElement instanceof Node) {
1134
+ container.appendChild(input.datalistElement);
1135
+ }
1130
1136
  }
1131
1137
  } else {
1132
1138
  // No custom input function — just add the default input
1133
1139
  container.appendChild(input);
1140
+ if (input.datalistElement && input.datalistElement instanceof Node) {
1141
+ container.appendChild(input.datalistElement);
1142
+ }
1134
1143
  }
1135
1144
 
1136
1145
  // Add explanation if provided
@@ -1156,7 +1165,7 @@ class FTableFormBuilder {
1156
1165
  attributes: {
1157
1166
  id: 'real-' + fieldName,
1158
1167
  type: 'hidden',
1159
- value: value || '',
1168
+ value: value,
1160
1169
  name: fieldName
1161
1170
  }
1162
1171
  });
@@ -1166,7 +1175,7 @@ class FTableFormBuilder {
1166
1175
  id: `Edit-${fieldName}`,
1167
1176
  type: 'text',
1168
1177
  'data-date': value,
1169
- placeholder: field.placeholder || '',
1178
+ placeholder: field.placeholder || null,
1170
1179
  readOnly: true
1171
1180
  };
1172
1181
  // Set any additional attributes
@@ -1220,8 +1229,8 @@ class FTableFormBuilder {
1220
1229
  const attributes = {
1221
1230
  type: inputType,
1222
1231
  id: `Edit-${fieldName}`,
1223
- placeholder: field.placeholder || '',
1224
- value: value || ''
1232
+ placeholder: field.placeholder || null,
1233
+ value: value
1225
1234
  };
1226
1235
 
1227
1236
  // extra check for name and multiple
@@ -1242,7 +1251,7 @@ class FTableFormBuilder {
1242
1251
  attributes.name = name;
1243
1252
 
1244
1253
  const input = FTableDOMHelper.create('input', {
1245
- className: field.inputClass || '',
1254
+ className: field.inputClass || null,
1246
1255
  attributes: attributes
1247
1256
  });
1248
1257
 
@@ -1264,8 +1273,8 @@ class FTableFormBuilder {
1264
1273
  type: 'text',
1265
1274
  name: fieldName,
1266
1275
  id: `Edit-${fieldName}`,
1267
- placeholder: field.placeholder || '',
1268
- value: value || '',
1276
+ placeholder: field.placeholder || null,
1277
+ value: value,
1269
1278
  list: `${fieldName}-datalist`
1270
1279
  };
1271
1280
 
@@ -1276,7 +1285,7 @@ class FTableFormBuilder {
1276
1285
  }
1277
1286
 
1278
1287
  const input = FTableDOMHelper.create('input', {
1279
- className: field.inputClass || '',
1288
+ className: field.inputClass || null,
1280
1289
  attributes: attributes
1281
1290
  });
1282
1291
 
@@ -1292,10 +1301,7 @@ class FTableFormBuilder {
1292
1301
  this.populateDatalistOptions(datalist, field.options);
1293
1302
  }
1294
1303
 
1295
- // Append datalist to the document body or form
1296
- document.body.appendChild(datalist);
1297
-
1298
- // Store reference for cleanup
1304
+ // Store reference
1299
1305
  input.datalistElement = datalist;
1300
1306
 
1301
1307
  return input;
@@ -1330,7 +1336,7 @@ class FTableFormBuilder {
1330
1336
  type: 'hidden',
1331
1337
  name: fieldName,
1332
1338
  id: `Edit-${fieldName}`,
1333
- value: value || ''
1339
+ value: value
1334
1340
  };
1335
1341
 
1336
1342
  // Apply inputAttributes
@@ -1346,7 +1352,7 @@ class FTableFormBuilder {
1346
1352
  const attributes = {
1347
1353
  name: fieldName,
1348
1354
  id: `Edit-${fieldName}`,
1349
- placeholder: field.placeholder || ''
1355
+ placeholder: field.placeholder || null
1350
1356
  };
1351
1357
 
1352
1358
  // Apply inputAttributes
@@ -1356,9 +1362,9 @@ class FTableFormBuilder {
1356
1362
  }
1357
1363
 
1358
1364
  const textarea = FTableDOMHelper.create('textarea', {
1359
- className: field.inputClass || '',
1365
+ className: field.inputClass || null,
1360
1366
  attributes: attributes,
1361
- value: value || ''
1367
+ value: value
1362
1368
  });
1363
1369
  return textarea;
1364
1370
  }
@@ -1387,7 +1393,7 @@ class FTableFormBuilder {
1387
1393
  attributes.name = name;
1388
1394
 
1389
1395
  const select = FTableDOMHelper.create('select', {
1390
- className: field.inputClass || '',
1396
+ className: field.inputClass || null,
1391
1397
  attributes: attributes
1392
1398
  });
1393
1399
 
@@ -1432,7 +1438,7 @@ class FTableFormBuilder {
1432
1438
 
1433
1439
  const radio = FTableDOMHelper.create('input', {
1434
1440
  attributes: radioAttributes,
1435
- className: field.inputClass || '',
1441
+ className: field.inputClass || null,
1436
1442
  parent: radioWrapper
1437
1443
  });
1438
1444
 
@@ -1566,11 +1572,10 @@ class FTableFormBuilder {
1566
1572
  }
1567
1573
  attributes.name = name;
1568
1574
 
1569
- const input = FTableDOMHelper.create('input', {
1570
- className: field.inputClass || '',
1575
+ return FTableDOMHelper.create('input', {
1576
+ className: field.inputClass || null,
1571
1577
  attributes: attributes
1572
1578
  });
1573
- return input;
1574
1579
  }
1575
1580
  }
1576
1581
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liedekef/ftable",
3
- "version": "1.1.43",
3
+ "version": "1.1.45",
4
4
  "description": "Modern, lightweight, jQuery-free CRUD table for dynamic AJAX-powered tables.",
5
5
  "main": "ftable.js",
6
6
  "module": "ftable.esm.js",