2

I have a page on my website were I display alot of entries. Now I want those entries to be sorted by Date, Title etc. I know how to change that hard coded but I want to make it dynamic with a <select>. I guess I need to use Ajax for this but after a long search I still cant figure it out.

The Select

        <select>
            <option value="{% set order = "postDate asc" %}">New - Old</option>
            <option value="{% set order = "postDate desc" %}">Old - New</option>
            <option value="{% set order = "title asc" %}">A-Z</option>
            <option value="{% set order = "title desc" %}">Z-A</option>
        </select>

The loop

        {% set counter = 0 %}
        {% for entry in craft.entries.section('tips').order('{{ order }}') %}
            {% set counter = counter + 1 %}
            {% include 'includes/tip-blocks' %}
        {% endfor %}

To make the question short.

Sort entries dynamicly through a select form. Prefer not to reload the page but, it's oke if it does.

4

Okay so you can either do this through ajax or through a page reload, a page reload is going to be much easier, but you can get it to work without reloading the page...

Reloading the page

You can basically make it so that when a user selects an option, use jQuery to redirect to the current page and append the <option> value to append as a query string, so your template could look like this:

<select id="sortQuery">
 <option value="postDate asc">New - Old</option>
 <option value="postDate desc">Old - New</option>
 <option value="title asc">A-Z</option>
 <option value="title desc">Z-A</option>
</select>

Then, you can do this in your template:

{% set orderJs %}
  $(function(){

    $('#sortQuery').on("change", function(e){

     // Get the value from the select
     var filter = $(this).val();

     // We can use twig because we are setting this in template, if you extracted this to its own file, you would need a different means to output the page url
     document.location.href = '{{ craft.request.getUrl() }}?order=' + filter;

   });

  });
{% endset %}

{# let craft include the script to the end of our template #}
{% includeJs orderJs %}

Then, in your template file your code could be:

{% set counter = 0 %}

{# Either get the order from the query or use a default #}
{% set order = craft.request.getParam('order', 'title asc')  %}

{% for entry in craft.entries.section('tips').order(order) %}
  {% set counter = counter + 1 %}
  {% include 'includes/tip-blocks' %}
{% endfor %}

This should then reload the request with the query string, craft will see it and update the response accordingly. I must stress this is untested, but it should work...

Without reloading the page

This gets a little more complex and would involve more jQuery/Javascript than craft so I won't go into too much detail about it.

The steps are pretty much the same as above, except within the script tags (where you listen for a select change) you would make an ajax request to either a html template (which contains the sorted results) or even using the ElementApi plugin to return json (from a template) which you can then iterate over in jQuery and then update your DOM accordingly.

I hope this helps get you on track!

| improve this answer | |
  • This is all i get: CDbCommand failed while performing the following SQL statement: SQLSTATE [ 42S22 ] : Column not found: 1054 Unknown column ' craft_order ' in ' order clause ' Thanks for the answer though still figuring this one out! – Justin Dekkers Sep 3 '15 at 7:35
  • Sorry there was an error in the way the entries were fetched, was passing {{ order }} as a string when it should have just referenced the variable, I have updated my answer. – Alec Ritson Sep 3 '15 at 7:40
  • That was the last fix to it :D I'll be trying to get it without reloading now. – Justin Dekkers Sep 3 '15 at 7:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.