As far as I can tell I can't expose sort options using Views. What I mean is for a displayed view (a simple unformatted list) I want a drop down to order by popularity, alphabetical on title field, etc..

Any recommendations on how I should go about achieving what I want?

Comments

WorldFallz’s picture

Views v3 adds exposed sorts. Works great.

just_fixed_it’s picture

Thanks very much for taking the time to reply.

I've done lots of searching around and the only exposed sort functionality I can find for Views v3 is when using a table format. Is this what you've been using? What I am after is exposed sorts for a simple list.

I've found a thread that offers a patch to add some sort functionality, but I'm a little unsure if this is the right way to go about it.

Any more help would be very welcome.

Thanks,
Aaron

WorldFallz’s picture

Nope-- when you add sort criteria there's an 'expose' button just like with filters. That's the exposed sort to which I was referring.

just_fixed_it’s picture

Thanks for that ... I'll take another look.

just_fixed_it’s picture

Right, after just simply not seeing what you were talking about, I eventually discovered a reason why I may not be seeing the same views screens as you ... errrr ... (embarrassing silence) ....

... I had previously rolled back to Views 2 because Views 3 was causing me stability problems. Sorry to be so careless in my earlier post. I had just forgotten about the roll back, and didn't take the time to check my module version until now. Stupid.

