Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We're retiring the forums!

The SilverStripe forums have passed their heyday. They'll stick around, but will be read only. We'd encourage you to get involved in the community via the following channels instead:

Archive /

Our old forums are still available as a read-only archive.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo

Set order in ComplexTableField

Go to End

8 Posts   4192 Views


Community Member, 17 Posts

31 May 2008 at 10:40pm

I need to be able to set order of items in a ComplexTableField - this order has to be preserved and items should be listed in the same order on the page.

Currently I see one solution that I am unfortunately unable to implement :)
I would add a "Position" field to my DataObjects and this field would be edited in the ComplexTableField. I would like to add "Up" and "Down" links (or any similar solution that doesn't require the user to type position integers into field) to each item to change position. This may be implemented with setFieldFormatting that would generate appropriate links.

The the "appropriate" word is the tricky part.
I don't know how to:
1. create operation that would change the position value of item and its neighbour (should be easy),
2. call this operation when the link is clicked,
3. reload the table view (maybe this would be automatic).

The tutorial [1] has a link as an example: <a href=\"admin/security/index/1?executeForm=EditForm&ID=1&ajax=1&action_callfieldmethod&fieldName=Members&ctf[childID]=$ID&ctf[ID]=1&ctf[start]=0&methodName=edit\">

What I need most is a general overview of how to achieve this and where to look for details.



Forum Moderator, 801 Posts

5 June 2008 at 9:55am

editable sorting is currently not implemented in CTF, and needs some thinking about UI/usability in the first place - e.g. what happens if you have a predefined sorting (e.g. by created date) in your CTF listing? what about paging?

you might want to have a look how yahoo YUI components solve this problem (on the clientside perhaps?)


Community Member, 17 Posts

6 June 2008 at 3:38am

Edited: 06/06/2008 3:39am

It seems that you are talking about sorting in the CTF component which is not what I intend to do.

I need to define order of elements. This will require a "position" column for the objects. I need a way to easily edit this field. Ideally I would create buttons "up" and "down" for each element that would move it with respect to its neighbours (i.e. swap their "position" values).

Sorting by position would be the predefined and only one in CTF.

The problem I need to solve is how to add two buttons/links to each element in the CTF. Or rather, how to handle clicking on such buttons, since I know how to generate HTML for each row.


Community Member, 17 Posts

11 June 2008 at 9:34am

I'm moving forward with this :)

I was able to create a subclass of ComplexTableField with two additional buttons next to "show": "up" and "down". They swap position of the items, great.

But clicking on them causes a popup to show up, as if I was going to edit the item. I need behaviour similar to the "delete" button, where there is no popup but the ComplexTableField component gets redrawn with javascript (I don't need AJAX). How should I approach this?

I generate the link for the button like this:

class OrderedComplexTableField_Item extends ComplexTableField_Item {                                                                                         

        function MoveUpLink() {                
                return Convert::raw2att($this->PopupBaseLink() . "&methodName=moveUp");                                                                      

        function MoveDownLink() {              
                return Convert::raw2att($this->PopupBaseLink() . "&methodName=moveDown");                                                                    


and handle them with moveUp() and moveDown() methods in OrderedComplexTableField (subclass of ComplexTableField) like this:

function moveUp() {
   $this->methodName = "moveUp";                                                                                                                

   $childObject = $this->getChildObject();
   if ($childObject) $childObject->moveUp();                                                                                                    


Forum Moderator, 801 Posts

11 June 2008 at 11:23am

you need to bind an onclick event to your buttons which returns false (and stops the event from bubbling up to the <td>, which causes it to open the popup). see ComplexTableField.js for examples.
have a look at GB_RefreshLink in the same file for determining how to refresh the CTF by javascript.


Community Member, 17 Posts

15 June 2008 at 1:11am

Edited: 15/06/2008 1:12am

Ok, thanks.

I've managed to implement the functionality.

I just added

return $this->ajax_render()

at the end of moveUp and moveDown functions.

Then I had to cope with replacing the component div without loosing its Behaviour :)

Now I'm trying to factor out the DataObject part of the solution to either a subclass of DataObject or a DataObjectDecorator.

I think I could create a tutorial on this (i.e. "How to attach multiple images/files/other objects to a page and specify their order"), how should I approach it?


Community Member, 17 Posts

15 June 2008 at 3:19am

About the event getting to <td>...

The openPopup function picks the first link/button from the left to use when the table row is clicked and that is probably what you were referring to. But is it correct behaviour? Seems like a design fault for me...

Anyway, calling Event.stop(e) or returning false from my event handler doesn't help. I can even delete my javascript file and the openPopup does the same still (my code is simply never run - only when I click on the link/image).
Putting the 'Show' button first helps but I'd rather have up/down buttons first.

Would you be able to suggest another workaround?


Community Member, 54 Posts

24 June 2008 at 12:23am

The javascript that's hogging the <a> tags in the table ignores an element if it's an input tag.

So I've used the following to bypass the popup:

'Invoice' => '<input type=\"button\" name=\"OrderReport_Popup/index/$ID/\" onclick=\";\" value=\"Invoice\" />'));

Again messy code to deal with the popups but, I hope that helps.