Check_box_tag input id - html

I have a check_box_tag that looks like this :
check_box_tag('shipping_method[shipping_categories][]', category.id,
#shipping_method.shipping_categories.include?(category))
When inspecting the output in browser, I have the following :
<input id="shipping_method_shipping_categories_"
name="shipping_method[shipping_categories][]" type="checkbox" value="1" />
I don't get why the id has no "id", meaning that the underscore at the end of
id="shipping_method_shipping_categories_"
makes me expect an id for this particular shipping_category.
Any of you guys and gals have thoughts on this ?
Thanks !

I don't get why the id has no "id", meaning that the underscore at the
end of id="shipping_method_shipping_categories_" makes me expect an id
for this particular shipping_category.
That is the default behavior of the check_box_tag. In other words it is constructed that way. When you look upon the code of how it is constructed, you will see the below
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 374
def check_box_tag(name, value = "1", checked = false, options = {})
html_options = { "type" => "checkbox", "name" => name, "id" => sanitize_to_id(name), "value" => value }.update(options.stringify_keys)
html_options["checked"] = "checked" if checked
tag :input, html_options
end
So, the "id" is constructed with the method sanitize_to_id(name). So I've further looked upon sanitize_to_id(name) to see its code and I've found this
def sanitize_to_id(name)
name.to_s.delete("]").tr("^-a-zA-Z0-9:.", "_")
end
So, shipping_method[shipping_categories][].to_s.delete("]").tr("^-a-zA-Z0-9:.", "_") returns shipping_method_shipping_categories_. That explains its behavior.
If you want to achieve what you are expecting, I recommend you to go with collection_check_boxes
For example,
collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial)
returns
<input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" checked="checked" />

Related

How do I validate a checkbox array in laravel?

I've been trying to validate all 10 checkbox array items but I cannot seem to find or understand how to use Laravels validator to validate a checkbox array.
The below code is my array HTML.
<div id="CLAagree" style="display: none;">
<div class="form-group form-check">
<div class="col-sm-2">
<div class="checkbox checkbox-green ck-button">
<input type="checkbox" class="form-check-input" oninput="this.className = ''" name="claAgree[]" id="CLAagreeCB1" onclick="saveOnboard()" >
</div>
</div>
</div>
I have tried to get all info that I can about this but I just can't seem to understand arrays in validation for some reason.
I know adding "required" made the inputs required but I have 10 so at least one will be required but I need 10 to be required. Does anyone have any options? I'm just lost at this point lol
$rules = array(
"claAgree" => "required",
"claAgree.*" => "required",
);
$validation = Validator::make($request->all(),$rules);
if($validation->fails()) return back()->with('error',$validation->messages()->first());
Here is a link to show how the array is posted
You can do like that ,check you request array name (claAgree.*.claAgree) ,
then define the input value , if same then you can use same like that
$rules = array(
"claAgree" => "required",
"claAgree.*.claAgree" => "required",
);
$validation = Validator::make($request->all(),$rules);
if($validation->fails()) return back()->with('error',$validation->messages()->first());

How do I submit more than one checkbox in an HTML form?