If you would be so kind ... which version of Views 3 are you running, and is it stable for you (there doesn't seem to be a 'full' release of Views 3).

Cheer,
Aaron

WorldFallz’s picture

lol, no worries. I'm using the current d6 dev of views3 and it's been rock solid for me. I'm so used to the new exposed sort and aggregation features I don't think I could go back to v2 even if it weren't stable.

tatewaky’s picture

Hi guys, im comming a little late for this conversation i know, however, from all my google research, as usuarl in every developers day, y finally get with it, but i have install the views3 and when i add the sort criteria, boom, there are no expose button anywhere, is there something i can possible doing wrong?, i just disable view, remove the directories, put the files and enable the views module again, and nothing. help please.

thanks in advance

--
Jason Acuna

WorldFallz’s picture

I've got the current dev of views3, and when I add a field to the sort the expose button is in the upper right corner just like with the filters section.

tom.camp’s picture

I think you are looking for something like this - http://www.mercycorps.org/gift/category/all

I used a simple form in the View header:

<form action="" method="GET">
	<label>Sort by: </label>
	<select onchange="this.form.submit()">
		<option value="">Newest</option>
		<option value="title">Name (A to Z)</option>
		<option value="low">Price low to high</option>
		<option value="high">Price high to low</option>
	</select>
</form>

I then used hook_views_query_alter() to change the sort order

It is not the ideal way to do this, but it works.

WorldFallz’s picture

yep-- that's it, and views 3 now has this built-in to the sort options.

frankspin’s picture

How do you use this code? Can you post your hook_views_query ?

tom.camp’s picture

Ok, first you need to have all of the sort options that you would like to use as sort options in your view with the default first.

Then you need to add this function:

function [your_module]_views_query_alter( &$view, &$query ) {
	
  if ( $view->name == '[view_name]' ) {
    $sort = $_REQUEST[ 'sort-order' ];
    if ( $sort == 'pr_low' ) {
      $query->orderby[ 0 ] = 'node_[first_sort_criteria] ASC';
      $query->orderby[ 1 ] = 'node_[second_sort_criteria] ASC';
      $query->orderby[ 2 ] = 'node_[third_sort_criteria] DESC';
    } elseif ( $sort == 'pr_high' ) {
      $query->orderby[ 0 ] = 'node_[first_sort_criteria] DESC';
      $query->orderby[ 1 ] = 'node_[second_sort_criteria] ASC';
      $query->orderby[ 2 ] = 'node_[third_sort_criteria] DESC';
    } elseif ( $sort == 'title') {
      $query->orderby[ 1 ] = 'node_[second_sort_criteria] ASC';
      $query->orderby[ 2 ] = 'node_[third_sort_criteria] DESC';
      $query->orderby[ 0 ] = 'node_[first_sort_criteria] DESC';
    } else {	
      $query->orderby[ 2 ] = 'node_[third_sort_criteria] DESC';
      $query->orderby[ 0 ] = 'node_[first_sort_criteria] DESC';
      $query->orderby[ 1 ] = 'node_[second_sort_criteria] ASC';
    }
  }
	
} // function [your_module]_views_query_alter()

You can get the field names, node_[first_sort_criteria], etc., by looking at the query that Views generates.

You do not need to return anything as the &$view and &$query are variable references.

That is all that there is to it.

frankspin’s picture

Thanks, but it does not work properly.

I have the following:

Views name: taxonomy_term
Filters: Node title asc
Filters: Node title desc

Views header code:

<form action="" method="GET">
<label>Sorteer op: </label>
<select onchange="this.form.submit()">
<option value="">Name (A to Z)</option>
<option value="title_za">Name (Z to A)</option>
</select>
</form>

Module file:

<?php

function studion_viewsfilter_views_query_alter( &$view, &$query ) {

  if ( $view->name == 'taxonomy_term' ) {
    $sort = $_REQUEST[ 'sort-order' ];
    if ( $sort == 'title_az' ) {
    	  	$query->orderby[ 0 ] = 'node_title ASC';
 			$query->orderby[ 1 ] = 'node_title DESC';
    }
	else {
      $query->orderby[ 1 ] = 'node_title DESC';
      $query->orderby[ 0 ] = 'node_title ASC';
    }
  }

}  
?>

the page just refreshes and nothing happens

tom.camp’s picture

You don't need the second value of your ->orderby array.

You simply need to change the ASC to DESC. So it should look like:

function studion_viewsfilter_views_query_alter( &$view, &$query ) {

  if ( $view->name == 'taxonomy_term' ) {
    $sort = $_REQUEST[ 'sort-order' ];
    if ( $sort == 'title_az' ) {
              $query->orderby[ 0 ] = 'node_title ASC';
    }
    else {
      $query->orderby[ 0 ] = 'node_title DESC';
    }
  }

}

You will only need the Title ASC sort criteria in the View if that is all that you want to do.

tom.camp’s picture

You could also simply change the else case to

      $query->orderby[ 0 ] = 'node_title DESC';
      $query->orderby[ 1 ] = 'node_title ASC';

I had it written the other way, but the way that it was written, it wasn't changing the highest sort criteria.

tom.camp’s picture

I got a little lazy when I posted this.

The $query->orderby array should be


      $query->orderby[ 0 ] = 'node_[first_sort_criteria] ASC';
      $query->orderby[ 1 ] = 'node_[second_sort_criteria] ASC';
      $query->orderby[ 2 ] = 'node_[third_sort_criteria] DESC';
    } elseif ( $sort == 'pr_high' ) {
      $query->orderby[ 0 ] = 'node_[first_sort_criteria] DESC';
      $query->orderby[ 1 ] = 'node_[second_sort_criteria] ASC';
      $query->orderby[ 2 ] = 'node_[third_sort_criteria] DESC';
    } elseif ( $sort == 'title') {
      $query->orderby[ 0 ] = 'node_[second_sort_criteria] ASC';
      $query->orderby[ 1 ] = 'node_[third_sort_criteria] DESC';
      $query->orderby[ 2 ] = 'node_[first_sort_criteria] DESC';
    } else {	
      $query->orderby[ 0 ] = 'node_[third_sort_criteria] DESC';
      $query->orderby[ 1 ] = 'node_[first_sort_criteria] DESC';
      $query->orderby[ 2 ] = 'node_[second_sort_criteria] ASC';
    }

The way that I had it written originally wouldn't change the order of the sorting.

My bad. :/

frankspin’s picture

Thanks for the help. My code is now working for 50%. When i change the default sorting order in my module file it is working.

<?php

