1

I have a SelectControl in a custom block, to set a meta field. It works, but would be better if it were a ComboboxControl, as the list of options is likely to grow, but I get errors when I switch it over to a Combobox - leaving all other settings the same. This is currently running on localhost, using WAMP.

Here's the definition:

                <ComboboxControl
                    label="Speaker"
                    options={speakeropts()}
                    help='Choose from list - new speakers need to be added to the list by an administrator'
                    value={ speakerValue }
                    onChange={ updateSpeakerValue }
                />

and the setup

        const speakerlist=wp.data.select('core').getEntityRecords('taxonomy', 'speakers',{order_by: 'name', per_page: 100});
        function speakeropts(){
            var options=[]; 
            options.push({value:'0', label:''}); // first entry on list is blank
        
            if (speakerlist) {
                speakerlist.forEach((sp) => { // simple foreach loop
                    options.push({value:sp.id, label:sp.name});
                });
            }
            return options;
        }
        const speakerValue = meta['ach-td-speaker'];
        function updateSpeakerValue( newValue ) {
            setMeta( { ...meta, 'ach-td-speaker': newValue } );
        };

There are two issues.

  1. Clicking in the box (setting focus) gives and error in Chrome's console window
react-dom.min.js?ver=16.13.1:32 Uncaught TypeError: p is not a function
    at onFocus (components.min.js?ver=863b0e64189bf5cd6b5aced6797bc2d6:7)
    at Object.ki (react-dom.min.js?ver=16.13.1:176)
    at ji (react-dom.min.js?ver=16.13.1:13)
    at mi (react-dom.min.js?ver=16.13.1:13)
    at lf (react-dom.min.js?ver=16.13.1:13)
    at wi (react-dom.min.js?ver=16.13.1:187)
    at Kd (react-dom.min.js?ver=16.13.1:32)
    at pc (react-dom.min.js?ver=16.13.1:32)
    at Wf (react-dom.min.js?ver=16.13.1:34)
    at react-dom.min.js?ver=16.13.1:236

and then when I save the post (selecting an item gives no problems, and calls the 'onChange' function) I get another javascript error

POST http://localhost/wp-json/wp/v2/talks/34?_locale=user 400 (Bad Request)

and also an error message on the Wordpress Admin screen

Updating failed. meta.ach-td-speaker is not of type string.

The latter message makes no sense to me, as it certainly is of type string

        register_post_meta( 'talks', 'ach-td-speaker', array(
            'show_in_rest' => true,
            'single' => true,
            'type' => 'string',
        ) );

I'm assuming that the problem is something I've done that works differently if the control is a Combobox rather than a Select, but I can't imagine what it might be - the documentation of the parameters seems identical. Although I've 50 years of prgramming experience, I'm still new to Javascript so there could easily be things I've missed. Has anyone any thoughts, or suggestions what to try next?

UPDATE: I changed the options code to

        const speakerlist=wp.data.select('core').getEntityRecords('taxonomy', 'speakers',{order_by: 'name', per_page: 100});
        function speakeropts(){
            var options=[]; 
            if (speakerlist) {
                speakerlist.forEach((sp) => { // simple foreach loop
                    options.push({value:String(sp.id), label:sp.name});
                });
            }
            return options;
        }

and although the Javascript error appears in the Chrome console when the control gets the focus, everything works, and the error message when the post is saved does not appear. I don't understand what makes the difference.

1 Answer 1

3

This took me a while to figure out... It's a bug. The JavaScript error occurs because the onFilterValueChange function is not defined... Even though the WordPress documentation says this function is optional. Simply adding onFilterValueChange with an anonymous function removes the JavaScript error.

E.g.

<ComboboxControl
    label="Font Size"
    value="small"
    options={[
        {
            value: "small",
            label: "Small"
        },
        {
            value: "normal",
            label: "Normal"
        },
        {
            value: "large",
            label: "Large"
        },
        {
            value: "huge",
            label: "Huge"
        }
    ]}
    onInputChange={(inputValue) =>
        setFilteredOptions(
            [
                {
                    value: "small",
                    label: "Small"
                },
                {
                    value: "normal",
                    label: "Normal"
                },
                {
                    value: "large",
                    label: "Large"
                },
                {
                    value: "huge",
                    label: "Huge"
                }
            ].filter(option =>
                option.label.toLowerCase().startsWith(inputValue.toLowerCase())
            )
        )
    }
    onFilterValueChange={() => {}}
/>
2
  • Great investigative work!! Based on this answer, it seems issue #30948 is related and can provide more insight into the problem here.
    – bosco
    Jun 23, 2021 at 0:37
  • I really appreciate the effort you've gone to in answering this. The project has been on hold for a while due to overload (it's a volunteer thing), but is likely to restart soon so this is really helpful. Jul 28, 2021 at 12:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.