7921 Posts in 1359 Topics by 933 members
DataObjectManager Module
SilverStripe Forums » DataObjectManager Module » New Stuff!
Discuss the DataObjectManager module, and the related ImageGallery module.
Moderators: martimiz, UncleCheese, Howard, Sean, Ryan M., biapar, Willr, Ingo, swaiba, simon_w
| Go to End | Next > | |
| Author | Topic: | 2812 Views |
-
New Stuff!

23 November 2009 at 4:33pm Last edited: 3 December 2009 11:19am
Just checked in a bunch of new stuff:
Custom DOM Actions
A lot of people have been asking about how to create a custom action on the list view of a DOM in addition to edit, delete, and recently, duplicate. In the following example, I'll show you how to add a custom action to a Listing object that sets its status to "Approved" or "Unapproved" by clicking an an icon in the DOM, without having to edit the record in the popup.
Listing.php
public function customDOMActions()
{
$title = $this->Approved ? "Disapprove" : "Approve";
$image = $this->Approved ? "delete.png" : "accept.png";return new DataObjectManagerAction(
$title,
"/ListingPage_Controller/approve/$this->ID",
"refresh",
"/mysite/images/$image"
);
}public function toggleApproved()
{
if($this->getField('Approved') == 1)
$this->setField('Approved',0);
else
$this->setField('Approved',1);
$this->write();
}
We create a function with the name "customDOMActions" in the DataObject. The name of this function is compulsory. If you have multiple custom actions, you can return them in a DataObjectSet. The arguments for a DataObjectManagerAction are as follows:
$title : The title of the action. In this case, "approve" or "disapprove"
$link : Link to the action. We'll handle the request on the ListingPage controller
$behaviour : Options for the behavior of this action:- "refresh" : Runs the action and refreshes the DOM on success.
- "popup" : Load the link into a popup window (like edit view)
- "delete" : Remove the record from the DOM after executing the link$icon : URL to the icon for the action
In the function toggleApprove we run a simple update that toggles the object status.
Now we'll handle the custom action request in a custom controller.
Listing_Controller
class Listing_Controller extends Controller {
static $url_handlers = array(
'approve/$ID' => 'handleApprove'
);public function handleApprove($request)
{
if($listing = DataObject::get_by_id("Listing",$request->param('ID'))) {
$listing->toggleApproved();
}
}
}That's it! You can now click the approve/disapprove icon in your list view to update the record without instantiating a popup. There are many other applications for this feature. This is just one of many possibilities.
Many thanks to forum member Nick Jacobs for sponsoring this feature.
New Popup Form Styling
Updated CSS of the DOM popup to place the pagination and save button in a fixed position at the bottom of the frame, so they are always visible regardless of your scroll. Also add a transparent PNG to help ease the bottom of the viewport and bring some definition to the actions bar against the fieldset.
Bug Fix: DOM Items Lose Sort in Popup Pagination
Fixed this issue. You can now act on the DOM sort or pagination and the records retain their order when paginated in the popup with the prev/next buttons.
-
Re: New Stuff!

25 November 2009 at 7:20am
Hi UncleCheese
Thanks a lot for these great new features. I think the Custom DOM Actions are especially useful.
I tested this and found the following issues:
Your example code didn't work for me. I had to remove the slashes before the action link and the image.return new DataObjectManagerAction(
$title,
"ListingPageController/approve/$this->ID",
'refresh',
"site/images/$image"
);There's also a potential security risk in your example code.
When somebody uses your example, it becomes possible to alter DataObjects without being logged in to the CMS. This by simply visiting an address like this:
http://somedomain.xx/ListingPage_Controller/approve/2This would approve the Listing DataObject with ID 2, and doesn't require a login!
I'm aware that this kind of URL is probably pretty hard to figure out, but as soon as somebody posts some example code here, his site can be modified this way.So to anybody who wants to use this feature, secure the access to your method(s) by putting something like this in your Controller class:
static $allowed_actions = array(
'handleApprove' => 'CMSMain'
);Access to the 'handleApprove' method will then only be granted if the current user has access to "CMSMain" (Site Content).
If you got actions like "rss" for RSS Feeds and the like, add them to the array of allowed actions, without access constraint:static $allowed_actions = array(
'rss',
'myPublicAction',
'handleApprove' => 'CMSMain'
);This just as a notice/warning to anybody who wishes to use these features.
And thanks to UncleCheese for providing us with these nice updates ;)
Way to go. -
Re: New Stuff!