This is a project for school, and so far I only know Ruby, Sinatra, HTML & CSS. I've looked online but only came across PHP and Javascript insturctions (which I'm not supposed to use yet).
I have a form for checkboxes, and although I can check off more than one, only one of the checkbox values gets posted. How do I get it so all of the checked off ones are passed?
Also, 'abbreviation' comes out nil for each state. Am I doing this wrong in my form? And if anything it just uses ONE of the abbreviations and adds it to every state. Finally, how do I make it so the checkboxes remain checked for the states users have already added in the past?
Here's some code:
<form method="POST" action="/states">
<h3>Northeast:</h3> <br>
<input type="checkbox" name="state_name" value="Connecticut" name="abbreviation" value="CT"> Connecticut<br>
<input type="checkbox" name="state_name" value="Deleware" name="abbreviation" value="DE"> Deleware <br>
<input type="checkbox" name="state_name" value="Maine" name="abbreviation" value="ME"> Maine<br>
<input type="checkbox" name="state_name" value="Maryland" name="abbreviation" value="MD"> Maryland<br>
require 'pry'
class StatesController < ApplicationController
get '/states' do
if logged_in?
#user = current_user
#states = current_user.states
erb :'states/states'
else
redirect to '/login'
end
end
get '/states/new' do
if logged_in?
erb :'/states/create'
else
redirect to '/login'
end
end
post '/states' do
if logged_in? && params[:state_name] != ""
#state = State.create(:state_name => params[:state_name], :abbreviation => params[:abbreviation])
# binding.pry
#state.users << current_user
if #state.errors.any?
"Error, try again"
else
redirect "/states"
end
else
redirect to "/states/new"
end
end
get '/states/:id' do
if logged_in?
#state = State.find_by_id(params[:id])
if #state != nil
erb :'/states/show'
else
redirect to '/states'
end
else
redirect to '/login'
end
end
get '/states/:id/edit' do
if logged_in?
#state = State.find_by_id(params[:id])
if #state && current_user
erb :'states/edit'
else
redirect to '/states'
end
else
redirect to '/login'
end
end
patch '/states/:id' do
#state = State.find_by_id(params[:id])
if params[:state_name] != "" && #state.update(:state_name => params[:state][:state_name])
#state.update(:state_name => params[:state][:state_name])
redirect to "/states/#{#state.id}"
else
redirect to "/states/#{#state.id}/edit"
end
end
delete '/states/:id/delete' do
if logged_in?
#state = State.find_by_id(params[:id])
if #state && current_user
#state.destroy
end
redirect to '/states'
else
redirect to '/login'
end
end
end
You need to append [] to your name attribute to support array value i.e. more than one checked values:
<input type="checkbox" name="state_name[]" value="Connecticut"> Connecticut<br>
<input type="checkbox" name="state_name[]" value="Deleware"> Deleware<br>
<input type="checkbox" name="state_name[]" value="Maine"> Maine<br>
<input type="checkbox" name="state_name[]" value="Maryland"> Maryland<br>
Now on your server, you will see the checked values as state_name: ['Connecticut', 'Maine', ...].
Note: You have specified the name and value attributes twice for each checkbox. I am using the first one.
I have always known that in html's forms the ids and names must be unique, unless you are working with radio buttons or in this case checkboxes. Your code seems to be a bit overmade, meaning, you have 2 names and 2 values on each checkbox, and just the last one of both of them will work, so instead of this:
<input type="checkbox" name="state_name" value="Connecticut" name="abbreviation" value="CT"> Connecticut<br>
Try just having one of those attributes:
<input type="checkbox" name="abbreviation" value="CT"> Connecticut<br />
Usually, in for php we would append a '[]' at the end of the name, and you will recieve an array of the values that were checked. But since you are using ruby, which I am a bit familiar to, I've seen the ruby developers like to be a bit more expressive in their code, and sometimes they do things like this:
<input type="checkbox" name="abbreviation[city_1]" value="CT">Connecticut<br />
<input type="checkbox" name="abbreviation[city_2]" value="DE">Delaware<br />
And so on.
You can see an example of it, here, even though I believe you can do it with the empty '[]', but just so you know I've been told that's the php-ish way to do it.
Cheers!
Use only one name and value per input, like:
<input type="checkbox" name="state_name" value="CT"> Connecticut<br><input type="checkbox" name="state_name" value="DE"> Deleware <br><input type="checkbox" name="state_name" value="ME"> Maine<br><input type="checkbox" name="state_name" value="MD"> Maryland
Check your POST array for state_name and their should be an array of all check-boxes selected.

HTML Form: POST an array of objects

Submitting a class roster. Adding 3 students at once. Each student has first, last, age.
Question: How can we get all of the students in an array of arrays?
students[0] => Array (
["first"] => "first name for 0",
["last"] => "last name for 0",
["age"] => "age for 0"
),
students[1] => Array (
["first"] => "first name for 1",
["last"] => "last name for 1",
["age"] => "age for 1"
),
...
Details
For one student:
<input type="text" name="first">
<input type="text" name="last">
<input type="text" name="age">
We can return multiple students in separate arrays like this:
<input type="text" name="students[first][]">
<input type="text" name="students[last][]">
<input type="text" name="students[age][]">
which returns an array of firsts, lasts and ages
students["first"] = [array of first names]
students["last"] = [array of last names]
students["age"] = [array of ages]
Theoretically we can get all the info for a student by accessing the same index (say "3" for each array).
We do not want to programatically add an index in the form.
Do not want:
<input type="text" name="students[hardcoded_index][first]">
<input type="text" name="students[hardcoded_index][last]">
<input type="text" name="students[hardcoded_index][age]">
If for any reason it matters, we are using Rails for views but can use form helpers or HTML.
tl;dr: Add empty brackets ([]) after students to the input names.
Fiddling with Rack::Utils.parse_nested_query it seems you can get the payload you want like this:
<!-- first student -->
<input type="text" name="students[][first]">
<input type="text" name="students[][last]">
<input type="text" name="students[][age]">
<!-- second student -->
<input type="text" name="students[][first]">
<input type="text" name="students[][last]">
<input type="text" name="students[][age]">
Note the empty brackets ([]) after students. This tells Rack you want the students param to be an array. Subsequent params encountered (with the same name) will start a new element.
POST /myroute?students[][first]=foo&students[][last]=bar&students[][age]=21&students[][first]=baz&students[][last]=qux&students[][age]=19
Gets parsed like this:
{"students" => [
{
"first" => "foo",
"last" => "bar",
"age" => "21"
},
{
"first" => "baz",
"last" => "qux",
"age" => "19"
}
]}
Further reading: http://codefol.io/posts/How-Does-Rack-Parse-Query-Params-With-parse-nested-query
I know the question is old , but I would like to add my experiences
also for future readers.
For those of you who want to process the data in a PHP enviroment ,
#messanjah's method won't work ,
The methods for parsing data like the built-in serializeArray or serialize are not parsing it as expected either.
This is what I tried so far ...
students[name]
students[][name] - Very Strange since it was meant to automatically index the array
students[name][]
Neither of them worked, but this students[<hardcoded-index>][name] worked for PHP ,
I know that although the question is against this method , but it
will be useful for PHP users who will land here in the nearby future
as the asker needed it for Ruby On Rails.
The method you choose to hard code the indexes is upto you , you can use a cleaner method by using javascript or you can manually hard code them initially in your form element.
Cheers

