nested_form displays a partial twice - ruby-on-rails

I'm using the gem nested_form in a Rails 3.1 application. The problem is that when I click on the link generated by "link_to_add", it displays the partial twice, whereas it should display it just once. There you go some code:
Form:
<%= nested_form_for #product, :html => {:multipart => true} do |f| %>
<%= f.fields_for :safety_info_files %>
# adds a link for displaying the template
<%= f.link_to_add "Add file", :safety_info_files %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Template:
<div class="fields">
<%= f.link_to_remove "remove" %><br />
<%= f.label :doc, "File" %>
<%= f.file_field :doc %><br />
</div>
Did anybody else have the same problem?
EDIT:
Silly mistake, silly me. Sorry if I made some of you wasting time, the problem was that I was loading "nested_form.js" twice, so it called the function that appended the partial the same number of times.
Sorry again.

Silly mistake, silly me. Sorry if I made some of you wasting time, the problem was that I was loading "nested_form.js" twice, so it called the function that appended the partial the same number of times.

For those having this issue using rails 4 / turbolinks and not finding nested_form.js included twice, try removing turbolinks from application.js. Once I did this and bounced the server this issue was resolved.
Credit here: https://github.com/ryanb/nested_form/issues/307

I was facing same issue.
I had included nested_form.js in my application layout file.
And I haven't changed my app/assets/javascripts/application.js file, it is as it is, when it was created at time of creating rails application.
When I removed entry from my application layout, problem was solved.

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.

#Simple_form rendering but not showing

I just switched to rails and started on my first application. Im struggling a bit with the forms and bootstrap however!
It says my form is rendering and Im not receiving any errors, but none of my form code is showing.
Im running rails 4.2.5 with the latest bootstrap-sass and simple_form versions.
Im not sure whether my bootstrap css is actually working at all either, it doesnt appear to be. Been trying different versions, installing and uninstalling and changing the code for hours but canẗ seem to get it working. Would be immensely grateful for help!
Kind regards,
Jens
Form (_form.html.erb) code;
<%= simple_form_for #book, html: ({ cĺass:'form-horizontal'}) do |f| %>
<div class = "field">
<%= f.input :title, label: "Book Title" %>
<%= f.input :description %>
<%= f.input :author %>
<%= f.button :submit %>
<% end %>
I renamed my application.css to .scss, it now contains only;
#import "bootstrap-sprockets";
#import "bootstrap";
application.js contains:
//= require jquery
//= require jquery_ujs
//= require bootstrap-sprockets
//= require turbolinks
//= require_tree .
your code is a partial so where are you calling it from? It needs to be rendered inside of another file like index.html.erb.
Whenever the name starts with a _ it means its a partial not a full page, its to be rendered inside another page.
Also there's a div that doesn't end in your code but why even use a div for a class when you can pass that in through Rails ? class: "field" or something along those lines.
Try viewing the resulting html source and looking for one of the inputs to make sure that it's really getting rendered. If it is than the problem may be that you're missing a closing div for your <div class = "field">.
If not then I would suggest you take a look at your new.html.erb (or wherever your rendering your partial and making sure you have something like:
<%= render 'form' %>
Notice that the = is important here. If you're missing this it could be the cause of your issue.
#app/views/books/new.html.erb
<%= render "form", locals: { book: #book } %>
#app/views/books/_form.html.erb
<%= simple_form_for book, html: ({ cĺass:'form-horizontal'}) do |f| %>
<%= f.input :title, label: "Book Title" %>
<%= f.input :description %>
<%= f.input :author %>
<%= f.submit %>
<% end %>
The above should make sure you're outputting a valid form (HTML).
If you're still not seeing the form appear, it will likely be a CSS issue. The difference being that CSS gives styling definition to HTML.
As mention in other answers, the solution to this lies in the classes you're giving to your HTML elements. Since you're using bootstrap, it means you have to first ensure you have bootstrap installed and loaded.
You can use rails-assets to pull from the bootstrap repo directly:
#Gemfile
source "https://rails-assets.org"
source "https://rubygems.org"
gem 'rails-assets-bootstrap', ">= 4.0.0.alpha"
#app/assets/stylesheets/application.sass
#import bootstrap
--
If you wanted to test your HTML/CSS directly, you need to remove the class: "form-horizontal" class from your HTML. If this shows the form, it means your CSS is incorrect, in which case I'd recommend you post back on here with it.
Thanks a lot guys! I got it to work, I had simply forgotten the "=" before render! The other oddities were just last minute tired scrabbling in an attempt to make it work. :P Again, thanks a ton for your help guys!

uploading empty file goes to edit instead of new

I recently noticed that on my form, if I try to upload an empty file the page will get redirected to edit instead of create. If I try to upload the file with some text in it, the form will direct to create. I couldn't find any indication that this would happen as I create my object every time (it's never persisted). Is there an explanation behind this?
The code looks something like this:
//controller
def upload
#new_cool_file = CoolFile.new
end
//form in upload.html.erb
<%= form_for #new_cool_file, html: {role: "form"} do |f| %>
<div class="form-group">
<%= f.label :file %>
<%= f.file_field :file %>
</div>
<%= f.submit "Submit"%>
<% end %>
I think you do some wrong in the rails routes.rb file , can you please see tutorial about file upload.
https://richonrails.com/articles/allowing-file-uploads-with-carrierwave
http://railscasts.com/episodes/253-carrierwave-file-uploads

Trouble dynamically adding fields with 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 :-)

