📜 ⬆️ ⬇️

Realization of live viewing

Problem
I would like to give users the opportunity to quickly view the data in the editing process, so that it does not work out that after sending from the form, the data appeared in a corrupted format (when it comes to, for example, the diary entry, which they are going to put on public display).


Decision
Live viewing is easy with the built-in Rails JavaScript helpers. For this recipe, we will manage the creation of an on-line viewing of the simplest form intended for creating a diary entry.
The first thing to do when creating any Rails effect associated with using Ajax is to ensure that the necessary JavaScript libraries are included in the code. To achieve the effect of real-time viewing, you need to include only one library - Prototype. I recommend doing this in the main application template (in our case, in the layouts / standard.rhtml file):

< html >
< head >
<% = javascript_include_tag "prototype" %>
</ head >
< body >
...
</ body >
</ html > * This code was highlighted with Source Code Highlighter .

Now, after loading the required JavaScript libraries, you need to create a model and controller that will support the input of diary entries. We will call the Entry model class, passing it the title and body properties. If you want to continue working without defining the corresponding Active Record table, then the file app / models / entry.rb should take the following form:
')
class Entry
attr_accessor: title,: body
end this source code was highlighted with Source Code Highlighter .


The controller will be called DiaryController. We will create it in app / control-lers / diary_controller.rb. Let's stick to the basics, and call the action to create a new record new ():

def new
entry = Entry. new
end this source code was highlighted with Source Code Highlighter .


Now it is the turn of the function itself. In the presentation created for this action, all our magic will be created. Create the file app / views / diary / new.rhtml and give it the following view:

<% 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 code was highlighted with Source Code Highlighter .


We have created a standard, universal form with an id that has an entry-form value, so you can refer to it from the rest of the code. The form definition is followed by a call to the assistant observe_form (), which generates the required JavaScript code to poll each form element displayed on the page (referring to it by id) and search for changes. The survey will be conducted at intervals of time (in seconds) specified by the frequency parameter. As soon as changes are noticed, a call will be sent to the URL defined by the parameter: url, to which the form data will be passed as parameters. The: update parameter defines the HTML element (again by its id), which will be updated with the results of the URL call. In this case, the contents of the element that is used for live viewing will be updated so that it will ultimately be sent as a result of a call to the preview () action.
To make the live view element invisible when the page was initially loaded, we used inline CSS. Until the user enters any data, there will be nothing to show in the online view item. The parameter: complete, passed to the assistant observe_form (), instructs that after the completion of the call to the action preview (), the execution of the JavaScript fragment, which will include the display of the operational view element.
If only one field needs to be displayed in the live view, we can use the observe_field () helper instead.
Now it remains to ensure the execution of the action preview (). Here is the code taken from the controller:

def preview
render: layout => false
end this source code was highlighted with Source Code Highlighter .


The only task performed by the action code is to “short-circuit” the usual data sending scheme used in the application. Since we are going to update the live view item on the daily diary creation page and use only the results returned by the preview () action for this purpose, it is not required to return the entire HTML page. We need only a passage that has a definite meaning in the composition of the larger content of the screen.
The view intended for the preview () action is in the file app / views / diary / preview.rhtml and should look like this:

< h2 > Preview: </ h2 > <br />
< h3 > <% = params [: entry] [: title] %> </ h3 >
<% = textilize params [: entry] [: body] %>
* This source code was highlighted with Source Code Highlighter .


That's all! This view uses the HTML header for the title of the entry, and then, using the textilize () method, generates the HTML output. Inside this method, the RedCloth library is used to convert simple textual markup to HTML.
Now you can load the diary entry form and see how plain text is converted to HTML before you click the Save button.


PS
The frequency parameter used in the observe_field () and observe_form () methods can be assigned a zero or negative value, which will lead to a real-time field survey. It would seem that there may be a bad instantaneous user interface response, but in fact it will be suppressed, not to mention the additional heavy load on the servers. When tracking changes in real time, each change will trigger a request to the server, from which you need to wait for the result to see the update on the screen. Changes are queued, as a result of which the live view updates slowly follow them, waiting for the next interception.

Crosspost from my blog

PS
Yes, please, if something is not clear to you - write in comments. Stop minus karma for topics that seem to (IMHO) carry useful information.

Source: https://habr.com/ru/post/38893/


All Articles