Jake Vanderwerf
2026-02-07 8b82035f3f8be1462a7125ad7eafb990ca17fa94
assets/js/concise/FormController.js
@@ -73,7 +73,7 @@
         },
         tagList: {
            tagList: '.field.tag-list',         //querySelectorAll
            input: '.tag-input-row',
            input: '.row',
            add: '.add-tag',
            remove: '.remove-tag',
            label: '.tag-label',
@@ -325,6 +325,7 @@
      if (e.target.closest('[data-ignore]') || this.isRestoring) return;
      let field = this.getField(e.target);
      //Dependencies
      if (this.dependencies.has(field.dataset.field)) {
         let dependency = this.dependencies.get(field.dataset.field);
@@ -333,6 +334,11 @@
         });
      }
      if (Object.hasOwn(field.dataset, 'repeater-id') || Object.hasOwn(field.dataset,'tag-list-id')) {
         this.updateCollectionField(field);
         return;
      }
      let form = this.getForm(e.target);
      this.updateItem(field.dataset.field, this.getFieldValue(e.target), form);
   }
@@ -377,9 +383,6 @@
      if (this.subscribers.size > 0) {
         e.preventDefault();
         console.log('Cancelling scheduled backup and manually backing up');
         if (form.options.cache) {
            this.cancelBackup();
@@ -608,8 +611,11 @@
                        this.removeQuantityListeners(item.element);
                        break;
                  }
                  if (check.has(item.id)) {
                     check.delete(item.id);
                  }
               });
               check.delete(item.id);
            }
         }
@@ -790,6 +796,7 @@
               }
            }
         checkForRepeaters(form) {
            if (!form.querySelector(this.selectors.repeater.repeater)) return;
            form.querySelectorAll(this.selectors.repeater.repeater).forEach(repeater => {
@@ -802,7 +809,7 @@
                  sortable: false,
               };
               if (!config.ui.addButton) return;
               if (!config.ui.add) return;
               let template = repeater.querySelector('template');
               this.templates.define(
@@ -814,9 +821,10 @@
                     setup({el, refs, manyRefs, data}) {
                        let index = config.ui.items?.children?.length??0;
                        el.dataset.index = index;
                        manyRefs.inputs?.forEach(input => {
                           let wrapper = el.closest('[data-field]');
                           window.prefixInput(input, `${el.dataset.fieldName}:${index}:`, wrapper);
                           window.prefixInput(input, `${data.repeater.dataset.fieldName}:${index}:`, el);
                        });
                     }
                  },
@@ -845,13 +853,18 @@
            }
            handleRepeaterClick(e) {
               if (e.target.matches(this.selectors.repeater.add)) {
                  console.log('Add Repeater Row');
                  this.addRepeaterRow(e.target.closest('[data-repeater-id]'));
               } else if (e.target.matches(this.selectors.repeater.remove)) {
                  this.removeRepeaterRow(e.target);
                  console.log('Remove Repeater Row');
                  this.removeRepeaterRow(e.target.closest('[data-index]'));
               }
            }
            addRepeaterRow(repeater) {
               repeater.append(this.templates.create(repeater.dataset.repeaterId));
               let data = {};
               data.repeater = repeater;
               repeater.append(this.templates.create(repeater.dataset.repeaterId, data));
               this.initializeFields(repeater, this.getField(repeater).config??{});
               this.a11y.announce('Row added');
            }
            removeRepeaterRow(row) {
@@ -869,6 +882,7 @@
                  form: form.dataset.formId,
                  format: field.dataset.tagFormat??'first_field'
               };
               console.log('Registering Tag List with config', config);
               if (!config.ui.input || !config.ui.add || !config.ui.items) return;
               field.dataset.tagListId = config.id;
@@ -887,7 +901,7 @@
                        let index = config.ui.items?.children?.length??0;
                        el.dataset.index = index;
                        manyRefs.inputs?.forEach(input => {
                           let wrapper = window.closest('.tag-item');
                           let wrapper = input.closest('.tag-item');
                           window.prefixInput(input, `${el.dataset.fieldName}:${index}:`, wrapper)
                        });
@@ -897,8 +911,10 @@
                     }
                  },
               );
               config.ui.inputs = Array.from(field.querySelectorAll(this.selectors.tagList.inputs));
               config.ui.value = Array.from(field.querySelectorAll(this.selectors.tagList.value));
               this.tagLists.set(config.id, config);
               console.log('Adding tag list listeners to ', field);
               this.addTagListListeners(field);
            });
@@ -913,7 +929,7 @@
            }
            handleTagListClick(e) {
               if (e.target.matches(this.selectors.tagList.add)) {
               if (window.targetCheck(e,this.selectors.tagList.add)) {
                  this.addTagListItem(e.target.closest('[data-tag-list-id]'));
               } else if (e.target.matches(this.selectors.tagList.remove)) {
                  this.removeTagListItem(e.target.closest(this.selectors.tagList.remove));
@@ -925,7 +941,6 @@
                  let data = {};
                  let hasValue = false;
                  for (let input of config.ui.inputs) {
                     this.validateField(input);
                     const fieldName = input.name.replace('new_','');
@@ -957,7 +972,7 @@
                        label = Object.values(data).join(', ');
                        break;
                     default:
                        if (format.includes('{')) {
                        if (config.format.includes('{')) {
                           let label = config.format;
                           for (const [key, value] of Object.entries(data)) {
                              label = label.replace(`{${key}}`, value);
@@ -982,6 +997,8 @@
                  config.ui.items.append(newItem);
                  config.ui.inputs[0]?.focus();
                  this.updateCollectionField(tagList);
                  this.a11y.announce('Item added');
               }
               removeTagListItem(tag) {
@@ -1207,6 +1224,28 @@
            );
         });
      });
      this.updateCollectionField(container);
   }
   /**
    * Update the entire repeater/tagList field data
    * Call this whenever rows are added, removed, or reordered
    */
   updateCollectionField(element) {
      const field = element.closest('[data-field]');
      if (!field) return;
      const fieldType = field.dataset.fieldType;
      if (!['repeater', 'tag-list'].includes(fieldType)) return;
      const form = this.getForm(element);
      if (!form) return;
      // Get all current data for the collection
      const value = this.getFieldValue(field.querySelector('input, select, textarea'));
      this.updateItem(field.dataset.field, value, form);
   }
   /**********************************************************************
    VALIDATION