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 trying to create a new wordpress template and inside it I added a Control Panel, inside this control panel there is an option that allows user to choose where he want's to place a on a map, I try to explain: user can set div's left and top attributes via control panel. Now I know how to add an iframe that can show a preview of the changes but it doesn't work as I would like (how to add the preview? read here: Modify CSS via Theme Control Panel) What I would like to add is a real time preview. As soon as the user modify TOP or LEFT attribute preview has to show what it is happening without showing it to "live" blog.

Here is my function.php:

array( "name" => "Before we start",
    "type" => "section"),
array( "type" => "open"),
array( "name" => "Where is the map?",
    "desc" => "Insert map page url",
    "id" => $shortname."_pama",
    "type" => "text",
    "std" => "http://examplepage.com"),
array( "type" => "close"),
array( "name" => "Zona 1",
    "type" => "section"),
array( "type" => "open"),
array(  "name" => "Activate zona 1?",
    "desc" => "Choose yes or no",
    "id" => $shortname."_zona1c",
    "type" => "checkbox",
    "std" => "false"),
array( "name" => "Zona 1 X-Axis",
    "desc" => "Where do you want it on x-axis?",
    "id" => $shortname."_zona1x",
    "type" => "text",
    "std" => "Left:???"),
array( "name" => "Zona 1 Y-Axis",
    "desc" => "Where do you want it on y-axis?",
    "id" => $shortname."_zona1y",
    "type" => "text",
    "std" => "Top:???"),
array( "type" => "close"),
array( "name" => "Zona 1",
    "type" => "section"),
array( "type" => "open"),
array(  "name" => "Activate zona 2?",
    "desc" => "Choose yes or no",
    "id" => $shortname."_zona1c",
    "type" => "checkbox",
    "std" => "false"),
array( "name" => "Zona 2 X-Axis",
    "desc" => "Choose where you want it on X-Axis",
    "id" => $shortname."_zona2x",
    "type" => "text",
    "std" => "Left:???"),
array( "name" => "Zona 2 Y-Axis",
    "desc" => "Choose where you want it on Y-Axis",
    "id" => $shortname."_zona2y",
    "type" => "text",
    "std" => "Top:???"),
array( "type" => "close"),
array( "type" => "close"),
);

This is the iframe that I use to show the preview inside Control Panel:

<iframe src="<?php echo clean_url(apply_filters('preview_post_link', add_query_arg('preview', 'true', get_option('appacqua_pama')))); ?>" width="100%" height="600" ></iframe>

Ok, now the big question is there a STEP TO STEP way to add a preview on real time (I don't know how to explain it better, I'm really sorry...), what do you think will it be possible to use ajax? (I heard about it but I'm not a programmer so please write in a Dummy Proof way!!!) Will I need to add also a PREVIEW button instead of only SAVE button? How to add it? Do you know Mystique theme by digitalnature? something like this will be GREAT! If you can't write it here why don't you write a very good, and step to step, tutorial on your website? There is a lack of good articles about how to create a very good Theme-Option panel with a lot of functionalities for wordpress 3.x maybe you'll be the next and you'll also help us...poor noobs :-) Thank you very much for your time and patience!

share|improve this question
add comment

2 Answers 2

up vote 4 down vote accepted

If you look at Mystique theme (a great example of option panel with preview BTW) you can see that the main idea is to lavrage the form fields OnChange or change() events to load the theme's preview with Jquery and a bit of ajax.

So you have one function to load by ajax the preview

function mystique_get_site_preview() {
  check_ajax_referer("site_preview"); ?>
  <iframe id="themepreview" name="themepreview" src="<?php echo get_option('home'); ?>/?preview=1"></iframe>
  <?php die();
}

and to create the auto preview effect you use some JQuery with PHP:

$nonce = wp_create_nonce('site_preview');
?>
<script type="text/javascript">
    jQuery(document).ready(function () {
        jQuery("#$zona1y").change(function() {// if a user changed the y-Axis
            check_preview_refresh();
            }
        );
        jQuery("#$zona1x").change(function() {// if a user changed the x-Axis
            check_preview_refresh();
            }
        );
    });

    function check_preview_refresh(){
        if (jQuery("#zona1y").val() != '' && jQuery("#zona1x").val() != '' ){
            jQuery.ajax({
                type: "post",url: "admin-ajax.php",data: { action: 'site_preview', _ajax_nonce: '<?php echo $nonce; ?>' },
                success: function(html){
                    jQuery("#themepreview").html(html);
                    jQuery("#themepreview").show();
                }
            });
        }
    }
</script>

Now this code assumes that you have two input fields with the id of "zona1y" and "zona1y" and a div wrapping your Iframe with the id of "themepreview".

and that should get you started.

Update:

I forgot you will need to add:

add_action('wp_ajax_site_preview', 'mystique_get_site_preview');

Now

the first part + the last line of code go in your functions.php

and the second part needs to go on your theme option panel page.

share|improve this answer
    
@Bairnet First thing to say...Thank you for your fast reply :-) Second thing...let's try to understand, what I have to do now is: 1 - Take this: function mystique_get_site_preview() { check_ajax_referer("site_preview"); ?> <iframe id="themepreview" name="themepreview" src="<?php echo get_option('home'); ?>/?preview=1"></iframe> <?php die(); } and add my template shortname (appacqua is the shortname) then overwrite my existing iframe preview code. 2 - take the second part of the code that you gave me and add it to my function.php? Am I right? –  Downloadtaky Mar 22 '11 at 14:34
    
