Изменение порядка отображения
Изменение порядка отображения
Приветствую!
Каким образом в Yii реализован механизм изменения последовательности записей при отображении. Например, древо каталога, необходимо один из элементов поднять/опустить вверх относительно родителя.
Каким образом в Yii реализован механизм изменения последовательности записей при отображении. Например, древо каталога, необходимо один из элементов поднять/опустить вверх относительно родителя.
Re: Изменение порядка отображения
Чисто Yii такого не делает.
Это надо реализовывать самостоятельно (я про дерево). А для сортировки - делай поле position и присваивай ему нужное значение, в defaultScopes модели пиши order => position
Есть расширение nestedSets - возможно там есть готовое, я им не пользовался.
Это надо реализовывать самостоятельно (я про дерево). А для сортировки - делай поле position и присваивай ему нужное значение, в defaultScopes модели пиши order => position
Есть расширение nestedSets - возможно там есть готовое, я им не пользовался.
Re: Изменение порядка отображения
mitaichik писал(а):А для сортировки - делай поле position и присваивай ему нужное значение, в defaultScopes модели пиши order => position
- В модели мы переопределяем метод defaultScopes(). А что дальше, каким образом мне указать поле (parent) в рамках которого происходит сортировка?
- Как мне указать, что бы при создании поле увеличивалось на единицу, т.е. становился последним в последовательности?
- Как реализована валидация порядка сортировки, что бы не получилось, что то типа 1, 2, 5, 6?
- Какие методы реализут поднять и опустить позицию?
Re: Изменение порядка отображения
Присоеденяюсь к вопросам zbn.
Раз никто не ответил - по-видимому, придется изобретать велик?
Раз никто не ответил - по-видимому, придется изобретать велик?
- slavcodev
- Сообщения: 3134
- Зарегистрирован: 2009.04.02, 21:42
- Откуда: Valencia
- Контактная информация:
Re: Изменение порядка отображения
Я например не очень понял вопросов и не отвечал, попробую предположить что имелось виду
1)
2) При вставке записи, я не ищу какое там последнее число (лишний запрос), я ставлю COUNT, можно использовать MAX, т.е все средствами Mysql
3) А для чего? Чем плоха такая последовательность?
4) Собственные.
1)
Код: Выделить всё
public function defaultScope()
{
return array(
'order'=>'parent DESC',
);
}
3) А для чего? Чем плоха такая последовательность?
4) Собственные.
Жду Yii 3!
Re: Изменение порядка отображения
mc-bear Спасибо за ответ. Вобщем-то все и прояснил.
На счет валидации последовательности. Если делать возможность для пользователя поднять и опустить позицию, скажем с помощью drag'n'drop, то важно, мне кажется, чтобы не было случаев 1, 3, 4 или 1, 3, 3.
При добавлении новой записи, лучше все-тки использовать MAX, тогда избежишь случаев 1,3,3
Про валидации последовательности у меня еще такой вопрос. Понятно, что ее надо будет отслеживать при удалении записи и после удаления переписывать значения поля position для каждой записи. Можно удалять категори, подкатегории, товары и тд и тп. Для каждой сущность свой контроллер, следовательно свой actionDelete. Как сделать так, чтобы не писать каждый раз в различных actionDelete код этой проверки.
Я старый быдлокодер и только въезжаю в ООП и у меня пока постоянные затыки на элементарных местах.
На счет валидации последовательности. Если делать возможность для пользователя поднять и опустить позицию, скажем с помощью drag'n'drop, то важно, мне кажется, чтобы не было случаев 1, 3, 4 или 1, 3, 3.
При добавлении новой записи, лучше все-тки использовать MAX, тогда избежишь случаев 1,3,3
Про валидации последовательности у меня еще такой вопрос. Понятно, что ее надо будет отслеживать при удалении записи и после удаления переписывать значения поля position для каждой записи. Можно удалять категори, подкатегории, товары и тд и тп. Для каждой сущность свой контроллер, следовательно свой actionDelete. Как сделать так, чтобы не писать каждый раз в различных actionDelete код этой проверки.
Я старый быдлокодер и только въезжаю в ООП и у меня пока постоянные затыки на элементарных местах.
- slavcodev
- Сообщения: 3134
- Зарегистрирован: 2009.04.02, 21:42
- Откуда: Valencia
- Контактная информация:
Re: Изменение порядка отображения
если нужно перемещать последовательность, тогда поле где хранить идишку следующей модели
тогда при перетаскивании нужно будет только поменять эти идишки у трех моделей
тогда при перетаскивании нужно будет только поменять эти идишки у трех моделей
Жду Yii 3!
Re: Изменение порядка отображения
onAfterDelete() - понял, копаю
Поясни последнее. Айдишки то зачем менять? Они постояны - меняем только position. Или ты про перетаскивание субкатегории из одной категории в другую? Это кстати, тоже надо посоображать как делать.
Поясни последнее. Айдишки то зачем менять? Они постояны - меняем только position. Или ты про перетаскивание субкатегории из одной категории в другую? Это кстати, тоже надо посоображать как делать.
- slavcodev
- Сообщения: 3134
- Зарегистрирован: 2009.04.02, 21:42
- Откуда: Valencia
- Контактная информация:
Re: Изменение порядка отображения
не ИД модели менять! именно position, только в него уже нужно ставить ИД предстоящей модели.
Жду Yii 3!
Re: Изменение порядка отображения
Нет не могу понять. Нарисовал себе схемы - все равно не понимаю зачем надо "связывать" id и position. id никогда не меняется, а значение position может быть любым. Если будет время и желание - объясни подробнее.
С событиями вроде разобрался - мощная вещь. Спасибо
С событиями вроде разобрался - мощная вещь. Спасибо
Re: Изменение порядка отображения
Просто я думаю делать как то вот так: http://habrahabr.ru/blogs/jquery/70837/#comment_2031446. Другой способ пока не вырисовывается
-
- Сообщения: 21
- Зарегистрирован: 2011.05.14, 03:10
Re: Изменение порядка отображения
из ядра одной движки
к примеру опустить по списку вниз если сортировка ASC (от меньшего к большему)
находим запись с весом (поле weight отвечает за позицию в сортировке и по умолчанию равно id) большим чем запись , т.е. выбрать все записи с большим весом сортируя по ASC и выбрать из этого первую строчку. Далее просто меняем значения местами у исходной записи и полученной
Все просто и легко:
рабочий код
// поднимает по списку вверх
function rc_down($id,$field = 'weight'){
if ($this->desc != 'desc') {
// вес нужно уменьшить
$this->rc_swap_weight_asc($id,$field);
} else {
// вес нужно увеличить
$this->rc_swap_weight_desc($id,$field);
}
}
// опускает по списку вниз
function rc_up($id,$field = 'weight'){
if ($this->desc != 'desc') {
// вес нужно увеличить
$this->rc_swap_weight_desc($id,$field);
} else {
// вес нужно уменьшить
$this->rc_swap_weight_asc($id,$field);
}
}
// if desc == desc
// Обменивает вес указанного элемента с элементом имеющего наибольший вес среди
// элементов с меньшим весом
function rc_swap_weight_desc($id, $field) {
//echo 'rc_swap_weight_desc';
//die();
$cur_line = $this->rc_get_record($id);
$query = "
SELECT
*
FROM
".$this->doc_type."
WHERE
`$field` < ".$cur_line['weight']."
and
(rasdel='".$this->rasdel."') ".($cur_line['parent']!=''?" and (parent='".$cur_line['parent']."')":'')."
ORDER BY
`$field` DESC
LIMIT 1
";
$res = mysql_query($query) or die("up: ".mysql_error());
if (mysql_num_rows($res)>0) {
$row = mysql_fetch_array($res);
$query = "update ".$this->doc_type." set `$field`=".$row[$field]." where id=".$cur_line["id"];
$res = mysql_query($query) or die("смена веса вышестоящей строки: ".mysql_error());
$query2 = "update ".$this->doc_type." set `$field`=".$cur_line[$field]." where id=".$row["id"];
$res = mysql_query($query2) or die("смена веса текущей строки: ".mysql_error());
}
}
// if desc == asc
// Обменивает вес указанного элемента с элементом имеющего наименьший вес среди
// элементов с большим весом
function rc_swap_weight_asc($id, $field) {
//echo 'rc_swap_weight_asc';
$cur_line = $this->rc_get_record($id);
//$query = "select * from ".$this->doc_type." where `$field` > ".$cur_line[$field]." and ((rasdel='".$this->rasdel."') and (parent='".$cur_line['parent']."')) order by $field asc limit 1";
$query = "
SELECT
*
FROM
".$this->doc_type."
WHERE
`$field` > ".$cur_line['weight']."
and
(rasdel='".$this->rasdel."') ".($cur_line['parent']!=''?" and (parent='".$cur_line['parent']."')":'')."
ORDER BY
`$field` ASC
LIMIT 1
";
//echo $query;
//die();
$res = mysql_query($query) or die("up: ".mysql_error());
if (mysql_num_rows($res)>0) {
$row = mysql_fetch_array($res);
$query = "update ".$this->doc_type." set `$field`=".$row[$field]." where id=".$cur_line["id"];
$query2 = "update ".$this->doc_type." set `$field`=".$cur_line[$field]." where id=".$row["id"];
$res = mysql_query($query) or die("смена веса вышестоящей строки: ".mysql_error());
$res = mysql_query($query2) or die("смена веса текущей строки: ".mysql_error());
}
}
к примеру опустить по списку вниз если сортировка ASC (от меньшего к большему)
находим запись с весом (поле weight отвечает за позицию в сортировке и по умолчанию равно id) большим чем запись , т.е. выбрать все записи с большим весом сортируя по ASC и выбрать из этого первую строчку. Далее просто меняем значения местами у исходной записи и полученной
Все просто и легко:
рабочий код
// поднимает по списку вверх
function rc_down($id,$field = 'weight'){
if ($this->desc != 'desc') {
// вес нужно уменьшить
$this->rc_swap_weight_asc($id,$field);
} else {
// вес нужно увеличить
$this->rc_swap_weight_desc($id,$field);
}
}
// опускает по списку вниз
function rc_up($id,$field = 'weight'){
if ($this->desc != 'desc') {
// вес нужно увеличить
$this->rc_swap_weight_desc($id,$field);
} else {
// вес нужно уменьшить
$this->rc_swap_weight_asc($id,$field);
}
}
// if desc == desc
// Обменивает вес указанного элемента с элементом имеющего наибольший вес среди
// элементов с меньшим весом
function rc_swap_weight_desc($id, $field) {
//echo 'rc_swap_weight_desc';
//die();
$cur_line = $this->rc_get_record($id);
$query = "
SELECT
*
FROM
".$this->doc_type."
WHERE
`$field` < ".$cur_line['weight']."
and
(rasdel='".$this->rasdel."') ".($cur_line['parent']!=''?" and (parent='".$cur_line['parent']."')":'')."
ORDER BY
`$field` DESC
LIMIT 1
";
$res = mysql_query($query) or die("up: ".mysql_error());
if (mysql_num_rows($res)>0) {
$row = mysql_fetch_array($res);
$query = "update ".$this->doc_type." set `$field`=".$row[$field]." where id=".$cur_line["id"];
$res = mysql_query($query) or die("смена веса вышестоящей строки: ".mysql_error());
$query2 = "update ".$this->doc_type." set `$field`=".$cur_line[$field]." where id=".$row["id"];
$res = mysql_query($query2) or die("смена веса текущей строки: ".mysql_error());
}
}
// if desc == asc
// Обменивает вес указанного элемента с элементом имеющего наименьший вес среди
// элементов с большим весом
function rc_swap_weight_asc($id, $field) {
//echo 'rc_swap_weight_asc';
$cur_line = $this->rc_get_record($id);
//$query = "select * from ".$this->doc_type." where `$field` > ".$cur_line[$field]." and ((rasdel='".$this->rasdel."') and (parent='".$cur_line['parent']."')) order by $field asc limit 1";
$query = "
SELECT
*
FROM
".$this->doc_type."
WHERE
`$field` > ".$cur_line['weight']."
and
(rasdel='".$this->rasdel."') ".($cur_line['parent']!=''?" and (parent='".$cur_line['parent']."')":'')."
ORDER BY
`$field` ASC
LIMIT 1
";
//echo $query;
//die();
$res = mysql_query($query) or die("up: ".mysql_error());
if (mysql_num_rows($res)>0) {
$row = mysql_fetch_array($res);
$query = "update ".$this->doc_type." set `$field`=".$row[$field]." where id=".$cur_line["id"];
$query2 = "update ".$this->doc_type." set `$field`=".$cur_line[$field]." where id=".$row["id"];
$res = mysql_query($query) or die("смена веса вышестоящей строки: ".mysql_error());
$res = mysql_query($query2) or die("смена веса текущей строки: ".mysql_error());
}
}
Re: Изменение порядка отображения
Ну, проблемы особо-то и нет. В grid-view можно добавлять свои кнопки и навешивать события. Потом в контроллере добавить действие move. А дальше дело техники - выбирать предыдущий/следующий объект по order и менять этот order местами. Ну, а пересчет сортировки (например при удалении), как говорилось выше, навешивать на стандартные события.