| | |
| | | <?php |
| | | namespace JVBase\forms; |
| | | |
| | | use JVBase\registrar\Registrar; |
| | | use WP_Term; |
| | | |
| | | if (!defined('ABSPATH')) { |
| | |
| | | protected string $base; |
| | | protected string $title; |
| | | protected array $config; |
| | | protected Registrar $registrar; |
| | | |
| | | public function __construct(string $id, string $taxonomy, array $config = []) { |
| | | $this->id = sanitize_key($id); |
| | | $this->taxonomy = jvbCheckBase($taxonomy); |
| | | $this->name = jvbNoBase($taxonomy); |
| | | |
| | | $this->title = JVB_TAXONOMY[$this->name]['plural']; |
| | | $this->base = $config['base']??''; |
| | | $registrar = Registrar::getInstance($this->name); |
| | | if ($registrar) { |
| | | $this->registrar = $registrar; |
| | | } |
| | | |
| | | $this->title = $registrar->getPlural(); |
| | | $this->base = $config['base']??''; |
| | | $this->config = wp_parse_args($config, [ |
| | | 'types' => false, // for feed block implementation |
| | | 'max' => 0, // 0 = unlimited |
| | |
| | | 'update' => true, // Whether to update on close |
| | | ]); |
| | | |
| | | $this->plural = JVB_TAXONOMY[$taxonomy]['plural']; |
| | | $this->singular = JVB_TAXONOMY[$taxonomy]['singular']; |
| | | $this->plural = $registrar->getPlural(); |
| | | $this->singular = $registrar->getSingular(); |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public static function getTermPath(WP_Term $term, bool $returnArray = false): string|array { |
| | | if (!is_taxonomy_hierarchical($term->taxonomy)) { |
| | | return $term->name; |
| | | return html_entity_decode($term->name); |
| | | } |
| | | |
| | | $path = []; |
| | | $currentTerm = $term; |
| | | |
| | | while ($currentTerm) { |
| | | array_unshift($path, $currentTerm->name); |
| | | array_unshift($path, html_entity_decode($currentTerm->name)); |
| | | |
| | | if ($currentTerm->parent) { |
| | | $currentTerm = get_term($currentTerm->parent); |
| | |
| | | <h3 id="modal-title">Select Taxonomy</h3> |
| | | </header> |
| | | |
| | | <div class="selected-items-section"> |
| | | <div class="selected-items row" role="region" aria-label="Selected items"> |
| | | <!-- Selected items will be populated here --> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="selected-items row" role="region" aria-label="Selected items"></div> |
| | | |
| | | <div class="items-wrap"> |
| | | <!-- Common/Favorite terms section --> |
| | | <details class="favourite-terms" hidden> |
| | | <summary class="title row btw">Your Go Tos:</summary> |
| | | <ul class="favourite-list row btw"></ul> |
| | | <summary class="title row x-btw">Your Go Tos:</summary> |
| | | <ul class="favourite-list row x-btw"></ul> |
| | | </details> |
| | | |
| | | <!-- Pagination info --> |
| | |
| | | </button> |
| | | </nav> |
| | | |
| | | |
| | | <p class="message" hidden aria-live="polite"> |
| | | { <span>loading items</span> } |
| | | </p> |
| | | <!-- Terms list --> |
| | | <ul class="items-container col start" role="listbox" aria-label="Available terms"> |
| | | <ul class="items-container col top" role="listbox" aria-label="Available terms"> |
| | | <!-- Terms will be populated here --> |
| | | </ul> |
| | | |
| | | <!-- Loading indicator --> |
| | | <p class="loading" hidden aria-live="polite"> |
| | | <span>loading items</span> |
| | | </p> |
| | | <button class="submit-term" hidden data-ignore><strong>Create: </strong> "<span></span>"</button> |
| | | |
| | | <!-- Infinite scroll sentinel --> |
| | | <div class="scroll-sentinel" aria-hidden="true"></div> |
| | |
| | | <!-- Search section --> |
| | | <div class="search-wrapper"> |
| | | <div class="search-bar"> |
| | | <?= jvbSearch('Search terms') ?> |
| | | <?= jvbSearch('Search terms', 'search-terms') ?> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- Create new term section --> |
| | | <details class="create-new-term" hidden> |
| | | <summary class="row btw">Add New Term</summary> |
| | | <details class="create-term" hidden> |
| | | <summary class="row x-btw">Add New Term</summary> |
| | | <div class="create-new-term-section"> |
| | | <form class="create-term-form" data-nocache data-form-id="create-term" data-save="terms"> |
| | | <form class="create-term" data-nocache data-form-id="create-term" data-save="terms"> |
| | | <div class="form-group"> |
| | | <label for="term_name">Term Name:</label> |
| | | <input type="text" name="term_name" id="term_name" required> |
| | |
| | | <option value="0">None (Top Level)</option> |
| | | </select> |
| | | </div> |
| | | |
| | | <button type="button" class="submit-term">Add Term</button> |
| | | </form> |
| | | |
| | | <div class="loading-message create-term" hidden> |
| | | <span id="typed-text"></span> |
| | | <span class="cursor">|</span> |
| | | </div> |
| | | </div> |
| | | </details> |
| | | <?= jvbModalActions(); ?> |
| | |
| | | <template class="loadingItems"> |
| | | <p>{ <span>loading items</span> }</p> |
| | | </template> |
| | | <template class="noResults"> |
| | | <template class="autocompleteItem"> |
| | | <li class="autocomplete item btn"></li> |
| | | </template> |
| | | <template class="noTermResults"> |
| | | <p>{ <span>nothing found</span> }</p> |
| | | </template> |
| | | <template class="termListItem"> |
| | | <li> |
| | | <input type ="checkbox"> |
| | | <input type="checkbox"> |
| | | <label> |
| | | <span class="term-name"></span> |
| | | </label> |
| | |
| | | <template class="selectedTerm"> |
| | | <div class="selected-item row"> |
| | | <span class="item-name"></span> |
| | | <button type="button" class="remove-item row"><?=jvbIcon('x')?></button> |
| | | <button type="button" class="remove-term row"><?=jvbIcon('x')?></button> |
| | | </div> |
| | | </template> |
| | | <template class="termBreadcrumb"> |
| | |
| | | ?> |
| | | <div class="jvb-selector <?= esc_attr($this->name) ?>" |
| | | id="<?= esc_attr($this->id) ?>"<?= $hidden ?>> |
| | | <div class="field-group-header row btw"> |
| | | <div class="field-group-header row x-btw"> |
| | | <label for="<?= $this->base ?><?= esc_attr($this->config['name']) ?>-autocomplete"> |
| | | <?= ($this->config['icon']) ? jvbIcon($this->config['icon']) : '' ?> |
| | | <span><?= $this->config['label'] ?></span> |
| | |
| | | </button> |
| | | <?php if ($hasAutocomplete !== '') { ?> |
| | | <input type="text" id="<?= $this->base ?><?= esc_attr($this->config['name']) ?>-autocomplete" autocomplete="off" data-ignore data-autocomplete> |
| | | <ul class="autocomplete-dropdown" hidden> |
| | | </ul> |
| | | <p class="message" hidden aria-live="polite"> |
| | | { <span>loading items</span> } |
| | | </p> |
| | | <div class="auto-wrapper" hidden> |
| | | <ul class="search-results"> |
| | | </ul> |
| | | <button class="submit-term" hidden data-ignore><strong>Create: </strong> "<span></span>"</button> |
| | | </div> |
| | | |
| | | <?php } ?> |
| | | </div> |
| | | |
| | | <div class="selected-items row" role="region" aria-label="Selected <?= esc_attr($this->plural) ?>"> |
| | | <?php if (!empty($selected)): ?> |
| | | <?php foreach ($selected as $termId): ?> |
| | | <?php $this->renderSelectedTerm($termId); ?> |
| | | <?php endforeach; ?> |
| | | <?php endif; ?> |
| | | </div> |
| | | |
| | | <?php |
| | | $selectedItems = ''; |
| | | if (!empty($selected)): |
| | | ob_start(); |
| | | foreach ($selected as $termId): |
| | | $this->renderSelectedTerm($termId); |
| | | endforeach; |
| | | $selectedItems = ob_get_clean(); |
| | | endif; |
| | | ?> |
| | | <div class="selected-items row" role="region" aria-label="Selected <?= esc_attr($this->plural) ?>"><?=$selectedItems?></div> |
| | | <?= $extra ?> |
| | | </div> |
| | | <?php |
| | |
| | | |
| | | protected function renderTaxonomyToggle(array $selected = [], string $extra = ''): string |
| | | { |
| | | return '<button type="button" data-filter="taxonomy" data-taxonomy="'.$this->name.'" title="Filter by '.$this->singular.'">'.jvbIcon($this->config['icon']).'<span class="label">'.$this->singular.'</span></button>'; |
| | | return sprintf( |
| | | '<button type="button" data-icon="%s" data-filter="taxonomy" data-taxonomy="%s" data-type="selector" data-single="%s" data-plural="%s" title="Filter by %s">%s<span class="label">%s</span></button>', |
| | | $this->registrar->getIcon(), |
| | | $this->name, |
| | | $this->singular, |
| | | $this->plural, |
| | | $this->singular, |
| | | jvbIcon($this->registrar->getIcon()), |
| | | $this->singular |
| | | ); |
| | | } |
| | | |
| | | /** |
| | |
| | | <div class="selected-item row" data-id="<?= esc_attr($termId) ?>"> |
| | | <span><?= esc_html($termPath) ?></span> |
| | | <button type="button" |
| | | class="remove-item row" |
| | | aria-label="Remove <?= esc_attr($term->name) ?>"> |
| | | class="remove-term row" |
| | | aria-label="Remove <?= html_entity_decode($term->name) ?>"> |
| | | <?= jvbIcon('x') ?> |
| | | </button> |
| | | </div> |