the Customizer - proper way to instantiate an image upload control via javascript

I am trying to create an image control using:

wp.customize.control.add(
  new wp.customize.Control(
    myControlSettingID
    {
      type: image,
      button_labels: {select: 'Select image', change: 'Change image', remove: 'Remove', default: 'Default', placeholder: 'No image selected'...}
      description: Upload or select an image for this featured link
      id: issue_section_term_apple_settings_link_image
      label: Custom image
      priority: 1
      section: issue_section_term_apple_section
    }
  )
);

I am using the type property and set it to image which is what the WP_Customize_Image_Control php class has set for the class type property.

This is only spitting out the label and description, and an empty attachment media view div and doesnt produce an active media UI:

div class=attachment-media-view
            
    div class=actions
                    
    /div
/div

Do I need to instantiate the control another way, or trigger a JS function to activate the controls?

Also - somewhat related. Because I am creating the control via javascript that means that wont work right? I am trying to toggle this control based on the value of another control. Will I need to manually bind the controls together?

Topic theme-customizer Wordpress javascript

Category Web


You would just need to add a canUpload: true to your control's options (the 2nd parameter for wp.customize.Control) and then the .actions div would have an upload button.

However, clicking the button would not do anything (the media modal/popup would not appear), hence you need to instead use the specific class for image upload control, which is wp.customize.ImageControl.

Working Example (tested with WordPress v5.9.3):

wp.customize.control.add( new wp.customize.ImageControl( myControlSettingID, {
    section: 'issue_section_term_apple_section',
    label: 'Custom image',
    button_labels: {
        select: 'Select image',
        ...
        frame_title: 'Select image',
        frame_button: 'Choose image'
    },
    canUpload: true,
    setting: wp.customize( myControlSettingID )
} ) );

Remember though, that the image upload control will return only the image URL, so if you need its ID, then use new wp.customize.MediaControl instead.

References, or resources that might help you further:

As for this:

I am trying to toggle this control based on the value of another control. Will I need to manually bind the controls together?

Excerpt from the 3rd link/resource above:

There are also activate() and deactivate() methods now for manipulating this active state, for panels, sections, and controls. The primary purpose of these states is to show or hide the object without removing it entirely from the Customizer.

So if that's your purpose, then you can use the above methods, like Twenty Twenty-One did, like so: (see assets/js/customize.js)

// Wait until the customizer has finished loading.
wp.customize.bind( 'ready', function() {
    // Hide the "respect_user_color_preference" setting if the background-color is dark.
    if ( 127 > twentytwentyoneGetHexLum( wp.customize( 'background_color' ).get() ) ) {
        wp.customize.control( 'respect_user_color_preference' ).deactivate();
        wp.customize.control( 'respect_user_color_preference_notice' ).deactivate();
    }

    ...
} );

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.