| | |
| | | |
| | | initElements() { |
| | | this.selectors = { |
| | | details: 'details.create-new', |
| | | details: 'details.create-term', |
| | | parent: '#select_parent', |
| | | summary: '.create-new summary', |
| | | summary: '.create-term summary', |
| | | suggestion: '.term-suggestions', |
| | | name: '#term_name', |
| | | button: '.submit-term', |
| | |
| | | this.ui = window.uiFromSelectors(this.selectors, this.selector.container); |
| | | } |
| | | |
| | | handleOpen(field) { |
| | | this.field = field; |
| | | if (this.ui.details) { |
| | | this.ui.details.hidden = !field.canCreate; |
| | | |
| | | if (this.ui.summary) { |
| | | this.ui.summary.textContent = `Add new ${field.singular}`; |
| | | } |
| | | if (this.ui.label.name) { |
| | | this.ui.label.name.textContent = `Name this ${field.singular}`; |
| | | } |
| | | if (this.ui.label.parent) { |
| | | this.ui.label.parent.textContent = `Nest it under`; |
| | | } |
| | | if (this.ui.button) { |
| | | this.ui.button.textContent = `Add ${field.singular}`; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Initialize event listeners |
| | | */ |
| | |
| | | |
| | | if (this.ui.form) { |
| | | this.ui.form.addEventListener('change', (e) => { |
| | | console.log('Creator form change, prevents default'); |
| | | e.preventDefault(); |
| | | e.stopPropagation(); |
| | | }) |
| | | }); |
| | | } |
| | | } |
| | | |
| | |
| | | this.ui.name?.focus(); |
| | | } |
| | | this.resetParentOptions(); |
| | | } |
| | | |
| | | // Handle term creation submission |
| | | if (window.targetCheck(e, this.selectors.button)) { |
| | | this.handleTermCreation(e).then(() => {}); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Handle term creation from modal form |
| | | */ |
| | | async handleTermCreation(e) { |
| | | let field = this.selector.currentField(); |
| | | const taxonomy = field.taxonomy; |
| | | if (!taxonomy) return; |
| | | |
| | | let data = { |
| | | parent: 0, |
| | | taxonomy: taxonomy |
| | | }; |
| | | // If it's open, we can get the parent element and everything |
| | | if (this.selector.container.open) { |
| | | data.name = this.ui.name.value.trim(); |
| | | data.parent = parseInt(this.ui.parent?.value??0); |
| | | } else if (this.selector.activeField) { |
| | | //It's autocomplete, so just the term name |
| | | data.name = this.selector.store.query; |
| | | } |
| | | if (!data.name || data.name.length < 2) return; |
| | | |
| | | async handleTermCreation(data) { |
| | | if (!data.name || data.name.length < 2) return false; |
| | | try { |
| | | if (this.ui.button) { |
| | | this.ui.button.disabled = true; |
| | | } |
| | | |
| | | const response = await this.createTerm(data); |
| | | |
| | | if (!response.success) { |
| | | // Term already exists - still add it |
| | | if (response.term && response.term.id) { |
| | | this.selector.setMessage(true, `Using existing "${response.term.name}"`); |
| | | return response.term; |
| | | } |
| | | |
| | | // Other failure |
| | | this.selector.setMessage(true, response.message || 'Creation failed', false); |
| | | return false; |
| | | } |
| | | if (response.term?.pending) { |
| | | // Term requires approval |
| | | this.selector.setMessage( |
| | | true, |
| | | `"${data.name}" submitted for approval`, |
| | | false |
| | | ); |
| | | // Don't add to selection since it's pending |
| | | return false; |
| | | } |
| | | if (response.success && response.term) { |
| | | await this.handleSuccessfulCreation(response.term, data); |
| | | this.clearForm(); |
| | | } |
| | | return response.term; |
| | | } catch (error) { |
| | | console.error('Error creating term:', error); |
| | | this.selector.handleError(error, 'handleTermCreation'); |
| | | } finally { |
| | | if (this.ui.button) { |
| | | this.ui.button.disabled = false; |
| | | } |
| | | return false; |
| | | } |
| | | } |
| | | |
| | |
| | | * Handle successful term creation |
| | | */ |
| | | async handleSuccessfulCreation(term, data) { |
| | | const termPath = term.path || term.name; |
| | | // Close create form |
| | | this.ui.details.open = false; |
| | | |
| | | // Clear cache to ensure fresh data |
| | | await this.selector.store.clearCache(); |
| | | |
| | | // Add to DataStore |
| | | this.selector.store.data.set(term.id, { |
| | | id: term.id, |
| | | name: term.name, |
| | | path: termPath, |
| | | taxonomy: data.taxonomy, |
| | | parent: data.parent, |
| | | count: 0, |
| | | hasChildren: false, |
| | | slug: term.slug || term.name.toLowerCase().replace(/\s+/g, '-') |
| | | }); |
| | | |
| | | // Add to modal selection |
| | | this.selector.addSelected(term.id,this.selector.activeField); |
| | | |
| | | // Refresh current view if we're viewing the same parent |
| | | if (this.selector.container.open) { |
| | | const currentParent = this.selector.store.filters.parent || 0; |
| | | if (currentParent === data.parent) { |
| | | await this.selector.store.setFilters({ |
| | | taxonomy: data.taxonomy, |
| | | parent: data.parent, |
| | | page: 1, |
| | | search: '' |
| | | }); |
| | | } |
| | | } |
| | | this.selector.store.clearCache(); |
| | | await this.selector.store.fetch(); |
| | | } |
| | | |
| | | /** |
| | |
| | | if (this.ui.name) { |
| | | this.ui.name.value = ''; |
| | | } |
| | | if (this.selector.ui.search.input){ |
| | | this.selector.ui.search.input.value = ''; |
| | | } |
| | | } |
| | | |
| | | /** |