Backend Interface - Poll List |
Adding Paragraph Options ![]() |
Module Tutorial: User Polling / Rating: Outputting to a partial
Let’s now attack the problem of how to display our polls to users and let them vote and see the results. To start with, we’re going to display a random poll to the user whenever they visit a page, let them select the answer they want and press ‘Submit’. We’re going to ignore the Webiva site feature system right now, and just output to a partial.
Step 1: Getting our ducks in a row
First, we need to open up page_renderer.rb and assemble the data that we need for our view. Remember, renderers are like controllers except for the front end of the website. They render paragraphs instead of entire websites. We’re going to need to check if the user has responded, then either add their response or find a random poll from our database. Let’s add that logic into the renderer. Replace the view method with the one below:
vendor/modules/poll_demo/app/controllers/poll_demo/page_renderer.rb
def view
if !params[:poll]
@poll = PollDemoPoll.random_poll
@response = @poll.poll_demo_responses.build if @poll
@state = 'question'
else
@poll = PollDemoPoll.find_by_id(params[:poll][:poll_demo_poll_id])
if @poll && @poll.add_response(params[:poll][:response],request.remote_ip)
@state = 'responded'
end
end
render_paragraph :partial => '/poll_demo/page/view'
end
The logic should be pretty simple to understand - we check if there’s a submitted poll (by checking params[:poll]), and if not we get ourselves a random poll and build a response object that we’ll use in the form. We also set a state variable to ‘question’.
If we do have a poll, we try to find the submitted poll by the submitted ID and then try to add a response. If that succeeds, we set the state to ‘responded’.
We also need to add a random_poll class method to PollDemoPoll - the following should do the trick (add it anywhere in poll_demo_poll.rb)
vendor/modules/poll_demo/app/models/poll_demo_poll.rb
def self.random_poll
cnt = PollDemoPoll.count
PollDemoPoll.find(:first,:offset => rand(cnt))
end
Step 2: The view
Whether the user has answered the poll yet or not, we want to output a partial called view. Notice that we need to explicitly tell the renderer the path of the partial. Let’s create that partial now to output our form:
vendor/modules/poll_demo/app/views/poll_demo/page/_view.html.erb
<% if poll -%>
<% if state == 'responded' -%>
<%= poll.results_graph -%>
<% else -%>
<% cms_unstyled_form_for :poll, response, :url => '' do |f| -%>
<b><%= h poll.question -%></b><br/>
<%= f.hidden_field :poll_demo_poll_id -%>
<%= f.radio_buttons :response, poll.answer_options, :separator => "<br/>" -%>
<br/>
<%= f.submit_tag 'Submit' -%>
<% end -%>
<% end -%>
<% end -%>
This is a relatively simple erb file that first checks if we have a poll, then sees if the user has responded. If they’ve responded, we show the results graph, otherwise we display the question, along with possible answers and a submit button.
There are a couple things to notice here. The first is that even though we set instance variables in the renderer, we need to access the variables that are set as locals. This is how Webiva currently renders partials. We could also have explicitly sent the locals along if we had wanted to. Secondly, we use a custom form builder called cms_unstyled_form_for. We could have used the standard form_for, but the cms_form_for and cms_unstyled_form_for give us a number of additional field types, including a radio_buttons field that we can use just like the built in select field. We’re using the unstyled variant here, because we don’t want any automatic labels or error messages, but just a vanilla form.
Step 3: The graph
We’re going to punt any actual work on the graph output for now and just hardcode some Google Graphs 3d Pie Chart code. Let’s add an instance method to PollDemo to return us a chart <img> tag (add it anywhere in poll_demo_poll.rb):
vendor/modules/poll_demo/app/models/poll_demo_poll.rb
def results_graph(width=400,height=200)
chart_src = "cht=p3&chs=#{width}x#{height}&chd=t:#{self.results.values.join(",")}"
chart_src << "&chdl=#{self.answers.map { |elm| CGI.escape(elm) }.join("|")}"
"<img src='http://chart.apis.google.com/chart?#{chart_src}'" +
" width='#{width}' height='#{height}' alt='#{CGI.escape(question)}' />"
end
Go ahead and load up the /poll page we created earlier in the tutorial and try submitting some answers and see the results. You should get something like:

Our next step is going to be adding some paragraph options to control the size of the output graph.
Backend Interface - Poll List |
Adding Paragraph Options ![]() |

Backend Interface - Poll List