Trouble dynamically adding fields with rails - ruby-on-rails

I'm dynamically generating nested form fields using the cocoon gem as follows:
<%= simple_form_for #incorporation do |f| %>
<%= f.simple_fields_for :company do |company| %>
<%= link_to_add_association 'Add ID', company, :persons, class: "btn btn-default add-button" %>
<%= company.simple_fields_for :persons do |person|%>
<%= render 'person_fields', f: person %>
<% end =%>
<% end =%>
<% end =%>
And _person_fields is (currently) as follows:
<div>
<div class="col-md-6"><%= f.input :fname, input_html: {class: 'form-input form-control'}, label: "First Name" %></div>
</div>
The link_to_add_association should, through the cocoon gem and javascript, add another row of _person_fields to the form
The problem is that the button in fact adds nothing. Rather, it seems to just bring me to the top of the page. I know that javascript is installed (and working) via therubyracer gem. I know javascript is working because I've got bootstrap running on the site.
I know cocoon works and I've used it on a few apps. Does anyone see something that I might be leaving out?

Turns out I needed to RFTM I was missing the line:
//= require cocoon
in my application.js
I figure I'll keep this question up in case anyone else needs the reminder as well :-)

Related

How can I create a button which adds fields to a Rails form

I have a form in Rails which uses fields_for to accept nested attributes:
<%= form_with(model: #combat_tracker, url: form_url) do |f| %>
…
<%= f.fields_for :zones do |zone| %>
<div class="zone-field">
<%= zone.text_field :name %>
<%= zone.check_box :_destroy %>
<%= zone.label :_destroy, "Remove zone" %>
</div>
<% end %>
…
<% end %>
Currently this gives me input fields for any existing zones on #combat_tracker. I want to add a button that will dynamically add a new zone-fields div for a new zone to be added when the form is submitted.
I’m using Rails 7 and assume the solution will involve the use of Turbo or possibly Stimulus, but can’t quite figure out the best way to do this. Thanks.
I don't think you need Turbo or Stimulus. Take a look at cocoon gem, it should do exactly what you're looking for.
Explaining all process here is quite complex for me, but try to follow this guide if the gem's one is too long.

Select or create from view in rails

In rails is there any simple way to implement select or create from view.
Eg:
Product has_many(or has_one) Tags.
While creating new Product I can select existing tags or create new one.
This can be done by using JavaScript and other ways are there.. But all will take more time and effort.
Please share if you know other simple way...
Edit:
Something like this.
But imagine you have 100 tags or more ! your page will look bad with 100 checkbox or more..., one elegant way to do this is by using a jQuery plugin called jQuery Tokeninput i use it in my project and it's very helpful for what do you want, you can find the plugin Here
This is a screencast on how to use it : Token fields
and this is the revised version : Token Fields (revised)
check also this blog post about the same plugin if you want too How to create a token input field where the user can also add new items
cheer
Yep.
You are after nested forms. Try, https://github.com/ryanb/nested_form
For example,
<% form_for #product do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<% f.fields_for :tags do |tag| %>
<p>
<%= tag.label :content, "Tag Name" %><br />
<%= tag.check_box :content %>
</p>
<%= tag.link_to_remove "Remove this tag" %>
<% end %>
<%= tag.link_to_add "Add new tag" %>
<p><%= f.submit "Submit" %></p>
<% end %>
Setup the controller and model as given in the documentation and try the above code in the view. This railscast will help you a lot in figuring nested forms http://railscasts.com/episodes/197-nested-model-form-part-2

Nested_form, link_to_add ... three times

I have a problem with my nested_form, now when I click on my link_to_add button, three forms are displayed... It is the same for all my nested forms and this is new. I really don't know the reason, any idea ?
My code :
<div id="new_upload">
<%= f.fields_for :uploads do |file| %>
<%= file.label :filename, 'Nom pièce jointe :'%>
<%= file.text_field :name, :size => "19", :id=>"field" %>
<%= file.file_field :file if file.object.new_record? %>
<%= file.link_to_remove "Supprimer" %>
<% end %>
</div>
<%= f.link_to_add "Ajouter pièce jointe", :uploads, :class=>"btn" %>
</div>
This issue is linked with Rails 4 and Turbolinks. See https://github.com/ryanb/nested_form/issues/307 for instance.
You should be able to add data-no-turbolinks to your div to locally disable turbolinks.
With me it was because the application.js was called in the body instead of head. Duh! See https://github.com/ryanb/nested_form/issues/286

CarrierWave and Nested Form Gem Redisplay

I have CarrierWave (0.6.1) and Nested Form gem installed. I have a Resource model with many Attachments which have a FileUploader.
I have a nested form where users can upload multiple files with one resource. I am following the section on github (https://github.com/jnicklas/carrierwave) that says how to make uploads work across redisplays unfortunately it's only for 1:1 ratio.
Here's the code that I have:
<%= nested_form_for #resource, :html=>{:multipart => true } do |f| %>
<p>
<%= f.label :title %>
<%= f.text_field :title %>
</p>
<%= f.fields_for :attachments, #attachment do |attachment_form| %>
<p>
<%= attachment_form.label :file %>
<%= attachment_form.file_field :file %>
<%= attachment_form.hidden_field :file_cache %>
<%= image_tag(attachment_form.file_url) if attachment_form.file? # DOESN'T WORK!!! %>
</p>
<%= attachment_form.link_to_remove "Remove this attachment" %>
<% end %>
<%= f.link_to_add "Add attachment", :attachments %>
<p><%= f.submit %></p>
<% end %>
Everything works and it populates the file_cache variable just fine for the attachment_form however I somehow need to add the following line in there to show the user the image of the document:
<%= image_tag(attachment_form.file_url) if attachment_form.file? %>
However there's a number of problems with this. First of all attachment_form is referencing the form_builder whereas I want the actual attachment. Second, attachment knows nothing about file.
Probably need to use another type of looping mechanism, but I'm new to Ruby so any help is appreciated.
Thanks all!
If you try this:
<%= image_tag(attachment_form.object.file_url) if attachment_form.object.file? %>
You will be able to show previous uploaded images. But if you want to display uploaded right now, you need to use something else. For example: https://github.com/blueimp/jQuery-File-Upload/wiki/jQuery-File-Upload-v4-for-Rails-3
Sorry, if I misunderstood your question.

How to use AJAX with multiple nested forms? "The Gym Plan" problem

I want to be able to fill a table with some data through AJAX. My problem is that this data is from two different models. This will be long but please bear with me.
Imagine an application that would fill the plan for working out at the gym (clearly not an application for me :D). This plan has many routines (per type basis or day basis) which has many steps to go through.
Is it possible to use AJAX to fill a nice table that fills dynamically? Ideally I would prefer to save and display a table each time the user fills any new data.
What I have so far:
In the models I added the accepts_nested_attributes_for property.
I am using nested_form that allows us to add and remove nested models.
Let's take a look at our form:
app/views/plans/_form.html.erb
<%= nested_form_for #plan, :url => plan_path(#plan), :html => { :class => :form } do |f| %>
<%= f.label :name, "Plan Name" %>
<%= f.text_field :name %>
<%= f.fields_for :routines do |r| %>
<%= render 'routine_fields', :f => r %>
<% end %>
<%= f.submit %>
<%= f.link_to_add "Add a routine", :routines %>
<% end %>
So fields_for allows us to save many routines inside a plan, NICE! Let's define our fields views:
app/views/plans/_routine_fields.html.erb
<%= f.label :name, "Routine Name" %>
<%= f.text_field :name %>
<%= f.fields_for :steps do |s| %>
<%= render 'step_fields', :f => s %>
<% end %>
<%= f.link_to_add "Add a step", :steps %>
<%= f.link_to_remove "Remove this routine" %>
app/views/plans/_step_fields.html.erb
<%= f.label :name, "Step Name" %>
<%= f.text_field :name %>
<%= f.link_to_remove "Remove this step" %>
This works great! We can add as many routines inside a plan and many steps inside a routine we are able to create a complete plan in one view.
BUT IS UGLY! and also very confusing! So my problem again: How would I update the table each time the user fills any new data?
Ideal:
One approach that you could use for this would be to break up the form into different forms that are loaded via ajax, and just continuously update attributes on a model. You could also just use the form that you have now and break up the html so that it doesn't all show in a table.
For dealing with forms, you could check out the railscast on wicked
For dealing with ajax, there is a very good railscast on ajax/jquery
You could also break up this logic into different partials, and change the UX a bit, so that a user still has the same functionality, but it lives on a different view. You can add ajax to this by following the previously mentioned ajax railscast or using the turbolinks gem (though turbolinks is a bit different).
It seems to me that this is primarily a UX problem, and you're trying to crowbar a particular implementation into a rigid UX. I would try reframing the UX to see if there is a more elegant solution to the problems you have mentioned.

Resources