Sinatra: wrong number of arguments (4 for 0..2)

I'm currently developing an app with Sinatra, ActiveRecord and MySQL. I'm working on the sign up form, which looks like this:
app.rb:
post '/signup' do
password_salt = BCrypt::Engine.generate_salt
password_hash = BCrypt::Engine.hash_secret(params[:password], password_salt)
#usuarios = User.new(params[:nombre], params[:cedula], password_hash, "admin")
if #usuarios.save
redirect './signup', :notice => "Usuario creado exitosamente."
else
redirect './signup', :error => "Ha ocurrido un error, intente nuevamente."
end
end
And the view looks like this, signup.erb:
<form id="registro" action="/signup" method="POST">
<fieldset>
<legend>Ingrese sus datos</legend>
<label>Nombre
<input type="text" name="nombre">
</label>
<label>Cédula
<input type="text" maxlength="10" name="cedula">
</label>
<label>Contraseña
<input type="password" name="password">
</label>
<!-- TO-DO:
Dropdown list con los diferentes tipos de usuarios, i.e.: admin, secretario, etc.
-->
<input type="submit" id="registerButton" class="button small">Finalizar registro</a>
</fieldset>
</form>
Whenever I try to create a new user, I get the following error:
ArgumentError - wrong number of arguments (4 for 0..2)
Considering that the table I'm trying to insert the values has 4 columns, I don't understand why I'm getting this error.
Any insight to help me solve this inconvenience would be greatly appreciated!
Thanks in advance.
ActiveRecord::new method allows only 2 parameters as arguments, it should be a hash. fix:
User.new(params[:nombre], params[:cedula], password_hash, "admin")
to:
User.new(nombre: params[:nombre], cedula: params[:cedula], password: password_hash, role: "admin")
You should always check the documentation, in 99% cases you can find a problem:
New objects can be instantiated as either empty (pass no construction
parameter) or pre-set with attributes but not yet saved (pass a hash
with key names matching the associated table column names). In both
instances, valid attribute keys are determined by the column names of
the associated table – hence you can’t have attributes that aren’t
part of the table columns.
new(attributes = nil, options = {})
Examples:
# Instantiates a single new object
User.new(:first_name => 'Jamie')
# Instantiates a single new object using the :admin mass-assignment security role
User.new({ :first_name => 'Jamie', :is_admin => true }, :as => :admin)
# Instantiates a single new object bypassing mass-assignment security
User.new({ :first_name => 'Jamie', :is_admin => true }, :without_protection => true)

Ruby on rails password field and text field alignment

I am new to ruby on rails platform. I am designing a form with text fields. In the beginning, I created a simple html file with css to align the text fields. Below is my css
#input{
padding-left:50px;
padding-bottom:30px;
}
I created text fields using following code:
<div id = "input"><input type = "text" size = "25" name = "fname" value = "first name"></input></div>
<div id = "input"><input type = "text" size = "25" name = "lname" value = "last name"></input></div>
When I ran the web page, I saw the text field aligned properly the way I wanted inside form. However I tried to convert the code in RoR, I am not able to see padding. Below is my code in RoR
<div class="input"><%= f.text_field :fname, :size => 25, :placeholder => 'first name' %></div>
<div class="input"><%= f.text_field :lname, :size => 25, :placeholder => 'last name' %></div>
Can anyone tell me what might be the issue with my approach?
In the css code #input{..} the hash # means that it is looking for an id. After you have changed the code, you set it to class="input". Therefore the css can't find it by id. Change the css to .input{..}.