| | |
| | | if (!confirm('Remove this item?')) return; |
| | | |
| | | if (uploadId) { |
| | | // New upload managed by stores |
| | | await this.removeUpload(uploadId); |
| | | } else { |
| | | // Existing server-rendered attachment |
| | | const fieldId = this.getFieldIdFromElement(button); |
| | | item.remove(); |
| | | |
| | | if (fieldId) { |
| | | this.updateHiddenInput(fieldId); |
| | | this.maybeLockUploads(fieldId); |
| | | this.notify('attachment-removed', { attachmentId, fieldId }); |
| | | } |
| | | } |
| | | |
| | | this.a11y.announce('Item removed'); |
| | | } |
| | | |
| | | updateHiddenInput(fieldId) { |
| | | const field = this.fields.get(fieldId); |
| | | 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) |
| | | .filter(Boolean); |
| | | |
| | | field.ui.hidden.value = remaining.join(','); |
| | | field.ui.hidden.dispatchEvent(new Event('change', { bubbles: true })); |
| | | } |
| | | async setBulkUpload(uploads, key, value) { |
| | | const promises = Array.from(uploads).map(async (upload) => { |
| | | if (typeof upload === 'string') upload = await this.stores.uploads.get(upload); |
| | |
| | | async removeUpload(uploadId) { |
| | | let upload = this.stores.uploads.get(uploadId); |
| | | if (!upload) return; |
| | | const fieldId = upload.field; // grab before clearing |
| | | |
| | | if (upload.group) { |
| | | let group = this.stores.groups.get(upload.group); |
| | | group.uploads = group.uploads.filter(id => id !== uploadId); |
| | |
| | | } |
| | | |
| | | await this.clearUpload(uploadId); |
| | | this.maybeLockUploads(upload.field); |
| | | this.updateHiddenInput(fieldId); |
| | | this.maybeLockUploads(fieldId); |
| | | |
| | | let handler = this.selectionHandlers.get(upload.field); |
| | | if (handler){ |
| | | let handler = this.selectionHandlers.get(fieldId); |
| | | if (handler) { |
| | | handler.deselect(uploadId); |
| | | } |
| | | |
| | |
| | | return; |
| | | } |
| | | |
| | | // Get current order from DOM |
| | | let items = Array.from(target.children) |
| | | .filter(el => el.matches(this.selectors.items.item) && !el.classList.contains('ghost')) |
| | | .map(upload => upload.dataset.uploadId) |
| | | .filter(id => id); |
| | | |
| | | if (!groupId) { |
| | | let hiddenInput = this.fields.get(fieldId)?.ui.hidden; |
| | | if (hiddenInput) { |
| | | hiddenInput.value = items.join(','); |
| | | } |
| | | this.updateHiddenInput(fieldId); |
| | | } else { |
| | | let items = Array.from(target.children) |
| | | .filter(el => el.matches(this.selectors.items.item) && !el.classList.contains('ghost')) |
| | | .map(upload => upload.dataset.uploadId) |
| | | .filter(id => id); |
| | | |
| | | let group = this.stores.groups.get(groupId); |
| | | if (group) { |
| | | group.uploads = items; |