Geo
Geo

Reputation: 96827

How should I handle this Rails use case?

I have an Exercise model, which has these columns (pseudo Ruby):

model Exercise do
  string :name
  calories_burned :float
end

I want that when a user adds an exercise to be able to do it in this fashion:

The thing is, I don't know how I should put this in my view. Here's how the else case is handled:

<div class="field">
  <%= f.label :name %><br />
  <%= f.text_field :name %>
</div>

I have something like this now:

  <div class="field">
    <% if @exercise_added %>
        <div id="select_div">
            <%= select_tag :name,options_for_select(@exercise_added) %>
            <input type="checkbox" name="custom_type_checked" id="which_type">New type?</input>
        </div>
    <% end %>
    <div id="regular_field">
        <%= f.label :name %><br />
        <%= f.text_field :name %>
    </div>
  </div>

In @exercise_added I have a list of names of all exercises from the database. What would be the best/cleanest way of handling this?

EDIT: For now,I have a textfield and a select, and by using Javascript, I'm changing the name of the element ( and hiding the other one ). So far, it's working, but I'd still be interested if other approaches exist.

Upvotes: 2

Views: 319

Answers (3)

CambridgeMike
CambridgeMike

Reputation: 4622

What if you used two forms? One form to handle the case when the exercise is in @exercise_added, and a second form to handle the creation of a new exercise. It might even boil down to the difference between a POST and a PUT, depending on what you're doing once an exercise is submitted from the drop-down list.

I'd be curious to see more of the code, as well as the controller, since it seems like this form might be nested?

Upvotes: 0

Mahesh
Mahesh

Reputation: 6426

You can check if the array @exercise_added is empty or not and show the select field or text field accordingly.

      <div class="field">
        <% if !@exercise_added.empty? %>
            <div id="select_div">
                <%= select_tag :name,options_for_select(@exercise_added) %>
                <input type="checkbox" name="custom_type_checked" id="which_type">New type?</input>
            </div>
        <% else %>
        <div id="regular_field">
            <%= f.label :name %><br />
            <%= f.text_field :name %>
        </div>
        <%end%>
      </div>

Upvotes: 4

dantswain
dantswain

Reputation: 5467

I would, by default, have the select box and a button shown, with the textbox hidden unless a variable @show_textbox is true. Something like this:

<div class="field">
    <div id="select_div">
        <%= select_tag :name,options_for_select(@exercise_added) %>
        <%= f.submit "New Exercise" %>
    </div>
    <div id="regular_field" <%= hidden_unless @show_textbox %> >
        <%= f.label :name %><br />
        <%= f.text_field :name %>
    </div>
</div>

Where I've written a helper function

def hidden_unless cond
  raw "style=\"display: none;\"" unless cond
end

# this one is helpful, too
def hidden_if cond
  raw "style=\"display: none;\"" if cond
end

Then, in my controller, check if the "New Exercise" button was pressed. If so, essentially set @show_textbox to true and then re-render the new form.

def create
  # .....

  # did we get here because the user pressed "New Exercise"?
  if params[:commit].eql?("New Exercise")
    @show_textbox = true
    # probably some other code to replicate what happens in your #new action
    render :action => new
  end

  # ....
end

You can check in your controller if the :name field has any text in it, and use that to override the select box.

This should work without javascript. I'd add some jQuery to replace the button with either a link or a check box, with the click handler for that connected to a function that shows the textbox, i.e. $('#regular_field').toggle();.

I didn't deal with hiding the select box. I actually think it might be better to leave that available. You could hide it using a similar method, anyways.

Upvotes: 0

Related Questions