По следам "Кофейных ссылок" или "Rails в клеточку"

Grid

На написание этого поста меня натолкнула ссылка на AJAX грид найденная на блоге “Записки из тех. отдела”. Грид конечно ещё молодой и мало функциональный, я бы рекомендовал, если нужен действительно AJAX грид, посмотреть в сторону ExtJS Grid-a. Но речь пойдёт не о нём.

Вообще найти грид работающий на Ruby on Rails это большая проблема, да… что-то найти несомненно можно, но вот вряд ли эти находки оправдают ваше ожидание. Около пяти месяцев назад я сам занялся подобными поисками и так и не нашел грида который бы устроил меня. И за прошедшее время существенных изменения в этом направлении не произошло. Но жить как-то с этой проблемой надо и я нашел устраивающее меня решение.

Основная проблема при создании грида (построенного с помощью HTML тегов) на Rails для меня заключалась в том что приходилось создавать довольно много HTML кода вперемешку со вставками Ruby кода, который управлял рендерингом рядов и ячеек грида. Часто в приложении используется несколько гридов, поэтому приходится прибегать к copy-paste чтобы не заниматься рутиной связанной с созданием грида с нуля. Понятно что поступать так не красиво и не правильно. Подумав, я решил что исправить эту ситуацию можно если найти способ с помощью которого можно было быстро и коротко описать как должен выглядеть грид не прибегая к HTML разметке (например так поступают при создании ExtJS грида). И такой способ был мною найден. Точнее был найден плагин под незамысловатым названием table_helper.

Всё что вам нужно сделать при использовании этого плагина так это описать во View из каких столбцов должен состоять ваш грид, и чем заполнять его ячейки. Выглядит это так:

collection_table(@hosts, {}, :id => 'hosts', :class => 'table') do |header, body|
  header.hide_when_empty = false
  body.alternate_rows = :odd

  header.column :name
  header.column :uri
  header.column :deploy_directory, 'Deploy Directory'
  header.column :actions

  body.build do |row, host, index|
    row.name link_to h(host.name), host_url(host)
    row.uri link_to h(host.uri), 'http://' + host.uri, :target => '_blank'
    row.actions host_actions(host)
  end
end

Как видите всё довольно просто. Метод collection_table который собственно и создаёт разметку грида принимает три аргумента узнать больше о них можно из документации. Внутри его блока можно можно указать несколько дополнительных опций которые влияют на элементы грида. Например опция header.hide_when_empty указывает на то стоит ли скрывать заголовок грида если сам грид пустой, а body.alternate_rows указывает как будет называться CSS класс для чётных рядов.

Следом за списком опций перечисляются колонки которые будет иметь ваш грид. Первым аргументом указывается идентификатор колонки. Он будет использоваться позже для ссылки на конкретную ячейку в ряде, а так же если не задан второй аргумент, то на его основе будет строиться название этой колонки. Вторым необязательным аргументом может идти имя колонки, если то имя которое генерируется на основе первого аргумента вас не устраивает.

За списком колонок идёт блок кода который отвечает за заполнение ячеек. Как видите в блок передаются три аргумента:

  • row - объект ассоциированный с текущим рядом грида. Используя этот аргумент и идентификатор колонки (указанный нами выше) можно установить определённой ячейки какое либо значение. Например вставить ссылку используя метод link_to или например вызвать свой хелперный метод (host_actions) который может проделать более сложную работу по формированию содержимого ячейки.
  • host - в этом аргументе содержится один из элементов массива @hosts на основе которого собственно и происходит заполнение грида данными.
  • index - порядковый номер ряда

После этого остаётся применить к сформированной HTML разметки CSS стиль. Например такой:

/* Common styles for tables */

.table {
  width: 100%;
  border: #909 1px solid;
}

.table thead {
  background-color: #909;
  color: white;
}

.table th, .table td {
  padding: 3px;
  border-left: white 1px solid;
  text-align: left;
}

.table th:first-child, .table td:first-child {
  border-left: none;
}

.table tr.alternate {
  background-color: #FFE1FF;
}

.table tr:hover td {
  background-color: #F9F;
}

/* End common styles for tables */

/* Start table: Hosts */

table#hosts th[class='name'] {
}

table#hosts td[class='name'] {
}

table#hosts th[class='uri'] {
}

table#hosts td[class='uri'] {
  width: 250px;
}

table#hosts th[class='deploy_directory'] {
}

table#hosts td[class='deploy_directory'] {
  width: 350px;
}

table#hosts th[class='actions'] {
  text-align: center;
  width: 70px;
}

table#hosts td[class='actions'] {
  text-align: center;
}

table#hosts td[class='actions'] a {
  margin: 0 3px;
}

table#hosts td[class='actions'] a.edit-host {
  padding-left: 18px;
  background: url(images/icon-edit-host.png) no-repeat;
}

table#hosts td[class='actions'] a.delete-host {
  padding-left: 18px;
  background: url(images/icon-delete-host.png) no-repeat;
}

/* End table: Hosts */

И получить такой вот грид:

Результат работы плагина table_helper
Результат работы плагина table_helper

На мой взгляд получился довольно удобный рецепт изготовления простых гридов. Конечно в нём нет никакой сортировки, фильтров, пэйджинга и он не блещет AJAX-ом, но в большинстве случаев этого вполне достаточно, а недостающие фичи уже можно прикрутить самому или озадачить автора этого плагина.

Тэги: grid
Будь всегда в курсе последних новостей блога подписавшись на новости
в формате RSS. Присоединяйся!
* * *

Комментарии

* * *

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

Доступные BB теги

*

* (не будет опубликован)

(если есть)

  • Multi CAPTCHA Refresh2
  • *

1. Проверьте комментарий перед отправкой
2. Все комментарии проходят модерацию перед публикацией в блоге