|
Submitting a Text_Area Field into an Array
By: Bruce Bahlmann - Contributing Author (your
feedback
is important to us!)
In rails development, when working with Text_Area fields, occasionally you
will want to allow the user to enter a list of items into the text_area
field (one item per line of the text_area field). What seems like a good
idea, can be difficult to process at the controller level so this post is
about how to handle submissions of such lists of items.
The image below represents the text_area form field being used to allow a
user to enter choices for a survey question. The choices that the user
desires to associate with the survey question are listed - one per line in
the text_area field at the left. The text to the right shows the format of
the posted data representing these choices which must be processed by the
rails controller.
|
View: |
How this information is received by the controller: |
 |
choices":"dd answer 1\r\ndd answer 2\r\ndd answer 3\r\ndd answer
4" |
The code within the rails view to produce the desired text_area field
resides below. In this case, [key] represents a special case related to the
desired implementation where there are actually several survey questions,
and so the key identifies each question within a given survey.
[/app/views/surveys/_form.htm.erb]
<table><tr class="tarow<%= key %>">
<td style="vertical-align: top">Choices:</td>
<td><%= text_area("survey[question]["+key+"]", :choices, :rows=>5, :value=>value["choices"]) %></td>
</tr></table>
Finally, there is the consolidated code at the controller which processes
the array choices submitted. First the code that goes in the create and
update areas which is responsible for fixing and parsing user input so that
it can be properly stored within an array.
[/app/controllers/surveys_controller.rb]
# Fix question choices
params[:survey]["question"].each do |key,value|
if ((value["questionType"] == "1")||
(value["questionType"] == "2")) &&
(value.has_key?("choices"))
## Remove leading/trailing spaces and everything in-between - leave only valid entry PER LINE
params[:survey]["question"][key]["choices"] =
params[:survey]["question"][key]["choices"].strip.split(/[\r\n]+/)
else
## Any other processing per question type
end
end
Finally, there is the consSome important things to consider when looking at the
above. First, notice that we are working with "params[:survey]" - this
contains the contents of the POST. We want the contents of the POST
because within the POST lies the raw text of the post (dd answer 1\r\ndd answer 2\r\ndd answer 3\r\ndd
answer 4) which we need to split out into an array. We use the "strip"
command to first strip the leading/trailing spaces (additional \r\n either
before or after the user provided list) from the submitted list. We also
combine a regex operation (namely: /[\r\n]+/) into the split.
One note about the regex is that it does not have double quotes
(") around it. While there are many way to use/express regex (one of
which just allows you to put double quotes around some text), the double
quoted encased regex doesn't appear to support the plus (+) or grouping
functions. Therefore you need to use the without quotes version of regex
to use the grouping and plus(+) functions.
Using the plus (+) function says that one or
more instances of [\r\n] will be interpreted as one, so whether we have (dd answer 1\r\ndd answer 2\r\ndd answer 3\r\ndd
answer 4) or (dd answer 1\r\n\r\ndd answer 2\r\ndd answer 3\r\n\r\n\r\ndd
answer 4), the array stored will be identical.
This allows users who mistakenly add a carriage return/enter here or there,
won't have a blanks in their list, rather all blanks will be removed.
The second piece of controller code goes in the edit and show areas where a
person is accessing an individual record thus the items stored within an
array must be uncoded to present them in a way that the text_area field
understands.
[/app/controllers/surveys_controller.rb]
if !@survey["question"].nil?
@survey["question"].each do |key,value|
if ((value["questionType"] == "1")||(value["questionType"] == "2")) && (value.has_key?("choices"))
## serialize choices (for text area manipulation)
@survey["question"][key]["choices"] = value["choices"].join("\r\n")
end
end
end
This last piece of code determines if a survey
question has been added (some surveys may be a work in progress, so you have
to satisfy the case of when surveys are saved without adding questions) -
this is done by checking for nil. If some questions exist, then we want to
walk through all the questions in the array, and serialize them (using join)
to re-create the format that text_area likes (which is the \r\n separator
between entries).
Can Birds-Eye.Net help you or your Company?
Receive your Birds-Eye.Net articles and white
papers hot off
the presses by adding our RSS feed to your reader.
|
|