Продолжаю серию постов про разработку на симфони. На этот раз задача состояла в том, чтобы сделать администрирование тегов. Задача:" все теги можно редактировать на одной странице, теги можно только редактировать и удалять, если тег после редакции совпадает с уже существующим - они склеиваются". Ну что ж, поехали.
Почти сразу у меня возникла идея использовать input_in_place_editor. То есть табличка, в ней теги, тыкаешь на ячейку, появляется поле редактирования, изменения происходят аяксово. С самим in_place_editor возникло немало сложностей из-за его опций. Сделать табличку и насовать в каждую ячейку по эдитору несложно. Не забудьте, надо облачить это все в див, который будет обновляться. Мы же хотим показывать сохраненный тег.
Первое, с чем мне пришлось столкнуться - эффект затухания. Это очень красиво, когда наводишь на элемент, который можно редактировать, фон загорается цветом, и медленно затухает, когда уводишь мышку. Изначально фон загорается желтым, а так как админка у меня выдержана в цветах Админ-генератора, то есть синем, то и цвет надо поменять. Однако, изменив цвет на '#eef', я обломался. Затухания не было. Фон сначала загорался, а потом через время менял свой цвет на изначальный. И только позже, случайно я догадался расписать цвет полностью на '#efefff'.
Следующим моментом стало изменение текстов сохранения. То есть тот текст, который написан на элементе пока идет аякс запрос. Нашел опцию, поставил значение, и... ничего не работает. Оказалось, что некоторые опции (а они задаются ассоциативным массивом) надо задавать особенно. Например опцию 'save_text' надо не просто заключать в кавычки (потому что это строка), а еще и добавлять кавычки внутри самой строки. Иначе это дело парсится без кавычек. Тупизм, неужели создаетли Protoype'а не могли сами ставить кавычки? Приходится теперь писать так:
'savingText' => '\'Сохранение...\''
Кнопочку удаления так же сделал дивом, но это просто. Position: relative, height: 0px, align: right; Надо заметить, что на время редактирования тега, кнопочку надо скрывать, иначе она уезжает вниз и портит вид. А делается это с помощью опции 'onEnterEditMode'. Вот так:
'onEnterEditMode' => "function(form, value) { $('delete_".$tag['tag_id']."').hide(); }"
Ну и наконец, сделать надо было системку, которая находит дубликаты тегов. А сделал я так: при сохранении тега, я нахожу ВСЕ теги с таким названием. Если такой тег один (которы мы только что сохранили), то все прекрасно, а если нет, тогда в цикле генерим 2 запроса. Один UPDATE, другой DELETE. UPDATE'ом, все товары, которые были привязаны к дубликату тега перепривязываем к самому первому найденному. Он в итоге остается у нас единственным. А DELETE'ом, удаляем дубликаты. Вот так вот:
$criteria = new Criteria(); $criteria->add(TagsPeer::TITLE, $value); $duplicates = TagsPeer::doSelect($criteria); //В качестве итогового тега берем самый первый if (count($duplicates) > 1) { $original = $duplicates[0]; $query_update = "UPDATE tags_bouquets SET tag_id='{$original->getTagId()}' WHERE tag_id IN("; $query_delete = "DELETE FROM tags WHERE tag_id IN ("; $pass_first = true; foreach ($duplicates as $duplicate) { if ($pass_first) { $pass_first = false; } else { $query_update .= $duplicate->getTagId().','; $query_delete .= $duplicate->getTagId().','; } } $query_delete = rtrim($query_delete, ',').');'; $query_update = rtrim($query_update, ',').');'; $conn = Propel::getConnection(); $conn->query('BEGIN; '.$query_update.$query_delete.'COMMIT;'); $this->getUser()->setFlash('notice_duplicated', 'Были найдены и удалены дубликаты тега '.$value);
Результат на картинке. Легкая синева - это как раз затухание фона, я специально мышкой повозил.

А еще я писал про:









