Jump to content

AJAX tutorial

Recommended Posts

Hello guys,

I know there are several AJAX threads, but I have been struggling for weeks with AJAX and I really want to get it working... Theoretically I understand what is happening, but how can I make it work in a ProcessWire context?

Let's say I have 10 events (pages). I am displaying 5 and when I click 'Load More' it loads 5 more, etc.
What I understand until now is:
1. Make a button 'Load More'.
2. Connect the button to AJAX function in JS (vanilla or JQuery or infinite Ajax Scroll). I prefer to be as simple as possible so I can tweak it myself.
3. Send the AJAX request to a php template that renders my content ( the 5 more events ) and returns it to my JS.
4. JS takes the returned content and appends it to my container in the DOM

Step 3 is impossible for me. I tried so many different ways to just create a simple query, render my content and return it.

If you can share your workflow and small bits of code, that will be the best thing ever.

Thank you!

Share this post

Link to post
Share on other sites

Where exactly are you stuck? Differentiating between normal and AJAX requests, rendering content (are you doing that server- or client-side?), encoding the content for the AJAX response? An example of your current code and what's not working about it would be helpful.

A couple of observations, in no particular order:

  • The first thing I notice is that the infinite scroll library you linked seems to employ a non-standard way of doing "load more" buttons. Instead of requesting only the new items, it works with an existing classic pagination and just loads the entire next page, throws away everything but the new items and adds them to the existing container. While this does work, it's incredibly wasteful, loading entire pages just to discard most of them immediately. So don't let that library trip you up if you want to build "real" AJAX-powered pagination.
  • What endpoint are you calling in your AJAX request? I remember some tutorials around here recommending to hit the same URL as a regular page view, and differentiating between normal page views and AJAX calls by checking the X-Requested-With header – in my opinion, that's not a good approach. It doesn't even work properly if you use the Fetch API (the modern alternative to XMLHttpRequest). Depending on how much side-loaded content you need on your site, I would either use a URL parameter (?ajax=1) or build an entirely separate endpoint (/api/events/...). The latter approach scales much better.
  • Are you returning HTML or structured data from your endpoint? Depending on that:
    • Returning structured data, i.e. a JSON-encoded object with information about the events is the cleaner way to go about this. But since the first five elements are already rendered server-side, that means you have to replicate your template-logic in JavaScript to create the same HTML structure that the server-rendered events have. Not ideal. In general, I only use this approach if the entire app is client-side rendered (like the Architekturführer Köln).
    • Returning server-rendered HTML is not great, because it makes your API non-reusable (for example, if you want to display side-loaded events in different places with slightly different layouts, you'll need separate endpoints or parameters). It's also just not very clean to insert raw HTML into your page. Though it is a bit easier for simple use cases.
  • I need to mention this: Do you really need to side-load your events? It's one of those features that clients go crazy about because it's "cool and modern", but why not use a regular pagination, which works out of the box and is also better for SEO? If the reason is that your visitors need to load too many pages this way, is there any reason why you can't just show 25 events per page instead of 5?
  • Like 9

Share this post

Link to post
Share on other sites

Wow @MoritzLost, that's quite a response. Thanks so much! I will post a few examples here of my code but reading all your point made me realise a few things.
Let's start from back: We don't need to load the events, but eventually there is going to be many of them in the archive. My idea was to display the most recent ones and if you want you can pull the next most recent, etc. With pagination maybe it will work the best as I can render everything on the server and just display what I need.

My idea was to render everything at the server side as it is easier for me. But I completely get your point why this is not scalable. The Infinite scroll was also too complicated for the same reason, I didn't know what's going on in the back scenes.

Right now:

	let postData = {
        "ajax:": true,
        "itemOffset": itemOffset,

        type: "POST",
        url: url,
        data: postData,
        beforeSend: function (xhr) { xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded") },
        success: function (data, status) {
            pageData = data;
            itemOffset += itemsToLoad;
    }).done(function () { // when finished and successful
        container.insertAdjacentHTML("afterbegin", 'loaded: ' + pageData + ' (by jquery ajax)');

and then I wanted to execute that with my load_events.php template:

	$num_new_events = $_POST['itemOffset'];
	$events = $pages->find('template=nk-event, limit=$num_new_events');

	// Render something about these events title, images, etc...
	foreach ($events as $event) {
            $event_title = $event->title;
			$events_output+= '<div class='event'>'. $event_title .'</div>';

	return $events_output;

and then my JS will take it again from there. Of course, this didn't work last week, now it works but only from the home page, because it cannot find my load_events.php file or CORS policy issues.

So at the end, I thought it's a bit more straight-forward but it seems like I need to rethink my approach. I have spent a lot of time on this project, so maybe I will try to make what I have until now work or switch to pagination.

Thanks for the feedback!


  • Like 1

Share this post

Link to post
Share on other sites

I haven’t read to deeply on this thread but just wanted to point out quickly that infinite scroll libraries lean towards leaving HTML page markup in place for seo reasons in that you most likely want those pages indexed like any other paginated content.

  • Like 2

Share this post

Link to post
Share on other sites
21 hours ago, MoritzLost said:

[...] but why not use a regular pagination, which works out of the box and is also better for SEO?

And also for a11y 😉

  • Like 2

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...