25 November 2009 at 7:53am
Thanks, Banal. Yeah, I coded that up pretty quickly, and I wasn't thinking. Thanks very much for pointing that out. It's so easy to forget that just because a URL is usually called from the CMS doesn't mean it has to be.
Glad you like everything. I think this will get a lot of use.
-
Re: New Stuff!

25 November 2009 at 10:30am
once again, congratulations Uncle Cheese. great addition. how would I go about putting a header on to the top of the table so that can people can tell straight away that that is the approve column without having to hover over it? Thanks
Will
-
Re: New Stuff!

25 November 2009 at 10:38am
Yeah, good point. It isn't really set up to do that right now. The other buttons -- edit, delete do not have a header. They rely on definitive icons to state their purpose. If you omit the icon argument, the text "Approve" will display, and that will be clearer to the user.
-
Re: New Stuff!

25 November 2009 at 11:10am Last edited: 25 November 2009 11:11am
How do you combine it in to a dataobjectset
First I tried this which I guess wasn't really the point but I thought I'd give it a try
public function customDOMActions()
{
$title = $this->Approved ? "Disapprove" : "Approve";
$image = $this->Approved ? "disapprove.png" : "approve.png";
$featuredTitle = $this->IsFeaturedProject ? "Disable Featured" : "Make Featured";
$featuredImage = $this->IsFeaturedProject ? "disapprove.png" : "approve.png";return new DataObjectManagerAction(
$title,
"/ProjectPage_Controller/approve/$this->ID",
"refresh",
"/assets/graphics/$image"
);
return new DataObjectManagerAction(
$featuredTitle,
"/ProjectPage_Controller/feature/$this->ID",
"refresh",
"/assets/graphics/$featuredImage"
);
}then I tried this
public function customDOMActions()
{
$title = $this->Approved ? "Disapprove" : "Approve";
$image = $this->Approved ? "disapprove.png" : "approve.png";
$featuredTitle = $this->IsFeaturedProject ? "Disable Featured" : "Make Featured";
$featuredImage = $this->IsFeaturedProject ? "disapprove.png" : "approve.png";
$collection = new DataObjectSet;
$collection = ((
new DataObjectManagerAction(
$title,
"/ProjectPage_Controller/approve/$this->ID",
"refresh",
"/assets/graphics/$image"
)),(
new DataObjectManagerAction(
$featuredTitle,
"/ProjectPage_Controller/feature/$this->ID",
"refresh",
"/assets/graphics/$featuredImage"
)));
return $collection;
}They both work seperately so I was hoping it is an easy fix to combine them together. I had a look on the dataobjectset page but couldn't see how to add them together. Thanks again
-
Re: New Stuff!

25 November 2009 at 11:17am Last edited: 25 November 2009 11:48am
Had a look a bit further and I found the easy fix
public function customDOMActions()
{
$title = $this->Approved ? "Disapprove" : "Approve";
$image = $this->Approved ? "disapprove.png" : "approve.png";
$featuredTitle = $this->IsFeaturedProject ? "Disable Featured" : "Make Featured";
$featuredImage = $this->IsFeaturedProject ? "disapprove.png" : "approve.png";
$collection = new DataObjectSet();
$collection->push(
new DataObjectManagerAction(
$title,
"/ProjectPage_Controller/approve/$this->ID",
"refresh",
"/assets/graphics/$image"
));
$collection->push(
new DataObjectManagerAction(
$featuredTitle,
"/ProjectPage_Controller/feature/$this->ID",
"refresh",
"/assets/graphics/$featuredImage"
));
return $collection;
}worked just as I hope. Thanks UncleCheese
edit: I guess the key lines I was looking for were
$collection = new DataObjectSet();
$collection->push(
if that helps anyone else hope that is useful. -
Re: New Stuff!

25 November 2009 at 12:17pm
Yup. You got it. You can also do:
new DataObjectSet(
new DataObjectManagerAction(),
new DataObjectManagerAction()
);
| 2812 Views | ||
| Go to Top | Next > |


