По следам "Кофейных ссылок" или "Rails в клеточку"
-
12 декабря 2008 20:12
-
Комментарии

На написание этого поста меня натолкнула ссылка на 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 */
И получить такой вот грид:
На мой взгляд получился довольно удобный рецепт изготовления простых гридов. Конечно в нём нет никакой сортировки, фильтров, пэйджинга и он не блещет AJAX-ом, но в большинстве случаев этого вполне достаточно, а недостающие фичи уже можно прикрутить самому или озадачить автора этого плагина.
в формате RSS. Присоединяйся!
Комментарии
Добавить новый комментарий
Вы можете использовать следующие BBCode теги в комментариях:
| BBCode тег | Результат |
|---|---|
| [b]Жирный текст[/b] | Жирный текст |
| [i]Курсив[/i] | Курсив |
| [u]Подчёркнутый текст[/u] | Подчёркнутый текст |
| [url]http://example.com[/url] | http://example.com |
| [url=http://example.com]Example[/url] | Example |
|
[code]for message in @messages puts message.name end[/code] |
|
|
[quote] IE6 must die! [/quote] |
IE6 must die! |


Да, я тоже провел много времени в поисках, в итоге пришлось написать самому. :) Работает непосредственно с ActiveRecord. Таблица описывается в controller`е:
adminka :article do |index_entity, view_entity|
index_entity.excluded_fields = [:created_at, :id, :full_text, :user_id]
index_entity.fields_order = [:title, :author]
index_entity.link_fields = [:title, :author]
index_entity.lookup_contents = {:article_type => Article.article_types, :language_id=>Banner.banner_languages}
view_entity.fields_order = [:title, :author, :article_type, :language_id, :lead_text, :full_text]
view_entity.excluded_fields = [:created_at, :updated_at, :id, :user_id]
view_entity.lookup_contents = {:article_type => Article.article_types, :language_id => Banner.banner_languages}
end