Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AJAX and head/foot updates best practice

A standard setup for me is to have a head.inc and a foot.inc and then everything in-between is updated via AJAX calls with some transition. Getting a bit boring but that's currently how it is. The issue I have is most of the time the main site nav/menu, which is in the head.inc, is contextual and will change based on the page being view. This can cause a lot of duplication of code as 1) I write it with PW in PHP so if the page is visited directly it is reflected and 2) I also have to do the same in JS if the page is visited via an AJAX call. You see the dilemma.

What I've started to do recently is build a PHP array in an include file for the menu, and also json_encode it so I have an array, of the same code, one for PHP to use and one for the JS to use. Something like the below...

$menuArray = array();

$menuLeft = $pages->find("template=work|news, sort=sort");
$menuRight = $pages->find("template=clients|about, sort=sort");

if ($page->id !== 1) {
    $menuLeft->filter("id={$page->id}");
    $menuRight->filter("id={$page->id}");
}

foreach ($menuLeft as $item) {

    $menuArray['left'][] = array(
        'id' => $item->id,
        'name' => $item->name,
        'url' => $item->url,
        'title' => $item->title,
        'x' => '100%'
    );

    // If current page then prepend 'Close'
    if ($page->template->name == $item->name) {
        array_push($menuArray['left'], array(
            'name' => 'close',
            'url' => $pages->get(1)->url,
            'title' => 'Close',
            'x' => '100%'
        ));
    }

}

foreach ($menuRight as $item) {

    $menuArray['right'][] = array(
        'id' => $item->id,
        'name' => $item->name,
        'url' => $item->url,
        'title' => $item->title,
        'x' => '100%'
    );

    // If current page then append 'Close'
    if ($page->template->name == $item->name) {
        array_unshift($menuArray['right'], array(
            'name' => 'close',
            'url' => $pages->get(1)->url,
            'title' => 'Close',
            'x' => '100%'
        ));
    }

}

// Return JSON for JS (PHP can grab $menuArray directly)
$menuJSON = json_encode($menuArray);

if ($config->ajax) {
    echo '<script id="menuJSON">';
        echo "menuJSON = {$menuJSON}";
    echo '</script>';
}

Then in the head.inc loop through $menuArray and in the JS loop through, on AJAX changes, menuJSON.

updateMenu: function(e) {

    var $header = document.querySelector('header.main'),
        headerContent = '';

    for (var menu in menuJSON) {
        headerContent += '<ul class="menu --' + menu + '">';
        menuJSON[menu].forEach(function(item) {
            headerContent += '<li data-template-name="' + item.name + '"><a data-ajax data-x="' + item.x + '>" href="' + item.url + '">' + item.title + '</a></li>';
        });
        headerContent += '</ul>';
    }
    $header.innerHTML = headerContent;

}

The issue I'm having is I have no idea if this is the best way to work with something like this and wondered if anyone had any input?

It also feels weird echo'ing out script tag with PHP then relying on the JS finding it in the DOM. You know?

Anyway... I'll put this out there and see what happens 🙂

like image 871
John the Painter Avatar asked Oct 19 '19 11:10

John the Painter


1 Answers

Not sure what exactly you mean when you say "dynamic content" I would definitely go for RESTFull methods. If you give more details for types (like textual statics, video or images, etc.) I'd think of more details. Let's assume that you have dynamic content of a page which has only texts.

Let's assume a user visits the page which it's url is "/page/1" and a user logged in with some kind of authentication.

You could have another restful api end point and it will take two parameters( can have more than that, for the sake of simplicity I hold it to 2) to populate your head and footer include files with what ever you wanted to return. Let's call your api end point for this time "/populateHeadAndFooter". You can pass "1" for page, "{{token}}" for token parameters. It's possible to whatever you do with those parameter to evaluate the situation and prepare the response. If you need more details for the page "1", like user inputs or whatever an action will be taken, you can have a mechanism to pass it as parameter, directly or after converting it to other formats (hashing, encoding, etc.). After that you could have AJAX to refresh your actual page.

like image 185
hatirlatici Avatar answered Nov 16 '22 21:11

hatirlatici