A user can input a custom :action
or choose a featured :action
:
<%= f.text_field :action %> Or choose a featured challenge: <%= f.collection_radio_buttons :action, [['Run a Mile','Run a Mile'], ['Drink 16oz of Water','Drink 16oz of Water'], ['Take a Picture','Take a Picture'], ['1 Drink Max','1 Drink Max'], ['See Eiffel Tower','See Eiffel Tower'], ['Write a Book','Write a Book'], ['Skydive','Skydive'], ['Start a Business','Start a Business'], ['No Snooze','No Snooze'], ['Visit All 50 States','Visit All 50 States'], ['Talk to a Stranger','Talk to a Stranger'], ['Try a New Recipe','Try a New Recipe'], ['Media-fast','Media-fast']], :first, :last %>
If a user chooses a featured :action
the new challenges/_form is pre-populated with his chosen :action
, but now I'd like to take it to the next level with your help!
<%= form_for(@challenge) do |f| %> Challenge: <%= f.text_field :action %> Do On: <%= f.collection_check_boxes :committed %> Do For: <%= f.number_field :days_challenged %> <% end %>
How can I pre-populate the other attributes of a featured challenge like, "Do For" or "Do On"?
For example if a user chose the featured :action
: 'Run a Mile
then I would pre-populate the form with Run a Mile
, Mon, Wed, Fri
, 30 Days
.
UPDATE
challenges_controller
class ChallengesController < ApplicationController before_action :set_challenge, only: [:show, :edit, :update, :destroy, :challenging, :mark_accomplished, :mark_completed, :create_freebie, :like] before_action :populate_challenge, only: [:create] respond_to :html, :json # User chooses featured challenge action or creates custom challenge action here def new @challenge = Challenge.new respond_modal_with @challenge, location: root_path end # User is then redirected to create.html.erb where we can input the other attributes of the object. def create @challenge = Challenge.new(challenge_params) @form = ChallengeForm.new(@challenge) if params[:step] == '2' @challenge = current_user.challenges.build(challenge_params) @challenge.save redirect_to @challenge end end private def populate_challenge require "reform/form/dry" Reform::Form.class_eval do feature Reform::Form::Dry end end def set_challenge @challenge = Challenge.find(params[:id]) end def challenge_params params.require(:challenge).permit( :action, :category, :deadline, :date_started, :days_challenged, :send_email => [], :committed => []) end end
1 Answers
Answers 1
You can use simple_form
with reform
. Reform will give you form object, where you can override methods that will populate your form.
Here is a watered-down example (you will have to adjust it to your case):
class ChallengeForm < Reform::Form property :action property :committed property :days_challenged model :challenge def commited super || action_to_commited_hash[model.action] end def days_challenged super || action_to_days_challenged_hash[model.action] end def action_to_days_challenged_hash { 'Run a Mile' => 30, 'Take a Picture' => 12 } end def action_to_commited_hash { 'Run a Mile' => ['Mon', 'Wed', 'Fri'], 'Take a Picture' => ['Tu', 'Thu'] } end end
super
in the methods above will delegate to the model
. Note that you are overriding getter
methods, and it doesn't affect setters
(you can override setters too if you wanted to change form data before writing it).
In your template, instead of
form_for @challenge
you will have:
simple_form_for @form
It's a super common form library for Rails and I can't imagine not using it myself!
0 comments:
Post a Comment