| 1 |
/** |
| 2 |
* Fields admin page — section visibility toggling and client-side validation. |
| 3 |
* |
| 4 |
* @package ContactForms |
| 5 |
* @since 2.2.5 |
| 6 |
*/ |
| 7 |
/* global accuaFieldsPage */ |
| 8 |
jQuery( function( $ ) { |
| 9 |
var typeSelect = $( '#parent' ); |
| 10 |
var l10n = accuaFieldsPage.l10n; |
| 11 |
|
| 12 |
// Field types that support each section |
| 13 |
var hasDefaultValue = [ 'textfield', 'textarea', 'email', 'autoreply_email', 'telephone', 'checkbox', 'select', 'radio', 'multiselect', 'multicheckbox', 'colorpicker', 'hidden', 'password', 'password-and-confirm' ]; |
| 14 |
var hasAllowedValues = [ 'select', 'radio', 'multiselect', 'multicheckbox', 'post-select', 'post-multicheckbox', 'file' ]; |
| 15 |
var hasDate = [ 'date' ]; |
| 16 |
var hasCustomRequired = [ 'textfield', 'textarea', 'email', 'autoreply_email', 'telephone', 'checkbox', 'select', 'radio', 'multiselect', 'multicheckbox', 'post-select', 'post-multicheckbox', 'colorpicker', 'file', 'password', 'password-and-confirm', 'date' ]; |
| 17 |
var hasCustomFormat = [ 'email', 'autoreply_email', 'telephone' ]; |
| 18 |
var hasDescription = [ 'textfield', 'textarea', 'email', 'autoreply_email', 'telephone', 'checkbox', 'select', 'radio', 'multiselect', 'multicheckbox', 'post-select', 'post-multicheckbox', 'colorpicker', 'hidden', 'file', 'password', 'password-and-confirm', 'date' ]; |
| 19 |
|
| 20 |
function updateVisibility() { |
| 21 |
var type = typeSelect.val(); |
| 22 |
$( '#field-section-default-value' ).toggle( hasDefaultValue.indexOf( type ) !== -1 ); |
| 23 |
$( '#field-section-allowed-values' ).toggle( hasAllowedValues.indexOf( type ) !== -1 ); |
| 24 |
$( '#field-section-date' ).toggle( hasDate.indexOf( type ) !== -1 ); |
| 25 |
$( '#field-section-custom-required' ).toggle( hasCustomRequired.indexOf( type ) !== -1 ); |
| 26 |
$( '#field-section-custom-format' ).toggle( hasCustomFormat.indexOf( type ) !== -1 ); |
| 27 |
$( '#tag-description' ).closest( '.form-field' ).toggle( hasDescription.indexOf( type ) !== -1 ); |
| 28 |
|
| 29 |
// Update allowed values help text based on type |
| 30 |
if ( type === 'file' ) { |
| 31 |
$( '#allowed-values-label' ).text( l10n.allowedExtensionsLabel ); |
| 32 |
$( '#allowed-values-help' ).text( l10n.allowedExtensionsHelp ); |
| 33 |
} else { |
| 34 |
$( '#allowed-values-label' ).text( l10n.allowedValuesLabel ); |
| 35 |
$( '#allowed-values-help' ).text( l10n.allowedValuesHelp ); |
| 36 |
} |
| 37 |
} |
| 38 |
|
| 39 |
typeSelect.on( 'change', updateVisibility ); |
| 40 |
updateVisibility(); |
| 41 |
|
| 42 |
// Client-side validation |
| 43 |
var typesNeedingAllowedValues = [ 'select', 'radio', 'multiselect', 'multicheckbox' ]; |
| 44 |
|
| 45 |
$( '#addtag' ).on( 'submit', function( e ) { |
| 46 |
var valid = true; |
| 47 |
var errors = []; |
| 48 |
|
| 49 |
// Remove previous error highlights and messages |
| 50 |
$( this ).find( '.form-invalid' ).removeClass( 'form-invalid' ); |
| 51 |
$( this ).prev( '.field-error-message' ).remove(); |
| 52 |
|
| 53 |
// Validate label |
| 54 |
var $label = $( '#tag-name' ); |
| 55 |
if ( $.trim( $label.val() ) === '' ) { |
| 56 |
$label.closest( '.form-field' ).addClass( 'form-invalid' ); |
| 57 |
errors.push( l10n.errorLabelRequired ); |
| 58 |
valid = false; |
| 59 |
} |
| 60 |
|
| 61 |
// Validate slug (only when adding) |
| 62 |
var $slug = $( '#tag-slug' ); |
| 63 |
if ( ! $slug.prop( 'disabled' ) && $.trim( $slug.val() ) === '' ) { |
| 64 |
$slug.closest( '.form-field' ).addClass( 'form-invalid' ); |
| 65 |
errors.push( l10n.errorSlugRequired ); |
| 66 |
valid = false; |
| 67 |
} |
| 68 |
|
| 69 |
// Validate allowed values (when visible and required) |
| 70 |
var type = typeSelect.val(); |
| 71 |
if ( typesNeedingAllowedValues.indexOf( type ) !== -1 ) { |
| 72 |
var $allowed = $( '#form-field-allowed-values' ); |
| 73 |
if ( $.trim( $allowed.val() ) === '' ) { |
| 74 |
$allowed.closest( '.form-field' ).addClass( 'form-invalid' ); |
| 75 |
errors.push( l10n.errorAllowedValuesRequired ); |
| 76 |
valid = false; |
| 77 |
} |
| 78 |
} |
| 79 |
|
| 80 |
if ( ! valid ) { |
| 81 |
e.preventDefault(); |
| 82 |
// Show error message |
| 83 |
var errorHtml = '<div class="notice notice-error field-error-message" role="alert"><p>' + errors.join( '</p><p>' ) + '</p></div>'; |
| 84 |
$( this ).before( errorHtml ); |
| 85 |
// Announce for screen readers |
| 86 |
if ( window.wp && wp.a11y && wp.a11y.speak ) { |
| 87 |
wp.a11y.speak( errors.join( '. ' ), 'assertive' ); |
| 88 |
} |
| 89 |
// Focus first invalid field |
| 90 |
var $firstInvalid = $( this ).find( '.form-invalid:first' ); |
| 91 |
if ( $firstInvalid.length ) { |
| 92 |
$firstInvalid.find( 'input, textarea, select' ).first().trigger( 'focus' ); |
| 93 |
} |
| 94 |
} |
| 95 |
} ); |
| 96 |
|
| 97 |
// Remove error highlight on input |
| 98 |
$( '#addtag' ).on( 'input change', 'input, textarea, select', function() { |
| 99 |
$( this ).closest( '.form-field' ).removeClass( 'form-invalid' ); |
| 100 |
} ); |
| 101 |
} ); |
| 102 |
|