How to localize inline script called with ajax

I have a loop of posts and I allow a user to edit each post using ajax. When the edit button is clicked for the post I use ajax to retrieve the template part containing the edit form for the post. Easy enough to do by creating a function with ‘get_template_part’ and then localizing a script where I use $ajax to execute the function.

Now here is my problem. I need to process the form with ajax that is in the template part we’ve called. In order to do anything with jquery for that form, the jquery has to be added as an inline script to the template. So when the button is clicked inside the from to save and edits made, I then need to run my php function that processes any edits made. But I can’t do that because I can’t actually localize the inline script that will allow me to use that php function I’ve made. Any ideas.

UPDATE:

Ok so instead of adding the scripts to the template inline, I register the script inside the function that gets the template part and then print it which I thought would give me a chance to localize. The script works for the template part but it isn’t localized.

 add_action('wp_ajax_fetch_dashboard_edit_form', 'fetch_dashboard_edit_form'); 
 function fetch_dashboard_edit_form() {
    $post_id = $_POST['postId'];
    $edit_type = $_POST['editType'];
    include(locate_template('edit-'.$edit_type.'.php'));    
    wp_register_script(
     'fod_edit_script',
     get_bloginfo('stylesheet_directory') . '/libs/edit.js',
     array( 'jquery' ),
     null,
     true
    );
    wp_localize_script(
     'fod_edit_script',
     'editAjax',
     array(
        'ajaxurl' => admin_url( 'admin-ajax.php' )
     )
    );
    wp_print_scripts("fod_edit_script");
 }

1 Answer
1

Sidestep the entire issue and just include fo_edit_script in the header of the page, rather than in the AJAX part. There’s no need at all to do this.

You might think that by only including it when its needed your optimising but your not, because it’s having to load it every time you open an edit form.

I’d go as far to say that what you’re trying to do is bad practice. Avoid pulling in html via AJAX containing references to remote JS files or script tags at every opportunity.

So the simple answer to how to do this is: don’t.

You have:

Foreach post
    On AJAX
        include HTML
        Setup JS

Instead:

Setup JS
foreach post
    On ajax
        include HTML

As a metaphor:

A car salesman has 5 customers arrive at his dealership. They each ask for a Honda Civic. What your doing is the equivalent, of the Honda Salesman building 5 factories to produce a single car for each customer.

What you have, is a problem building new factories quickly. Instead of figuring out the solution to the instant new factory problem, build 1 single factory at the start when the car is designed, and use it to produce all the cars.

So only return the needed html in your AJAX call:

add_action('wp_ajax_fetch_dashboard_edit_form', 'fetch_dashboard_edit_form'); 
function fetch_dashboard_edit_form() {
    $post_id = $_POST['postId'];
    $edit_type = $_POST['editType'];
    include(locate_template('edit-'.$edit_type.'.php'));
}

Enqueue your script on the screen showing the posts:

function add_fod_script(){
    wp_register_script(
     'fod_edit_script',
         get_bloginfo('stylesheet_directory') . '/libs/edit.js',
         array( 'jquery' ),
         null,
         true
    );
    wp_enqueue_script('fod_edit_script');
}
add_action('admin_init','add_fod_script');

And adjust edit.js accordingly.

This also has the bonus that when you first edit a post, you dont have a delay when the browser is grabbing edit.js, because it has already been loaded.

It also means you’ve only included your JS once, so you don’t litter your DOM with the same script tag over and over again

You should keep in mind that once the AJAX html is setup and inserted into the DOM, the new elements will not have the event triggers that you setup on DOM ready attached, they will need to be re-added, either more calls, or by orignally using things such as the ‘on’jquery functionality:

.on()

e.g. instead of saying:

$("#dataTable tbody tr").click( function(event){
    alert($(this).text());
});

Which means for any dataTabletbody tr that we can find at this moment in time, add an event click handler, do this instead:

$(document).on("click", "#dataTable tbody tr", function(event){
    alert($(this).text());
});

Which means the same thing but for any datatable tbody tr that currently or will ever exist in the future.

So we can elaborate on what we had earlier:

Include JS
Setup JS for page
foreach post
    On ajax
        include AJAX HTML
        Setup JS events again, for the AJAX HTML

Should you really, really, really want to continue doing it the way you’re doing it, there is a solution, but as I have said, what you’re doing is bad, bad practice, and will only lead to more difficulties, duplication, and problems. It’s putting band aids on band aids. Refer to this:

https://stackoverflow.com/questions/235967/calling-a-jquery-function-inside-html-return-from-an-ajax-call

Leave a Comment