Mixed PHP with jQuery AJAX

Posted on

Problem

I have a quick script I came up with and I was wondering if this is a bad idea.

First let me explain what I want to do. I want to create a dynamic script which will add custom AJAX calls for whatever tab element I need it to. For instance, if the user clicks on Profile, then I want to load profile.php from my files.

This is simple enough, however, I have a lot of calls, and I came up with a quick fix. I am creating an array with all the scripts I need to call in PHP, and when the page loads PHP it creates AJAX call functions from the array list:

<?php
$tab_options = array('home', 'profile', 'news', 'api');
foreach ($tab_options as $option) 
{
    ?>
    $(<?php echo $option; ?>).click(function() {
        $.ajax({
            type: "POST",
            url: "_template/<?php echo $option; ?>.php",
            dataType: "html",
            success: function(response){
                window.top.document.title = '<?php echo ucwords($option); ?>';
                window.history.pushState("string", "<?php echo ucwords($option); ?>", "?tab=<?php echo $option; ?>");
                $("#<?php echo $option; ?>").html(response);
            },
            error: function(){
                console.log("Problem found!");
            }
        });
    });
    <?php
}
?>

So in this case I would have PHP loop 4 times over the code, and create the 4 functions for me. It works well, and I am able to switch between tabs smoothly. However, I am not sure if this is good practice, or if it should be avoided.

Solution

However, I am not sure if this is good practice, or if it should be avoided.

While I don’t think it is bad practice, it could be simplified. One technique to simplify it is using event delegation.

For example, the array of tab options could be added to a JavaScript array:

$tab_options = array('home', 'profile', 'news', 'api');
echo 'var tab_options = '.json_encode($tab_options).';';

Then add a click handler to the document and check if the id attribute corresponds to one of those tab options.

$(document).click(function(clickEvent) {
    var targetId = clickEvent.target.id;
    if (tab_options.indexOf(targetId) > -1) {

In that code Array.indexOf() is used but one could also use Array.contains() though it isn’t supported by as many (mostly older) browsers (e.g. IE).

Then to get the equivalent of ucwords(), a solution like from this answer can be used:

var properCaseOption = targetId.replace(/b[a-z]/g, function(letter) {
    return letter.toUpperCase();
});                    
window.top.document.title = properCaseOption;

With this approach, the JavaScript code is not duplicated once for each tab option. Perhaps it may not be a big issue because that code could easily be updated with the PHP code, it would yield a larger HTML/JS page size.

See a demonstration of this in this playground example but note that the AJAX requests won’t yield the pages as expected so the code to update the containers has been commented out. However I made a phpfiddle that has the response from the AJAX request utilized.

Leave a Reply

Your email address will not be published. Required fields are marked *