CodeIgniter и Ajax

Решил провести полный рефакторинг своей CMS (да-да, каждый веб-разработчик просто обязан написать свою систему управления контентом), и заодно сделать панель управления удобнее.

Задача такая: есть дерево меню сайта в админке. Рядом с каждым пунктом меню — кнопка, нажав её, переходим на страницу редактирования свойств пункта меню: ссылки, активности, картинки. Задача следующая — не переходить на другую страницу, как в «суровые девяностые», а используя AJAX открыть тут же, в псевдо всплывающем окне, типа лайтбокса, который заполонил весь инет.

Начнём, как говорят «37 signals», с проектирования интерфейса. Использовать плагины и чужие скрипты не хочется, люблю, чтобы страницы загружались быстро. Поэтому обойдёмся без лайтбокса и jquery tools. Всплывающее окно будет у нас слоем с абсолютным позиционированием и следующими свойствами:

Copy Source | Copy HTML

  1. #divedit
  2. {
  3.      position: absolute;
  4.      z-index:0;
  5.      background: silver;
  6.      display: none;
  7.      top:50%;
  8.      left:50%;
  9.      width: 400px;
  10.      height: 274px;
  11.      margin-left: -200px;
  12.      margin-top: -137px;
  13.      border: gray solid;
  14. }

Copy Source | Copy HTML

  1. <div id=»divedit»>
  2.             <div class=»box content»>
  3.                 <form id=»editform» name=»editform» method=»post» action=»{base}cms/menu/edit»>
  4.                     <input type=»hidden» value=»1″ name=»old_parent»/>
  5.                     <input type=»hidden» value=»2″ name=»lft»/>
  6.                     <label>Название: </label>
  7.                     <input type=»text» style=»width: 50%;» name=»title» id=»title»/>
  8.                     <br/>
  9.                     <br/>
  10.                     <label>Ссылка: </label>
  11.                     <input type=»text» style=»width: 50%;» value=»» name=»alias»/>
  12.                     <br/>
  13.                     <br/>
  14.                     <label>Родитель: </label>
  15.                     <div id=»parent»></div>
  16.                     <br/>
  17.                     <br/>
  18.                     <label>Включён: </label>
  19.                     <div id=»visible»></div>
  20.                     <br/>
  21.                     <br/>
  22.                     <label>Картинка: </label>
  23.                     <br/>
  24.                     <div id=»picture» align=»center»></div>
  25.                     <br/>
  26.                     <div align=»center»>
  27.                         <input class=»subm i-accept» type=»submit» value=»Сохранить» name=»submit_edit»/>
  28.                         <input class=»subm i-cancel» type=»button» value=»Отмена» id=»cancel_ed» name=»cancel_ed»/>
  29.                     </div>
  30.                 </form>
  31.             </div>
  32.         </div>

Напишем функцию контроллера, которая должна будет передавать данные о пункте меню:

Copy Source | Copy HTML

  1. function ajaxitemdata()
  2. {
  3.     if ($this->input->post(‘id’))
  4.     {
  5.         $id = $this->input->post(‘id’);
  6.         $this->MPTtree->set_table(‘menu_tree’);
  7.         $node = $this->MPTtree->get_ORM($id);
  8.         $parent = $node->parent();
  9.         $arr = array(
  10.             ‘title’ => $node->get(‘title’),
  11.             ‘alias’ => $node->get(‘alias’),
  12.             ‘parent’ => $this->MPTtree->display_as_select(1,$parent->get(‘lft’),‘parent’),
  13.             ‘visible’ => form_checkbox(‘visible’, ‘visible’,$node->get(‘visible’)),
  14.             ‘picture’ => img($this->Menu_model->get_pic_by_id($node->get(‘id’)))
  15.         );
  16.         echo json_encode($arr);
  17.     }
  18.     else
  19.     {
  20.         $arr = array(‘title’ => ‘Error’);
  21.         echo json_encode($arr);
  22.     }
  23. }

В CodeIgniter для хранения деревьев я использую модель MPTtree, реализующую алгоритм Nested Sets. Надеюсь, вы в своих проектах не используете рекурсивное построение дерева сотней запросов в цикле? display_as_select — метод, выводящий сразу HTML код выпадающего списка со всеми пунктами меню, чтобы не парсить на стороне клиента каждую опцию. Результат выводится в формате JSON, легко читаемом и гораздо быстрее обрабатываемым, чем XML.

Следующий пример показывает JSON-представление объекта, описывающего человека. В объекте есть строковые поля имени и фамилии, объект, описывающий адрес, и массив, содержащий список телефонов.

{
   "firstName": "Иван",
   "lastName": "Иванов",
   "address": {
       "streetAddress": "Московское ш., 101, кв.101",
       "city": "Ленинград",
       "postalCode": 101101
   },
   "phoneNumbers": [
       "812 123-1234",
       "916 123-4567"
   ]
}

На языке XML подобная структура выглядела бы примерно так:

<person>
  <firstName>Иван</firstName>
  <lastName>Иванов</lastName>
  <address>
    <streetAddress>Московское ш., 101, кв.101</streetAddress>
    <city>Ленинград</city>
    <postalCode>101101</postalCode>
  </address>
  <phoneNumbers>
    <phoneNumber>812 123-1234</phoneNumber>
    <phoneNumber>916 123-4567</phoneNumber>
  </phoneNumbers>
</person>

http://ru.wikipedia.org/wiki/JSON

Теперь нужно вызвать эту функцию со стороны клиента:

Copy Source | Copy HTML

  1. $(«button[name*=’edit’]»).click(function() {
  2.                     $.post(«{base}cms/menu/ajaxitemdata/», {id: this.value}, getitem, «json»);
  3.                 });

При нажатии на кнопку, имя которой начинается с ‘edit’, отправляем POST запрос к серверу со значением id, равному value кнопки. Так же передаём имя callback функции (она выполнится после запроса и будет обрабатывать ответ) и указываем формат ответа — json.

Код callback функции:

Copy Source | Copy HTML

  1. function getitem(data)
  2.             {
  3.                 document.editform.title.value = data.title;
  4.                 document.editform.alias.value = data.alias;
  5.                 $(«#parent»).html(data.parent);
  6.                 $(«#visible»).html(data.visible);
  7.                 $(«#picture»).html(data.picture);
  8.                 $(«#divedit»).show(«slow»);
  9.             }

Значения полей ввода подставляем прямо в атрибут value элемента формы, для выпадающего списка, флажка и картинки — в пустые слои формы с соответствующими id подставляем html код. После этого открываем слой со спецэффектом.

Далее форма либо сабмитится, либо слой закрывается при нажатии на кнопку отмены. Для этого вешаем на неё обработчик:

Copy Source | Copy HTML

  1. $(«#cancel_ed»).click(function() {
  2.                     $(«#divedit»).hide(«slow»);
  3.                 });

Всё просто.

Добавить комментарийОтменить ответ

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.