Ajax-EE: Sort and Order Data with ExpressionEngine and Ajax part one

Terris Kremer / Posted 5.8.2012

Ajax-EE: Sort and Order Data with ExpressionEngine and Ajax part one


When working with large amounts of data entries we often find it useful to let users order and sort the output of channel tag entries on the fly without re-rendering an entire page.

Here I’ll show a common way to accomplish this using Ajax and a typical set of ExpressionEngine channel tag entries.

Making it work when it doesn’t work.

The first step to making something work with Ajax is to make sure it works without Ajax. If a user doesn’t have JavaScript enabled I want to be sure they can still sort entries. Those users will just have to load the entire page.

Let’s start with a basic template that has a header, footer and content section. In the content section I’ll add channel entry tags that loop through article entries. By default they’ll be sorted by date in descending order. My template looks like this:

{embed='site/header'}
<h2>Articles</h2>
<table>
<thead>
  <tr>
    <th>Date</th>
    <th>Title</th>
    <th>Author</th>
    <th>Status</th>
  </tr>
</thead>
<tbody>
  {exp:channel:entries channel="articles" dynamic="no"}
    <tr>
      <td>{entry_date format="%M %d, %Y"}</td>
      <td><a href="{path='articles/{url_title}'}">{title}</a></td>
      <td>{author}</td>
      <td>{status}</td>
    </tr>
  {/exp:channel:entries}
</tbody>
</table>
{embed='site/footer'}


Now I’ll add links to the table headers with URL segments that will act as sort parameters that we use later:

<thead>
  <tr>
    <th><a href="{path='ajaxee/date/asc'}">Date</a></th>
    <th><a href="{path='ajaxee/title/asc'}">Title</a></th>
    <th><a href="{path='ajaxee/username/asc'}">Author</a></th>
    <th><a href="{path='ajaxee/status/asc'}">Status</a></th>
  </tr>
</thead>


The links I’ve added will point to the same template I’m working in now but the second and third URL segments declare the orderby and sort parameters we’ll use later. The following diagram illustrates how each segment is used.

Now, when the user clicks one of these links we can grab the orderby and sort segments from the URL and add them as parameters in our channel entries tag. I’ll update that section to look like this:

{exp:channel:entries channel="articles" dynamic="no"
orderby="{segment_2}"
sort="{segment_3}"
}
<tr>
  <td>{entry_date format="%M %d, %Y"}</td>
  <td>{title}</td>
  <td>{author}</td>
  <td>{status}</td>
  <td><a href="{path='articles/{url_title}'}">View &raquo;</a></td>
</tr>
{/exp:channel:entries}


Here I’ve added two parameters to my opening channel entries tag: orderby and sort. In the orderby parameter I use {segment_2} as the value and in sort I use {segment_3}. When a user clicks any of the links in the table header the channel entries tag will use those URL segments to set orderby and sort. This also works well because if neither segment is available the tag just assumes the default; order by date in descending order.

One problem is that my table header links will still have “asc” as the sort value in their segments. So, in order to let the user switch the sort order, I can use an if/else statement to test for asc or desc in the url segment. I’ll update my table header section like this:  

{if segment_3 == "asc"}
  <th><a href="{path='ajaxee/date/desc'}">Date</a></th>
  <th><a href="{path='ajaxee/title/desc'}">Title</a></th>
  <th><a href="{path='ajaxee/username/desc'}">Author</a></th>
  <th><a href="{path='ajaxee/status/desc'}">Status</a></th>
{if:else}
  <th><a href="{path='ajaxee/date/asc'}">Date</a></th>
  <th><a href="{path='ajaxee/title/asc'}">Title</a></th>
  <th><a href="{path='ajaxee/username/asc'}">Author</a></th>
  <th><a href="{path='ajaxee/status/asc'}">Status</a></th>
{/if}

This bit of code tests for “asc” in the third segment. If it’s there we switch up the links to use “desc.” Now, for example, the user can click the date sort link once and the data will be sorted by date in ascending order. If the user clicks the date link once more consecutively, the data will be sorted by date but in descending order. This pattern will persist as long as the user is clicking the same table header link.

Next Week: We Make it Ajaxee

This wraps up part one of using Ajax to sort and order entries in ExpressionEngine where we made sure that our sort and order functionality works without Ajax for those users who don’t have JavaScript enabled. Feel free to ask any questions you might have so far in the comments below. See you next week!

Terris Kremer

Terris Kremer

Front-end developer at Q Digital Studio

Terris Kremer is a front-end developer at Q Digital Studio. Largely self-taught, Terris was playing around with bits of html while most kids were still figuring out how to type up a term paper. In college, Terris dabbled in programs from music to marketing but found a real passion in designing for the web.

He spent a few years on the freelance circuit in Denver, honing his skills and was once paid with a bike for his incredible web work. Terris realized that while he loved the vocation, he wanted to collaborate with like-minded individuals and didn't want to worry about when the next job would come: he just wanted to design. He enjoys being part of Q Digital Studio and working to create sustainable designs and better communities.

While Terris may joke that both front- and back-end developers are œdweebs, he really does make development look cool. For Terris, work is a game that he can (and does) play all day long. At Q Digital Studio, he is the go-to guy when design and development must learn to play nice. He is working to become the resident typography guru and loves every ligature, loop and stem that comes out of the Hoefler & Frere Jones foundry.

Terris noodles on a guitar in his free time and enjoys revamping an old piece of furniture every now and again.