views:

230

answers:

2

I am using markItUp for a textarea in a WP widget (that is, on widgets.php page, while creating and editing a widget).

The textarea is markItUp'ed when I first open the widget, but after I click save the functionality is lost and I am back to a regular textarea.

I compared the source code for the before-save and after-save versions of the page and there is no difference -obviously, as the page isn't reloaded. Does jQuery need to be invoked for every ajax call?

I tried adding

jQuery(".markitup").markItUp(mySettings);

inside the widget's form handling function but that didn't help. I tried to make changes binding this event to the save button too but that didn't seem to make a difference (there is a good chance that I got it all wrong).

I am a petty code-hacker with minimal knowledge of PHP, Ajax and jQuery, so any pointer can help. Thanks.

+3  A: 

The jQuery

So, the first thing you need to do is hook into the AJAX call so you are notified when the widgets have been saved. To do this, we will use the jQuery ajaxSuccess function. Put this in its own js file:

// Use a self executing function so we can safely use
// $ inside and know it = jQuery
(function($){

    // Tie into all jQuery AJAX requests
    $(document).ajaxSuccess(function(e, x, o){

        // Make sure our widget is the one being saved
        // id_base will equal whatever is set in the PHP for the widget
        // In this example, we target the text widget 
        if(o.data && o.data.indexOf('id_base=text') > -1){

           // Now, lets quickly find all the right elements
           // and filter out the ones already set up, and finally
           // apply the `markItUp` call, but we will delay just to give
           // WP a chance to update the widget
           window.setTimeout( function(){
               $("textareas.markItUp:not(.markItUpEditor)").markItUp(mySettings);
           }, 200 );
        }
    });

})(jQuery);

The PHP/WordPress

Finally, tell WP to include your new js file only on the widgets page. You will need to incorporate this either into functions.php or if you are building a widget, into the widgets PHP file:

function register_markitup(){
    wp_enqueue_script( 'markitup-widgets', WP_PLUGIN_URL . '/your-plugin/js/markitup-ajax.js' );
}

add_action( "admin_print_scripts-widgets.php", 'register_markitup' );

Edit I had an incorrect add_action hook when I posted. It needed the .php which I just added. The code is correct now.

Doug Neiner
Thanks for this. When I implemented this as it is, I came across a problem where the widget I was working on was succesfully regaining its markitupedness (markitupidity?), while the other widgets of the same type (active or not) would get an additional markitup area within the original markituped ones (like cascading windows.) So, I had to make a change to the ajax function you have above. [I can't seem to be able to paste the code here though...]
Necati
@Necati please paste the working code to http://pastie.org/ and paste the link in the comments so I can update the answer accordingly.
Doug Neiner
I had put it into an answer node in the below. You can take it from there. Please do go ahead and change the jQuery code too if you think it can be improved.Thanks again.
Necati
+1  A: 

Doug's solution worked great. I only had to change the window.setTimeout function as follows:

 window.setTimeout( function(){
   $("textarea.markItUp").each(function () {
      if (!($(this).hasClass('markItUpEditor'))) {
          $(this).markItUp(mySettings);
      }
    });                                    
 }, 200 );
Necati
You should be able to replace insides of the `setTimeout` function with this: `$("textarea.markItUp:not(.markItUpEditor)").markItUp(mySettings);` Since that is what you are doing. My original code probably failed because `.markItUp` was too ambiguous and it needed the `textarea.markItUp`.
Doug Neiner
Hmmm, I could swear that was my first attempt at trying to get your original code to work...I think, what made me look for an alternative was that one -or more- of the widget instances I already had on my widgets page was already messed up because of changes brought by earlier code. Or perhaps I forgot to change the class names from 'markitup' to 'markItUp' (without proper knowledge of these languages I find myself frantically making changes and applying them until something works.) You are right, now that I make this small change everything is in order.Thanks a lot for your time, Doug.
Necati
@Necati Happy to help. I updated my other answer to reflect the working code. Thanks for taking the time to help me fix my answer so it will work for other searchers. Welcome to Stack Overflow and I hope to see you around the site!
Doug Neiner