0

I create new sortable checkboxes control for customizer. This code works, but I'm interest about other methods to save values (checkboxes and order). I save values as text. How to save values as a array to optimize the code? How to save JS array? My output:

author:1,date:1,category:0,rtime:1,comments:1

PHP code:

// Sortable Multicheckbox Control Class
class Customize_Sortable_Multicheckbox_Control extends WP_Customize_Control {

    public $type = 'sortable_multicheckbox';

    public function enqueue() {
        wp_enqueue_script( 'customizer_js', trailingslashit( get_template_directory_uri() ) . 'assets/js/admin/customizer.js', array(), '1.0', 'all' );
        wp_enqueue_style( 'customizer_css', trailingslashit( get_template_directory_uri() ) . 'assets/css/admin/customizer.css', array(), '1.0', 'all' );
    }

    public function render_content() {

        if ( empty( $this->choices ) ) {
            return;
        }

        $input_id = '_customize-input-' . $this->id;
        $description_id = '_customize-description-' . $this->id;
        ?>
        <div class="customize-control control-sortable-multicheckbox">
            <?php if ( ! empty( $this->label ) ) : ?>
                <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
            <?php endif; ?>
            <?php if ( ! empty( $this->description ) ) : ?>
                <span id="<?php echo esc_attr( $description_id ); ?>" class="description customize-control-description"><?php echo esc_html( $this->description ); ?></span>
            <?php endif; ?>

            <?php
            $defaultValue = explode( ',', $this->value() );

            $input_values = '';
            $return = array();
            $s_return = array();
            $choices = $this->choices;
            $values = $this->value();

            if ( is_string( $values ) ) {
                $s_return = array();
                $values = explode( ',', $values );
                foreach( $values as $value ){
                    $keyval = explode( ':', $value );
                    if ( count( $keyval ) > 1 ){
                        $s_return[$keyval[0]] = $keyval[1];
                    } else {
                        $s_return[$keyval[0]] = '';
                    }
                }
                $values = $s_return;
            }

            // List all saved or default options with values.
            foreach ( $values as $key => $val ) {
                if( array_key_exists( $key, $choices ) ) {
                    $return[$key] = $val;
                }
            };

            // List all options that are not used and set default value.
            foreach ( $choices as $key => $val ) {
                if( !array_key_exists( $key, $values ) ) {
                    $return[$key] = 0;
                }
            };

            // Convert array() to string - input value
            if ( is_array( $return ) ) {
                // Default values
                $i_return = array();
                foreach ( $return as $key => $val ) {
                    if( 1 === $val || true === $val ){
                        $val = 1;
                    } else {
                        $val = 0;
                    }
                    $i_return[] = $key . ':' . $val;
                };
                $input_values = implode( ',', $i_return );
            }
            ?>

            <ul class="sortable-multicheckbox-list sortable">
                <?php foreach( $input as $key => $value ) : ?>
                    <li>
                        <input id="<?php echo esc_attr( $key ); ?>" name="<?php echo esc_attr( $key ); ?>" type="checkbox" class="sortable-multicheckbox-item" value="<?php echo esc_attr( $value ); ?>" <?php checked( $value ); ?>/>
                        <label for="<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $choices[$key] ); ?></label>
                        <i class="dashicons dashicons-menu sortable-multicheckbox-handle"></i>
                    </li>
                <?php endforeach; ?>
            </ul>

            <input type="hidden" id="<?php echo esc_attr( $input_id ); ?>" class="sortable-multicheckbox-val" value="<?php echo esc_attr( $input_values ); ?>" <?php $this->link(); ?>/>

        </div>

    <?php
    }

}

// Settings
$wp_customize->add_setting(
    'my_homepage_featured_meta', array(
        'default' => array(
            'author'   => true,
            'date'     => true,
            'category' => false,
            'rtime'    => true,
            'comments' => true
        ),
        'transport'         => 'refresh',
        'sanitize_callback' => 'wp_kses_post'
    )
);
$wp_customize->add_control(
    new ED_Customize_Sortable_Multicheckbox_Control(
        $wp_customize,
        'homepage_featured_meta',
        array(
            'settings'    => 'my_homepage_featured_meta',
            'section'     => 'my_section_homepage_featured',
            'label'       => esc_html__( 'Meta data', 'my' ),
            'descripyion' => esc_html__( 'Check and re-order which meta data you want to display', 'my' ),
            'type'        => 'sortable_multicheckbox',
            'choices'     => array(
                'author'   => esc_html__( 'Author', 'my' ),
                'date'     => esc_html__( 'Date', 'my' ),
                'category' => esc_html__( 'Category', 'my' ),
                'rtime'    => esc_html__( 'Reading time', 'my' ),
                'comments' => esc_html__( 'Comments', 'my' )
            )
        )
    )
);

JS code:

/* Customize_Control_Sortable_Multicheckbox */
$( '.ed-control-sortable-multicheckbox' ).each( function() {
    if( 0 === $(this).length ){
        return true;
    }

    // Set the sortable container.
    var controlContainer = $(this),
        controlSortableContainer = controlContainer.find( 'ul.sortable' ).first();

    // Init sortable.
    controlSortableContainer.sortable( {
        handle: '.ed-sortable-multicheckbox-handle',
        axis: 'y',
        stop: function() {
            updateValue();
        }
    } ).click( function() {
        updateValue();
    } );

    function updateValue() {
        var inputValues = controlSortableContainer.find( 'input.ed-sortable-multicheckbox-item' ).map( function() {
            var name = $(this).attr('name'),
                value = $(this).prop('checked') ? 1 : 0;

            return name + ':' + value;
        }).get().join(',');

        controlSortableContainer.parents( '.ed-control-sortable-multicheckbox' ).find( 'input.ed-sortable-multicheckbox-val' ).prop( 'value', inputValues ).trigger('change');

        console.log( inputValues );
    }
});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.