views:

3835

answers:

5

Hi

I've been developing a site over the past few weeks using CodeIgniter as the framework. It's a great framework, however I've been puzzling over the best way to accomplish something which in a lot of other frameworks / languages is relatively simple: sortable tables.

CodeIgniter switches off query strings by default, because your URLs contain method parameters.

so a URL might look like: /controller/method/param1/param2

So you might think that you could just add in 'sortBy' and 'sortOrder' as two additional parameters to the controller method. I don't particularly want to do that, mainly because I want to have a re-usable control. When you use query string parameters, PHP can easily tell you whether there is a parameter called 'sortBy'. However when you're using URL based parameters, it will vary with each controller.

So I was wondering what my options were, as far as I can see it it's something like this:

  • Pass in my 'sortBy' and 'sortOrder' parameters, just suck it up and develop some less-than-reusable component for it.
  • Have an additional controller which will store the sortBy and sortOrder in the session - although it would have to know where you came from and send you back to the original page.
  • Have some kind of AJAX function which would call the controller above and then reload the page.
  • Hack CodeIgniter to turn query strings back on! [Actually if this is the only option, any links to how to do this would be appreciated...]

I just can't quite believe such a simple task would present such a problem! Am I missing something? Anyone have any recommendations?

Edit for clarification: I love jQuery (and I'm already using it on the site) so TableSorter is a good option, however I would like to do server-side sorting as there are some pages with potentially large numbers of results (including pagination).

Thanks very much! - Phill

A: 

I recently added this Table sorter (which uses Prototype) to a bunch of my pages. It's fast and pretty easy to implement.

Mark Biek
+3  A: 

If you're OK with sorting on the client side, the Tablesorter plugin for jQuery is pretty nice.

Nathan Long
Thanks a lot, this will save me a lot of time
Click Upvote
Tablesorter loads the entire query result in one go, which isn't suitable if you want to load a lots of data.
Randell
@Randell - it does have a pagination feature built in, but I haven't tried it, and you're still right if the data set is large enough.
Nathan Long
A: 

When I had this problem, I personally modified CI so it could support both query strings an segments. I don't understand why it doesn't do that by default (despite my suggestion) but that's their choice.

The alternative is to use their associative URLs feature... which isn't exactly what you're looking for but better than using indexes to refer to them. I would link to the documentation but their server seems to be down.

Lewis
+2  A: 

I ran into this with a fairly complex table. The hard part was that the table could grow/shrink depending on certain variables!! Big pain :(

Here's how I handled it..

Adjusted system/application/config/config.php to allow the comma character in the URI:

$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-,';

Adjust my controller with a sorting function:

function sorter() {
  //get the sort params
  $sort = explode(",",$this->uri->segment(3)); //the 3rd segment is the column/order
  //pass the params to the model
  $data = $this->model_name->get_the_data($sort[0],$sort[1]);
  $this->_show($data);
}
function _show($data) {
  //all the code for displaying your table
}

I've oversimplified, but you get the idea. The purpose is to have a url like this:

/controller/sorter/columnname,sortorder

The sorter function calls another internal function to deal with the display/template/view logic - it's job is to deal with the sorting call and get the appropriate data from the model.

Of course, this could be reduced to just your current function:

function showGrid() {
  $sort = $this->uri->segment(3);
  if ($sort) {
    //get the data sorted
  } else {
    //get the data the default way
  }
  //rest of your view logic
}

That way, you don't even need a separate function - and can use the third segment to define your sorting.

JayTee
You could accept an argument to the sorter function instead of hard-coding URI segment 3. Otherwise it seems like a pretty good idea.
Christian Davén
Thanks, that's very helpful!
Phill Sacre
+4  A: 

I have been using this method: http://codeigniter.com/forums/viewthread/45709/#217816

I also expanded it to set cookies based off the sort so when someone comes back the table is sorted the same as before.

Eric