I've created an events system using Views 3 & the Date module. See it in action here: http://www.thehealingtrust.org.uk/drupal/events.

Some of the events we will have won't have a date because they will be By Arrangement or To Be Confirmed.

The list is sorted by date (ascending). Events without dates are appearing at the top of the list. Really they should be listed at the bottom so people don't have to scroll past a bunch of unscheduled events in order to see the next upcoming event.

What can I do to get events with empty date fields listed after the last occuring event?

Thanks.

Richard

Comments

span’s picture

Did you find a solution to this? Also looking for this type of sorting.

span’s picture

I didn't find a way in Views to do this but with the help of this:
http://drupal.org/node/727418#comment-3351666

I came up with this:

/**
 * Alter views query to handle sorting of empty fields
 */
function MODULENAME_views_pre_execute(&$view) {
    if($view->name == 'VIEWNAME') {
        $view->build_info['query'] = str_replace("FULL_FIELD_NAME ASC", "ISNULL(FULL_FIELD_NAME), FULL_FIELD_NAME", $view->build_info['query']);
    }
}
UserFriendly’s picture

@span That's great, thanks for posting that here. Would you mind explaining how to use / where to put the code?

span’s picture

You would have to create your own module to use this code. Check this out if you are not comfortable with that:
http://drupal.org/node/231276

You don't need any other code in the module except for the above so the tutorial might be a bit overkill if you don't want to learn. Basically what you need is to create a folder that you call "MODULENAME". In that folder you create 2 files, one called "MODULENAME.info" and one called "MODULENAME.module".

Put this in the info file:

name = MODULENAME
description = A description
core = 7.x

And in the module file:

/**
 * Alter views query to handle sorting of empty fields
 */
function MODULENAME_views_pre_execute(&$view) {
  // dsm($view);
    if($view->name == 'VIEWNAME') {
        $view->build_info['query'] = str_replace("FULL_FIELD_NAME ASC", "ISNULL(FULL_FIELD_NAME), FULL_FIELD_NAME", $view->build_info['query']);
    }
}

You can use the "Devel" module and then use the command dsm($view) and then visit any page where the view loads. This will give you an oversight on the view object where you can easily locate your FULL_FIELD_NAME.

Remember to activate the module.

To get back on topic, I suppose this is a Views issue and not a Date issue but it would be nice to have the possibility to decide how the sorting works on empty fields without writing code.

UserFriendly’s picture

I still haven't managed to get this to work. The ORDER BY line (found by setting Views to display SQL) is as follows:

ORDER BY field_data_field_start_date_field_start_date_value ASC, taxonomy_term_data_name ASC

The code I've been using in my module (called sortfix) is:

<?php
function sortfix_views_pre_execute(&$view) {
    if($view->name == 'events') {
        $view->build_info['query'] = str_replace("field_data_field_start_date_field_start_date_value ASC", "ISNULL(field_data_field_start_date_field_start_date_value), field_data_field_start_date_field_start_date_value", $view->build_info['query']);
    }
}
?>

What am I doing wrong?

Thanks.

KarenS’s picture

Status: Active » Fixed

There are answers to the question and it is something that we won't provide in Date module probably because I try not to override the Views sql handling. You can more easily do it in custom code. If I added it in to the Date module I would have to add options to be sure it plays nicely with anything else that might be in that view.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

crantok’s picture

Component: Date CCK Field » Code

This post was the first thing I found through google when searching on this problem. Tweaking the solution above did not work for me. I posted my working solution for a similar case in the more general thread that was mentioned in #2 above.

http://drupal.org/node/727418#comment-6095488

marcelæ’s picture

I managed to put together a little module that sorts empty date fields last on a general level, i.e. it's not specific to the naming of your view / fields. It's for Drupal 7 / Views 3.

sites/all/modules/sort_empty_dates_last/sort_empty_dates_last.info

name = sort_empty_dates_last
description = Make Views sort empty date fields after filled in date fields when sorting ascending
core = 7.x

---

sites/all/modules/sort_empty_dates_last/sort_empty_dates_last.module

/**
* Alter views query to handle sorting of empty datetime fields
*/
function sort_empty_dates_last_views_query_alter(&$view, &$query) {
    foreach ($view->display_handler->handlers['field'] as $field) {
        if (isset($field->field_info['type']) and $field->field_info['type'] == 'datetime') {
            $table_name = $field->table_alias ? $field->table_alias : $field->table;
            $column = $field->real_field;
            foreach ($query->orderby as $key => $orderby) {
                if ($orderby['field'] == $table_name . '_' . $column or
                    $orderby['field'] == $table_name . '.' . $column) {
                    array_splice($query->orderby, $key, 0, '');
                    $query->orderby[$key] = array('field' => 'ISNULL(' . $table_name . '.' . $column . ')', 'direction' => 'ASC');
                }
            }
        }
    }
}

It works by hooking into hook_views_query _alter and iterating over each field in the view. If there's a field of type datetime it then iterates over the orderby list, to see if the view is set to be sorted by the date field. If that is the case, it insert an orderby before the one sorting by date, sorting by whether the date is null (empty), using the SQL function ISNULL.

thanks to this thread, the thread http://drupal.org/node/727418, and the page http://grayside.org/2011/08/infinite-null-sorting-null-last

ashrafabed’s picture

Thank you marcelæ. I tried your module out, but I had to change

 and $field->field_info['type'] == 'datetime') {

to

 and $field->field_info['type'] == 'date') {

for it to work. Maybe it should be

 and (($field->field_info['type'] == 'date') || ($field->field_info['type'] == 'datetime'))) {

.. not sure if that's a better fit for all cases. But the change from datetime to date made your code work for me.

zincdesign’s picture

#9 worked for me without any modification. Thank you so much marcelæ

Sinan Erdem’s picture

Issue summary: View changes

For future reference, this module may solve the issue:
https://www.drupal.org/project/views_sort_null_field

sfelder’s picture

#12 the Views Sort Null field module works. I created my own "Rank" field, so in my view's Sort Criteria I have:

Content: Rank:value:null sort (NULL Last)
Content: Rank (asc)
Content: Post date (asc)

I had to arrange the rank null field before the actual rank field with values.

Thanks