| | |
| | | $validationAttrs = $this->buildValidationAttributes($field); |
| | | $conditional = array_key_exists('condition', $field) ? $this->handleConditionalField($field) : ''; |
| | | |
| | | $pattern = array_key_exists('pattern', $field) ? $field['pattern'] : ''; |
| | | $customData = ''; |
| | | if (array_key_exists('data', $field) && !empty($field['data'])) { |
| | | foreach ($field['data'] as $key => $v) { |
| | |
| | | <div class="field <?= esc_attr($field['type']) ?> <?= esc_attr($name) ?>" |
| | | <?= $conditional ?> |
| | | data-field="<?= esc_attr($name) ?>" |
| | | data-field-type="<?=esc_attr($field['type'])?>" |
| | | <?= $validationAttrs ?>> |
| | | |
| | | <?php $this->renderLabel($name, $field); ?> |
| | |
| | | value="<?= esc_attr($data['value']) ?>" |
| | | <?= $inputAttrs ?> |
| | | <?= $customData?> |
| | | <?= $pattern?> |
| | | > |
| | | <span class="validation-icon success" hidden aria-hidden="true"> |
| | | <?= jvbIcon('check-circle') ?> |
| | |
| | | <div class="field <?= esc_attr($field['type']) ?> <?= esc_attr($name) ?>" |
| | | <?= $conditional ?> |
| | | data-field="<?= esc_attr($name) ?>" |
| | | data-field-type="<?=esc_attr($field['type'])?>" |
| | | <?= $validationAttrs ?>> |
| | | |
| | | <?php $this->renderLabel($name, $field); ?> |
| | |
| | | <div class="field <?= esc_attr($field['type']) ?> <?= esc_attr($name) ?> row" |
| | | <?= $conditional ?> |
| | | data-field="<?= esc_attr($name) ?>" |
| | | data-field-type="<?=esc_attr($field['type'])?>" |
| | | <?= $validationAttrs ?>> |
| | | |
| | | <?php $this->renderLabel($name, $field); ?> |
| | |
| | | <div class="field <?= esc_attr($field['type']) ?> <?= esc_attr($name) ?>" |
| | | <?= $conditional ?> |
| | | data-field="<?= esc_attr($name) ?>" |
| | | data-field-type="<?=esc_attr($field['type'])?>" |
| | | <?= $validationAttrs ?>> |
| | | |
| | | <?php $this->renderLabel($name, $field); ?> |
| | |
| | | <div class="field <?= esc_attr($field['type']) ?> <?= esc_attr($name) ?>" |
| | | <?= $conditional ?> |
| | | data-field="<?= esc_attr($name) ?>" |
| | | data-field-type="<?=esc_attr($field['type'])?>" |
| | | <?= $validationAttrs ?>> |
| | | |
| | | <fieldset> |
| | |
| | | <div class="field <?= esc_attr($field['type']) ?> <?= esc_attr($name) ?>" |
| | | <?= $conditional ?> |
| | | data-field="<?= esc_attr($name) ?>" |
| | | data-field-type="<?=esc_attr($field['type'])?>" |
| | | <?= $validationAttrs ?>> |
| | | |
| | | <fieldset> |
| | |
| | | <div class="field true-false <?= esc_attr($name) ?> row btw" |
| | | <?= $conditional ?> |
| | | data-field="<?= esc_attr($name) ?>" |
| | | data-field-type="<?=esc_attr($field['type'])?>" |
| | | <?= $validationAttrs ?>> |
| | | |
| | | <label class="toggle-switch row" <?= $describedBy ?>> |
| | |
| | | ?> |
| | | <div class="field repeater <?=$name?>" |
| | | data-field="<?= esc_attr($name); ?>" |
| | | data-field-type="<?=esc_attr($field['type'])?>" |
| | | <?= $describedBy ?> |
| | | <?= $row_label ? 'data-label="' . esc_attr($row_label) . '"' : ''; ?> |
| | | <?=$conditional?>> |
| | |
| | | ?> |
| | | </div> |
| | | |
| | | <template class="<?=uniqid('repeaterTemplate')?>"> |
| | | <template class="<?=uniqid('repeaterRow')?>"> |
| | | <?php $this->renderRepeaterRow($field['fields'], array(), '', '', $rowTitle); ?> |
| | | </template> |
| | | |
| | |
| | | ?> |
| | | <<?= $fieldset?> class="field group <?= esc_attr($name) ?>" |
| | | <?= $conditional ?> |
| | | data-field="<?= esc_attr($name) ?>" |
| | | data-field="<?= esc_attr($name) ?>" |
| | | data-field-type="<?=esc_attr($field['type'])?>" |
| | | <?= $validationAttrs ?> |
| | | <?= $describedBy ?>> |
| | | <<?=$legend?>><?= esc_html($field['label']) ?></<?=$legend?>> |
| | |
| | | { |
| | | foreach ($field['fields'] as $field_name => $config) { |
| | | // Set the group context for proper field naming |
| | | $config['group'] = $groupName; |
| | | if (!array_key_exists('wrap', $field) || $field['wrap'] !== 'details') { |
| | | $config['group'] = $groupName; |
| | | } |
| | | |
| | | // Get the value for this specific field |
| | | $field_value = $values[$field_name] ?? ''; |
| | |
| | | |
| | | // Build accept attribute for input |
| | | $acceptExtensions = $this->getMimeExtensions($acceptedTypes); |
| | | $acceptAttr = implode(',', $acceptExtensions); |
| | | $acceptAttr = implode(',', $acceptedTypes); |
| | | |
| | | // Determine field attributes |
| | | $subtype = $config['subtype'] ?? 'image'; |
| | |
| | | } |
| | | ?> |
| | | <div class="field upload <?= esc_attr($name) ?>" |
| | | data-field="<?=esc_attr($name)?>" |
| | | data-field-type="upload" |
| | | <?= $dataAttrString ?> |
| | | <?= $conditional ?>> |
| | | |
| | |
| | | $dataID = ($id) ? ['id' => $id] : ''; |
| | | ?> |
| | | <div class="item upload"<?= ($id) ? ' data-id="'.$id.'"' : '' ?>> |
| | | <div class="preview"> |
| | | <?php jvbRenderProgressBar('',true) ?> |
| | | <input type="checkbox" class="upload-select" name="select-item" id="select-item<?=$addID?>"> |
| | | <label for="select-item<?=$addID?>" aria-label="Select image"> |
| | | <?= ($attachment) ?: '<img> |
| | | <video></video> |
| | | <span></span>' ?> |
| | | </label> |
| | | <div class="item-actions row btw"> |
| | | <div class="radio-button"> |
| | | <input type="radio" class="featured btn" name="featured" id="featured" hidden> |
| | | <label for="featured"> |
| | | <?=jvbIcon('star')?> |
| | | <?=jvbIcon('star', ['style' => 'fill'])?> |
| | | <span class="screen-reader-text">Set as featured image</span> |
| | | </label> |
| | | </div> |
| | | |
| | | <button type="button" data-action="delete-upload" title="Remove from Group"> |
| | | <?=jvbIcon('trash')?> |
| | | </button> |
| | | <div class="preview"> |
| | | <?php jvbRenderProgressBar('',true) ?> |
| | | <input type="checkbox" class="upload-select" name="select-item" id="select-item<?=$addID?>"> |
| | | <label for="select-item<?=$addID?>" aria-label="Select image"> |
| | | <?= ($attachment) ?: '<img> |
| | | <video></video> |
| | | <span></span>' ?> |
| | | </label> |
| | | <div class="item-actions row btw"> |
| | | <div class="radio-button"> |
| | | <input type="radio" class="featured btn" name="featured" id="featured" hidden> |
| | | <label for="featured"> |
| | | <?=jvbIcon('star')?> |
| | | <?=jvbIcon('star', ['style' => 'fill'])?> |
| | | <span class="screen-reader-text">Set as featured image</span> |
| | | </label> |
| | | </div> |
| | | |
| | | <button type="button" data-action="delete-upload" title="Remove from Group"> |
| | | <?=jvbIcon('trash')?> |
| | | </button> |
| | | </div> |
| | | <details> |
| | | <summary class="row btw"><?=jvbIcon('pencil-simple')?><span>Edit Info</span></summary> |
| | | </div> |
| | | <details> |
| | | <summary class="row btw"><?=jvbIcon('pencil-simple')?><span>Edit Info</span></summary> |
| | | |
| | | <?php |
| | | <?php |
| | | |
| | | $fields = array_key_exists('fields', $config) ? $config['fields'] : []; |
| | | $fields = array_merge([ |
| | | 'upload_data' => [ |
| | | 'type' => 'group', |
| | | 'wrap' => 'details', |
| | | 'label' => 'Image Info', |
| | | 'hint' => 'These will be automatically generated if left blank.', |
| | | 'fields' => [ |
| | | 'image-title'.$addID => [ |
| | | 'type' => 'text', |
| | | 'label' => 'Image Title', |
| | | 'value' => $title, |
| | | 'data' => $dataID |
| | | ], |
| | | 'image-alt-text'.$addID => [ |
| | | 'type' => 'text', |
| | | 'label' => 'Alt Text', |
| | | 'value' => $alt, |
| | | 'hint' => 'Alt text helps the visually impaired, as well as some benefits for SEO.', |
| | | 'data' => $dataID |
| | | ], |
| | | 'image-caption'.$addID => [ |
| | | 'type' => 'textarea', |
| | | 'value' => $caption, |
| | | 'label' => 'Image Caption', |
| | | 'data' => $dataID |
| | | $fields = [ |
| | | 'image_data' => [ |
| | | 'type' => 'group', |
| | | 'wrap' => 'details', |
| | | 'label' => 'Image Fields', |
| | | 'fields' => [ |
| | | 'image-title'.$addID => [ |
| | | 'type' => 'text', |
| | | 'label' => 'Image Title', |
| | | 'value' => $title, |
| | | 'data' => $dataID |
| | | ], |
| | | 'image-alt-text'.$addID => [ |
| | | 'type' => 'text', |
| | | 'label' => 'Alt Text', |
| | | 'value' => $alt, |
| | | 'hint' => 'Alt text helps the visually impaired, as well as some benefits for SEO.', |
| | | 'data' => $dataID |
| | | ], |
| | | 'image-caption'.$addID => [ |
| | | 'type' => 'textarea', |
| | | 'value' => $caption, |
| | | 'label' => 'Image Caption', |
| | | 'data' => $dataID |
| | | ] |
| | | ] |
| | | ] |
| | | ] |
| | | ] |
| | | ], $fields); |
| | | |
| | | $meta = new MetaManager($id); |
| | | foreach ($fields as $field => $config) { |
| | | $meta->render('form', $field, $config); |
| | | } |
| | | ?> |
| | | </details> |
| | | ]; |
| | | $fields = array_key_exists('fields', $config) ? array_merge($fields, $config['fields']) : $fields; |
| | | $meta = new MetaManager($id); |
| | | foreach ($fields as $field => $config) { |
| | | $meta->render('form', $field, $config); |
| | | } |
| | | ?> |
| | | </details> |
| | | </div> |
| | | <?php |
| | | } |
| | |
| | | <?php jvbRenderProgressBar('',true) ?> |
| | | <input type="checkbox" class="upload-select" name="select-item" id="select-item<?=$addID?>"> |
| | | <label for="select-item<?=$addID?>" aria-label="Select image"> |
| | | <?= ($attachment) ? $attachment : '<img> |
| | | <?= ($attachment) ?: '<img> |
| | | <video></video> |
| | | <span></span>'; ?> |
| | | </label> |
| | |
| | | <?php jvbRenderProgressBar('',true) ?> |
| | | <input type="checkbox" class="upload-select" name="select-item" id="select-item<?=$addID?>"> |
| | | <label for="select-item<?=$addID?>" aria-label="Select image"> |
| | | <?= ($attachment) ? $attachment : '<img> |
| | | <?= ($attachment) ?: '<img> |
| | | <video></video> |
| | | <span></span>'; ?> |
| | | </label> |
| | |
| | | * Generic selector field renderer |
| | | * Handles both taxonomy and post selectors with consistent structure |
| | | */ |
| | | private function renderSelectorField(string $name, mixed $value, array $field, string $type): void |
| | | public function renderSelectorField(string $name, mixed $value, array $field, string $type): void |
| | | { |
| | | $conditional = $this->handleConditionalField($field); |
| | | $validationAttrs = $this->buildValidationAttributes($field); |
| | | $describedBy = (!empty($field['description'])) ? ' aria-describedby="' . $name . '-help"' : ''; |
| | | |
| | | $isSimple = (array_key_exists('mode', $field) && $field['mode']==='simple'); |
| | | // Parse selected values |
| | | $value = (is_array($value)) ? array_filter(array_map('absint', $value)): $value; |
| | | $selected = ($value === '') ? [] : (is_array($value) ? $value : explode(',', $value)); |
| | |
| | | } |
| | | |
| | | ?> |
| | | <div class="field <?= esc_attr($type) ?> <?= esc_attr($name) ?>" |
| | | <div class="field selector <?= esc_attr($type) ?> <?= esc_attr($name) ?>" |
| | | <?= $conditional ?> |
| | | data-field="<?= esc_attr($name) ?>" |
| | | data-field-type="selector" |
| | | data-type="<?=esc_attr($field['type'])?>" |
| | | <?= $validationAttrs ?> |
| | | <?= $describedBy ?>> |
| | | |
| | |
| | | |
| | | <div class="field location <?= esc_attr($field_id) ?>" |
| | | data-field="<?= esc_attr($field_id) ?>" |
| | | data-field-type="<?=esc_attr($field['type'])?>" |
| | | data-location-field-init="<?= $json_config ?>"<?=$describedBy?>> |
| | | |
| | | <?php |
| | |
| | | |
| | | // Default types based on subtype |
| | | $defaults = [ |
| | | 'image' => ['image/jpeg', 'image/png', 'image/gif', 'image/webp'], |
| | | 'video' => ['video/mp4', 'video/webm', 'video/ogg'], |
| | | 'document' => ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'], |
| | | 'any' => ['image/*', 'video/*', 'application/pdf'] |
| | | 'image' => ['image/*'], |
| | | 'video' => ['video/*'], |
| | | 'document' => ['application/pdf', 'application/msword', 'application/vnd.ms-excel', 'text/plain', '.odt','application/vnd.openxmlformats-officedocument.wordprocessingml.document'], |
| | | ]; |
| | | $defaults['any'] = array_merge($defaults['image'], $defaults['video'], $defaults['document']); |
| | | |
| | | return $defaults[$config['subtype']] ?? $defaults['image']; |
| | | } |
| | |
| | | ?> |
| | | <div class="field tag-list <?= esc_attr($name) ?>" |
| | | data-field="<?= esc_attr($name) ?>" |
| | | data-field-type="<?=esc_attr($field['type'])?>" |
| | | data-tag-format="<?= esc_attr($tagFormat) ?>" |
| | | <?= $describedBy ?> |
| | | <?= $conditional ?> |
| | |
| | | </div> |
| | | |
| | | <!-- Template for new tags --> |
| | | <template class="tag-template"> |
| | | <template class="<?=uniqid('tagListItem')?>"> |
| | | <?php $this->renderTagItem($field['fields'], [], '', $name, $tagFormat); ?> |
| | | </template> |
| | | |
| | |
| | | <input type="hidden" |
| | | name="<?= esc_attr($full_name) ?>" |
| | | value="<?= esc_attr($value) ?>" |
| | | data-field="<?= esc_attr($field_name) ?>" /> |
| | | data-field="<?= esc_attr($field_name) ?>" |
| | | data-field-type="<?=esc_attr($field_config['type'])?>" /> |
| | | <?php endforeach; ?> |
| | | |
| | | <button type="button" class="remove-tag" aria-label="Remove"> |