New butterbean control for image-gallery

1 Reply ·

  1. Hi Justin,

    I’ve built a new control for butterbean metabox called ‘image-gallery’. It’s based on image control built in and code from a Gallery Metabox I have. All is working fine, I can add multiple images and so on. I have the drag and drop feature implemented and user could reorder the images. This seems to work only first time I enter the page or when page is updated.

    When I try to add images for the first time (when there is no gallery saved) or when I add another images to a gallery already created, the sortable options doesn’t work anymore.

    This is the code used at the bottom of butterbean.js file:

    api.views.register_control( 'image-gallery', {     
        
            // Adds custom events.
            events : {
                'click .butterbean-add-media'    : 'showmodal',
                'click .butterbean-change-media' : 'showmodal',
                'click .butterbean-remove-media' : 'removemedia'
            },
    
            // Executed when the show modal button is clicked.
            showmodal : function() {        
    
                // If we already have a media modal, open it.
                if ( ! _.isUndefined( this.media_modal ) ) {
    
                    this.media_modal.open();
                    return;
                }
    
                // Create a new media modal.
                this.media_modal = wp.media( {
                    frame    : 'select',
                    multiple : true,
                    editing  : true,
                    title    : this.model.get( 'l10n' ).choose,
                    library  : { type : 'image' },
                    button   : { text:  this.model.get( 'l10n' ).set }
                } );
                
                // Runs when the media modal is opened.
                this.media_modal.on( 'open', function() {             
                    
                    var selection = this.media_modal.state().get('selection'),
                        ids       = '[' + this.model.get( 'value' ) + ']',
                        parsedIds,
                        attachment;                                 
                    
                    this.media_modal.reset();
                    
                    try {
                        parsedIds = JSON.parse(ids);
                        parsedIds.forEach(function (id) {
                            attachment = wp.media.attachment(id);
                            if (attachment.id) {
                                selection.add(attachment);
                            }
                        });
                    } catch (e) { }
                    
                    /* 
                    // Array alternative ( slower than JSON above )
                    var selection = this.media_modal.state().get('selection');
                    var ids = this.model.get( 'value' ).split(',');
                    
                    ids.forEach(function(id) {
                        var attachment = wp.media.attachment(id);
                        attachment.fetch();
                        selection.add( attachment ? [ attachment ] : [] );
                    });
                    */
                    
                }, this );
    
                // Runs when an image is selected in the media modal.
                this.media_modal.on( 'select', function() {
                    
                    var media     = this.media_modal.state().get( 'selection' ),                  
                        media_ids = [], // Create media ids array.
                        choices   = []; // Create choices array.
                    
                    // Size of image to display.
                    var size = this.model.attributes.size;
                                
                    media.each(function (attachment) {
                        var get_src, get_alt;
                        
                        media_ids.push( attachment.id );                    
                                            
                        get_src = attachment.get('sizes')[ size ] ? attachment.get('sizes')[ size ]['url'] : attachment.get('url');                 
                        get_alt = attachment.get('alt');
                                        
                        choices.push({id: attachment.id, src: get_src, alt: get_alt});                          
                    });
                                                
                    this.model.set( {
                        value : media_ids.toString()
                    } );
                    
                    // Because <code>choices</code> is an array, it's not recognized as a change.  So, we
                    // have to manually trigger a change here so that the view gets re-rendered.
                    this.model.set( 'choices', choices ).trigger( 'change', this.model );                                   
                    
                }, this );
    
                // Opens the media modal.
                this.media_modal.open();            
            },
    
            // Executed when the remove media button is clicked.
            removemedia : function() {
    
                // Updates the model for the view.
                this.model.set( { choices : '', value : '' } );
            },
                    
            ready : function() {            
                /*
                var $this    = jQuery( this.$el ),
                    elements = {
                        $container     : $this.find( '.qodx-image-gallery-container' ),
                        $image_gallery : $this.find( '.qodx-image-gallery' ),
                        $ids           : $this.find( '.butterbean-attachment-ids' )
                    },
                    get_images_order = function () {                
                        var ids = [];
                        elements.$image_gallery.find('li.image').each( function() {
                            ids.push( jQuery(this).data('attachment_id') );
                        } );
                        return ids.toString();              
                    };
                    
                console.log( get_images_order() );
                            
                // Image ordering
                elements.$image_gallery.sortable( {
                    items                : 'li.image',
                    cursor               : 'move',
                    scrollSensitivity    : 40,
                    forcePlaceholderSize : true,
                    forceHelperSize      : false,
                    helper               : 'clone',
                    opacity              : 0.65,
                    placeholder          : 'wc-metabox-sortable-placeholder',
                    start                : function( event, ui ) {
                        ui.item.css( 'background-color', '#f6f6f6' );
                    },
                    stop                 : function( event, ui ) {
                        ui.item.removeAttr( 'style' );
                    },
                    update               : function( event, ui ) {      
                        var ids = get_images_order();
                        elements.$ids.val( ids );
                    }
                } );
                */      
            }
        } );
    
    }() );
    
    ( function( $ ) {
    
        'use strict';
    
        $( document ).on( 'ready', function() {
    
            // Uploading files      
            var $this = $( '.qodx-image-gallery-container' ),
                elements = {
                    $container     : $this,
                    $image_gallery : $this.find( '.qodx-image-gallery' ),
                    $ids           : $this.find( '.butterbean-attachment-ids' )
                },
                get_images_order = function () {                
                    var ids = [];
                    elements.$image_gallery.find('li.image').each( function() {
                        ids.push( $(this).data('attachment_id') );
                    } );
                    return ids.toString();              
                };      
    
            // Image ordering
            elements.$image_gallery.sortable( {
                items                : 'li.image',
                cursor               : 'move',
                scrollSensitivity    : 40,
                forcePlaceholderSize : true,
                forceHelperSize      : false,
                helper               : 'clone',
                opacity              : 0.65,
                placeholder          : 'wc-metabox-sortable-placeholder',
                start                : function( event, ui ) {
                    ui.item.css( 'background-color', '#f6f6f6' );
                },
                stop                 : function( event, ui ) {
                    ui.item.removeAttr( 'style' );
                },
                update               : function( event, ui ) {      
                    var ids = get_images_order();
                    elements.$ids.val( ids );
                }
            } );
    
        } );
    
    } ) ( jQuery );

    I’ve tried to put the code outside your code but still doesn’t work. What I’ve noticed (after new images are added in gallery) when inspected it was that the “ui-sortable” class which is added initially by sortable script for images ul container is not there anymore.

    The ids of images are saved as below:

    <input type="hidden" class="butterbean-attachment-ids" name="butterbean_page-options_setting_nextgen_general_image_gallery" value="191,203,200,199,198,194">

    Is there some place where I can provide you WP details to test?

    Thanks for your time,
    Regards

  2. Florin

    Hi,

    Seems that I solved it by adding this.ready(); at the end ‘this.media_modal.on( ‘select’ )’ function and uncommented the control ready function.

    Thanks anyway