Concatenating adjacent form fields into hidden field value in Rails - ruby-on-rails

I want to concatenate two form text field values and assign them to my hidden form field in a Rails view:
<%= f.hidden_field :shortcode, :value => :package :pins %><br />
<div class="field">
<%= f.label :package_type %><br />
<%= select("package", "package_type_id", PackageType.all.collect {|p| [p.packagetype, p.id]} ) %>
</div>
<div class="field">
<%= f.label :pins %><br />
<%= f.text_field :pins %>
</div>
I want :shortcode to return the concatenated values of the :package + :pins values entered into their respective form fields.
How do I do that?
Editing to show code used to implement this as the "answer":
$('#package_pins').blur(function() {
var combined = $('select#package_package_type_id option:selected').text() + $('#package_pins').val();
$('#package_shortcode').val(combined);
});
Added this code to my "packages.js" in app/assets/javascripts dir.
Note that because the package_type selector is pulling in a belongs_to record in the model, the select options get populated like so:
<select id=package_package_type_id name="package[package_type_id]">
<option value="551">FFG</option>
<option value="552">FFC</option>
<option value="553">FTA</option>
</select>
where what I wanted to grab from the "FFG" text, rather than the value "551", which is the record id from ActiveRecord, in this case. I was able to do this by using the option:selected').text() jquery code.
Thanks again to #maprihoda for pointing me in the right direction!

You need to write some client-side Javascript code for this. Using eg JQuery you can easily get the values of the package and pins fields (after the user fills in the pins field), concatenate them, and update the value of the hidden field.
Something roughly like this (you need to add the the right classes to the divs that wrap the fields for this to work):
$('selector for the pins field').blur(function() {
combined = $('selector for the package_type field').val() + $('selector for the pins field').val()
$('selector for the hidden field').val(combined)
})

Related

Rails editing form with selects

I've created a form in my Rails project with scaffold.
All the fields are strings or text, and some of them I've declared in the view as select fields, for example:
<div class="field">
<%= f.label :device %><br />
<%= f.select :device, options_for_select([["iPhone", "iPhone"], ["iPad", "iPad"], ["All", "All"]]) %>
</div>
Creating and viewing the elements there's no problem. But when I'm editing the fields, the loaded values in the form are the default, not the saved values.
How to solve it?
You are incorrectly using options_for_select, which returns HTML options text, when in fact the f.select call just wants the array.
This will work for you:
<div class="field">
<%= f.label :device %><br />
<%= f.select :device, [["iPhone", "iPhone"], ["iPad", "iPad"], ["All", "All"]] %>
</div>

RoR MongoDB Arrayfield usage

