4

When a user clicks, for example, "Take a Picture" how can we prepopulate the create.html.erb form with attributes specifically set for that featured challenge, like do for 12 days and do on Tue, Thu?

I am using the reform gem.

#challenges_controller
def new
  @challenge = Challenge.new
  respond_modal_with @challenge, location: root_path
end

#challenges/new.html.erb
<%= simple_form_for(@challenge, html: { data: { modal: true } })  do |f| %>
  <%= f.text_field :action, placeholder: 'Enter a Custom Challenge' %><br>
    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 %>
  <%= f.submit %>
<% end %>

enter image description here

#challenges_controller
def create
  @challenge = Challenge.new(challenge_params) #create is being used to GET and then POST
  if params[:step] == '2'
    @challenge = current_user.challenges.build(challenge_params)
    @challenge.save
    redirect_to @challenge
  end
end

#challenges/create.html.erb
<%= simple_form_for(@challenge)  do |f| %>
<%= hidden_field_tag :step, 2 %>
  Challenge: <%= f.text_field :action %>
  Do For: <%= f.number_field :days_challenged, value: 10 %>
  Do On: <%= f.collection_check_boxes :committed %>
<% end %>

enter image description here

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' => ['Tue', 'Thu']
    }
  end
end

As it is now ChallengeForm has had no effect on create.html.erb. How can we get it to properly insert the defaults into create.html.erb depending on the featured :action?

AnthonyGalli.com
  • 2,796
  • 5
  • 31
  • 80

2 Answers2

2

Try this:

challenges_controller

  def new
    @form = ChallengeForm.new(Challenge.new)

    respond_modal_with @form, location: root_path
  end

  def create
    challenge = Challenge.new(challenge_params)
    @form = ChallengeForm.new(challenge)

    if params[:step] == '2'
      @form.validate(user_id: current_user.id)
      @form.save
      redirect_to challenge
    end
  end

challenges/new.html.erb

<%= simple_form_for @form, html: { data: { modal: true } }, url: 'your_challenge_create_path', method: :post do |f| %>

  <%= f.text_field :action, placeholder: 'Enter a Custom Challenge' %><br>
  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 %>
  <%= f.submit %>
<% end %>

challenges/create.html.erb

<%= simple_form_for @form, html: { data: { modal: true } }, url: 'your_challenge_create_path', method: :post do |f| %>
  <%= hidden_field_tag :step, 2 %>
  Challenge: <%= f.text_field :action %>
  Do For: <%= f.number_field :days_challenged %>
  Do On: <%= f.collection_check_boxes :committed %>
<% end %>

I might be a bit off, but you get the point?

Petr Gazarov
  • 3,602
  • 2
  • 20
  • 37
  • @AnthonyGalli.com When you say 'the controller logic' what do you mean by that? It would be helpful if you can provide details on what you have tried and where exactly it does not perform as expected. Perhaps follow the code with a `binding.pry`? Just a suggestion. – Petr Gazarov Apr 21 '16 at 17:54
  • 1
    Thanks for your help! I gave you the bounty because you were so patient. I couldn't get reform to work so I had to use a mix of javascript and ruby to get me in the right direction. Your answer was helpful though in pushing me in the right direction and I may come back to it in the future as I add more featured challenges. – AnthonyGalli.com Apr 27 '16 at 15:40
0

You're passing the @challenge to the form, but you might want to be passing the form object.

To do that add some code in the controller:

@challenge_form = ChallengeForm.new(@challenge)

and then in the view:

<%= simple_form_for(@challenge_form, html: { data: { modal: true } })  do |f| %>
  • I just realized that you were asking about create.html.erb, which has different form code. The principle is the same, pass the form object. But it's not super conventional to have a create view. If you need two new views, you might want to break those out into separate controllers. – regulation_d Apr 16 '16 at 21:15
  • @AnthonyGalli.com Can you post your errors? Are you still having trouble with `uninitialized constant Reform`? – Petr Gazarov Apr 19 '16 at 23:31
  • No errors @PetrGazarov. I don't get that error anymore with the suggestions you gave me in my last question. The problem I face is that nothing is happening. When a user clicks on "Take a Picture" the default properties we set in ChallengeForm are not being set for the user in Create.html.erb – AnthonyGalli.com Apr 20 '16 at 17:56