Rails 3 + Simple Form: Specifiy label class when using f.association - ruby-on-rails-3

How can I specify the label class when using f.association instead of f.input in simple_form?
For example, this works:
f.input :name, :label_html => { :class => 'some-class' }
But this doesn't
f.association :periods, :as => :check_boxes, :label_html => { :class => 'some-class' }
Meaning that the label related to :name will have some-class as part of its class, but the label related to :periods won't. Any way to do this without changing f.association to f.input? Thank!

I think you can't add custom class to each label but you can do it for each item wrapper, e.g:
<%= simple_form_for(#user) do |f| %>
<%= f.association :group, as: :check_boxes, item_wrapper_class: 'custom-class' %>
<%= f.button :submit %>
<% end %>

Related

Rails simple_form grouped collection not working

In my Rails app, I'm using simple_form.
I'm trying to use grouped collection selects.
Without simple_form, this works:
<%= f.label :employee_id, "Lead3:" %>
<%= f.grouped_collection_select :employee_id, Workgroup.order(:id) , :employees, :group, :id, :employee_full_name %>
But, my simple_form attempt doesn't - the dropdown is empty:
<%= f.input :employee, collection: #workgroups, as: :grouped_select, group_method: :employees, :label => 'Lead2:' %>
OR
<%= f.association :employee, collection: #workgroups, as: :grouped_select, group_method: :employees, :label => 'Lead2:' %>
I would suggest to check your #workgroups definition in the controller. It probably returns nil or is not specified. Depending on what action calls your form, you should have something like this:
#workgroups = Workgroup.all(order: id)

How to write routes with model inherit

I have a model in app/models/post.rb
class Post < ActiveRecord::Base
end
And I have another model in app/models/post/note.rb
class Post::Note < Post
mount_uploader :file, FileUploader
end
In my controller :
def new
#note = Post::Note.new
end
My view form is :
<%= simple_form_for #post, :validate => true, :html => {:class => 'form-horizontal'} do |form| %>
<%= form.input :title, :validate => {:presence => true} %>
<%= form.button :submit %>
<% end %>
The error is undefined methodpost_notes_path' for #<#:0x007fe3d3fe2b08>`
I want to know how to write the correct route config ?
You can specify the url as an option to simple_form, to override the default path it uses. So if your Post::Note model has a path helper note_path, then this should work:
<%= simple_form_for #post, :url => note_path, :validate => true, :html => {:class => 'form-horizontal'} do |form| %>
<%= form.input :title, :validate => {:presence => true} %>
<%= form.button :submit %>
<% end %>
Ref: How do you handle single table inheritance in SimpleForm so a single helper handles all models?

Does a Rails plugin exist to build a show page (like a formbuilder)

I'm looking for a Rails plugin providing a builder for show.html.erb pages.
For example, with SimpleForm, an new.html.erb page might look like this :
<%= simple_form_for(#user, :url => user_registration_path, :html => ... }) do |f| %>
<%= f.input :email, :required => true %>
<%= f.input :password, :required => true %>
<%= f.input :password_confirmation, :required => true %>
...
<% end %>
But I was not able to find an equivalent for just displaying fields.
A generated show.html.erb page looks like :
<p>
<b>Email:</b>
<%= #user.email %>
</p>
...
But I'd like something like :
<%= simple_display_for(#user, :html => ... }) do |d| %>
<%= d.output :email %>
<%= d.output :name %>
...
<% end %>
Does this kind of builder exist?
Thanks
EDIT : If the builder use Twitter Bootstrap, that's even better :)
I don't know of any gems, but here is a simple example of how to build this feature yourself, which you can expand on:
lib/simple_output.rb
class SimpleOutput
def initialize(resource)
#resource = resource
end
def output(attribute)
#resource.send attribute
end
end
config/initializers/simple_output.rb
require_dependency 'lib/simple_output'
helpers/simple_output_helper.rb
module SimpleOutputHelper
def simple_output_for(resource, options={}, &block)
content_tag :div, yield(SimpleOutput.new(resource)), options[:html] || {}
end
end
users/show.html.erb
<%= simple_output_for(#user, html: { style: "background-color: #dedede" }) do |r| %>
<%= r.output :name %>
<%= r.output :email %>
<% end %>
Now, obviously this is just a very simple example, but hopefully it will get you started on the right track. Look at the simple_form source to see how they organize their code, and how they "typecast" fields. The simple_form codebase is very clean and easy-to-follow Ruby, and is a great example of what a gem should look like.

Default value on select field in formtastic form with no model

I have a formtastic form to gather parameters for report generation. I know formtastic is designed to be used with models but I need to use it here as the form is in an activeadmin page.
It's all working well but I can't set a default value for the selects. I'm willing to implement a "despicable hack" to get this working. I'd prefer not to implement a fake model
just to set default values on a form.
The form code looks like this
<%= semantic_form_for "report", :url => report_admin_payments_path do |f| %>
<%= f.inputs do %>
<%= f.input :report_type, :as => :select, :collection => report_types, :input_html => {:style => "width:180px"} %>
<%= f.input :start_date, :as => :string, :input_html => {:class => 'datepicker', :style => "width:60px", :value => 1.month.ago.strftime("%Y-%m-%d")} %>
<%= f.input :end_date, :as => :string, :input_html => {:class => 'datepicker', :style => "width:60px", :value => Time.zone.now.strftime("%Y-%m-%d")} %>
<%= f.input :country, :as => :select, :collection => locales, :input_html => {:style => "width:180px"}%>
<% end %>
<%= f.actions :submit %>
<% end %>
Thanks in advance,
Matt
This or something similar should meet your needs.
class LightModel
# Subclass this for a model that looks like an ar model but has no persistence
# good for formtastic forms
include ActiveModel::Naming
include ActiveModel::Validations
def initialize(attributes = {})
#attributes = attributes
end
# read only atm
def method_missing(m, *args, &block)
#attributes[m]
end
end
Thanks,
Matt

Submitting AJAX form for a nested child with another nested child (AssociationTypeMismatch)

My models
I'm trying to create a form for an Annotation. This annotation belongs to a Map, and each annotation should have one Boundary. A map can have many annotations.
I first created the association by letting both Annotation and Map has_one Boundary, but later I switched to using a polymorphic boundary_object. The error was the same regardless.
has_one :boundary, :as => :boundary_object # <= Map
has_one :boundary, :as => :boundary_object # <= Annotation
belongs_to :boundary_object, :polymorphic => true # <= Boundary
Views and Controller
Here's the thing: First I used Boundary.new to create a new boundary object here, since I didn't have a pre-set annotation object, since the form can be submitted multiple times.
maps/show.html.erb
<%= form_for([#map, Annotation.new], :remote => true ) do |f| %>
<%= f.text_area :body, :cols => 80, :rows => 10, :style => "width: 500px" %>
<%= f.fields_for Boundary.new do |b| %>
<%= b.text_field :ne_x, :style => "display:none" %>
<%= b.text_field :ne_y, :style => "display:none" %>
<%= b.text_field :sw_x, :style => "display:none" %>
<%= b.text_field :sw_y, :style => "display:none" %>
<% end %>
<% end %>
I could use f.fields_for :boundary too, if I have this in the maps_controller.rb:
#annotation = #map.annotations.build
#annotation.boundary = Boundary.new
But the result is still the same.
annotations_controller.rb
def create
#annotation = Annotation.new(params[:annotation])
respond_to do |format|
if #annotation.save
format.js { }
end
end
The Error
When submitting that form, this results in the following error at the first line in the create method.
ActiveRecord::AssociationTypeMismatch (Boundary(#2158793660) expected, got ActiveSupport::HashWithIndifferentAccess(#2165684420))
Obviously, the form works without the whole boundary thing. These are the parameters submitted:
{
"utf8"=>"✓",
"authenticity_token"=>"6GDF6aDc6GMR3CMP+QzWKZW9IV9gSxfdkxipfg39q7U=",
"annotation"=>
{
"body"=>"foo bar",
"boundary"=>
{
"ne_x"=>"11312",
"ne_y"=>"5919",
"sw_x"=>"6176",
"sw_y"=>"1871"
}
},
"map_id"=>"1"
}
What do I have to do to be able to create the Boundary object for this annotation right away?
According to your associations:
First, you need to build a new boundary object (see here for more info):
def show
#map = ...
#annotation = #map.annotations.build
#boundary = #annotation.build_boundary # build new boundary
end
Second, you need to edit your view:
<%= form_for([#map, #annotation], :remote => true ) do |f| %>
<%= f.text_area :body, :cols => 80, :rows => 10, :style => "width: 500px" %>
<%= f.fields_for :boundary do |b| %>
...
<% end %>
<% end %>
Third, check that you have accepts_nested_attributes_for for your Boundary in the Annotation model.
accepts_nested_attributes_for :boundary
The form will then look like this – note that the name of the association needs _attributes:
<input … name="annotation[boundary_attributes][ne_x]" … />