Support » Developing with WordPress » Updating Gutenberg block properties from external JS and persisting

  • I have a plugin that is using a jQuery script that creates a popup when certain text input form elements are clicked on within the WP admin pages/editors to provide a nice UI to select data to populate these. When this popup overlay is closed the chosen value is then passed back and updates the input text field value.

    The popup UI is used as the selection is more complex than feasible within the block’s property sidebar. It is also shared with other areas of WordPress, e.g. admin pages, MCE shortcode UIs and classic/block widget UIs. Hence, nice to have something common that can popup, take user input and propagate the value back to the original form element.

    However, I’ve come unstuck when using this in the Gutenburg block editor. The property field input is populated, however, the change is not registered, the post ‘Update’ button remains disabled and any interaction with other fields will revert the content of the programmatically updated text input.

    The field has an onChange event handler to persist updates to the props array passed into the edit function:

    el(TextControl,
      {
        type: 'text',
        label: __( 'Category ID', 'myplugin' ),
        value: props.attributes.category,
        class: 'category_input',
        onChange: function ( value ) {
          props.setAttributes( { category: value } );
        },
      }
    ),

    The script that updates this text input field despatches a change event that bubbles up (this was required to get the classic widget editor to enable the ‘save’ button):

    
        $($category_input).val( $("#cat_popup_chosen").val() );
        $category_input.dispatchEvent(new Event('change', { 'bubbles': true }));
    

    However, this does not trigger the above onChange within the block editor edit UI.

    Any suggestions on how to trigger the block editor’s edit UI onChange to ensure the new value is persisted in the properties would be much appreciated.

    Is this even the right approach? Or will I need a different tact and have to interact with the Block editor back store of data, e.g. via wp.data.dispatch?

    Many thanks!

    • This topic was modified 2 weeks, 6 days ago by Arthur Yarwood. Reason: formatting
Viewing 4 replies - 1 through 4 (of 4 total)
  • Hi @arfa_

    However, I’ve come unstuck when using this in the Gutenburg block editor. The property field input is populated, however, the change is not registered, the post ‘Update’ button remains disabled and any interaction with other fields will revert the content of the programmatically updated text input.

    To clarify here, are you saying that the popup’s functionality works, and when the popup overlay closes, the data entered in the popup is populated in the TextControl element in the block editor, but it’s just not saved, i.e. not triggering the TextControl’s onChange event, which would pass the data back to the block attributes?

    Have you been able to confirm that there are no errors in your browser’s console when the popup overlay is closed?

    Thread Starter Arthur Yarwood

    (@arfa_)

    Hi @pyskro

    Yes, that was correct, and no errors in the console window. The input field would update visually, but revert if I edited any other field on the form, or clicked away from the block and back. Clearly the new value was not being persisted in the underlying data model as no onchange event was hit. Setting a debugger breakpoint on the block editor form input onchange handler confirmed this.

    As it happens, I’ve since resolved this myself, these are the changes I needed when setting the value and firing the event, for those interested:

    var nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
        nativeInputValueSetter.call($category_input, $("#cat_popup_chosen").val());
        var ev2 = new Event('input', { bubbles: true});
        $category_input.dispatchEvent(ev2);
    

    The crucial part was applying the new value to the input via the getOwnPropertyDescriptor method and not trying to set it directly via the $($category_input).val() method. It was only when I removed this call to $($category_input).val() did the above code.

    I admit I’m not 100% sure of why there is a difference here with the Gutenberg editor. In other areas, either approach works (e.g. classic widget editor, TinyMCE editor, admin page input fields etc). Eitherway, it works now!

    Ah, thanks for the update @arfa_. Congrats on figuring it out. Please feel free to mark this as resolved.

    Thread Starter Arthur Yarwood

    (@arfa_)

    No prob, many thanks nonetheless!

Viewing 4 replies - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.