i'm new to MongoDB and unsure how to use the Array-Field-Type.
So i created in my model
field :admins, type: Array
in this field i wanna store all user_ids that are "admins" of the model. But when I try to set this field, it doesnt save the Information in the Array it just simple creates an String with the ID. And due to my constrain that only Admins can edit my filter function
def check_if_admin
unless Agency.find(params[:id]).admins.include?(current_agent.id)
flash[:notice] = "Only possible as Admin."
redirect_to root_path
end
end
gets the error that
"can't convert Moped::BSON::ObjectId into String"
So I tried to initiate my field with in the create def as an array with ID:
#agency.admins = [current_agent.id]
That does the Trick for one user in the Array but how do I add IDs to this field?
When I go into my Edit Form:
<%= form_for(#agency) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :admins %><br />
<%= f.text_field :admins %> <br />
</div>
<div class="field">
<%= f.label :agents %><br />
<%= f.text_field :agents %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And Type in another User_ID by hand, I'm back to my error again.
Anyone knows how to get around that?
Thanks a ton for ur help!
This message means that at some point you stored a string where there should be an ObjectId. Ruby is trying to compare current_agent.id (an ObjectId) with params[:id] (a string).
It seems like you are not converting the input from the text_field in the form to an ObjectID before you push it onto the array.
Take the input from the admins field and make ObjectId's like this:
BSON::ObjectId.new(string_representing_admin_id)
I'm guessing the admins field is a comma separated array of admin _ids and that you are using some _id values that are easy to work with, like a username instead of a generated ObjectId as this would be very burdensome to work with.
In that case you would probably split and strip the input and then make an array of the ObjectIds using a map/select.
It would be much easier to use a select field that displayed usernames for something like this in rails right?
Anyway, show some sample documents from the collection if you need more help.

How should I handle this Rails use case?

I have an Exercise model, which has these columns (pseudo Ruby):
model Exercise do
string :name
calories_burned :float
end
I want that when a user adds an exercise to be able to do it in this fashion:
if previous exercises exist
show a select element with names of existing added
show a checkbox to allow adding a new one, switching the input
field to a textfield
else
show a textfield
The thing is, I don't know how I should put this in my view. Here's how the else case is handled:
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
I have something like this now:
<div class="field">
<% if #exercise_added %>
<div id="select_div">
<%= select_tag :name,options_for_select(#exercise_added) %>
<input type="checkbox" name="custom_type_checked" id="which_type">New type?</input>
</div>
<% end %>
<div id="regular_field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
</div>
In #exercise_added I have a list of names of all exercises from the database. What would be the best/cleanest way of handling this?
EDIT: For now,I have a textfield and a select, and by using Javascript, I'm changing the name of the element ( and hiding the other one ). So far, it's working, but I'd still be interested if other approaches exist.
You can check if the array #exercise_added is empty or not and show the select field or text field accordingly.
<div class="field">
<% if !#exercise_added.empty? %>
<div id="select_div">
<%= select_tag :name,options_for_select(#exercise_added) %>
<input type="checkbox" name="custom_type_checked" id="which_type">New type?</input>
</div>
<% else %>
<div id="regular_field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<%end%>
</div>
I would, by default, have the select box and a button shown, with the textbox hidden unless a variable #show_textbox is true. Something like this:
<div class="field">
<div id="select_div">
<%= select_tag :name,options_for_select(#exercise_added) %>
<%= f.submit "New Exercise" %>
</div>
<div id="regular_field" <%= hidden_unless #show_textbox %> >
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
</div>
Where I've written a helper function
def hidden_unless cond
raw "style=\"display: none;\"" unless cond
end
# this one is helpful, too
def hidden_if cond
raw "style=\"display: none;\"" if cond
end
Then, in my controller, check if the "New Exercise" button was pressed. If so, essentially set #show_textbox to true and then re-render the new form.
def create
# .....
# did we get here because the user pressed "New Exercise"?
if params[:commit].eql?("New Exercise")
#show_textbox = true
# probably some other code to replicate what happens in your #new action
render :action => new
end
# ....
end
You can check in your controller if the :name field has any text in it, and use that to override the select box.
This should work without javascript. I'd add some jQuery to replace the button with either a link or a check box, with the click handler for that connected to a function that shows the textbox, i.e. $('#regular_field').toggle();.
I didn't deal with hiding the select box. I actually think it might be better to leave that available. You could hide it using a similar method, anyways.
What if you used two forms? One form to handle the case when the exercise is in #exercise_added, and a second form to handle the creation of a new exercise. It might even boil down to the difference between a POST and a PUT, depending on what you're doing once an exercise is submitted from the drop-down list.
I'd be curious to see more of the code, as well as the controller, since it seems like this form might be nested?

form multiple select

I am learning rails and have been struggling with this for over a day now and can not figure out how to get this to work. I want a select box in my form that can select multiple elements. I have this working with this code:
<div class="field">
<%= f.label :products %><br />
<%= f.select :products, {"A"=>1, "B"=>2, "C"=>3, "D"=>4},{},:size=>5,:multiple=>true %>
</div>
This works fine and produces this HTML:
<div class="field">
<label for="script_products">Products</label><br />
<select id="script_products" multiple="multiple" name="script[products][]" size="5">
<option value="1">A</option>
<option value="2">B</option>
<option value="3">C</option>
<option value="4">D</option></select>
</div>
What I can figure out is how the results get sent/stored. In my view for the "show" action, if I simply print out :products I get this:
Products: --- - '1' - '2' - '3'
If I print out :products.inspect I get this:
Products: "---\n- '1'\n- '2'\n- '3'\n"
and the class is a string. I would think it would be stored as an array, but I can not get it to work. I don't know where the dashes or the newlines come from.
I would consider adding the options as a has-many relationship on the model. Thus you can iterate through them, attach them and involve them in a multiple select in a (IMO) better way.
I would do something like in my model:
has_many :special_options
In my view:
f.select :special_options, :multiple => true
This would avoid the problem of having to serialize and deserialize the objects before storing them.

Ruby on Rails: Submitting a form referring to another controller via collection_select

Today is the first day I'm looking into Ruby on Rails, and now I'm stuck. I have two scaffolds, artist and song.
In songs/new.html.erb, I have these lines:
...
<%= f.label :name %><br />
<%= f.text_field :name %>
...
<%= f.label :Artist %>
<%= collection_select(:song, :Artist, #artists, :id, :sort_name) %>
...
In the form for creating a new song, I want a <select> list with all artists. Using the code above works fine. The form is created as I want it, and the artists are listed. However, when submitting the new song, I get this error:
Artist(#69916999335860) expected, got String(#69917057438720)
The generated HTML code for the select looks like this:
<select id="song_Artist" name="song[Artist]">
<option value="1">Vreeswijk, Cornelis</option>
<option value="2">De lyckliga kompisarna</option>
<option value="3">Wiehe, Mikael</option>
<option value="4">Demian, Lars</option>
<option value="5">Sundström, Stefan</option>
</select>
I guess the second last parameter for collection_select() is wrong, but what should it be?
I think this should be:
<%= collection_select(:song, :artist_id, #artists, :id, :sort_name) %>
The second parameter is the method to be assigned in the model being created/updated. So in your controller the value would be retrieved from the params hash with params[:song][:artist_id]
A detailed explanation can be found in the Rails API docs under "collection_select"

Resources