Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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.

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.

share|improve this question
    
You'll need to save this using the methods described under ajax. –  kaiser Jan 24 '13 at 10:45
    
@kaiser: thanks for your suggestion. But in this case, every point move will be instantly published to the frontend. Is there a way to save it only to the theme customizer, and then save it in the database when the user clicks the "save & publish" button ? –  Fabien Quatravaux Jan 24 '13 at 10:50
    
Hold it in a javascript var? –  kaiser Jan 24 '13 at 11:09
    
I already have it in a javascript var. But then, how do I get this value (which reside in the theme iframe, not in the admin area customizer) when the user clicks the "save & publish" button ? –  Fabien Quatravaux Jan 24 '13 at 11:21
    
Use a global var that you localized using wp_localize_script(). Then save the data using AJAX. See ajax questions/answers. –  kaiser Jan 24 '13 at 11:35

1 Answer 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.

share|improve this answer
    
@Brian: does this answer will helps you ? –  Fabien Quatravaux Apr 8 '13 at 8:51
    
it helps, but I guess I'm not sure how the positioning is happening on focus.tv5monde.com/languedelautre ... did you have to set the points position manually or is it happening via the jQuery draggable function updating the "Points position" input field? –  Brian Apr 8 '13 at 14:53

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.