By olalindberg on
Hi!
I have been working on a outputting a view as a customized table with the Drupal theme_table (http://api.drupal.org/?q=api/function/theme_table/5) method.
My data is being written correctly but I'm having issues with the Header. I generate the table by overriding the method that render my view. The table is created using the following code:
$table = array();
foreach ($nodes as $i => $node)
{
//Get the node
$node = node_load($node->nid);
// If this customer node is a premium customer we should include the company image in the table
$logoObj = null;
if(is_premium_customer($node)){
$logoObj = theme('image', $node->field_logo_low_resolution[0]['filepath']);
}
//Create a linked title object for this customer
$companyTitleObj = l($node->title, 'node/' . $node->nid);
//Get the links of taxonomy terms assosiated with this node
$taxonomyCategoriesLinks = get_taxonomy_categories_link_list($node);
//Generate the table array
$table[] = array($logoObj, $companyTitleObj, $taxonomyCategoriesLinks);
}
// Create the header for the table
$tableHeader[] = array(
array('data'=>"Logo"),
array('data'=>"Company Name"),
array('data'=>"Categories")
);
return theme_table($tableHeader, $table);
I get the following warning message when loading my list:
warning: htmlspecialchars() expects parameter 1 to be string, array given in /var/www/drupal/includes/bootstrap.inc on line 631.
The parameter field on the theme_table API description says that this parameter must be associated with the SQL field to make it sortable. Is there any way to make my header items sortable or do I need to make the SQL to get the data? If not what's the best way of creating the SQL for my view?
Comments
There's an example on the
How you've generated your header is wrong... There's a good example on the api page you've stuck in your post... Just change your header to;
That'll do it... As you're not fetching the data from a db table though you can't use Drupals pager/ sorting hooks (as you've rightly pointed out!) - you'll be pleased to know that it's easy to call them and set them up manually though. This is what I did in the Tablemanager module, check out its display function for tips (although most of the 'fancy work' in there is for manual pagination).
As you'll see above I've set 'field' for each header column to 'force' Drupal into rendering the table as sortable, check out the results of;
tablesort_get_order($tableHeader);tablesort_get_sort($tableHeader);I'm sure they'll help! ;o)
Pobster
edit: Obviously as the functions above use the $tableHeader variable, it's far better to build the header at the beginning of your function so you can get the sort order/ field first.
That did the trick!
Thanks a lot. It worked perfect.
Best regards,
Ola
I noticed that it doesn't sort
The arrows for sorting is displayed on the listing page but when I click the table headers it doesn't sort by that column. Any ideas why?
Here are the method that overrides the output of the view:
Thanks a lot. Best regards,
Ola
*YOU* have to sort them
*YOU* have to sort them that's why! Read the post I made above (again) to be able to tell which column needs sorting and which direction to sort it in... When I said you need to do it manually I really meant it!
Pobster
edit: ...sort routine from my tablemanager module;
...snip...
That explains it...
That explains it why my nodes aren't sorted! I guess I was a bit spoiled with all automatic functionality. Sorry!
Thanks for your help. I'll be able to manage it now. Best regards,
Ola
No worries! ;o) Afraid
No worries! ;o) Afraid it'll only integrate auto-sorting when the results are gained from a db table (as Drupal uses mysqls sort function) but as you're loading the arrays yourself - you're responsible I'm afraid!
I thought perhaps the sort routine I posted above was a little too specific for Tablemanagers requirements, so here's a skimmed down version;
It's from a very early version of Tablemanager (before it got complicated!) and sorts arrays while they're held in theme_table type arrays. Hope this helps!
Pobster
edit: You can swap
strnatcmpwithstrnatcasecmpif it suits better btw.subscribing
subscribing
http://SocialNicheGuru.com
Delivering inSITE(TM), we empower you to deliver the right product and the right message to the right NICHE at the right time across all product, marketing, and sales channels.
Trying to sprt.
I have a table, using the above code but I am having some problems sorting using this technique. Could some kind soul elaborate a bit more?? Thanks Ton.
What problems are you having
What problems are you having (and please be as specific as possible)??
Pobster
Thanks.
Okay, so I build my table. None of the data is directly from the db, rather, pulled from fields and calculated.
Of course this isn't sorted. It does make a nice table though! Clicking on the sort up and down arrow does nothing (as expected).
I'm assuming I insert your function into my code, which I did.
So now, I assume I need to pass my table array $table to your function which I do as follows with field '1' being the field to sort on.
Then return the sorted table..
This doesn't work. I have not yet checked the php error log but I am getting ready to do that. I just don't see how this will work, and what about sorting on more than one field?
I feel like there is a big concept I am missing. Thanks a ton for your help, and your function. This appears to be the ONLY post in the entire website that addresses sorting this custom table.
ARGH
I pulled a beginning php error. I now see the $table variable is passed by reference. No wonder the above code isn't working. Sorry!!!!
Should be..
So, I have actually sorted the first field ascending, However, the arrow keys on the header do not reverse the sort, and I am still working to try and figure out how to apply this to more than one field. If you happen to come along in the next year, I will likely still be messing with it. Again, thanks for taking the time.
Hiya! Afraid it's just a
Hiya!
Afraid it's just a little thing overlooked ;o)
You need to pass in the sort direction for tablemanager_sort as the third parameter.
You can use;
You seem to be hardcoding the field reference to '1' for some reason? This is obviously why only the first column is being sorted, use tablesort_get_order($tableHeader) which will return an array containing the field id.
Pobster
Hmm.
I feel like I just started using this CMS.
Not getting results..
I guess I'm an idiot. Been going through the API docs and it just isn't clicking. The above code does not sort.. Also the tablemanager_sort() function takes &$data so I don't need the $table_sorted variable.. It actually breaks it to use it. Sorry to be such a pain. I swear, I will answer 5 forum newbie posts for the exchange of this! ;)
Hmm
I am printing out the arrays $sort and $order and they are only giving me data on the first field. It feels like I need to loop through the $tableHeader and create an array for all of the fields?
It's okay, you just glossed
It's okay, you just glossed over the last part of what I wrote "...which will return an array containing the field id" you need to pass the correct array key into the function, it's not built to cope with parsing the array itself (just takes a string input) if you look to the api site; http://api.drupal.org/api/function/tablesort_get_order/6 it'll tell you which key you need (or you can just use
print_rto find out for yourself!)>I am printing out the arrays $sort and $order and they are only giving me data on the first field. It feels like I need to loop through the $tableHeader and create an array for all of the fields?
That is correct because you're only sorting on the first field - you hardcoded it at first and now, even though you're doing it dynamically - what you're doing is wrong and so Drupal is defaulting to only sorting the first field. What you're missing here though is that the function is sorting $table (which contains your rows) $sort and $order are just helper variables for the sorting function - I should know... I wrote it!
Pobster (Night! Bedtime!)
Professor.
I see what your doing. You COULD just give me all the code but instead force your students to figure this out on their own. For that, I applaud you (and curse you). No but seriously. Something is amiss.
debugging, I get the following array..
returns..
Array ( [name] => Room [sql] => 1 )
Shouldn't this be returning something for each cell? Looking over the code for tablesort_get_order(), it looks like it SHOULD be looping through $tableHeader and returning all of my 'field' values, instead it only returns the first column.
9 hours and counting on this task. Thanks again for the lessons.
Well... If you're going to
Well... If you're going to maintain any code you need to understand how it works and to understand something, you really have to write it yourself (with only a little prompting) if someone asks you to change something later down the line, you can thank me then ;o)
Nah you're misunderstanding what is happening, just pass in $order['sql'] and it'll work fine. The reason is that we've already set in the header the order in which the columns appear ('field' => '1', ... '2', etc) normally with this Drupal functionality you'd pass in database column names so we're essentially cheating by using Drupal functionality to do something other than what it was designed to do (reference keys in an array).
What you're missing here is that uasort in the sorting function is actually for sorting arrays (http://www.w3schools.com/PHP/func_array_uasort.asp) and that's why you only need to call it once.
Pobster
Well..
I actually then seem to have had it set up right and I am still not getting sorting.
Here is my code.
Here is the output without a call to tablemanger_sort().. ie remarked out. (all names are fictitious btw)
Room Last Name First Name Nursing Workflow Time
451 McFever Frankie 4S Team A: Nursealot, Sally, RN Admitted
466 Train Tyco 4N Team A: Bandager, Jamie, RN Admitted
450 Antonic Jen 4S Team A: Nursealot, Sally, RN Admitted
453 Sickly Jenny 4N Team A: Bandager, Jamie, RN Admitted
270 Eides Misty ICU Team B: Admitted
271 Deado Jacko ICU Team B: Admitted
272 Dartin Mean ICU Team A: Admitted
Calling tablemanager_sort() produces this output.
Room Last Name First Name Nursing Workflow Time
271 Deado Jacko ICU Team B: Admitted
272 Dartin Mean ICU Team A: Admitted
270 Eides Misty ICU Team B: Admitted
453 Sickly Jenny 4N Team A: Bandager, Jamie, RN Admitted
466 Train Tyco 4N Team A: Bandager, Jamie, RN Admitted
450 Antonic Jen 4S Team A: Nursealot, Sally, RN Admitted
451 McFever Frankie 4S Team A: Nursealot, Sally, RN Admitted
So, it's odd. There is some kind of rearrangement going on, but not a sort as I know it. Also, the header icon arrows don't do a thing except refresh the page. I thought it all made sense from the original post and the issue was me not doing it right, but I think I have it down as you explain.
Ah you're close, all that you
Ah you're close, all that you haven't done is build your rows using array('data' => // cell... in the same way you've built your header. If you look at the sorting function it takes e.g. $a['data']['$field'] as an argument, so... You can either supply it that way else you can just remove ['data'] from the strnatcmp (in both places!)
Pobster
Ahhh.
I thought the line from the api docs, "@verbatim $rows = array( // Simple row array( 'Cell 1', 'Cell 2', 'Cell 3' )" would be sufficient! Back to work!
Ah it is! But you're using
Ah it is sufficient! But you're using my own tablemanager_sort routine which is nothing to do with core! I use 'data' because it allows you to insert other stuff into the array as well (like colspan, attributes or whatnot).
Pobster
Cursed.
I see the logic.
replaced
with
and I get the exact same results. I also tried,
as this was closer to the example given on the theme_table API page. Still, exact same results. hmm.
added 'field' to $table.
Looked into the 8-Ball. It said, try this... So I did. Still no workie.
I keep thinking I understand this whole process and I don't. I am just going to print out all the code, and try to UNDERSTAND what it is doing because clearly, I dont. Every time I update, I think I have it and I don't.
Don't fret - this stuff is
Don't fret - this stuff is complicated, VERY complicated! Note that you don't need to pass in 'field' with table rows, that's only for the header and as I mentioned above somewhere - it relates to a db field, we're just hijacking it for our own purposes. I suspect the thing you're overlooking is that your fields are numbered 1, 2, 3, etc... Whereas machine numbers start from 0, 1, 2, etc...
Pobster
Hang on... I see what's
Hang on... I see what's going on here!
edit: No wait, maybe I don't... I thought perhaps the issue was with the old sort routine you're using but nope it appears to function correctly? There's a good example of it (and how it works) here; http://matt-darby.com/posts/625-sorting-a-multidimensional-array-the-eas...
Why don't you post up your code?
Pobster
Sure!
I am presently sitting in the waiting room of the car repair shop using their public computer so I can't at the moment but I will. To update, I have already tried using the full function from the last release of tablemanager that includes the strip_tags_c and renumbering operations. I got the same results. When I get home I will post up the entire function from the module that displays the page.
Thanks for the link to the sort function. I am starting to get it. The part that is perplexing is tryign to find where the heck the sort() function uses &$data??
EDIT: Oh I got it, it's passed to uasort().
What I really need to do is look at the code for usasort(), going to php.net now. Thanks again.
Code.
reposting to bigger block.
Code
I am attaching the portion of the module that you probably need. I did not include the functions called as they don't seem like they are needed.
I changed the field numbers to start with 0, but still no go. :(
Further testing.
Okay, so if I print out $order['sql'] and $sort below the table, these values are correct and change when clicking on the headers. They are updating as expected! One less possible problem. Moving along.
Apologies - the snow we've
Apologies - the snow we've been having here has let up today, so I'm actually in work (for a change!) I'll take a good look into this tonight when I get home. One thing I did think though is that as your rows are actually coming out of the database there's no real need to build the table in this way anyway. Later sorry... Working...
Pobster
Sure no problem
Oh I understand about work. I should be doing that now.
The problem is, I am not including any data from the nodes retrieved in the database query. Basically the table includes data from node references from the nodes collected from the database. This is the reason I didn't just use views. I tried, but the sheer number of relationships caused tons of duplicates that simply could not be filtered. I could have possibly used Views_or, but that module is still in dev and frankly, I could not get the results I needed. So.. now I have the table with all the data, I JUST CANT SORT IT! :). So, I am not sure I can use the db_query since all of the fields in the table are information from nodes referenced from the query nodes. :( You are a saint for helping. I understand the delay, work etc. Beggars can't be choosers!
Okay....
I was looking at the structure of my $table array and at your function..
The print_r ($table) looks like this before being run through tablesort().
The callback function for uasort() looks for..
Shouldn't it be $a['$field']['data']?
I switched these around as above and now the table STILL does not sort correctly (rather rearranges) BUT I do get the entire table flipped when I click the ASC and DESC arrows on the header. THIS is new and desired..
Not sure if I am just confusing things or if this is a lead..
I really need to go do my real job now. How challenging!
BINGO.
Okay. I have it working pretty much.
Not sure why but I have to transpose the ['data']['$field'] to ['$field']['data']. See above post. My Last Name field is NOT sorting but that is likely because that field is an l() entry. So, I am going to strip the html tags using a strip function, and then it should work.
The question is, why does my code require that I switcheroo your function, when it's been proven to work for a while now??? It has to be how I constructed my $table and $tableHeader arrays.. They look good to me though.
I'll give you an update after strip those tags.
Not so fast..
This will take some thinking. Since the $lastname field is wrapped in l(). It's messing up the sort. I think I'll need to rip the tags off inside the sort function, sort, then reapply them. I'll take a look at your most recent tablemanager_sort() for some ideas since you did something similar with the comment tags.
Sorry just literally walked
Sorry just literally walked through the door from work... Yep you can use the strip tags function that I wrote, which actually strips comments. All you'd need to do is put the last name as a comment BEFORE the link. It won't show (obviously as it's a comment) and it'll sort just fine!
Glad you got it working!
Pobster
Comments!
Ah, even easier. I just afix a comment with $lastname in front of my link and your function does indeed sort on this, and then it doesn't display in the table because.. It's a comment.
YAY! It works.
Really, I greatly appreciate your help on this. You have gone above and beyond.
Hey no problem, happy to
Hey no problem, happy to help!
Pobster
subscribing. this is AWESOME!
subscribing. this is AWESOME!
http://SocialNicheGuru.com
Delivering inSITE(TM), we empower you to deliver the right product and the right message to the right NICHE at the right time across all product, marketing, and sales channels.