htmlburger / carbon-fields

WordPress Custom Fields Library ✨
https://carbonfields.net/
Other
1.38k stars 244 forks source link

How to use the new js hooks? #725

Open alessandrotesoro opened 5 years ago

alessandrotesoro commented 5 years ago

I've noticed today that the old javascript hooks aren't working anymore in v3+ of CF. So I went into the docs to see if something has changed and noticed they've been replaced with the @wordpress/hooks package.

For the last two hours I've been trying to use the new validation but nothing that I've tried worked. Is there an actual example on how to use that package with carbon fields?

This is my code right here, which I'm pretty sure is wrong :/ but have no idea how it works.

import { createHooks } from '@wordpress/hooks';

let ValidateCF = createHooks();

ValidateCF.addFilter( 'carbon-fields.text.validate', 'whatever', ( field, value ) => {
    console.log( field, value )

    return 'error message here?'
} );
4irdev commented 5 years ago

I have the same problem+

lstoyanoff commented 4 years ago

I've been struggling with the same problem and I've found that workaround:

$(document).ready(function(){
    window.cf.hooks.addFilter('carbon-fields.text.validate', 'some_namespace', ( field, value ) => {
        return 'Error message';
    });
});
tcj-rocks commented 4 years ago

I'm having zero luck getting this to work in v3.1.20 and the documentation on it is garbage. Specifically I am attempting the field validation hook, and more specifically, text fields. Using @lstoyanoff's example exactly as written yields nothing.

Other hooks such as this works in the same space:

window.cf.hooks.addFilter('carbon-fields.field-wrapper', 'some_namespace', ( field ) => {
    // Do something here
    return field;
});

Can anyone enlighten me as to what to do for text field validation via JS? These are text fields within tabs within standard theme option containers.

pagelab commented 3 years ago

Until the documentation on JS hooks improves, you can add the HTML pattern attribute to your text field definition to validate it via browser (it doesn't work with the textarea field, unfortunately).

Example:

Field::make( 'text', 'cf_text', __( 'Field name', 'textdomain' ) )
    ->set_attribute( 'pattern', '[a-zA-Z0-9\-]+' ) // Any regex will do
) )

You can even customize the error messages with the native Constraint validation API

Here's an example.

pagelab commented 3 years ago

Custom error messages using the Constraint Validation API.

// This works in tandem with the pattern attribute for each text input.
jQuery(document).ready(function($) {

    // Displays error messages in the “blur” event of inputs.
    var forms = document.querySelector( '#theme-options-form' );
    document.forms[0].addEventListener( 'blur', function (e) {
        if ( e.target.matches('input') ) { // Exclude textareas.
            e.target.reportValidity();
        }
    }, true );

    // Custom error message for single text input.
    var singleTextField = document.querySelector( '.my-text-field input' );
    singleTextField.oninvalid = function (e) {
        e.target.setCustomValidity( '' );
        if ( ! e.target.validity.valid ) {
            e.target.setCustomValidity( my_i18n.input_error ); // Custom error message via wp_localize_script.
        }
    }

    // Custom error message for text inputs in a complex field.
    var multipleTextFields = document.querySelectorAll('.epc-metatags .cf-text__input' );
    for ( var i = 0; i < multipleTextFields.length; i++ ) {
        multipleTextFields[i].oninvalid = function (e) {
            e.target.setCustomValidity( '' );
            if ( ! e.target.validity.valid ) {
                e.target.setCustomValidity( my_i18n.input_error ); // Custom error message via wp_localize_script.
            }
        }
    }
});
aheissenberger commented 2 years ago

This worked for me to get a better validation of number fields - browser builtin validation failed to block negative values:

Field::make('text', 'participants_slots_max', __('Participants'))
                    ->set_attribute('type', 'number')
                    ->set_attribute('min', '0')
                    ->set_required(true)
                    ->set_default_value('60')
                    ->set_width(25),

carbonfields-validation.js:

jQuery(document).ready(function(){
    window.cf.hooks.addFilter('carbon-fields.text.validate', 'carbon-fields/text', ( field, value ) => {
        if (field?.attributes?.type==='number') {
            valueNumber = parseFloat(value)
            if (isNaN(valueNumber)) return 'No Number!'
            if (field.attributes?.min) {
                if (valueNumber<parseFloat(field.attributes.min)) return `Number lower than ${field.attributes.min}!`
            }
            if (field.attributes?.max) {
                if (valueNumber>parseFloat(field.attributes.max)) return `Number higher than ${field.attributes.max}`
            }
        }
    });
});

load the javascript in post editor only for the e.g. post type course, events:

add_action('admin_enqueue_scripts',   'xx_admin_scripts');
public function xx_admin_scripts($hook_suffix)
    {
        if (in_array($hook_suffix, array('post.php', 'post-new.php'))) {
            $screen = get_current_screen();
            if (is_object($screen) && in_array($screen->post_type, ['course', 'events'])) {
                wp_enqueue_script('a1b-carbonfields-admin-script', plugins_url( '/path-to-your/carbonfields-validation.js',__FILE__));
            }
        }
    }