function studion_viewsfilter_views_query_alter( &$view, &$query ) {

  if ( $view->name == 'taxonomy_term' ) {
    $sort = $_REQUEST[ 'sort-order' ];
    if ( $sort == 'title_az' ) {
        	$query->orderby[ 0 ] = 'node_title ASC';
			$query->orderby[ 1 ] = 'node_title DESC';
    }
    else {
     	 	$query->orderby[ 0 ] = 'node_title DESC';
      		$query->orderby[ 1 ] = 'node_title ASC';
    }
  }

} ?>

Only when i use the selectlist box, the page is only refreshing. There is no extra syntax after the url like: ?sort . Is there something wrong with my html code?

<form action="" method="GET">
<label>Sorteer op: </label>
<select onchange="this.form.submit()">
<option value="">Name (A to Z)</option>
<option value="title_za">Name (Z to A)</option>
</select>
</form>
tom.camp’s picture

I would get rid of the second option in the function code. So:

<?php

function studion_viewsfilter_views_query_alter( &$view, &$query ) {

  if ( $view->name == 'taxonomy_term' ) {
    $sort = $_REQUEST[ 'sort-order' ];
    if ( $sort == 'title_az' ) {
            $query->orderby[ 0 ] = 'node_title ASC';
    }
    else {
              $query->orderby[ 0 ] = 'node_title DESC';
    }
  }

} ?>

And make sure that you only have the node_title in the View Sort Order once. This way you are only going to use the function to change the ASC or the DESC, but the only criteria will be the node_title.

bhallnc’s picture

I appreciate your guidance so far on this. I have the right functionality all except for my select list always goes back to the default, "Newest". However, the product page is still sorted by the option that I selected. Here is what I have:

Sort Order:
Node: Post date asc
Node: Title asc
Product: Sell price asc

Form:

<form action="" method="GET" id="sort-order">
	<label for="sort-order">Sort by: </label>
	<select name="sort-order" onchange="this.form.submit()">
		<option value="">Newest</option>
		<option value="title">Name (A to Z)</option>
		<option value="pr_low">Price low to high</option>
		<option value="pr_high">Price high to low</option>
	</select>
</form>

Module:

function catalog_sorter_views_query_alter( &$view, &$query ) {
	
  if ( $view->name == 'product_grid_view' ) {
    $sort = $_REQUEST[ 'sort-order' ];
    if ( $sort == 'pr_low' ) {
      $query->orderby[ 0 ] = 'uc_products_sell_price ASC';
      $query->orderby[ 1 ] = 'node_title ASC';
      $query->orderby[ 2 ] = 'node_created DESC';
    } elseif ( $sort == 'pr_high' ) {
      $query->orderby[ 0 ] = 'uc_products_sell_price DESC';
      $query->orderby[ 1 ] = 'node_title ASC';
      $query->orderby[ 2 ] = 'node_created DESC';
    } elseif ( $sort == 'title') {
      $query->orderby[ 0 ] = 'node_title ASC';
      $query->orderby[ 1 ] = 'node_created DESC';
      $query->orderby[ 2 ] = 'uc_products_sell_price DESC';
    } else {	
      $query->orderby[ 0 ] = 'node_created DESC';
      $query->orderby[ 1 ] = 'uc_products_sell_price DESC';
      $query->orderby[ 2 ] = 'node_title ASC';
    }
  }
}

Do you see any errors that would cause this?

Thanks!
Brian

tom.camp’s picture

Ah, right....
I added

<?php $sel = $_REQUEST[ 'sort-order' ]; ?>

<form action="" method="GET" id="sort-order">
 <label for="sort-order">Sort by: </label>
  <select name="sort-order" onchange="this.form.submit()">
   <option value="">Newest</option>
   <option value="title" <?php echo ( $sel == 'title' ) ? 'selected' : '';?>>Name (A to Z)</option>
   <option value="pr_low" <?php echo ( $sel == 'pr_low' ) ? 'selected' : '';?>>Price low to high</option>
   <option value="pr_high" <?php echo ( $sel == 'pr_high' ) ? 'selected' : '';?>>Price high to low</option>
 </select>
