Jump to content

Basic AJAX request


Recommended Posts

Hello lads,

I know there is some AJAX threads, but my question is super basic. How do I connect and use AJAX within PW?
For now I am creating a request and sending it to my template which I want to do some search with PW's find() for me and return what I need as JSON eventually.

  let xhttp = new XMLHttpRequest();

  if (option == undefined) {
  } else {
    if (option.name == 'options-sorting') {
      optSorting = option.value;
    if (option.name == 'options-filtering') {
      optFiltering = option.value;

    xhttp.onreadystatechange = function () {
      if (this.readyState == 4 && this.status == 200) {

      'site/templates/includes/archive-list-render.php?q=' +
        optFiltering +
        ',' +

    //Send the proper header information along with the request
    xhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');


This code gives me 403, as PW doesn't allow me to access my archive-list-render.php. What should I do? I read some stuff about creating separate AJAX templates, is that really necessary in this simple case?

On the php side I am thinking of something like this:

$q = $_REQUEST["q"]; 
$options = explode(",", $q);

// Some logic to define exactly what my query is going to be, e.g. sort=nk-artist

$songs = $pages->findMany("template=nk-song, sort=$options");

Then I should get an array of objects that I can render little by little, because the expected results are about 8000 pages.

Thank you!


Link to comment
Share on other sites

26 minutes ago, michelangelo said:

I read some stuff about creating separate AJAX templates, is that really necessary in this simple case?

This is one of the most common solutions, but as in everything with PW, it's your call how you do it!

What you could do with your approach is place that php script outside of the sites directory which is protected by apache from being accessed directly for security reasons. 

So on your ajax request, the url is just /archive-list-render.php?q=etc

Now, on you archive-list-render.php, load the PW API:

//This is the index.php in the web root directory, sibling to site, wire, etc.
$q = $sanitizer->text($input->get('q'))
$foundPages = $pages->find("somfield=$q");

//imaginary doSomethingWithPages method..
$response = doSomethingWithPages($foundPages);
echo $response;

Another approach for simple cases is using the same page where the ajax requests originates from, and detect if it's an ajax call otherwise render the site. This can get tricky depending on appending or prepending files into the template. (Very well exemplified on Ryan's  post bellow)

	//ajax processing/render stuff
} else{
	//normal render stuff

Ryan's post:


  • Like 5
Link to comment
Share on other sites

16 hours ago, elabx said:

$q = $sanitizer->text($input->get('q'))

I really like the input api variable syntax: https://processwire.com/blog/posts/pw-3.0.125/#input-api-variable-upgrades

$q = $input->get('q', 'text');


16 hours ago, elabx said:

<?php if($config->ajax){ //ajax processing/render stuff } else{ //normal render stuff }

+1, just a little note that you don't need the ELSE and you could also do an include to keep things organized:

if($config->ajax) {
  // or use die()

// your template code

regarding $this->halt() vs. die() see https://processwire.com/blog/posts/processwire-2.6.8-brings-new-version-of-reno-admin-theme-and-more/#new-this-gt-halt-method-for-use-in-template-files

  • Like 3
Link to comment
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...