Jump to content
ryan

How to work with AJAX driven content in ProcessWire

Recommended Posts

Turns out I was using a selector that didn't work... I basically used the same one I use for regular search. In the end my selector just needed to define the parent, that was all.

It all works nicely now. I've added a little LazyCron task too: I save the JSON in certain intervals to a (hidden) PW page/field, and only query this JSON data with JS. It really speeds things up. Otherwise (with browser cache cleared) I had to wait a few seconds till the suggestions were loaded.

Thanks again for your help, suggestions + patience @AndZyk

  • Like 5

Share this post


Link to post
Share on other sites

Glad to hear it works now.

1 hour ago, dragan said:

I've added a little LazyCron task too: I save the JSON in certain intervals to a (hidden) PW page/field, and only query this JSON data with JS. It really speeds things up. Otherwise (with browser cache cleared) I had to wait a few seconds till the suggestions were loaded.

If your site doesn't frequently change, there is an cache option available in the Typeahead plugin:

Quote

cache: false,           // Improved option, true OR 'localStorage' OR 'sessionStorage'

But use whatever works best for you. ;)

  • Like 3

Share this post


Link to post
Share on other sites
On 8/26/2017 at 1:45 AM, dragan said:

I've added a little LazyCron task too: I save the JSON in certain intervals to a (hidden) PW page/field, and only query this JSON data with JS. It really speeds things up. Otherwise (with browser cache cleared) I had to wait a few seconds till the suggestions were loaded.

@dragan - Can you elaborate more on how you did this?  I would like to implement something like this on my sites.

Share this post


Link to post
Share on other sites
3 hours ago, gmclelland said:

@dragan - Can you elaborate more on how you did this?  I would like to implement something like this on my sites.

If I understand the needs correctly, I think this is a perfect use case for WtireCache (https://processwire.com/blog/posts/processwire-core-updates-2.5.28/#wirecache-upgrades). I use this to store the results of a complex set of selector queries that serve JSON to an AngularJS app.

  • Like 1

Share this post


Link to post
Share on other sites

@gmclelland Basically, what I did is installing this module: https://processwire.com/api/modules/lazy-cron/

Then I added this one line at the very bottom of my "search-input" template (the only place I need to ever access that index JSON):

wire()->addHook('LazyCron::everyHour', null, 'cronAutocompleteJSONCache');

In file _cron.php, that I

include_once("./_cron.php");

in my search-input template, I have this:

<?php namespace ProcessWire;

function cronAutocompleteJSONCache(HookEvent $e) {

    $selector = "parent=1041, has_parent!=2";
    $matches = wire('pages')->find($selector);

    foreach ($matches as $match) {
        $result = array(
            "title" => htmlspecialchars_decode($match->title),
            "year" => $match->year,
            "project_desc_short" => htmlspecialchars_decode($match->project_desc_short)
        );
        $results[] = $result;
    }

    $cacheHolderPage = wire('pages')->get(10029);
    $cacheHolderPage->setOutputFormatting(false);
    $cacheHolderPage->autocomplete_json = json_encode($results);
    $cacheHolderPage->last_update = date('d.m.Y h:i:s');
    $cacheHolderPage->save();

}

Of course, I could have also saved the JSON on the file-system, and check the timestamp, and decide on every request if the static JSON is older or newer than the PW-content, and load/generate one or the other, but for my needs, this seemed like the easiest and most straightforward solution.

 

PS

the field last_update I have only added for myself to see if it really works. I made it a "read-only" field in the settings. (not editable)

  • Like 1

Share this post


Link to post
Share on other sites

Hi all,

slightly different issue here - I'm working with a search form (multiple fields, also arrays) to filter the list of items showed in the same page. I've implemented ajax for filtering items as-you-type or as-you-select-options, which is working just fine.

The only problem is the pagination: while ajax pulls items correctly within the selected container, the pagination keeps all pages as no filter form were submitted. In fact, pagination and everything else works perfectly if the form is submitted, but by getting items via ajax without "click form submit" the pagination keeps all items regardless the applied filter . here's selected code part:

$("#formNews").on('change', function ajaxWorks(event){
    var form = $(this);
    $.ajax({
        type: form.attr('method'),
        url: form.attr('action'),
        data: $('#formNews').serialize(),
        success: function(data) {
            var data = $(data).find('#mediaGrid').html();
            data = '<div id="mediaGrid" class="content-current" uk-grid>' + data + '</div>'; // div container
            // remove old content
            $('#mediaGrid.content-current').remove();
            // scroll to the top of the page
            $('html, body').animate({ scrollTop: 0 }, 'slow');
            // append new content to the page
            $('#colMedia').append(data);
        }
    });
    event.preventDefault();
});

The div container contains also the pagination function, so once ajax successes, it pulls both items and the pagination into the div container.

Am I forced to submit the form even though I am using ajax? thanks!

EDIT: The pagination for the ajax pulled items is ok, and it works if I click on the second/next page (without form submission). Since I am using IAS Infinite Ajax Scroll, it seems that the problem is when IAS clicks on the next page ancor tag, as no URL is updated and therefore the pagination thing gets messed up..

Share this post


Link to post
Share on other sites

I'm not quite sure I understand... what is #colMedia?

Maybe use another variable name than data in your success function? i.e.

var d = $(data).find('#mediaGrid').html();

Do you add items with filtering, or remove? (remove would be the behavior that Lister Pro uses - i.e. show fewer items as you add more filter conditions)

Share this post


Link to post
Share on other sites
56 minutes ago, dragan said:

I'm not quite sure I understand... what is #colMedia?

#colMedia is the parent div of the #mediaGrid items container, I'm calling it to append the #mediaGrid div to the #colMedia div after ajax success.

I've found that probably is an IAS problem, and I'm testing some reinitialize options without success, like this

jQuery.ias().reinitialize();
//or
ias.destroy(); ias.bind();

 

Share this post


Link to post
Share on other sites

@AndZyk Hey this Autocomplete typeahead search is not working for me.  

$.typeahead is not a function this kind of error I am getting where's the problem? 

@AndZyk Hey this Autocomplete typeahead search is not working for me.  

$.typeahead is not a function this kind of error I am getting where's the problem? 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...