</form>

So that you can set the "selected" for the current sort order.

bhallnc’s picture

Works perfect... Thanks for your help!

vasrush’s picture

Thanks for your help.
It works perfect!!!

drupalina’s picture

I'm using Drupal7 and Views3.
I tried everything that was suggested in this thread and the results that I get is that the form changes, but the order doesn't.

Can this work for Drupal7 ? or do we need to use another function

I want to sort by Date posted and a numeric field called "field_rentpcm". Here is what I have:

MODULE:

<?php

function MODULE_NAME_views_query_alter( &$view, &$query ) {

  if ( $view->name == 'testing_order_by' ) {
    $sort = $_REQUEST[ 'sort-order' ];
    if ( $sort == 'pr_low' ) {
      $query->orderby[ 0 ] = 'field_data_field_rentpcm_field_rentpcm_value ASC';
      $query->orderby[ 1 ] = 'node_created DESC';
    } elseif ( $sort == 'pr_high' ) {
      $query->orderby[ 0 ] = 'field_data_field_rentpcm_field_rentpcm_value DESC';
      $query->orderby[ 1 ] = 'node_created DESC';
    } elseif ( $sort == 'title') {
      $query->orderby[ 0 ] = 'node_created DESC';
      $query->orderby[ 1 ] = 'field_data_field_rentpcm_field_rentpcm_value DESC';
    } else {	
      $query->orderby[ 0 ] = 'node_created DESC';
      $query->orderby[ 1 ] = 'field_data_field_rentpcm_field_rentpcm_value ASC';
    }
  }
}

and in my views header I inserted a Global PHP form.
FORM:

<?php $sel = $_REQUEST[ 'sort-order' ]; ?>
<form action="" method="GET" id="sort-order">
 <label for="sort-order">Sort by: </label>
  <select name="sort-order" onchange="this.form.submit()">
   <option value="">Newest</option>
   <option value="pr_low" <?php echo ( $sel == 'pr_low' ) ? 'selected' : '';?>>Price low to high</option>
   <option value="pr_high" <?php echo ( $sel == 'pr_high' ) ? 'selected' : '';?>>Price high to low</option>
   <option value="title" <?php echo ( $sel == 'title' ) ? 'selected' : '';?>>Name (A to Z)</option>
 </select>
</form>

An additional problem is that by default (before any choice is made) it will show the following error:

Notice: Undefined index: sort-order in __lambda_func() (line 1 of /usr/www/users/foo/sites/all/modules/views_php/plugins/views/views_php_handler_area.inc(39) : runtime-created function).

Can someone PLEASE help?

FooZee’s picture

This approach works in a great way. but unfortunately, not in my use case :( , I have a view of type "page" with a view of type "attachment" attached to it, using the approach stated here, one ends up editing the sorting of all queries and views on this page (the page view and the attachment)!

However, the approach found here works too, and enables you to generally manipulate specific displays :) (maybe only the page, or only one of the attachments attached to it)
http://stackoverflow.com/questions/2719850/how-to-change-the-sorting-of-...

it is based on hook_views_pre_view() you need to look at the answer not the question only:D

shwet’s picture

I have
field name : 'field_emp_salary' ,
table name : 'field_data_field_emp_salary' and

//implement the hook_views_query_alter();
function hook_views_query_alter(&$view, &$query) {
if($view->name == "employee_basic_salary") {
$query->orderby[0] = array(
'field' => 'field_data_field_emp_salary.field_emp_salary_value',
'direction' => 'ASC',
);
}
}

Can anyone solve below error :

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'field_data_field_emp_salary.field_emp_salary_value' in 'order clause'

...waiting for reply
Thanks in advance.

shwet’s picture

Hello Guys,

I got the solution and it shows appropriate sorted columns

function hook_views_query_alter(&$view, &$query) {
if($view->name == "employee_basic_salary") {
$view->query->add_orderby('field_data_field_emp_salary','field_emp_salary_value',$order = 'DESC', $alias = '', $params = array());
}
}