Rails form_for is engulfing entire new.html - ruby-on-rails

I'm trying to place a bootstrap modal to create a model inside another model's new page. The html follows:
new.html:
<div class="page-header">
<h1>Novo Parceiro</h1>
</div>
<%= render :partial => 'form' %>
<%= render :partial => "/contatos/form" %>
_form.html:
<%= form_for #parceiro, :html => { :class => "ketchup" } do |f| %>
(fields and submit here...)
<% end %>
<script type="text/javascript">
// some javascript here OUTSIDE the form
</script>
But what happens when the page is loaded is that everything inside new.html, including the partial "/contatos/form" which is an ajax-able form for another model, is being rendered inside the tag for #parceiro.
Why does Rails do this, and how do I keep my second form outside the first? As it is, I can't use AJAX because nested forms don't work very well (in fact it's wrong even for the html specifications)
[EDIT]: Issue solved, I had a div in the first form with a self closing tag (), so I changed that to a regular closing tag and it now works.

Related

Rails send email via pop up

I have created a form, which has a field which onclick() leads to opening up of a pop up (Invite Importer).
In this pop up, the customer has to input certain information and when it is inputted, I want all the information to be saved and email to be triggered with the inputted email. All this should happen when I click on submit (shown in below image as "Speichern").
How would I do it?
I have thought about creating 2 forms. One popup and the other base, but the submit button would lead to both of them being submitted.
how do you i save and submit email with pop up without the other form being submitted.
Make sure the html for the second form is not inside the main form. That will cause issues. You also probably want the modal form to be remote: true so that it will be submitted via AJAX. Instead of:
<%= form_for #model do |form| %>
...
<%= form.text_field :foo, onclick: 'openEmailModal()' %>
<div class="modal etc" id="email-modal">
<%= form_for #email do |form2| %>
...
<% end %>
</div>
<% end %>
You will have:
<%= form_for #model do |form| %>
...
<%= form.text_field :foo, onclick: 'openEmailModal()' %>
<% end %>
<div class="modal hide etc" id="email-modal">
<%= form_for #email, remote: true do |form| %>
...
<% end %>
</div>
In your views you can create a file named create.js.erb for example that would do something like:
closeEmailModal(); // this is just straight javascript
$('#notices').html("<%= escape_javascript(render 'my_partial') %>"); // reuse html your partials in JS
$('#notices').html("<%= j(render 'my_partial') %>"); // or use j (it's an alias for escape_javascript)
alert('I did stuff!');

Passing form to partial with remote true update - Rails

I'm using Rails 5.2.2. I have a form with remote: true. I have a partial that displays shipping methods where I render nested shipping methods available for a quote. My form accepts nested attributes also.
My form works fine, but on update I am wanting to render the updated shipping methods if they have changed but since I pass the original form to my partial, I don't have that variable available on update. Here is my partial
_shipping_rates.html.erb
<h2> Shipping Rates</h2>
<div id="quote-shipping-rates">
<%= form.collection_radio_buttons(:shipping_method_id, quote.shipping_methods.sort_by(&:price), :id, :name, { checked: quote.shipping_method_id }) do |b| %>
<%= b.radio_button %>
<%= b.label %>
(<span class="text-red"><%= number_to_currency(b.object.price) %></span>)
<br />
<% end %>
On the initial page load I call the partial like this:
<%= render 'shipping_methods', :form => u , :quote => #quote %>
On update, I have the following file that executes JavaScript to update the DOM.
update.js.erb
I want to do something like this but I wasn't sure if there was some Rails way to recreate the form variable and pass it to the partial.
$("#quote-shipping-rates").html("");
$("<%= escape_javascript(render :partial => "shipping_methods", :form => u , :quote => #quote) %>").appendTo("#quote-shipping-rates");

form_for was put inside fields_for

I'm having a problem with form_for and fields_for.
So, my problem is:
I had a form_for, and inside this form_for, I use a fields_for. Inside this fields_for, I use a form_tag (i used ajax for this form_tag).
But when I view the generated HTML, it didn't display form_tag, it only display form_for. And I didn't understand why.
Please explain for me, why it didn't display form_tag.
Here is my form_for:
<div class="row">
<%= form_for #real_estate, url: admin_real_estate_update_path do |f| %>
<%= f.fields_for(:client) do |client| %>
<%= text_field :real_estate, :assessment_start_at, value: #real_estate.assessment_start_at %>
<%= render partial: "admin/real_estate/form/assessment", locals: {real_estate_id: #real_estate.id} %>
<% end %>
<%= f.submit "Submut", class: "btn btn-primary"%>
<% end %>
</div>
Here is my form_for which i put inside fields_for:
<%= form_tag admin_search_assessment_path(real_estate_id), method: :post, remote: true do %>
<%= text_field_tag :company_name, params[:company_name] %>
<%= submit_tag "Submit" %>
<% end %>
And i tried to add <form></form> follow as:
<div class="row">
<%= form_for #real_estate, url: admin_real_estate_update_path do |f| %>
<form></form>
<%= f.fields_for(:client) do |client| %>
<%= text_field :real_estate, :assessment_start_at, value: #real_estate.assessment_start_at %>
<%= render partial: "admin/real_estate/form/assessment", locals: {real_estate_id: #real_estate.id} %>
<% end %>
<%= f.submit "Submut", class: "btn btn-primary"%>
<% end %>
</div>
And form_tag was display, but form_for didn't display.
Update:
So, i used $("form_2").submit(function() {....}); to solve this problem.
Actually, i still want to use form-nested.
Inside this fields_for, I use a form_tag (i used ajax for this form_tag)
N'est pas possible, mon ami.
--
Here's how it works...
form_for and form_tag both generate pure HTML forms:
<form action="/action" method="POST">
</form>
Many people get confused about how Rails works - it's really quite simple. Rails employs "helper" methods to generate pure HTML which your browser can read.
Browsers only understand HTML/CSS at the moment. Thus, whenever you send a request to Rails - it has to return that data, otherwise a "web page" simply wouldn't be able to be processed.
Thus, when you ask whether you can nest forms, you have to abide by how the forms work in pure HTML (spec):
Note you are not allowed to nest FORM elements!
HTML fill-out forms can be used for questionaires, hotel reservations,
order forms, data entry and a wide variety of other applications. The
form is specified as part of an HTML document. The user fills in the
form and then submits it. The user agent then sends the form's
contents as designated by the FORM element. Typically, this is to an
HTTP server, but you can also email form contents for asynchronous
processing.
In short, it means that everything within a <form> tag is counted as a form by HTTP. This means that if you have another <form> tag, it's going to cause an error, preventing either from working.
You know this already (otherwise you wouldn't have mentioned ajax).
Your main problem is the use of <form></form> inside your current <form> object. This will confuse HTML profusely, and thus I would recommend replicating the submission of a form, without the <form> object itself:
#app/views/admin/real_estate/form/assessment.html.erb
<%= text_field_tag "[company_name]", params[:company_name], id: real_estate_id %>
<%= button_tag "Submit", type: "button" , data: { id: real_estate_id } %>
#app/assets/javascripts/application.js
$(document).on("click", "button", function(e){
e.preventDefault();
var real_estate_id = $(this).data("id");
$.ajax({
url: "path/to/real/estate/form/assessment/" + $(this).data("id")),
data: {company_name: $("input[type=text]#" + real_estate_id).val()}
success: function(data) {
//do something on success
},
error: function(data) {
//do something on error
}
});
});
This code will still output what you need.
The difference will be two-fold:
The user will experience the same functionality (the input will still be present)
The embedded form will be passed to the main "form" submit, but will not be passed through your strong params method (making it
invisible to your controller)
In effect, you're replicating the functionality of an HTML form through Ajax. Whilst I still wouldn't do it this way, it will give you the functionality you require.

Ruby on Rails pass reference to yield (template)

To make long story short: each of my tabs has its own form, so I decided to make a single layout and just to have a forms themselves as a variable content for a layout.
But I need to have form_for to be in a layout, rather then having it in each of the forms, because I have some other common form elements in the layout.
So how can I pass the form builder's reference f to the template ?
Layout code:
<% content_for(:content) do %>
<%= form_for current_form do |f| %>
<%= yield %>
<%= f.submit "Submit" %>
<% end %>
<% end %>
Is it possible ?
P.S Found this one: DRYing up a helper: wrap form_for and access local form variable (#rubish's answer), but <%= yield f %> doesn't seem to be working, f still remains undefined for the view.
Why don't you make a common template (not layout) for the tabs, and use a partial template for the content of each tab?
Then you can do something like:
<%= render :partial => #tab_name, :locals => {:form => f} %>
You can render a template in Rails that accepts a block by using the layout option of render
Let's say you have a form that you render a few times but you would like to customize your submit section each time. You can achieve this by rendering your form partial as layout and passing in a block. Your template or partial then serves as the surrounding layout of the block that you pass in. You can then yield back the form to the block and access the form in your block.
record/_form.haml
= form_for record do |form|
...
.form-actions
yield(form)
In order to make your template record/_form.haml accept a block when you render it, you can render your template as the layout for your block using the layout option of render:
record/edit.haml
= render layout: 'form', locals: { record: record, ... } do |form|
.form-actions--primary
= form.button :submit

Best way to reload parts of a form

I want to reload a part of a form generated with the form_for-helper via AJAX.
After reloading the part I still want to have access to the form object.
How can I do this?
Best regards
I am not sure if your are using different terminology than I've heard, but what do you mean "still want to have access to the form object"?
Do you mean access to it in JavaScript? That should still work as long as you don't overwrite the form tags.
Do you mean in the html.erb code generating the partial? That doesn't really make sense, because that form_for object has already generated its html tags and gone out of scope. You need to use to the regular form of the helpers that takes the name of the object as the first parameter. There is no problem with this working with the tags generated by the form_for version of the helpers.
So, in your main page:
<%= form_for :person, #person, :url => { :action => "create" } do |f| %>
<%= f.text_field :name %>
<div id="reloadable">
</div>
<% end %>
And in your partial that fills that div:
<%= text_field :person, :name %>
No step 3.

Resources