In the new Theme Customizer API, how to send a value from the front back to the admin panel?

I’m digging a bit into the new Theme Customizer API, in particular into the javascript one, and what I find is delighting.
I’ve managed to add my own custom parameters, and I also have the javascript part to update those parameters live into the preview.

However, I would like to go a bit further : I need to place a point on an absolute position over a background image, and then record the position back into the database. Here is a screenshot.
enter image description here
I can move the point thanks to jQuery draggable plugin, but I don’t know how to send the resulting position back to the customizer.

Read More

Here is my code so far :

functions.php:

add_action( 'customize_register', 'minisites_customize_register' );
function minisites_customize_register($wp_customize){
    // gestion du placement des points
    class Minisites_Customize_Page_Control extends WP_Customize_Control {

        public function render_content() {
            ?>
            <label>
                <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
                Points position
                <input <?php $this->link(); ?> value="<?php echo $this->value()?>">
            </label>
            <?php
        }
    }
    $wp_customize->add_setting( 'points', array(
        'transport' => 'postMessage'
    ) );
    $wp_customize->add_control( new Minisites_Customize_Page_Control( $wp_customize, 'points', array(
        'label'      => __( 'Lier les pages', 'minisites' ),
        'section'    => 'background_image',
        'settings'   => 'points',
    ) ) );

}

customize-theme.js:

jQuery( function( $ ) {

    var points;
    wp.customize( 'points', function( value ) {
        points = value;
        value.bind( function( newval ) {
            // this code is called when the value change
            console.log('position change', newval);
        });
    } );

    $('.point').draggable({ 
        drag: function(event, ui){
            // update the position value
            point.set(ui.position);
        }
    });

});

The javascript points.set() call does update the position value (I get the correct info in the console) but can’t update the input element located in the theme customizer itself.

I had a look at the api.Value Class (witch is the class of my points variable) in wp-includes/js/customize-base.js. What I would need is to get the instance of the corresponding api.Element, and call its update method. But I cannot figure out from where I can get this.

Related posts

Leave a Reply

1 comment

  1. I finally managed to solve my issue, but not in the most elegant way : polling. I would still be interested in more elegant solution !

    The main issue I have is that the point move is done in the iframe containing the site preview, whereas the theme customizer form inputs are in the main document. So I need a way to pass variable from the iframe to the main document.

    Inside the iframe :

    // update point global var
    $('.point').draggable({ 
        drag: function(event, ui){
            // update the position value
            var ref = 'id'+$(this).attr('data-id');
            points[ref].top = ui.position.top;
            points[ref].left = ui.position.left;   
        }
    });
    

    In the theme customizer :

    setInterval(function(){
        if(frames.length) {
            var from = $('#customize-points').val();
            var to = JSON.stringify(frames[0].points);
    
            // use theme customizer API in order to enable the save button
            if(from != to) $('#customize-points').val(to).change();
        }
    }, 500);
    

    I have also added a system to calculate the points position relative to the background image, but that’s not the subject here.

    I know that the theme customizer generate events targetting the preview iframe to enable the theme author to live update the preview, but I can’t find how to do the other way round : generate an event from the preview to the theme customizer.

    You can see the result online here: focus.tv5monde.com, even if you cannot access to the backend.