Jump to content
Brian Scramlin

Two Little Frustrations with AJAX

Recommended Posts

I just wanted to share that I added an AJAX-powered gallery to an artist website that I developed and host: https://jackpinecreations.com/gallery/

3197az.gif.725dd8cdeb146d00f75b5533aac654f6.gif

There were two things that frustrated me about creating this. Perhaps you can show me a better way.

1. After creating my processing script, which I placed under /templates/scripts/get-items.php, I realized that I would get a 403, due to ProcessWire's routing and security. This forced me to have to create a template and page for this little script. This was frustrating simply because it seemed unnecessarily confusing. But worse, see #2.

2. I usually use config.php to prepend and append each of my templates with a head.inc and foot.inc, which keeps my templates easy to use and I don't have to go and use the GUI to do so on each template separately. However, since I realized I needed to create a new template and page so as to access it, whenever I sent POST params to it, I would get the header and footer along with it!!! I could find no workarounds and had to remove the pre/append calls in config.php and use the GUI on each template individually.  

Code Below if you're interested:

HTML and JavaScript (forgive my sad JavaScript skills, I know this can be tightened up)

<!-- Begin Grid -->
<div class="container mt-4">
  <div id="gallery" class="row">
    <?php foreach ($page->children("limit=9") as $child): ?>
      <div class="col-6 col-md-4 gallery-item">
        <a href="<?= $child->url ?>" title="View <?= $child->title ?>">
          <img class="gallery-item" src="<?= $child->item_featured_image->size(640, 640)->url ?>" alt="<?= $child->title ?> Image">
        </a>
      </div>
    <?php endforeach; ?>
  </div>
</div>
<!-- End Grid -->

<div class="center-block text-center">
  <button id="get-more-items" type="button" name="get-more-items" class="btn-vintage">Load More</button>
</div>

<script type="text/javascript">
  var buttonGetItems = document.getElementById("get-more-items");
  var indexStart = 0;

  buttonGetItems.addEventListener("click", function() {
    indexStart += 9;

    $.ajax({
      url: '<?= $pages->get(1186)->url ?>',
      type: "POST",
      dataType:'json', // add json datatype to get json
      data: ({page_id: <?= $page->id ?>, index_start: indexStart}),
      success: function(data){
        console.log(data);
        if (data[1]) {
          //for each element, append it.
          $.each(data, function(key, value) {
            $("#gallery").append(value);
          });
        } else {
          $("#get-more-items").after('<p class="center-block text-center">There are no more items to load.</p>');
          $("#get-more-items").remove();
        }
      }
    });
  });

</script>

Processing Script

<?php

$items_array = [];
$i = 0;

foreach ($pages->get($input->post->page_id)->children->slice($input->post->index_start, 9) as $child) {
  $i++;
  $items_array[$i] =
    "<div class='col-6 col-md-4 gallery-item'>
      <a href='$child->url' title='View $child->title'>
        <img src='{$child->item_featured_image->size(640,640)->url}' alt='$child->title Image'>
      </a>
    </div>";
}

echo json_encode($items_array);

I love ProcessWire for hundreds of reasons, but I've been using AJAX more and more, and I'm not liking having to create templates to access scripts. 

Any advice?

Edited by Brian Scramlin
added GIF so people don't have to go to link if they don't want to.

Share this post


Link to post
Share on other sites
11 minutes ago, Brian Scramlin said:

Any advice?

1. If you put your PHP file in the site root it won't be affected by the htaccess restrictions. You could also put it any other place besides those places with restricted access.

2. See the "Files" tab in the template settings: "Disable automatic prepend of file..." / "Disable automatic append of file..."

  • Like 4

Share this post


Link to post
Share on other sites
2 minutes ago, Brian Scramlin said:

1. Would the file be overwritten when upgrading PW? 

Not so long as you keep it outside of the /wire/ folder.

Share this post


Link to post
Share on other sites

my preferred way is to make a generic 'service' template, and have a 'services' index page, under which you can add as many services/ajax endpoints as you want; then you just have the template include the correct service php file by matching the name; in any given service file, you can do a return $this->halt() or exit() to stop the appending; you can also just turn off prepend/append for that service template and you'd be all set...

1 hour ago, Brian Scramlin said:

I usually use config.php to prepend and append each of my templates with a head.inc and foot.inc,

that's risky and not so future proof; also on some templates it might prevent you from doing some processing before the head loads, for that template – maybe add a dns prefetch to the header, or a custom script or style for that template's pages. if you don't have a lot of templates, it is probably better to just include head and foot in each template file and skip the auto prepend/append.

The benefit of using pages for your endpoints is that you have full native access to the api, and no bootstrapping necessary..

 

  • Like 6

Share this post


Link to post
Share on other sites

