0
votes

Sorry if this is a duplicate, I can't find the answer anywhere!

In short, I need to dynamically add an item to a drop down menu in a form without losing any edits.

More specifically, I'm adding a recipe in a rails form. Each ingredient has a field for quantity, a drop down containing all the existing ingredients and then a field for a description of the ingredient. My Rails form successfully adds the recipe, sets up the association between the recipe and the recipe_ingredients table (a go-between table that lists the recipe_id, the ingredient_id, amount and so on) and successfully pulls the name of the ingredient from the ingredients table. All good there. So, recipe.recipe_ingredients will list all the ingredients in the recipe and recipe.ingredient.first.name will say "Pasta" or whatever. Everything is working fine.

BUT, if the ingredient name doesn't already exist in the ingredients table I can't figure out the best way to add that ingredient to the drop down without scrapping the whole recipe and going to another page to add the ingredient to the ingredients table and going back to the recipe page to add the recipe again.

I'm not sure the best way to do this. I was thinking of having a form in the sidebar to add a new ingredient to the ingredients table (ingredients have a name and a category - dairy, produce, etc) so it's not enough to just have a blank field in the original form for the new name. But I have two problems with that. I'm not sure what to add to the ingredients form on the recipe page to have that form interact with ingredients controller and not the recipes controller. Something in the submit button telling it which controller to use? And I don't know how to then dynamically update the drop down menus in the recipe form to update the menus with the new item. Especially without resetting the state of the previous drop downs - which might be just saying update the "last" drop down of its class?

I'd be happy to supply any code to clarify, just don't want to overwhelm with unnecessary details.

2

2 Answers

0
votes

But I have two problems with that. I'm not sure what to add to the ingredients form on the recipe page to have that form interact with ingredients controller and not the recipes controller.

That is done via the form_helper:

<%= form_for :ingredient, :url => {:controller => "/recepies", :action => your-action-here %>

In order to update the dropdown field some JS is necessary:

  1. create the controller action that will be called from your form
  2. add the :remote => true option to the call of the form helper:

    {}, :remote => true %>

Then create a view: /recicpies/your-action-name.js.erb

In this template you can use Javascript to update your dropdown menu as the controller will render the .js.erb template and send it back to the browser because ':remote => true' option

If you provide some code details i'm sure i can tell you more details about how to do it

0
votes

Well, shoot. I think I just figured it out.

Using the cocoon gem I added a link_to_add_association after the ingredient dropdown. So if my ingredient wasn't included in the dropdown I can click the link which will add the necessary fields to the form to add a new ingredient.

So now the ingredient drop down looks like this:

<%= f.label :ingredient_id, 'Ingredient:' %>
  <div class="ing">
    <%= f.select(:ingredient_id, Ingredient.all.order('ingredients.name ASC').map{|i| [ i.name, i.id ] }, {include_blank: true})%>
  </div>

<%= link_to_add_association 'or add ingredient', f, :ingredient, 'data-association-insertion-node' => ".ing", 'data-association-insertion-method' => "append", :class => "add-ingredient" %>

And the link inserts this partial:

<div class="nested-fields">
  <%= f.text_field :name %>
  <%= f.text_field :category %>

  <%= link_to_remove_association "del", f, :class => "remove-ingredient" %>
</div>

That will dynamically add the form with all the right controllers. And it seems to work! I'd been struggling with that for two days. Figures as soon as I ask the question I'd figure it out...