Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prestashop custom admin module draggable sort/order not working

I'm building a very simple module for Prestashop 1.6 and I added an admin interface that allows to list my records, a form to add and edit and delete.

This is working fine as you can see here: enter image description here

The problem is that draggable reorder button is not draggable. Hence the reordering is not working...

According to the official docs, if you set the position option in your controller, you get the draggable functionality:

['position'] => 'position', // If set to position, the field will display arrows and be drag and droppable, which will update position in db (optional).

This is the relevant part of my module controller:

$this->fields_list = array(
        'id_quicklinks' => array(
            'title' => $this->l('ID'),
            'align' => 'center',
            'width' => 25
        ),
        'titulo' => array(
            'title' => $this->l('Titulo'),
            'width' => 'auto'
        )
        , 'lead' => array(
            'title' => $this->l('Subtitulo'),
            'width' => 'auto'
        ), 
        'position' => array(
            'title' => $this->l('Ordem'),
            'filter_key' => 'a!position',
            'position' => 'position',
            'align' => 'center',
            'class' => 'fixed-width-md'
        ),
        'active' => array(
            'title' => $this->l('Publicado'),
            'width' => '25',
            'active' => 'status'
        )
    );

As you can see in the print screen, is shows the handles but the drag-an-drop doesn't work. No javascript errors on the console, no nothing... And I can see in the source code that jQuery and jQueryUI are loaded. Other admin pages with reorder feature are working fine...

Any ideas? Thanks.

like image 539
fana Avatar asked Sep 13 '25 20:09

fana


1 Answers

Well, if anyone is interested, I managed to get this to work.

In my module admin controller, I've added (before the __construct method, right after opening the Class):

protected $position_identifier = 'id_quicklinks';
  • id_quicklinks is the primary key of the database table this module uses.

This enabled the drag and drop feature that I was looking for, but altough I could now drag and drop, the order was not saved in the database.

For that to work I've added two more methods adapted from the controllers/admin/AdminCarriersController.php and classes/Carrier.php:

public function ajaxProcessUpdatePositions()
    {
        $way = (int)Tools::getValue('way');
        $id_quicklinks = (int)Tools::getValue('id');
        $positions = Tools::getValue('quicklinks');

        if (is_array($positions))
            foreach ($positions as $position => $value)
            {
                $pos = explode('_', $value);

                if (isset($pos[2]) && (int)$pos[2] === $id_velcroquicklinks)
                {
                        if (isset($position) && $this->updatePosition($way, $position, $id_quicklinks))
                            echo 'ok position '.(int)$position.' for id '.(int)$pos[1].'\r\n';
                        else
                            echo '{"hasError" : true, "errors" : "Can not update id '.(int)$id_quicklinks.' to position '.(int)$position.' "}';

                    break;
                }
            }

    }

And:

public function updatePosition($way, $position, $id)
    {

        if (!$res = Db::getInstance()->executeS('
            SELECT `id_quicklinks`, `position`
            FROM `'._DB_PREFIX_.'quicklinks`
            ORDER BY `position` ASC'
        ))
            return false;

        foreach ($res as $quicklinks)
            if ((int)$quicklinks['id_quicklinks'] == (int)$id)
                $moved_quicklinks = $quicklinks;

        if (!isset($moved_quicklinks) || !isset($position))
            return false;
        var_dump($moved_quicklinks['position']);
        // < and > statements rather than BETWEEN operator
        // since BETWEEN is treated differently according to databases
        return (Db::getInstance()->execute('
            UPDATE `'._DB_PREFIX_.'quicklinks`
            SET `position`= `position` '.($way ? '- 1' : '+ 1').'
            WHERE `position`
            '.($way
                ? '> '.(int)$moved_quicklinks['position'].' AND `position` <= '.(int)$position
                : '< '.(int)$moved_quicklinks['position'].' AND `position` >= '.(int)$position.'
            '))
        && Db::getInstance()->execute('
            UPDATE `'._DB_PREFIX_.'quicklinks`
            SET `position` = '.(int)$position.'
            WHERE `id_quicklinks` = '.(int)$moved_quicklinks['id_quicklinks']));
    }

I hope this helps someone with the same problem.

like image 195
fana Avatar answered Sep 17 '25 18:09

fana