Thank you, everyone! These are helpful strategies and I will integrate them into my work. What a great community. Regarding the auto-pre/appending, this is documented on the PW (https://processwire.com/docs/tutorials/how-to-structure-your-template-files/) as Direct Output with Automatic Inclusions, but I know Delayed Output and Markup Regions are probably preferred and I will work on switching to those strategies.

  • 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.

  • Similar Content

    • By EyeDentify
      Hello Dear PW Gurus.

      Hope you fair well in these Corona Crisis times.

      Anyhow, i have a problem with a Cryptic error message that shows up when i am trying to Delete images out of a Images field.
      The Error message does say a little but it does not make sense to me why i can´t delete the images because of it.

      Is it some permission issue perhaps?

      I will attach screenshots of it and what i did prior to it.
      I am from sweden so ignore the funny words here and there.

      Hope you all can send me on the right track.
      i am running PW 3.0.139 on this install.

      Step1:

      Step 2: Select the images with the trashcan symbol

       
      Step 3: Cryptic Error message

      I am scratching my head on this one, have not seen this before.

      Thankfull for all help.
      /EyeDentify
    • By Guy Incognito
      This short script loops through some images from an XML feed and pushes new ones to an image field. It all works perfectly, except for some reason the last image (only) in the loop each time doesn't receive the image description... can everyone spot why? TIA! 🙂 
      foreach ($propertyImages as $img) { $fileName = trim($img[0]); if ( !empty($fileName) ) { $imgPath = '../property_data/'.$fileName; if(file_exists($imgPath) && !in_array(strtolower($fileName),$currentImages)) { $p->property_images->add($imgPath); $p->save(); $newImg = $p->property_images->last(); $newImg->description = $img[1]; $p->save(); } } }  
    • By ICF Church
      Hi 👋
      Anyone else having this problem?
      Requirements:
      - Repeater (matrix & normal) with mutlilanguage fields (text, textarea…) 
      - Backend language set to something other than default (ie. German) 
      Reproduce:
      - Add a new repeater Item (ajax, I found no way to possible to disable it with matrix)

      (Notice how the default language tab is active instead of the backend language…)
      - Write something into the (default language) field
      - Try to save, if field is required, this will not work. If not required, then when reloading, the content will be inside the backend language field, instead of the default language field who was (presumably) active
      Analysis:
      When  loading  a new repeater element with ajax, the default langue tab is active, but the backend language inputfield is visible (with no visual indication). When writing into the field, it will populate the backend language. When manually clicking on the default language tab (which is already active), the field will switch to the actual default language field (which is [now] empty) (that can now be populated…)
      Also Notice, the labels of the elements to be added are in default language as well instead of the translated label (images instead of Bilder)…
      ProcessWire 3.0.148, Profields 0.0.5…
      Is it my system configuration, or does anyone else have the same issue? This is a screen recording of the problem:

      Screen Recording 2020-02-25 at 14.18.31.mov
    • By ragnarokkr
      Hi everyone. A lot time not writing here but periodically checking for the nice updates.
      I'm facing a problem and not able to figure out how to solve it easily  🤕  (admitedly that something in programming is easy 😂).
      I'm trying to implement featured and gallery fields for generic post. My problem is that I need to have the Inputfield reading/writing the images from/to a system folder rather than a page. Reason of that is that:
      customer stressed me out about the need to have a WordPress-ish 🤮 central folder for images; if referencing images from a page, possible future changes to the source page will change accordingly all images src link, breaking everything (and I'm trying to keep the backend as lighter as possibile by not fill it with modules which keep track of this and that at every change). I'm actually using the great ImageReference module, but I'm still facing some issues I already exposed on its GitHub repo, which I'll try to summarize here:
      image preview not (yet) responsive in edit page, or at least in my case it doesn't work as (I) expected; no scrolling in image selection (widget expans a lot especially if the container is narrow); no description available for the uploaded images. What I would like to have is the power of the default FieldtypeImage combined to the huge range of choices ImageReference gives out of the box, but from what I did understand the author is not interested into merging the things.
      All this brings me to the final question, which is:
      since I actually cannot afford to spend a lot of time reinventing the wheel, and is low-budget work, is there a way to hook some event from the default FieldtypeImage right before it uploads or reads the file from the page's folder, in a way I can modify the path by routing it to a folder of my choice?
      I hope I've been able to make clear my thought 🙈
       
    • By Robin S
      Add Image URLs
      Allows images/files to be added to Image/File fields by pasting URLs.

      Usage
      Install the Add Image URLs module.
      A "Paste URLs" button will be added to all image and file fields. Use the button to show a textarea where URLs may be pasted, one per line. Images/files are added when the page is saved.
       
      https://github.com/Toutouwai/AddImageUrls
      https://modules.processwire.com/modules/add-image-urls/
×
×
  • Create New...