On a model, I have attr_accessor: :email_settings.
In a view, I have:
<%= form_for some_model do |f| %>
<%= f.fields_for :email_settings do |email_settings| %>
<%= email_settings.label :general, _("General updates") %>
<%= email_settings.check_box :general %>
General site updates
<% end %>
<% end %>
But in the HTML, this does not create one input for some_model[email_settings][general], it creates two. One hidden and one a checkbox:
<label for="user_email_settings_general">General updates</label>
<input name="user[email_settings][general]" type="hidden" value="0">
<input id="user_email_settings_general" name="user[email_settings][general]" type="checkbox" value="1">
General site updates
What's going on here? Why is there a hidden input and a checkbox for the same value, when I only want a checkbox?
Also in the controller action that the form is submitted to, I do this:
def update
puts "email_params: #{email_params}"
end
def email_params
params.require(:user).permit(:email_settings)
end
Which outputs:
Unpermitted parameters: email_settings
email_params: {}
Not sure how email_settings is being interpreted as "unpermitted" when I'm explicitly permitting it.
From the browser should always send a response.
If you do not select the box, will send the hidden field to understand that something has been sent.
In this way the rails will always receive an indication that the box was selected or not.
similar answer is here: Why does the check_box form helper generate two checkboxes, one hidden?
Related
I have a list of commentable models in my Rails view, represented by cards that each have their own comment form. The forms are identical (from the same partial), and have a rich_text_area for the commentable's body (defined as has_rich_text :body on the model, per the docs). It is close to the following (simplified) example:
<% #assignables.each do |assignables| %>
<!-- omitted code displaying the assignable object -->
<!-- ADD COMMENT FORM -->
<%= form_with model: Comment.new do |form| %>
<div class="">
<%= form.hidden_field :commentable_id, value: assignable.id %>
<%= form.hidden_field :commentable_type, value: assignable.class.name %>
<%= form.rich_text_area :body, data: { controller: "mentions" } %>
<%= form.submit "Submit", class: "button button-primary" %>
</div>
<% end %>
<% end %>
Only the first form on the page (in DOM order) actually submits a body parameter. Network requests from any other form shows a blank comment[body] parameter. Additionally, if I add text to the 2nd form's input, then go back and submit the first form without touching it, the submission includes the input I entered into the 2nd form.
From this, I understand I need to override some attribute which is supposed to be unique. I've scoured the Rails docs and the Trix docs, but I haven't found anything which indicates how to make Rails do this override such that Trix accepts it.
What attribute do I override, and how?
Turns out, the answer is simple: override the id attribute of the rich text area to include a unique value like a primary key, and Rails handles the rest.
E.g.:
<%= form.rich_text_area :body, data: { controller: "mentions" },
id: "commentable_#{commentable.id}_comment" %>
Translates to:
<form …>
<input id="commentable_1_comment" value="Editor content goes here" type="hidden" name="content">
<trix-editor input="commentable_1_comment"></trix-editor>
</form>
Now every instance of the text area has a unique ID (rather than the generic new_comment) and the hidden inputs all submit their values correctly.
For reference: The Trix documentation show what the HTML is supposed to look like at the after ERB is done with it, but the Rails rich_text_area docs don't indicate anything about attributes you might want to override.
I am trying to make a form where you select tables that you want to export. I made a simple form with a list of tables that can be exported. My plan was to allow the user to toggle check boxes for the tables they want to export and as a result they would be able to download a zip file containing the tables.
Currently, when I try to go to the page with the form, I get an error:
undefined method 'model_name' for nil:NilClass
The majority of the usage of simple forms that I see online consists of using forms to create new items to save in their models. As a result, it seems that the line simple_form_for #example would mean that when the user clicks the submit button, there is a line in the controller such as #example = SomeClass.new". My understanding is that the user input of the form is saved in #example and can be used by the controller. However, as I am not creating a new item in the model, I just want to use the values from #example, I am not sure what to put in the controller to get rid of the error so that I can code the rest of the function in the controller.
Controller:
class FormController < ApplicationController
def index
#options = []
print(#options)
end
end
The form used:
<h2>Which tables do you want to export?</h2>
<div class="well">
<% tables_in_model = %w(Table1 Table2 Table3) %>
<%= simple_form_for #selected_options, :url => form_index_path, :method => :get do |f| %>
<%= f.input :options, as: :check_boxes, collection: tables_in_model %>
<%= f.button :submit, as: :Submit %>
<% end %>
</div>
As you said correctly in your question, simple_form should be used to render forms to the user when her actions are related to the creation or edition of ActiveRecord models.
For instance, when writing down code to enable a search feature, where your goal is to simply pass a bunch of user chosen params to a controller, you should not use it. I believe you are in a similar position with the feature you described.
Simple solution though: use rails form related DSL to get your form going!
Hope it's the answer you needed. Feel free to ask for more details if needed. Cheers!
i think you are using simple_form you need to specify like
#selected_options = SelectedOptionModel.new(params)
into your controller
then it passes into View.
if you don't have any model you can use form_tag
like this:
<%= form_tag("/search", method: "get") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
<% end %>
this will create html form like this:
<form accept-charset="UTF-8" action="/search" method="get">
<input name="utf8" type="hidden" value="✓" />
<label for="q">Search for:</label>
<input id="q" name="q" type="text" />
<input name="commit" type="submit" value="Search" />
</form>
I'm using a submit_tag form helper in one of my apps. The value of this submit button should change dynamically. The two possible values for this submit button are Save and Update. So, in the view, I have done something like the following:
<% temp = 0 %>
<% text = '' %>
<% temp = ActivityLog.find_by_sql("SELECT COUNT(id) AS cnt FROM logs WHERE id > 0")%>
<% text = temp[0][:count].to_i > 0 ? 'Update' : 'Save' %>
<!-- other html contents -->
<%= submit_tag text, :id=>"submitBtn"+i.to_s, :onclick=>"submit_button_clicked(this)"%>
Now, when I run the view inside a browser, I can see the desired effect. But the rails controller receives the erroneous value for the commit options in the params hash.
For instance, when the value of text is evaluated to Save, I get the following in the Firebug:
<input type="submit" value="Save" style="" onclick="submit_button_clicked(this)" name="commit" id="submitBtn3">
But raise params.inspect in the associated controller shows the follwing:
{"commit"=>"Update",
"authenticity_token"=>"",
"time"=>{"292"=>"3.0",
"2"=>"1.0",
"456"=>"4.0"},
"date"=>"2011-09-20"}
See, although the value of the Submit button is shown as Save in the HTML, the rails controller shows the value of commit as Update. What's wrong in here?
If you are using Rails helpers, it provides a simple way to choose text on button with according to type of form:
<%= form_for #activity do |f| %>
<%= f.label :title %>:
<%= f.text_field :title %><br />
<%= f.submit %>
<% end %>
When no value is given, it checks if the object is a new resource or not to create the proper label. In the example above, if #activity is a new record, it will use "Create Activity" as submit button label, otherwise, it uses "Update Activity".
P.S. please do not use SQL in your views
I have the following select box that was created using nested form:
<select name="product[shop_attributes][id]" id="product_shop_attributes_id">
<option value="23">KMART</option>
<option value="24">Super Shop</option>
<option selected="selected" value="22">TARGET</option>
<option value="new">Create New Shop</option>
</select>
selected="selected" was created by passing :selected => "22" to f.select options.
The problem is that no matter what option is selected, the submitted value is always "22".
I noticed that a hidden input is created, which I believe causes the problem:
<input type="hidden" value="22" name="product[shop_attributes][id]" id="product_shop_attributes_id">
Thus, there are 2 elements with id=product_shop_attributes_id.
What could cause to this hidden input field to be generated ?
Relevant code of select box creation:
<%= form_for #product do |f| %>
<%= f.fields_for :shop do |sf| %>
sf.select(:id, <options>, {:prompt => true, :selected => <default_value>})
<% end %>
<% end %>
Relevant controller code:
def edit
#product = Product.find(params[:id]) # the select box indeed gets it's initial value from #product
end
def update
#temp = params.inspect
end
update.html.erb:
<%= #temp %>
I see here always the same (no matter what option is selected):
"product"=>{"shop_attributes"=>{"id"=>"22"},...}
There's nothing wrong with the rails generated HTML. It's probably the way you're accessing it in your controller. Could you post the original rails code that generated this HTML and the code you are using to process it?
The problem is, as I mentioned in the question, the hidden input field with the same id as the select.
I opened a separate question to investigate why this happens.
I have a Campaign model which I want the user to be able to check off and on a checkbox for each state, which I want to store in an array in one the fields, like ["CA", "NY", "OH", "FL"].
I'm not sure if serialized is the correct terminology here. I have some form fields generated like so:
<% State::NAMES.each do |state| %>
<%= check_box("states_allowed", state[1], :checked => true) %>
<label for="states_allowed_<%= state[1] %>"><%= state[0] %></label>
<% end %>
In which State::NAMES, is just an array of state names and abbreviations.
So this gives me the HTML of:
...
<input type="hidden" value="0" name="states_allowed[NE]"><input type="checkbox" value="1" name="states_allowed[NE]" id="states_allowed_NE">
<label for="states_allowed_NE">Nebraska</label>
...
But how can I save the check fields? The column content stays null and I don't receive an error.
Something I have tried is putting serialize :states_allowed in my Campaign model, but no luck.
I add the same problem today, it appears the form isn't properly built in the view.
I simply added at the beginning of my create action:
params[:campaign][:states_allowed] = params[:states_allowed]
And it works properly