@Bainternet (first time I used a bad @ tag...Sorry!) Will I need to add a preview button? How does it works? Have you seen my function? Will it work with it? Actually the only way to see modifications is to save the new position... so, once again, Will it work? –  Downloadtaky Mar 22 '11 at 14:36
    
@Downloadtaky: i updated my answer. –  Bainternet Mar 22 '11 at 14:49
    
@Bainternet I'm doing something wrong for sure! Each time I try to save the option it gives me: Warning: Cannot modify header information - headers already sent by (output started at /home/nextube/public_html/wp-content/themes/appartamentiacquario/functions.php:4‌​34) in /home/nextube/public_html/wp-content/themes/appartamentiacquario/functions/cpane‌​lfunction.php on line 191 Here you can see my files: Here is my function.php code: pastebin.com/8cVmne1s Here is optionpanel.php: pastebin.com/jvTx2MYX Here is postdropdown.php pastebin.com/qWVrXqV3 –  Downloadtaky Mar 22 '11 at 23:13
    
Here is adminfoot.php pastebin.com/NET7TfZr Here is cpanelfunction.php pastebin.com/xJv7F66w Here is firstimage.php pastebin.com/0KxeetNx Here is regsidebar.php pastebin.com/wPcDaAu5 –  Downloadtaky Mar 22 '11 at 23:16
show 12 more comments

Even though it appears the author solved his request, I'll post a better solution on how to achieve this (I'm also the author of Mystique btw). Maybe it will help others.

So, first you need the iframe document - your home page. I'm using ajax to get it just like in the function above, but you don't necessarily need to do this. You can just normally add the iframe above your theme setting fields, just like any HTML.

Remember to append a query argument to the iframe target URL, like <?php home_url(); ?>/?themepreview (or user add_query_arg or whatever). This is important, you'll see later.

Next, you need to find a way to communicate with the iframe. Check out the postMessage and JSON2 scripts. Enqueue them in your settings page.

Now, simply bind a function on the events you need to the live preview to fire. For example, assuming you have a text input named "page_width":

<input name="page_width" />

in your jQuery document.ready function you would have something like this:

// event can be anything, click/change/input or a custom colorpicker event...
$("input[name='page_width']").change(function(){

  // get the value entered by the user
  var current_page_width = $(this).val();

  // send this value trough postMessage to the iframe document
  pm({
    target: window.frames["themepreview"],  // this needs to be the iframe ID
    type: 'page_width',
    data: current_page_width
  });
});

So the pm function will send the input value to the iframe.

Now for the iframe to change its contents, you need to include the above scripts on the front-end too. But only do this if the query argument above is present, so you only include them when a theme preview is requested, and not on every page load.

In the front-end's document.ready handle the receiving part, with pm.bind():

// first argument should be the "type" from above
pm.bind('page_width', function(data){

  // data that's being received is the 'current_page_width', so just set the new width to the element you need to
  $('#page').css('width', data + 'px');

});

And that's it :)

You can also find sample code in version 3 of Mystique...

share|improve this answer
add comment

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.