I have the following in my model:
PRODUCTSTATES = %w[published coming_soon in_development cancelled]
I'm using that to populate a drop-down in a form, and I'm trying to use humanize to make the list look pretty, but can't seem to get it.
<%= f.select :status, Product::PRODUCTSTATES %>
Product::PRODUCTSTATES.humanize obviously doesn't work, nor does converting to a string before hand.
You can pass an array like
[['caption1', 'value1'], ['caption2', 'value2']]
to select helper and it'll generate smth like
<select>
<option value="value1">caption1</option>
<option value="value2">caption2</option>
</select>
In your case you can do like that:
<%= f.select :status, Product::PRODUCTSTATES.map { |s| [s.humanize, s] } %>
You'll get humanized versions of the statuses displayed on the page and the original (non-humanized) versions will be sent to the server when the form is submitted.
See select and options_for_select docs for more information.
Related
I'm starting using Rails.
In my form_for, I want to change label of default value YES / NO (which appear in my front view)
<div class="row">
<div class="col-sm-6">
<%= f.input :experience,
as: :radio_buttons,
label:"A t-il déjà saillie ?" %>
</div>
</div>
Which option should I add to change label ?
How can I display option in one line ?
Thank you for your help
Are you using simple_form_for? I think so from as: :radio_buttons. If you are, try:
<%= f.input :experience, as: :radio_buttons, collection: [['0', 'false'], ['1', 'true']], label_method: :second, value_method: :first %>
You can probably infer the logic from that line. Make an array of arrays for your collection, each sub array containing first the value of the radio button, and then the label.
I'm a real beginner with MongoDB and MongoID.
I created two scaffolds
class Objet
include Mongoid::Document
field :nom, type: String
embeds_one :coordonnee
end
And
class Coordonnee
include Mongoid::Document
field :adresse1, type: String
field :adresse2, type: String
field :code_postal, type: String
field :ville, type: String
embedded_in :objet
end
That's what I get when creating a new Objet :
Now, I'm trying to show only the field adresse1 for this document, but it doesn't work. I can display only the whole embedded document doing this :
When I do :
<%= #objet.coordonnees.adresse1 %>
I get this error :
undefined method `adresse1' for #<Hash:0x2b2b1f0>
How can I do that ?
EDIT
Doing that, I can display all the elements "Adresse1, adresse2, ville, code_postal" :
Controller
def show
#objet = Objet.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #objet }
end
end
View
<%= #objet.nom %>
<% #objet.coordonnee.each do |t| %>
<%= t[1] %>
<% end %>
But my question is : How to display ONLY one of them ? Such as ville, or code_postal or adresse1... ?
What was your code that works for the full document? It was dropped from your post.
In the mongo Shell, you could do this with dot notation db.collection.find({},{'coordonnees.adresse1':1,'_id':0}) You need to specify the '_id':0 because _id is always returned by default.
The other answer will not work because adresse1 is a subdocument. You must include the reference to coordonnees.
Not hugely familiar with MongoID, but assuming you can make calls straight to mongo, there is a second implicit parameter to all find-like statements called a projection that specifies what exactly you would like to return.
For instance, showing only adresse1 for all items in your collection:
db.collection.find({},{"coordonnees.adresse1": 1, "_id":0})
should return only the adresse1 parameter. I wasn't quite able to tell exactly what context you're displaying the objects in, but regardless of context, api calls to mongo should be fairly straightforward to make. Let me know if I've misinterpreted this question though.
In your posted example, you should change your find function to something like the following:
Objet.find({params[:id]}, {:fields => [coordonnees.adresse1]})
Hope that helps.
I found the solution to my problem.
To display only one element of the hash, I can do :
<%= #objet.coordonnees['adresse1'] %>
I am not sure if you are using embeds_one or embeds_many as you are using singular and plural forms of the relation name interchangeably in your question.
If it is a embeds_one the problem is that you should not iterate on #objet.coordonnee as it is a single document. Your view code should look like:
<%= #objet.nom %>
<%= #objet.coordonnee.address1 %>
If it is a embeds_many, your relation name should be plural, then you should be able to use t.address1 in your view.
# model Objet
embeds_many :coordonnees
# view
<%= #objet.nom %>
<% #objet.coordonnees.each do |t| %>
<%= t.address1 %>
<% end %>
I don't want to use the default
<%= f.submit %>
and have created a helper function for it, which also embeds an icon. The helper function expects a label to put on the newly created button.
I'm calling it like this:
<%= submit_button("icon-plus", I18n.translate("helpers.submit.create")) %>
But now on this text appears on the button:
%{model} toevoegen
Instead of:
Product type toevoegen
If I use the normal submit button then the correct text appears so my yml files are correct. How can I get the correct text to use in the helper?
Helper code:
def submit_button(icon, label)
link_to "javascript:void(0)", :class => 'btn btn-primary', :onclick => "$(this).closest('form').submit()" do
raw('<div class="') + icon + raw(' icon-white"> ') + label +raw('</div>')
end
end
As the I18n guide says, the translate function interpolates variables passed in the %{} brackets using its second argument (a hash).
In your case you need to tell it the model by doing this:
I18n.t("helpers.submit.create", model: "Product type")
If you want a generic option that would work for any model, you can see how Rails itself does it by looking at the source on GitHub - it's something like
I18n.t("helpers.submit.create", model: f.object.class.model_name.human)
As an aside, you don't need to (and probably shouldn't) use raw there. What you are trying to achieve could easily be done with the built-in helpers:
link_to ... do
content_tag :div, label, class: "#{icon} icon-white"
end
I am using SimpleForm to build my form.
I have say the following model:
class ScheduledContent < ActiveRecord::Base
belongs_to :parent
attr_accessible :lots, :of, :other, :fields
serialize :schedule, Array
end
I want to construct a form, where among many other fields and associations (this model is actually part of a has_many association already - so quite a complex form) a user is presented with a variable number of days (eg Day 1, Day 2, Day 3, etc) - and each day can be checked or unchecked. So if a user checks Day 1, and Day 5 say - I want to store [1, 5] in the schedule field. Before the form - I can construct a simple array of possible days to choose from, including obviously the days already chosen.
What is the best way to represent this form using SimpleForm's form helpers? If it is not possible to do so - I could use Rails' form helpers too to make it work, but my preference is SimpleForm as the rest of the form is already constructed using SimpleForm.
Yes, you can do it with SimpleForm. Here is an example:
<%= simple_form_for(#user) do |f| %>
<%= f.input :schedule, as: :check_boxes, collection: [['Day 1', 1], ['Day 2', 2]] %>
<%= f.button :submit %>
<% end %>
Answer to an old question, but I had to do something similar recently. To mark already-selected check box options, I used :checked similar to this:
<%=
form.input :schedule, {
as: :check_boxes,
collection: Days.my_scope.map { |day| [day.name, day.id] },
wrapper: :vertical_radio_and_checkboxes,
checked: form.object.schedule
}
%>
Was struggling with this one as well. Finally made it as the haml code below. It makes use of SimpleForm collection_check_boxes method and will output check boxes with labels vertically. List will not show general label in top for the whole checkbox list.
= f.collection_check_boxes :schedule, Day.all, :id, :label_name do |day|
= day.check_box
= day.label
%br
In my Rails 3 app I use both checkboxes and, in one case, a select helper to submit a search form. I applied some jQuery to the form so if I click a checkbox, the form submits. Same with the select helper. If I click the checkbox, after the page renders the checkbox remains checked as an indicator of the parameters used to get the search result. The problem is that the select helper defaults to "Select" after the search form is submitted. It doesn't maintain the value of the params used to perform the search.
For example, say I have three options: "Select", "Arts", and "Vocational". If Select is the default in my form and I want to search by Arts, clicking "Arts" submits the form, refreshes the page, and the records matching "Arts" are rendered. However the select helper doesn't display "Arts". It defaults back to "Select" when the form is submitted.
I'm using Ransack to do the search, so here are the actions in my Controller where I'm performing the search:
def index
#q = User.search(params[:q])
#users = #q.result(:distinct => true)
end
def search
index
render :index
end
Here's my select helper:
<%= f.select :profile_subject_eq, options_for_select([['Select', ''], ['Arts'], ..., ['Vocational']], :selected => #q) %>
(As you can see I've tried to change the :selected to no avail.)
Finally, here's the jQuery I'm using to submit the form:
$(function(){
$('select').live('change',function() {
$(this).closest('form#index').submit();
});
});
UPDATE: Here is the HTML output of the select helper:
<fieldset>
<select id="q_profile_subject_eq" name="q[profile_subject_eq]">
<option value="nil">Select</option>
<option value="Arts">Arts</option>
...
<option value="Vocational">Vocational</option>
</select>
</fieldset>
Try
options_for_select([['Select', 'nil'], ['Arts'], ..., ['Vocational']], #q)
According to the API doc the second parameter is the selected item itself, not a hash like :selected => ...
If your set on using just select, then you can do it this way.
<%= f.select :profile_subject_eq, [["Arts"], ["Vocational"]], {:include_blank => 'Select', selected: params[:q] ? params[:q].try(:[], :profile_subject_eq) : ""} %>