Prestashop пользовательский админ модуль перетаскиваемый сортировка / порядок не работает
Я создаю очень простой модуль для Prestashop 1.6, и я добавил интерфейс администратора, который позволяет перечислять мои записи, форму для добавления, редактирования и удаления.
Это работает нормально, как вы можете видеть здесь:
Проблема в том, что перетаскиваемая кнопка переупорядочивания не перетаскивается. Следовательно, переупорядочение не работает...
Согласно официальным документам, если вы установите опцию 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

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']));
}
Я надеюсь, что это поможет кому-то с той же проблемой.

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;
}
}
}
}