Monitoring the Content Length of a TextareaProblemYou have a form with a textarea element that corresponds to an attribute of your model. The model requires that this field is no longer than a specific maximum length. The textarea element in HTML does not have a built-in way to limit the length of its input. You want an unobtrusive way to indicate that a user has entered more text than the model allows. For example, you have a form that allows authors to enter a brief introduction to their articles. The introduction has a maximum length in characters. To enforce this requirement, you store the introduction in a fixed-length column in your database. Authors enter the text in a form containing a textarea element in which the maximum limit (255 characters) is stated. You want to let authors know when their brief introduction is too long, prior to submitting the forms. SolutionThe layout includes the Prototype JavaScript library and defines an error style for message display: app/views/layouts/articles.rhtml: <html> <head> <title>Articles: <%= controller.action_name %></title> <%= javascript_include_tag 'prototype' %> <style> #article_body { background: #ccc; } .error { background: #ffc; margin-bottom: 4px; padding: 4px; border: 2px solid red; width: 400px; } </style> </head> <body> <%= yield %> </body> </html> Your form contains a textarea element generated by the text_area helper and a call to observe_field that acts on that textarea: app/views/articles/edit.rhtml: <h1>Editing article</h1> <% form_tag :action => 'update', :id => @article do %> <p> <div id="length_alert"></div> <label for="article_body">Short Intro (255 character maximum)</label> <%= text_area 'article', 'body', "rows" => 10 %> </p> <%= submit_tag 'Edit' %> <% end %> <%= observe_field("article_body", :frequency => 1, :update => "length_alert", :url => { :action => "check_length"}) %> Your controller contains the check_length method, which repeatedly checks the length of the data in the textarea: app/controllers/articles_controller.rb: class ArticlesController < ApplicationController def edit end def check_length body_text = request.raw_post || request.query_string total_words = body_text.split(/\s+/).length total_chars = body_text.length if ( total_chars >= 255 ) render :text => "<p class=\"error\">Warning: Length exceeded! (You have #{total_chars} characters; #{total_words} words.)</p>" else render :nothing => true end end end DiscussionWhen your application contains a textarea for input of anything nontrivial, you should consider that users might spend a substantial amount of time composing text in that field. When enforcing a length limit, you don't want to make users learn by experimentation; if telling them their text is too long forces them to start over, they may not bother to try again. An alert message to tell the user that the text is too long is just about the right amount of intervention. It is a solution that allows your user to decide how best to edit the text, so that it's short enough for the field. The observe_field JavaScript helper monitors the contents of the field specified by its first argument. The :url option indicates which action to called, and :frequency specifies how often. The solution invokes the check_length action each second for the textarea field with an id of article_body. You can specify additional parameters by using the :with option, which takes a JavaScript expression as a parameter. observe_field can also take any options that can be passed to link_to_remote, which include:
Figure 8-4 shows the textarea with the warning displayed. Figure 8-4. A text entry form that warns when a length limit is reachedSee Also |