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've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Archive /

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

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

Extension: SortableDataObject


Go to End


10 Posts   7418 Views

Avatar
UncleCheese

Forum Moderator, 4102 Posts

21 November 2008 at 4:40am

What it is

Too many times I have encountered clients who need arbitrary sorts on their data. Silverstripe currently doesn’t support reordering in table lists, and even if it did, if the data bleeds over one page it would be a serious pain.

The SortableData extension makes any SortableDataObject sortable through drag-and-drop on the front end for admin users. As an example, let's consider an AboutPage that has a $has_many relation to StaffMember. The StaffMember objects are not pages -- just components of the AboutPage.

How it works

By changing the parent class from DataObject to SortableDataObject, the StaffMember table now has a Sort field and all the other built-in functionality to sort itself.

Now just add some minor enhancements to the template, we can make them sortable. There are two options for this. To keep it simple, use a UL. If your layout is more complex, use DIVs.

SortableDataObjects in a UL:

<h3>Our Staff</h3>
<% if StaffMembers %>
  {$StaffMembers.BeginSortableUL}
  <% control StaffMembers %>
    {$LI}$Name, <em>$Title</em>{$_LI}
  <% end_control %>
  {$StaffMembers.EndSortableUL}
<% end_if %>

SortableDataObjects in DIVs:

<h3>Our Staff</h3>
<% if StaffMembers %>
  {$StaffMembers.BeginSortableDIV}
  <% control StaffMembers %>
    {$DIV}
	<div class="staffProfile clearfix">
	   $Photo.SetWidth(100)
	   <div>
		<h4>$Name</h4>
		<h5>$Title</h5>
		<p>$Description</p>
	   </div>
	</div>
     {$_DIV}
   <% end_control %>
   {$StaffMembers.EndSortableDIV}
<% end_if %>

Anything within the {$LI} or {$DIV} pseudo-tag will drag as a single entity.

Note: The curly braces are not necessary, but they help to distinguish variables that contain content from those that contain structure only.

Well, have at it. It's super-beta!

Avatar
Tim

Community Member, 201 Posts

21 November 2008 at 4:49am

Sounds cool, can you post some screenshots of it in action?

Avatar
UncleCheese

Forum Moderator, 4102 Posts

21 November 2008 at 5:04am

Sure. Not too much to show, but here you go.

Avatar
Liam

Community Member, 470 Posts

21 November 2008 at 6:34am

Art Vandelay! baahahaha

Another great extension.

Avatar
UncleCheese

Forum Moderator, 4102 Posts

3 December 2008 at 2:15pm

Update: You can now add "/sort" to the URL of any Page (or subclass thereof) to get access to the sort features. Just makes it easier than going to /Security/login every time.

e.g.

http://www.mysite.com/about-us/sort

If you don't have the perms specified in SortableDataObject::$sorting_permission, you'll get a login form that will redirect back to the page.

Avatar
Ingo

Forum Moderator, 801 Posts

5 December 2008 at 2:11pm

Thanks for sharing your work, UncleCheese :)

I see "sortability" more as a behaviour than a subclass of DataObject, hence it should really be a DataObjectDecorator which you can attach to objects without changing their inheritance chain.

Its also mixing model and view in one class. The markup necessary for sorting should be rendered by a helper-method in a controller. Seems like you want to make sure the correct markup is used by wrapping it in PHP. In SilverStripe, we often just create default implementations ("best practices") for copy and paste usage. I think its a reasonable assumption for users to leave certain classes in their templates which trigger the sortable javascript functionality.

Modifying sort order could be decorated onto Page_Controller so it can be used on any page, without requiring a SortableDataObject_Controller.

Avatar
UncleCheese

Forum Moderator, 4102 Posts

5 December 2008 at 2:39pm

Funny you mention the decorator. I recently made a post in the site builders forum asking for someone to once and for all explain to me what a decorator is, and ever since I figured it out, I've been using them everywhere! Indeed, this is one of the first things that came to mind as a candidate for a decorator, and I'm going to re-release it soon.

I'm unsure, however, if the required instance_get() overload will carry through to the decorator.

I see what you're saying about mixing the markup into the model, and I rarely violate MVC in my work, but I just think this is a case where 99% of the time, the markup is going to be the same, so some "helper" functions are useful. Who wants to keep track of the class that the javascript library is going to be looking for? Might as well bundle it in. Users can always write their own instead. If you think about it, this is part of the reason why Ruby on Rails got so much hype. They were able to embrace MVC, but also recognize that using server-side functions to draw HTML could really streamline the development process without getting in the way.

Anyway, I really appreciate the feedback. I'm definitely going to do this as a decorator. I love those things!

Avatar
UncleCheese

Forum Moderator, 4102 Posts

9 December 2008 at 10:39am

Here's the revised version using decorators as you suggested, Ingo. Let me know what you think. I think it's a lot cleaner this way.

Go to Top