Rails turbolinks break submit remote form

I'm having a rather weird problem using Rails 4, Turbolinks and a remote form. I have a form looking like:
<%= form_for [object], remote: true do |f| %>
<td><%= f.text_field :name, class: 'form-control' %></td>
<td><%= f.email_field :email, class: 'form-control' %></td>
<td><%= f.submit button_name, class: 'btn btn-sm btn-primary' %></td>
<% end %>
This form adds (creates) a new object. It does however not always work:
When I load the page directly using the URL or a refresh; it works
When I navigate from my app to this page; it fails
When disabling Turbolinks for this link, the page worked perfectly.
I have two questions:
Why doesn't this work? Is this because the remote handlers aren't attached to the button because of a JQuery/Turbolinks problem?
How can I work around this problem?
Thanks in advance.
Solution
Thanks to #rich-peck, the solution was to add a piece of javascript that manually submits the form upon clicking the button:
<%= javascript_tag do %>
var id = "#<%= dom_id(f.object) %>";
var inputs = $(id).parent().find('input');
console.log(inputs);
$(id).parent().find('button').on('click', function(e) {
e.preventDefault();
$(id).append(inputs.clone());
$(id).submit();
});
<% end %>
This code adds javascript to the form table row, getting the inputs, appending them to the ID and submitting the form. The preventDefault(); prevents the query from getting sent twice when the page is refreshed and the form actually works.
Turbolinks
As mentioned, the problem with Turbolinks is that it reloads the <body> part of the DOM with an ajax call - meaning JS is not reloaded, as it's in the head
The typical way around this issue is to delegate your JS from the document, like this:
$(document).on("click", "#your_element", function() {
//your code here
});
Because document is always going to be present, it will trigger the JS continuously
Remote
With your issue, it's slightly more tricky
The problem is you're relying on the JQuery UJS (unobtrusive JavaScript) engine of Rails, which is difficult to remedy on its own
We've never had this issue & we use Turbolinks all the time - so I suppose the problem could be with how you're constructing your form / handling the request. This GitHub seemed to recreate the issue, and it was to do with the table
Maybe you could try:
<%= form_for [object], remote: true do |f| %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.submit button_name, class: 'btn btn-sm btn-primary' %>
<% end %>
Turbolinks don't fully reload your page, but only part of it. This is what makes them so fast, however if you have JavaScript requiring a full page reload you will run into trouble. The reason it does work with a refresh is because now you force the page to fully reload.
Edit: This gem might be worth trying out: https://github.com/kossnocorp/jquery.turbolinks
For a little bit of extra information about the inner workings of turbolinks: http://guides.rubyonrails.org/working_with_javascript_in_rails.html#turbolinks
Or: https://github.com/rails/turbolinks
P.s. Also make sure the javascript_include_tag is within the head tag (and not in the body)

Resources