October 29, 2010

Arbitrarily Order Your Views - Part 1: DraggableViews

It happens every once in a while that you need to order your nodes arbitrarily. That is, sorted neither "ascending" nor "descending". An example of this might be an employee listing page on a company website. It's likely that the employee listing needs to be sorted by order of importance (for lack of a better term) with the bosses at the top, the interns at the bottom, and everyone else in between.

The *simplest* solution is to just add some sort of weight field to your 'employee' content type and then create a View and sort by this weight field. But then as employees come and go, you'll find that opening and editing every node to adjust for the new company hierarchy will get tedious and frustrating. In comes DraggableViews and Nodequeue to save the day!

The DraggableViews and Nodequeue modules both allow you to arbitrarily/manually order your nodes but with a few slight differences in design and interface. In Part 1 of this tutorial we will create a View for a company's employee listing and order them using DraggableViews. In Part 2 (next week) we will examine using the Nodequeue module to achieve the same results, then compare the two modules' strengths and weaknesses.

This tutorial is specifically for Drupal 6 (but I suspect not much will change when they are released for Drupal 7)

Step 1 - The Employee Content Type:

We'll start with a fresh install of D6 with the following modules downloaded and installed:

  • Views
  • DraggableViews
  • Nodequeue (For part 2)


We'll then create the employee content type with the following fields:

  • Name (Node Title)
  • Job Title
  • Image
  • Bio (Node Body)

I've gone ahead and added all the employees here at Fuse Interactive, so let's jump into Views and create the employee listing page.

Step 2 - The employee listing page in Views:

I've started by creating a simple view with the fields we created for the employee content type and added a filter to show only nodes of the type: Employee.

And the output looks like this (I hid the image and the bio to conserve space):

Right now this doesn't make any sense. Why is the President at the bottom of the list and why am I, a lowly Drupal Developer, at the top? This is because it's ordering them by node nid right now. Since I didn't enter each employee in the *correct* order, I will need to use DraggableViews to re-sort them manually.

The concept here with DraggableViews is to create a view that produces an output of nodes or fields, and then create a separate views display that will act as a sorting interface for the view. The view will be manually re-orderable using the same drag 'n drop interface as other drupal admin tables (e.g. taxonomy terms, menu items, 'manage fields' in cck)

Step 3 - Adding the main page display:

First things first, we're going to create a page display for this employee listing  This will be the page that visitors of the site will see. We'll name it "DV_Page"...

...and assign it a path of employees/draggableviews...

Step 4 - Creating the DraggableViews sorting interface

Now we'll create another page display that with the DraggableViews style plugin enabled that we'll use for the sorting interface. We'll give it a name of "DV_Sort_Page"...

...and a path of employees/draggableviews/sort...

The next few steps need to be done in a specific order to avoid getting errors. Your first instinct may be to change the Style plugin to Draggable Table but there are a few things that need to be done before we enable it.

Firstly, we need to add the 'DraggableViews: Order' field. This is the actual "weight" of the row item that gets automatically changed as we drag 'n drop the rows. (Make sure you don't exclude this field from display, it will be needed a little later!)

Next, we need to add the field 'Node: nid' to the fields. This is because of how DraggableViews stores the order in the database. It creates a map of the Node's nid to a "weight" and saves it so that it can be used as a sorting criteria for ordering the rows.

SIDENOTE: Adding the nid only needs to be done in Views 3. In Views 2 the nid is passed into the result set by default, but it Views 3 you need to explicitly add it as a field!

We are also going to make the nid field excluded from display because we don't really care to see that when I'm sorting the rows later.

We also need to make sure these new fields are at the end of the fields list for DraggableViews to work. This is because DraggableViews will be attaching a little drag n drop handle to each row's first field and errors if the first field is hidden (remember, 'Node: nid' is excluded and 'DraggableViews: Order' will be hidden by default).

Also we can remove fields right now that will clutter up our sorting table. Remember, this is not the actual view, but just a table of the views results that can be re-ordered using Drupal's built in drag 'n drop functionality. In this case, for the purposes of sorting, I really only need to see the employee name and job title, so we'll remove the Body and Image fields.

Lastly, we need to change the sorting of the display to use the DraggableViews: Order (Ascending) rather than alphabetically. Our display at this point should look something like this

Now that our display is all set up, we need to change the style plugin from 'Unformatted' to the "Draggable Table" plugin.

And config the 'Order Field' to 'Order' (this is all you need to configure for the style plugin):

Step 5 - Adjust the Original View

The very last thing before you move on to arbitrary ordering glory is to change the sorting criteria of the original page view (The one we named "DV_Page") to match the DraggableViews order (from Node: Title to DraggableViews: Order)

It's important to note that the view 'preview' output at the bottom of the screen does not process the DraggableViews properly. You will need to visit the actual page (employees/draggableviews/sort) to get the proper functionality

Just Drag 'n Drop your new order and click 'Save Changes', then visit your employees/draggableviews page and voila! An Arbitrary order!

Stay tuned for Part 2 where we will explore the Nodequeue module and compare it to DraggableViews.