Проблема
Хотелось бы дать пользователям возможность оперативного просмотра данных в процессе редактирования, чтобы не получалось так, что после отправки из формы данные появились в испорченном формате (когда речь идет, к примеру, о дневниковой записи, которую собираются выставить на всеобщее обозрение).
Решение
Оперативный просмотр легко осуществить с помощью встроенных в Rails помощников JavaScript. Для данного рецепта мы обойдемся созданием оперативного просмотра простейшей формы, предназначенной для создания дневниковой записи.
Первым делом при создании любого Rails-эффекта, связанного с использованием Ajax, нужно обеспечить включение в код нужных JavaScript-библиотек. Для достижения эффекта оперативного просмотра требуется включить лишь одну библиотеку — Prototype. Я рекомендую сделать это в главном шаблоне приложения (в нашем случае — в файле layouts/standard.rhtml):
Теперь, обеспечив загрузку требуемых JavaScript-библиотек, нужно создать модель и контроллер, которые будут поддерживать ввод дневниковых записей. Мы будем вызывать класс модели Entry, передавая ему свойства title и body. Если хотите продолжать работу, не определяя соответствующей таблицы Active Record, то файл app/models/entry.rb должен приобрести следующий вид:
Контроллер будет называться DiaryController. Мы создадим его в файле app/control-lers/diary_controller.rb. Давайте придерживаться основ, и назовем действие по созданию новой записи new( ):
Теперь настал черед самой функции. В представлении, созданном для этого действия, и будет твориться все наше волшебство. Создайте файл app/views/diary/new.rhtml и придайте ему следующий вид:
Мы создали стандартную, универсальную форму с id, имеющим значение entry-form, поэтому на нее можно ссылаться из всего остального кода. За определением формы следует вызов помощника observe_form( ), который генерирует требуемый JavaScript-код для опроса каждого элемента формы, выведенной на странице (ссылаясь на нее по id), и поиска изменений. Опрос будет вестись через интервалы времени (в секундах), заданные параметром frequency. Как только будут замечены изменения, на URL, определенный параметром :url, будет направлен вызов, которому в качестве параметров будут переданы данные формы. Параметр :update определяет HTML-элемент (опять же по его id), который будет обновлен результатами URL-вызова. В данном случае содержимое элемента , который используется для оперативного просмотра, будет обновлено тем, что в конечном счете будет отправлено в результате вызова действия preview( ).
Чтобы сделать элемент оперативного просмотра невидимым при первоначальной загрузке страницы, мы воспользовались встроенным CSS. Пока пользователь не введет какие-либо данные, в элементе оперативного просмотра нечего будет показывать. Параметр :complete, передаваемый помощнику observe_form( ), предписывает после завершения вызова действия preview( ) выполнение фрагмента JavaScript, который включит отображение элемента оперативного просмотра.
Если в оперативном просмотре нужно отобразить всего лишь одно поле, то мы можем взамен воспользоваться помощником observe_field( ).
Теперь осталось только обеспечить выполнение действия preview( ). Вот его код, взятый из контроллера:
Единственная задача, выполняемая кодом действия, — это «закорачивание» обычной схемы отправки данных, используемой в приложении. Поскольку мы собираемся обновлять элемент оперативного просмотра на странице создания ежедневных дневниковых записей и использовать для этого лишь результаты, возвращаемые действием preview( ), возвращать целиком всю HTML-страницу не требуется. Нам нужен лишь отрывок, имеющий определенный смысл в составе более объемного содержимого экрана.
Представление, предназначенное для действия preview( ), находится в файле app/views/diary/preview.rhtml и должно иметь следующий вид:
Вот и все! Это представление использует HTML-заголовок для названия записи, а затем, используя метод textilize( ), генерирует HTML-выход. Внутри этого метода используется библиотека RedCloth для преобразования простой текстовой разметки в HTML.
Теперь можно загрузить форму ввода дневниковой записи и посмотреть, как обычный текст преобразуется в HTML еще до того, как будет сделан щелчок на кнопке Save.

