Create slide sorter view
Table vs Divs
In the folder_contents table, each row is draggable, and so each element had a common parent of the <table> or <tbody> tag. However, if we use a table with each image in a <td>, all the draggable element would not have the same parent (unless the table consisted of one row);
Therefore, I decided to use CSS to make the images display in a grid rather than an html table element, since this would mean all draggable elements could have the same parent node in the element tree.
Keeping all draggable elements inside the same parent element means that we have less to customize of the javascript used by folder_contents.
Also, the use of the CSS float property to position these elements means that the number of columns cam be gracefully determined by the size of the window.
Key components
There a few parts to the template which are necessary for the javascript to work.
- The parent element (the one containing all of the sortable items), must have the id= 'slide-sortable'
- Each of the sortable elements must have the class= 'sortable-cell'
- Each sortable element must also have a unique ID (ex. id = 'folder-content-item-my_img')
Use with custom image types
To use this with other content types, simply change the filter used in the call to getFolderContents, from {'portal_type':'Image'} to something more suitable.
Unrequired Extra
On each sortable element, I also include the attribute ondblclick, which calls a javascript function to open a dialog box of a larger view of the image. This particular javascript function (written by John Gardner), resizes the pop-up window to the size of the image. For this functionality, one must include this 'ondblclk' attribute, aswell as the script element that calls openpopup.js. Of course none of this is required for the primary sorting functionality.
Note: Instead of explicitly including the javascript files using the 'script' elements in this template, they can also be included using the portal_javascripts tool.
This is the source code for the slide sorter template:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"
lang="en-US"
metal:use-macro="here/main_template/macros/master"
i18n:domain="plone">
<body>
<div metal:fill-slot="main">
<tal:protect tal:condition="python: not checkPermission('List folder contents', here)"
tal:replace="here/raiseUnauthorized" />
<metal:main_macro define-macro="main">
<metal:pic_sorter_macro define-macro="pic_sorter"
tal:define="imgs python:context.getFolderContents({'portal_type':'Image'});">
<h1 class="documentFirstHeading">Slide Sorter</h1>
<script type="text/javascript" src="openpopup.js"></script>
<script type="text/javascript" src="dragdropslidesorter.js"></script>
<tal:albumsimages tal:condition="imgs">
<div id="slide-sortable"
class="listing"
width="100%">
<tal:items tal:repeat="item imgs">
<tal:itemdefs tal:define="index repeat/item/index;
numCols python:3;
sameRow python:index % numCols;">
<span tal:define="oddrow repeat/item/odd;
item_url item/getURL|item/absolute_url;
item_id item/getId;
item_title_or_id item/pretty_title_or_id;
item_description item/Description;
oddEven python:test(oddrow, 'even', 'odd');
large_view string:$item_url/image_large;"
tal:attributes="class string:$oddEven sortable-cell;
id string:folder-contents-item-${item_id};
ondblclick string:return openPopup('$large_view',
'$item_title_or_id');" >
<img src="" alt='' tal:attributes="src string:${item_url}/image_thumb;
alt item_title_or_id;
title item_description" />
<span tal:content="item_title_or_id" />
</span>
</tal:itemdefs>
</tal:items>
<div class="visualClear"><!-- --></div>
</div>
</tal:albumsimages>
<p class="discreet"
i18n:domain="atcontenttypes"
i18n:translate="text_no_albums_uploaded"
tal:condition="python:not imgs">
No images uploaded yet.
</p>
</metal:pic_sorter_macro>
</metal:main_macro>
</div>
</body>
