3

I have a View containing a list of events. There is a date field on the event content type which contains start and end time:

enter image description here

There is a filter for start time, which is setup using the Views Between Dates Filter:

enter image description here

This means that entering 11:00am in the filter will ensure that the event with time 10:00 AM to 3:00PM exists in the results since 11 falls between 10 and 3.

The full result set might look like the following when using 11am for the filter:

7am to 3pm
8am to 12pm
9am to 11:30pm
11am to 12:00pm
11am to 1pm

How can I create a custom sort, such that the exact matches for start time are ordered first? These are the results I need:

11am to 12:00pm
11am to 1pm
7am to 3pm
8am to 12pm
9am to 11:30pm

Is there a way to create a custom sort handler for views using filter values?

EDIT: I'd hoped I could use hook_views_post_execute to re-order the data but I'm using a pager, so only the first 10 results exist in $view->result

4
  • In views sort criteria did u try to sort using start date?
    – Cool
    Commented Mar 30, 2016 at 13:25
  • Start date would give me my first set of results (7, 8, 9, 11, 11), whereas I need a non-sequential order (11, 11, 7, 8, 9) Commented Mar 30, 2016 at 14:28
  • 1
    why 7 after 11? What kind of order you are trying to do asc or desc? If you want custom order, then add a separate field for ordering purposes only.. For example just add one more field name as Weight, then you can use that field in views for sorting. Otherwise try a traditional approach by using Nodequeue module.
    – Cool
    Commented Mar 31, 2016 at 6:06
  • It's based on the value the user chooses in the filter. I.e. if the user chooses 11 in the filter then we want 11 first. I came to the same conclusion as you mentioned, the only solution is to store data in fields since views relies on SQL for sorting. Commented Mar 31, 2016 at 8:35

1 Answer 1

0

In the end, my client agreed this feature was overkill and it was ommitted but I thought of a way it could be achieved.

Potential Solution

The following is only feasible if you have a finite and relatively low number of filter values because you need to create a field for every filter value.

  • Create a field of type boolean for every filter value. In our case we had 10, 11, 12, 1, 2, 3 as potential values for hour and 00, 15, 30, 45 for minute. 24 possible combinations, so 24 fields need added to the event type.
  • The field should be named according to the filter combination, e.g. Sort: 10:00, Sort: 10:15 etc.
  • The field value should be set as either 1 or 0. If the event start time matches the time in the name of sort field then this should be set to 1 otherwise it should be set to 0. hook_node_insert and hook_node_update could be used to set the values.

E.g on each event you would have:

Start Time - 11:00

Sort 10:00 - 0
Sort 10:15 - 0
Sort 10:30 - 0
Sort 10:45 - 0
Sort 11:00 - 1
etc (the rest would be set to 0).
  • When the filter is applied, use hook_views_query_alter to grab the filter value. Then set the sort based on that field.

E.g if the user entered 11:00 as the filter value, we could force the sort to use the Sort: 11:00 field. The following is written off the top of my head, so would need some tweaks:

function my_module_views_query_alter(&$view, &$query) {
  if($view->exposed_input['field_start_time'][0]['value'] == "11:00am") {
    $view->query->orderby[0]['field'] = "field_data_field_sort_11_00_value";
    $view->query->orderby[0]['direction'] = "DESC";
    // Add any secondary sorts.
  }
  else if($view->exposed_input['field_start_time'][0]['value'] == "11:15am") {
    $view->query->orderby[0]['field'] = "field_data_field_sort_11_15_value";
    $view->query->orderby[0]['direction'] = "DESC";
    // Add any secondary sorts.
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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