| | |
| | | |
| | | if (manyRefs.inputs) { |
| | | for (let input of manyRefs.inputs) { |
| | | let wrapper = input.closest('[data-field]')??el; |
| | | let wrapper = input.closest('[data-field]')??input.closest('.radio-button')??el; |
| | | |
| | | window.prefixInput(input, `${data.id??data.uploadId}-`, wrapper); |
| | | } |
| | | } |
| | |
| | | LISTENERS |
| | | *********************************************************************/ |
| | | handleClick(e) { |
| | | if (!window.targetCheck(e, this.selectors.fields.field)) return; |
| | | |
| | | //Open the file input if it's a dropzone |
| | | let dropZone = window.targetCheck(e, this.selectors.fields.dropZone); |
| | | if (dropZone && !e.target.matches('input, button, a')){ |
| | |
| | | if (data.config.type !== 'single') { |
| | | this.initSortable(data.id); |
| | | } |
| | | this.maybeLockUploads(data.id); |
| | | |
| | | return data.id; |
| | | } |
| | | |
| | | extractFieldConfig(fieldElement, autoUpload, imageMeta) { |
| | | extractFieldConfig(el, autoUpload, imageMeta) { |
| | | const config = { |
| | | autoUpload: autoUpload, |
| | | showMeta: imageMeta, |
| | | destination: fieldElement.dataset.destination || 'meta', |
| | | content: this.extractFieldContent(fieldElement), |
| | | mode: fieldElement.dataset.mode || 'direct', |
| | | type: fieldElement.dataset.type || 'single', |
| | | name: fieldElement.dataset.field, |
| | | itemID: this.extractFieldItemId(fieldElement) ?? 0, |
| | | maxFiles: parseInt(fieldElement.dataset.maxFiles) ?? 25, |
| | | subType: fieldElement.dataset.subtype ?? 'image', |
| | | destination: el.dataset.destination || 'meta', |
| | | content: this.extractFieldContent(el), |
| | | mode: el.dataset.mode || 'direct', |
| | | type: el.dataset.type || 'single', |
| | | name: el.dataset.field, |
| | | itemID: this.extractFieldItemId(el) ?? 0, |
| | | maxFiles: ('max-files' in el.dataset) ? parseInt(el.dataset.maxFiles) : 0, |
| | | subType: el.dataset.subtype ?? 'image', |
| | | repeaterPath: null |
| | | }; |
| | | |
| | | const repeaterRow = fieldElement.closest('[data-index]'); |
| | | const repeaterRow = el.closest('[data-index]'); |
| | | const repeater = repeaterRow?.closest('[data-field][data-repeater-id]'); |
| | | if (repeater && repeaterRow) { |
| | | config.repeaterPath = `${repeater.dataset.field}:${repeaterRow.dataset.index}:${config.name}`; |
| | |
| | | * @param button |
| | | */ |
| | | async handleRemoveItem(button) { |
| | | console.log('Handling remove upload'); |
| | | const item = button.closest(this.selectors.items.item); |
| | | if (!item) return; |
| | | |
| | |
| | | if (!field?.ui.hidden) return; |
| | | |
| | | const remaining = Array.from(field.ui.grid?.querySelectorAll(this.selectors.items.item) || []) |
| | | .map(el => el.dataset.id || el.dataset.uploadId) |
| | | .map(el => { |
| | | if (Object.hasOwn(el.dataset, 'id') && el.dataset.id > 0) { |
| | | return el.dataset.id; |
| | | } |
| | | |
| | | if (Object.hasOwn(el.dataset, 'upload-id') && el.dataset.uploadId > 0) { |
| | | return el.dataset.uploadId; |
| | | } |
| | | //For timeline |
| | | return el.dataset.itemId; |
| | | }) |
| | | .filter(Boolean); |
| | | |
| | | const newValue = remaining.join(','); |
| | |
| | | |
| | | let uploads = this.stores.uploads.filterByIndex({field: fieldId}); |
| | | let count = uploads.length; |
| | | let max = field.config.maxFiles??25; |
| | | let max = field.config.maxFiles??0; |
| | | |
| | | field.ui.dropZone.hidden = count >= max; |
| | | field.ui.dropZone.hidden = max > 0 && count >= max; |
| | | } |
| | | /******************************************************************************* |
| | | OPERATION METHODS |