13

I've developed a small component based on the Joomla Hello World tutorial, and now I would like to implement the same drag-n-drop reordering that many other Joomla components include:

enter image description here

By sorting by the first column, it's possible to drag each table row in order to change the position.

Is there a native way to add this functionality in Joomla, or do I have to program it myself?

Any nudge in the right direction appreciated.

1 Answer 1

17

There are some prerequisites and you have to do some modifications to your view template. But you don't have to develop this feature all on your own.

Prerequisites

  • You need a column ordering of type INT to your database table
  • Your list view should already be sortable (by clicking on the table column headers)

Modifications

This is the most important part to get make your table rows sortable by drag and drop:

JHtml::_('sortablelist.sortable', 'itemList', 'adminForm', strtolower($listDirn), $saveOrderingUrl);

You should only activate (ie execute the above line) if your table is sorted by the database table column ordering. You need to find out by which column your table is sorted and in which direction (ASC or DESC). Do this at the beginning of your default.php:

$listOrder = $this->escape($this->state->get('list.ordering'));
$listDirn  = $this->escape($this->state->get('list.direction'));

Check if your table is ordered by column ordering

$saveOrder = $listOrder == 'a.ordering';

Make your table rows sortable by drag and drop if $saveOrder is true. Replace com_example with your component name and "items" in task=items.saveOrderAjax with the name of your list controller:

if ($saveOrder)
{
    $saveOrderingUrl = 'index.php?option=com_example&task=items.saveOrderAjax&tmpl=component';
    JHtml::_('sortablelist.sortable', 'itemList', 'adminForm', strtolower($listDirn), $saveOrderingUrl);
}

The $saveOrderingUrl will be called via AJAX everytime you drop an item. If your controller is extending the right Joomla MVC class (JControllerAdmin) this method is automatically available for you. itemList is the ID of your HTML table, and adminForm is the name (or ID, not sure) of your HTML form:

<form action="<?php echo JRoute::_('index.php?option=com_example&view=items'); ?>" method="post" name="adminForm" id="adminForm">
    ...
    <table class="table table-striped" id="itemList">
        ...
    </table>
    ...
</form>

You will need a new column in your HTML table. In your screenshot it is the column far left. The table column header looks like this:

<th width="1%" class="nowrap center hidden-phone">
    <?php echo JHtml::_('searchtools.sort', '', 'a.ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING', 'icon-menu-2'); ?>
</th>

For your table body you most likely have a foreach loop going through all your list items. The first cell in each row of your HTML table will be that drag icon. If you have drag and drop disabled (because your table is not ordered by ordering) you should deactivate the icon and make a tooltip:

<tbody>
    <?php foreach ($this->items as $i => $item) :
        $ordering  = ($listOrder == 'ordering');
    ?>
    <tr class="row<?php echo $i % 2; ?>">
        <td class="order nowrap center hidden-phone">
        <?php
            $iconClass = '';
            if (!$saveOrder) {
                $iconClass = ' inactive tip-top hasTooltip" title="' . JHtml::tooltipText('JORDERINGDISABLED');
            }
         ?>
             <span class="sortable-handler <?php echo $iconClass ?>">
                 <span class="icon-menu"></span>
             </span>
             <?php if ($saveOrder) : ?>
             <input type="text" style="display:none" name="order[]" size="5" value="<?php echo $item->ordering; ?>" class="width-20 text-area-order " />
             <?php endif; ?>
        </td>
  ...
</tbody>
9
  • Thank you, very nice and extensive answer. I haven't actually managed to get it to work yet, but I'm getting closer :)
    – Bogowoe
    Nov 25, 2015 at 20:18
  • If you have any questions or if theres something in my guide thats wrong or needs improvement please let me know.
    – fruppel
    Nov 26, 2015 at 9:28
  • I got it! I forgot to change task=items.saveOrderAjax to task=myviews.saveOrderAjax. Now it's working fine.
    – Bogowoe
    Nov 27, 2015 at 0:51
  • Drag'n'Drop sorting is linked with the searchtools. If you haven't searchtools implemented (like in the articles) the sortable by drag'n'drop link doesn't work. Jan 11, 2016 at 11:19
  • Something is missing here. I can't drag the table items and also can't sort the ordering column.
    – TIIUNDER
    Sep 27, 2016 at 17:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.