P.S.
Параметру frequency, использующемуся в методах observe_field( ) и observe_form( ), можно присвоить нулевое или отрицательное значение, что приведет к обзору поля в реальном масштабе времени. Казалось бы, что может быть плохого в мгновенной реакции пользовательского интерфейса, но на самом деле она будет подавлена, не говоря уже о дополнительной тяжелой нагрузке на серверы. При отслеживании изменений в реальном масштабе времени каждое изменение вызовет отправку запроса на сервер, от которого нужно дождаться результата, чтобы увидеть обновление на экране. Изменения становятся в очередь, в результате чего обновления оперативного просмотра медленно следуют за ними, ожидая очередного перехвата.
Кросспост из моего блога
P.S.
Да, пожалуйста, если Вам что то не понятно — напишите в коментах. Хватит минусовать карму за топики, которые вроди бы (ИМХО) несут полезную информацию.
Хотелось бы дать пользователям возможность оперативного просмотра данных в процессе редактирования, чтобы не получалось так, что после отправки из формы данные появились в испорченном формате (когда речь идет, к примеру, о дневниковой записи, которую собираются выставить на всеобщее обозрение).
Решение
Оперативный просмотр легко осуществить с помощью встроенных в Rails помощников JavaScript. Для данного рецепта мы обойдемся созданием оперативного просмотра простейшей формы, предназначенной для создания дневниковой записи.
Первым делом при создании любого Rails-эффекта, связанного с использованием Ajax, нужно обеспечить включение в код нужных JavaScript-библиотек. Для достижения эффекта оперативного просмотра требуется включить лишь одну библиотеку — Prototype. Я рекомендую сделать это в главном шаблоне приложения (в нашем случае — в файле layouts/standard.rhtml):
<html>
<head>
<%= javascript_include_tag «prototype» %>
</head>
<body>
…
</body>
</html>* This source code was highlighted with Source Code Highlighter.
Теперь, обеспечив загрузку требуемых JavaScript-библиотек, нужно создать модель и контроллер, которые будут поддерживать ввод дневниковых записей. Мы будем вызывать класс модели Entry, передавая ему свойства title и body. Если хотите продолжать работу, не определяя соответствующей таблицы Active Record, то файл app/models/entry.rb должен приобрести следующий вид:
class Entry
attr_accessor :title, :body
end* This source code was highlighted with Source Code Highlighter.
Контроллер будет называться DiaryController. Мы создадим его в файле app/control-lers/diary_controller.rb. Давайте придерживаться основ, и назовем действие по созданию новой записи new( ):
def new
entry = Entry.new
end* This source code was highlighted with Source Code Highlighter.
Теперь настал черед самой функции. В представлении, созданном для этого действия, и будет твориться все наше волшебство. Создайте файл app/views/diary/new.rhtml и придайте ему следующий вид:
<% form_tag ({:action => «save»}, :id=> «entry-form») do %>
<%= text_field :entry, :title %> <br />
<%= text_area :entry, :body %> <br />
<%= submit_tag «Save» %>
<% end -%>
<%= observe_form «entry-form»,
:frequency=>2,
:update=>«live-preview»,
:complete=>«Element.show('live-preview')»,
:url=> {:action => «preview»} %>
<div id=«live-preview» style=«display:none; border:1px solid»></div>* This source code was highlighted with Source Code Highlighter.
Мы создали стандартную, универсальную форму с id, имеющим значение entry-form, поэтому на нее можно ссылаться из всего остального кода. За определением формы следует вызов помощника observe_form( ), который генерирует требуемый JavaScript-код для опроса каждого элемента формы, выведенной на странице (ссылаясь на нее по id), и поиска изменений. Опрос будет вестись через интервалы времени (в секундах), заданные параметром frequency. Как только будут замечены изменения, на URL, определенный параметром :url, будет направлен вызов, которому в качестве параметров будут переданы данные формы. Параметр :update определяет HTML-элемент (опять же по его id), который будет обновлен результатами URL-вызова. В данном случае содержимое элемента , который используется для оперативного просмотра, будет обновлено тем, что в конечном счете будет отправлено в результате вызова действия preview( ).
Чтобы сделать элемент оперативного просмотра невидимым при первоначальной загрузке страницы, мы воспользовались встроенным CSS. Пока пользователь не введет какие-либо данные, в элементе оперативного просмотра нечего будет показывать. Параметр :complete, передаваемый помощнику observe_form( ), предписывает после завершения вызова действия preview( ) выполнение фрагмента JavaScript, который включит отображение элемента оперативного просмотра.
Если в оперативном просмотре нужно отобразить всего лишь одно поле, то мы можем взамен воспользоваться помощником observe_field( ).
Теперь осталось только обеспечить выполнение действия preview( ). Вот его код, взятый из контроллера:
def preview
render :layout => false
end* This source code was highlighted with Source Code Highlighter.
Единственная задача, выполняемая кодом действия, — это «закорачивание» обычной схемы отправки данных, используемой в приложении. Поскольку мы собираемся обновлять элемент оперативного просмотра на странице создания ежедневных дневниковых записей и использовать для этого лишь результаты, возвращаемые действием preview( ), возвращать целиком всю HTML-страницу не требуется. Нам нужен лишь отрывок, имеющий определенный смысл в составе более объемного содержимого экрана.
Представление, предназначенное для действия preview( ), находится в файле app/views/diary/preview.rhtml и должно иметь следующий вид:
<h2>Preview:</h2><br />
<h3><%= params[:entry][:title] %></h3>
<%= textilize params[:entry][:body] %>
* This source code was highlighted with Source Code Highlighter.
Вот и все! Это представление использует HTML-заголовок для названия записи, а затем, используя метод textilize( ), генерирует HTML-выход. Внутри этого метода используется библиотека RedCloth для преобразования простой текстовой разметки в HTML.
Теперь можно загрузить форму ввода дневниковой записи и посмотреть, как обычный текст преобразуется в HTML еще до того, как будет сделан щелчок на кнопке Save.

P.S.
Параметру frequency, использующемуся в методах observe_field( ) и observe_form( ), можно присвоить нулевое или отрицательное значение, что приведет к обзору поля в реальном масштабе времени. Казалось бы, что может быть плохого в мгновенной реакции пользовательского интерфейса, но на самом деле она будет подавлена, не говоря уже о дополнительной тяжелой нагрузке на серверы. При отслеживании изменений в реальном масштабе времени каждое изменение вызовет отправку запроса на сервер, от которого нужно дождаться результата, чтобы увидеть обновление на экране. Изменения становятся в очередь, в результате чего обновления оперативного просмотра медленно следуют за ними, ожидая очередного перехвата.
Кросспост из моего блога
P.S.
Да, пожалуйста, если Вам что то не понятно — напишите в коментах. Хватит минусовать карму за топики, которые вроди бы (ИМХО) несут полезную информацию.