Prestashop пользовательский админ модуль перетаскиваемый сортировка / порядок не работает

Prestashop пользовательский админ модуль перетаскиваемый сортировка / порядок не работает

24.03.2015 01:22:34 Просмотров 55 Источник

Я создаю очень простой модуль для Prestashop 1.6, и я добавил интерфейс администратора, который позволяет перечислять мои записи, форму для добавления, редактирования и удаления.

Это работает нормально, как вы можете видеть здесь: enter image description here

Проблема в том, что перетаскиваемая кнопка переупорядочивания не перетаскивается. Следовательно, переупорядочение не работает...

Согласно официальным документам, если вы установите опцию position в своем контроллере, вы получите перетаскиваемую функциональность:

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

Это соответствующая часть моего контроллера модуля:

$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'
        )
    );

Как вы можете видеть на экране печати, это показывает ручки, но перетаскивание не работает. Никаких ошибок javascript на консоли, ничего... И я вижу в исходном коде, что jQuery и jQueryUI загружаются. Другие страницы администратора с функцией переупорядочивания работают нормально...

Есть идеи? Спасибо.

У вопроса есть решение - Посмотреть?

Ответы - Prestashop пользовательский админ модуль перетаскиваемый сортировка / порядок не работает / Prestashop custom admin module draggable sort/order not working

Является ответом!
fana

21.04.2015 01:58:43

Ну, если кто-то заинтересован, мне удалось заставить это работать.

В моем модуле admin controller я добавил (перед методом _ _ construct, сразу после открытия класса):

protected $position_identifier = 'id_quicklinks';
  • id_quicklinks-это первичный ключ таблицы базы данных, которую использует этот модуль.

Это включило функцию перетаскивания, которую я искал, но хотя теперь я мог перетаскивать, порядок не был сохранен в базе данных.

Для этого я добавил еще два метода, адаптированных к controllers/admin/AdminCarriersController.phpи 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;
                }
            }

    }

И:

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']));
    }

Я надеюсь, что это поможет кому-то с той же проблемой.

Jonathan Parent Lévesque

06.07.2016 04:45:48

Спасибо за ваше решение.

Мне потребовалось довольно много времени, чтобы понять, что ajaxProcessUpdatePositions()является каким-то вызовом сам по себе. Для тех, кто пытается реализовать этот метод, обратите внимание, что echoи var_dump()не будут печатать ничего, когда метод вызывается при перемещении элемента в таблице.

Кроме того, я нашел способ немного оптимизировать ваш код.

Вы могли бы заменить:

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 (!$moved_quicklinks  = Db::getInstance()->executeS('
       SELECT `id_quicklinks`, `position`
       FROM `'._DB_PREFIX_.'quicklinks`
       WHERE `id_quicklinks` = ' . (int) $id . '
       LIMIT 1;'
))
    return false;

Чем меньше строк (и полей) возвращается базой данных, тем лучше. Кроме того, он устраняет необходимость цикла в вашем PHP-коде.

Вы также можете объединить оба запроса обновления в одном вызове базы данных:

return (Db::getInstance()->execute('
            UPDATE `'._DB_PREFIX_.'quicklinks`
            SET `position`= `position` '.($way ? '- 1' : '+ 1').'
            WHERE `position`
            '.($way
                ? '> '.(int)$moved_quicklinks[0]['position'].' AND `position` <= '.(int)$position
                : '< '.(int)$moved_quicklinks[0]['position'].' AND `position` >= '.(int)$position.'
            ') . '; UPDATE `'._DB_PREFIX_.'quicklinks`
            SET `position` = '.(int)$position.'
            WHERE `id_quicklinks` = '.(int)$moved_quicklinks[0]['id_quicklinks']);

Вызовы баз данных являются дорогостоящими операциями, поэтому необходимо свести их к минимуму. Как и в вашем PHP-коде, второй запрос не будет выполнен, если первый не удастся.

Вот как ajaxProcessUpdatePositions():

public function ajaxProcessUpdatePositions()
{
    $id = (int) Tools::getValue('id');
    $positions = Tools::getValue("priority_level");
    $way = (boolean) Tools::getValue('way');

    //"and $id" because an ID of 0 is invalid (at least if you are using an auto-increment PK)
    if (is_array($positions) and $id)  
    {
        foreach ($positions as $position => $value)
        {
            $pos = explode('_', $value);

            if (isset($pos[2]) && (int) $pos[2] === $id)
            {
                $position = (int) $position;

                if ($priorityLevel = Db::getInstance()->executeS(
                        'SELECT `id_priority_level`, 
                            `priority_level`
                        FROM `pc_job_priority`
                        WHERE `id_priority_level` = ' . $id . '
                        LIMIT 1'
                )) {
                    Db::getInstance()->execute(
                        'UPDATE `pc_job_priority`
                        SET `priority_level` = `priority_level` '. 
                            ($way ? '- 1' : '+ 1') . '
                        WHERE `priority_level`' . (
                            $way ? 
                            ' > '. (int) $priorityLevel[0]['priority_level'] . 
                                ' AND `priority_level` <= '. $position :
                            ' < '. (int) $priorityLevel[0]['priority_level'] . 
                                ' AND `priority_level` >= '. $position 
                        ) . '; 
                        UPDATE `pc_job_priority`
                        SET `priority_level` = ' . $position . '
                        WHERE `id_priority_level` = ' . $id
                    );
                }

                break;
            }
        }
    }
}
Закрыть X