markItUp for Wordpress widget
Asked Answered
S

2

1

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).

Sidwel answered 2/1, 2010 at 1:51 Comment(2)
I have favorited this so I can answer tomorrow. Its 2:30AM here... The short answer is, yes, you need to re-call the markItUp function after each widget AJAX request as WP updates the widget contents after save. I can show you how tomorrow...Chorus
Thanks Doug. I look forward to it. For now though, I managed to find a workaround. I used to load the js file that activated markitup to admin_head. Instead, I moved the jQuery code to inside the widget form. Widget page seems to load a bit slower with multiple markItUp areas enabled though.Sidwel
C
3

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.

Chorus answered 3/1, 2010 at 4:53 Comment(3)
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...]Sidwel
@Sidwel please paste the working code to pastie.org and paste the link in the comments so I can update the answer accordingly.Chorus
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.Sidwel
S
1

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 );
Sidwel answered 5/1, 2010 at 0:10 Comment(3)
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.Chorus
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.Sidwel
@Sidwel 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!Chorus

© 2022 - 2024 — McMap. All rights reserved.