I have created a custom field into a metabox with a button that opens up the media manager and allows the selection of multiple images. On the "open" event, the gallery retrieves the images IDS of the current saved selection from the "data-ids" attribute of the button that triggers the media manager. The images are correctly displayed and already selected.

The issue i'm having is that, after i open up the media manager again, and select new images, although the "data-ids" attribute is updated with the new IDs of the newly selected images, the gallery won't update the previously selected images with the new ones unless i save the custom field first. What am i doing wrong? I can't figure out how to "refresh" the selection of the images. Can anybody figure it out?

This is my code

// Gallery Field Control
var wppf_gallery_ids,

GalleryControl = {
    // Initializes a new media manager or returns an existing frame.
    // @see wp.media.featuredImage.frame()
    frame: function() {
        if ( this._frame )
            return this._frame;

        this._frame = wp.media({
            title: 'something',
            library: {
                type: 'image'
            button: {
                text: 'something'
            multiple: 'toggle',

        this._frame.on( 'open', this.updateFrame ).state('library').on( 'select', this.select );

        return this._frame;

    select: function() {

        var selection = GalleryControl._frame.state().get( "selection" ).toJSON();
        var wppf_new_ids = '';

        // Empty previous images 

        // Load all stuff up
        jQuery(selection).each(function(index) {
            jQuery(wppf_get_gallery_list).append('<li><input type="hidden" name="'+ wppf_get_gallery_field +'['+ index +'][id]" value="'+ this.id +'"><input type="hidden" name="'+ wppf_get_gallery_field +'['+ index +'][url]" value="'+ this.url +'"><img src="'+ this.url +'"/></li>');
            wppf_new_ids += this.id + ',';

        // Remove last comma
        wppf_new_ids = wppf_new_ids.substr(0,wppf_new_ids.length-1);
        jQuery('#' + wppf_get_gallery_field).attr('data-ids',wppf_new_ids);


    updateFrame: function() {

        var selection = GalleryControl.frame().state().get('selection');

        // Grab all ids from gallery
        var all_ids = wppf_gallery_ids.split(',');

        // Add to selection
        if(all_ids !== '') {
            jQuery.each(all_ids, function(index, value) {
                var attachment = wp.media.attachment( value );
                selection.add( attachment ? [ attachment ] : [] );


    init: function() {
        // Handle media manager
        jQuery('body').on('click', '.wppf-open-gallery', function(e) {
            // Get the gallery id and details
            wppf_get_gallery_field = jQuery(this).attr('id');
            wppf_gallery_ids       = jQuery(this).data('ids');
            wppf_get_gallery_list  = jQuery(this).data('list');

// Run Gallery Editor

The button that opens up the gallery looks like this

<a href="#" id="wppf-gallery-gallery" class="wppf-open-gallery button button-primary wppf-gallery" data-list="#wppf-gallery-thumbs-gallery" data-ids="597,596">Create Gallery</a>

When i then open up the gallery and add 2 new images, the data-ids attribute is updated with the new ids and looks like this

<a href="#" id="wppf-gallery-gallery" class="wppf-open-gallery button button-primary wppf-gallery" data-list="#wppf-gallery-thumbs-gallery" data-ids="597,596,381,280">Create Gallery</a>

However, the media manager won't "preselect" the 4 images until i save the post. Anybody knows how to fix this issue?

Thank you.

1 Answer 1


I guess you copied that code from somewhere. Just from reading through it, I don't see wppf_gallery_ids set anywhere aside from the init function, which means that it can't update anything as the check is empty. I see two options: Either update it during selection within the select function, or just push wppf_new_ids into the wppf_gallery_ids array.

To me it seems that both variables wppf_new_ids/_gallery_ids have pretty much the same functionality and one could get dropped.

Aside from that, you should wrap your whole piece of code in a self executing function and push the globals into it:

( function( $ ) {
    'use strict';
    // your code
} )( jQuery || {} );

That also means that you can use $ instead of jQuery.

Another thing that I'd avoid is polluting the global namespace. When you just add GalleryControl like you did, then you already have window.GalleryControl set. With such a generic name, a collision with other code will likely happen yesterday than tomorrow. Better style is to use your own, already existing namespace on the window object: wppf. That means your final wrapper could look like this:

( function( $ ) {
    'use strict';

    var gallery;

    gallery.init = function() {

    gallery.frame = function() {

    gallery.select = function() {

    gallery.updateFrame = function() {

    window.wppf = window.wppf || {};
    window.wppf.gallery = window.wppf.gallery || {};
    window.wppf.gallery = new gallery();

} )( jQuery || {} );

More on that topic in excellent article about JS Objects.

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.