If you need a simple Views display switch to toggle e.g between a list and a grid display of a view, there are a couple of plug & play options already.
Display Suite and Quick Tabs are modules which provide this functionality but they seem to be quite an overkill for a simple display switch. View modes on the other hand seems to be exactly what is needed, however there is no stable version and the development one did not work for me.
How it needs to work
Our use case dictates that while switching a display, the view needs to retain the exposed filter values and page number. The page will be reloaded, no AJAX magic here.
So let's create our own views display switch. In order to do that you will obviously be needing a view with at least two page displays showing content in different ways. You will also have to put some code into your custom module. If in doubt, refer to the countless other tutorials.
Set up your view
In the view named [view] set the path of [display_1] to e.g [page/grid], the path to [display_2] to e.g [page/list].
Create callback function
Create a simple callback function which will provide the switch in ready-to-be-displayed HTML.
/** * Gets HTML output of a switch which will switch between grid and list display of a view. */ function [mymodule]_get_views_display_switch() { 'query' => drupal_get_query_parameters(), // This ensures the view will keep filter settings when switching the display. ) )); $switch .= ' | '; 'query' => drupal_get_query_parameters(), ) )); // Adding CSS class for whole switch. $switch = "<div class='page-display-switch'>" . $switch . "</div>"; return $switch; }
Implement views hook
Implement hook_views_pre_view hook to add the switch to the view.
/** * Implements hook_views_pre_view(). */ function [mymodule]_views_pre_view(&$view, &$display_id, &$args) { if ($view->name == '[view]' && $display_id == '[display1]' || $display_id == '[display_2]') { // Adds a display switch to the header of a view. // 'footer' as second parameter will add the display switch to the footer of the view instead. $view->add_item($display_id, 'header', 'views', 'area', array('content' => [mymodule]_get_views_display_switch(), 'format' => 'full_html')); } }
This should do it. The l() function will make sure the link is marked active when it's active and drupal_get_query_parameters() makes sure the exposed filters and current page are retained while swichting.
Update
Apparently there is now a Drupal 8/9 module which implements these solutions: views_display_switch. I have not tested it, but have a go and let me know how well it works.
Comments
Wow! This MUST be a module on drupal.org. Why? Because there are really shortage of the modules which are CMS user/visitor centric as the most Drupal modules are built "by engineers for engineers" and actual user experience is overlooked.
I agree there are many modules in the Drupal ecosystem that are hard to grasp without some Drupal site building experience and often PHP experience, however I wouldn't say there is a shortage of easy/user centric modules.
If you added this code as a module on drupal.org, the community would probably point out other modules with similar functionality, or tell you to collaborate on existing modules to add this functionality on top.
That's because there are loads of modules on drupal.org that are too specialized and/or not maintained anymore.
Adding another module to drupal.org for such specialized functionality would mean another name space taken away for a module that only few will use (it's starting to get quite hard to come up with a simple module name not already taken).
Thanks for commenting.
cause i need this functionality now too. thanks.
Which step of this tutorial is stopping you from imtlementing this module yourself? This one should be rather straight forvard. If you'd rather like me to create the module for you, feel free to contact me with some details.
Great code, thank you.
Is there a Drupal 8 example?
You should be able to do exactly the same thing in a Drupal 8 module using the same hook. In D8 it looks like this:
You may need to replace l() and drupal_get_query_parameters() with some Drupal 8 service methods.
Thanks for sharing this.
It would be great to switch the view using ajax without leaving the current page.
You can add a 'Link to display' global handler in Header or Footer (found at the Add menu of the Header or Footer in View UI), which:
"Displays a link to a path-based display of this view while keeping the filter criteria, sort criteria, pager settings and contextual filters."
I just published a module that does this for D8/9: https://www.drupal.org/project/views_display_switch
Great work! I will mention that in the article.
Add new comment