| | |
| | | } |
| | | |
| | | if (window.targetCheck(e, '.submit-term')) { |
| | | this.handleTermCreation(e); |
| | | this.handleTermCreation(e).then(()=>{}); |
| | | } |
| | | |
| | | // Handle autocomplete create button |
| | | if (window.targetCheck(e, '.create-term')) { |
| | | this.handleAutocompleteCreate(e); |
| | | this.handleAutocompleteCreate(e).then(()=>{}); |
| | | } |
| | | } |
| | | |
| | |
| | | if (!termName) return; |
| | | |
| | | try { |
| | | this.form.querySelector('button').disabled = true; |
| | | const submitButton = this.form.querySelector('button'); |
| | | if (submitButton) { |
| | | submitButton.disabled = true; |
| | | } |
| | | const response = await this.createTerm(termName, parentId, taxonomy); |
| | | |
| | | if (response.success && response.term) { |
| | | let term = response.term; |
| | | const termPath = term.path || term.name; |
| | | |
| | | this.createNew.open = false; |
| | | await this.selector.store.clearCache(); |
| | | |
| | | // Add to store's data BEFORE display update |
| | | this.selector.store.data.set(term.id, { |
| | | id: term.id, |
| | | name: term.name, |
| | | path: termPath, |
| | | taxonomy: field.taxonomy, |
| | | parent: 0, |
| | | taxonomy: taxonomy, |
| | | parent: parentId, |
| | | count: 0, |
| | | hasChildren: false, |
| | | slug: term.slug || termName.toLowerCase().replace(/\s+/g, '-') |
| | | }); |
| | | |
| | | this.selector.addSelectedTermToModal(term.id, term.name, term.path || term.name); |
| | | this.selector.addSelectedTermToModal(term.id, term.name, termPath); |
| | | |
| | | const currentParent = this.selector.store.filters.parent || 0; |
| | | if (currentParent === parentId) { |
| | |
| | | if (suggestionContainer) { |
| | | suggestionContainer.hidden = true; |
| | | } |
| | | this.selector.store.cache.clear(); |
| | | |
| | | } |
| | | } catch (error) { |
| | | console.error('Error creating term:', error); |
| | |
| | | const termPath = term.path || term.name; |
| | | |
| | | field.selectedTerms.add(parseInt(term.id)); |
| | | // Add to store's data BEFORE display update |
| | | this.selector.store.data.set(term.id, { |
| | | id: term.id, |
| | | name: term.name, |
| | |
| | | field.autocompleteDropdown.hidden = true; |
| | | if (input) input.value = ''; |
| | | |
| | | // Only clear cache, don't refetch - term is already in store.data |
| | | this.selector.store.clearCache(); |
| | | await this.selector.store.setFilters({ |
| | | taxonomy: field.taxonomy, |
| | | page: 1, |
| | | search: '', |
| | | parent: 0 |
| | | }); |
| | | } else if (response.reason === 'exists' && response.term) { |
| | | // Term already exists - just add it |
| | | const term = response.term; |
| | | field.selectedTerms.add(parseInt(term.id)); |
| | | this.selector.addTermToDisplay(field.id, term.id, term.name, term.path || term.name); |
| | |
| | | } |
| | | } catch (error) { |
| | | console.error('Error creating term:', error); |
| | | button.innerHTML = originalHTML; |
| | | button.disabled = false; |
| | | this.selector.error?.log(error, { |
| | | component: 'TaxonomyCreator', |
| | | action: 'handleAutocompleteCreate' |
| | | }); |
| | | } finally { |
| | | button.innerHTML = originalHTML; |
| | | button.disabled = false; |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | async createTerm(name, parent = 0, taxonomy) { |
| | | try { |
| | | // Search for the exact term first |
| | | await this.selector.store.setFilters({ |
| | | taxonomy: taxonomy, |
| | | search: name, |
| | | page: 1, |
| | | parent: 0 |
| | | }); |
| | | |
| | | // Check if exact match exists in results |
| | | // Check existing data first without fetching |
| | | const exactMatch = Array.from(this.selector.store.data.values()) |
| | | .find(term => |
| | | term.taxonomy === taxonomy && |
| | |
| | | ); |
| | | |
| | | if (exactMatch) { |
| | | // For modal context, show suggestions |
| | | if (this.createNew) { |
| | | this.showTermSuggestions([exactMatch], true); |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * Search for existing terms using the store |
| | | */ |
| | | async searchExistingTerms(searchQuery, taxonomy) { |
| | | return new Promise((resolve) => { |
| | | // Set up a one-time listener for the search results |
| | | const handleSearchResults = (event, data) => { |
| | | if (event === 'data-loaded') { |
| | | this.selector.store.unsubscribe(handleSearchResults); |
| | | resolve(data.data?.items || []); |
| | | } |
| | | }; |
| | | |
| | | this.selector.store.subscribe(handleSearchResults); |
| | | |
| | | // Trigger search |
| | | this.selector.store.setFilters({ |
| | | taxonomy: taxonomy, |
| | | search: searchQuery, |
| | | page: 1, |
| | | parent: 0 |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * Show term suggestions when similar terms exist |
| | | */ |
| | | showTermSuggestions(suggestions, isExact = false) { |