1 import {onChildEvent} from '../services/dom';
2 import {uniqueId} from '../services/util.ts';
3 import {Component} from './component';
7 * Allows easy row add/remove controls onto a table.
8 * Needs a model row to use when adding a new row.
10 export class AddRemoveRows extends Component {
13 this.modelRow = this.$refs.model;
14 this.addButton = this.$refs.add;
15 this.removeSelector = this.$opts.removeSelector;
16 this.rowSelector = this.$opts.rowSelector;
17 this.setupListeners();
21 this.addButton.addEventListener('click', this.add.bind(this));
23 onChildEvent(this.$el, this.removeSelector, 'click', e => {
24 const row = e.target.closest(this.rowSelector);
31 const clone = this.modelRow.cloneNode(true);
32 clone.classList.remove('hidden');
33 this.setClonedInputNames(clone);
34 this.modelRow.parentNode.insertBefore(clone, this.modelRow);
35 window.$components.init(clone);
39 * Update the HTML names of a clone to be unique if required.
40 * Names can use placeholder values. For exmaple, a model row
41 * may have name="tags[randrowid][name]".
42 * These are the available placeholder values:
43 * - randrowid - An random string ID, applied the same across the row.
44 * @param {HTMLElement} clone
46 setClonedInputNames(clone) {
47 const rowId = uniqueId();
48 const randRowIdElems = clone.querySelectorAll('[name*="randrowid"]');
49 for (const elem of randRowIdElems) {
50 elem.name = elem.name.split('randrowid').join(rowId);