I can't figure out, or find any solutions to a very simple question:
"How can I define my own input field in formtastic?"
This is what I got:
<%= semantic_form_for #someFantasticVariable, :url => "/someFantasticUrl.html" do |f|%>
<%= f.inputs do %>
<%= f.input :something_else_id, :required => true , :as => :select, :collection => SomethingElse.find(:all), :label =>"The something else"%>
<%= f.input :fantastic_max_cost, :label => "Budget (max cost)"%>
<%end%>
<%= f.buttons do%>
<%= f.commit_button :button_html => { :class => "primary", :disable_with => 'Processing...', :id => "commitButton"}%>
<%end%>
<%end%>
Now..
I want to have a very simple thing. I want to ad a field that is not part of the model. I want to have a date field that I can use to calculate some stuff in my controller. So I want to do this:
<%= f.inputs do %>
<%= f.input :something_else_id, :required => true , :as => :select, :collection => SomethingElse.find(:all), :label =>"The something else"%>
<%= f.input :fantastic_max_cost, :label => "Budget (max cost)"%>
<%= f.input :start_date, :as => :date , :label => "Start date"%>
<%end%>
But apparetly I'm not allowed, and I can't find any way to do this through my thrusted googling. Any help / ideas?
If you have some attribute that is not part of your model, then a getter and a setter should exist on the model:
def start_date
end
def start_date=(arg)
end
Then you can calculate your staff on a controller or whatever you want:
...
puts params[:somefantasticvariable][:start_date]
...
But this is a quick formtastic hack, you should find some better way, like non-formtastic input with some css etc.
Ruby provides a database-less construct called an attr_accessor. It is the equivalent of writing setter and getter methods. Formtastic will see this attribute similar to a database-backed attribute.
In your #someFantasticVariable model:
attr_accessor :start_date
If using attr_accessible in your #someFantasticVariable model, be sure to add the start_date variable there too:
attr_accessible :start_date
Because the attribute is type-less, Formtastic cannot derive the HTML input field to use. You will need to manually set the input type using :as. For your example:
<%= f.input :start_date, :as => :date_select %>
Cite:
http://apidock.com/ruby/Module/attr_accessor
https://github.com/justinfrench/formtastic#the-available-inputs
Related
I want to create a new pm_workload. I have the following code-snippet
<%= f.input :project_id, :collection => PmProject.order('name'), :label_method => :name, :value_method => :id, :label => "Project", :include_blank => false %>
Is there an option to use two values for :label_method? e.g.
:label_method => :name << (PmProject.project_number)
It's not possible to have to attributes or field name inside the label method. But I have an alternate soluction for you resolve this problem.
You are taking PmProject collections, So now create a instance level method insdie the PmProject model like as below.
def name_of_method
"#{name} #{project_number}"
end
Now to use the same on the view input of the simple form for use like that as below...
<%= f.input :project_id, :collection => PmProject.order('name'), :label_method => :name_of_method, :value_method => :id, :label => "Project", :include_blank => false %>
I've been looking at this problem this week. But a variation of it, in my case I wanted the label text to be wrapped in a <span>. I thought I was looking for was related to simple_form but actually it's still part of Rails ActionView tags helpers.
Yes, you could add another method on your model, but if you like to keep your models clean or you want to use something not in the model in the label. :label_method can also be a proc.
<% label_method = proc { |p| "#{p.name} #{p.project_number}" } %>
<%= f.input :project_id, collection: PmProject.order('name'), label_method: label_method, value_method :id, label: 'Project', include_blank: false %>
or in my case
<% label_method = proc { |p| "<span>#{p.name}</span>".html_safe } %>
<%= f.input :project_id, collection: PmProject.order('name'), label_method: label_method, value_method :id, label: 'Project', include_blank: false %>
Currently I have a has_one relationship betweeen Users and photos.
User model:
has_one :photo
accepts_nested_attributes_for :photo
Photo model:
belongs_to :user
Paperclip.options[:command_path] = "/usr/local/bin"
has_attached_file :image,
:path => ':rails_root/public/images/ads/:id/:basename.:extension',
:url => "images/ads/:id/:basename.:extension"
The nested form:
<%= f.simple_fields_for :photo_attributes, :html => { :multipart => true } do |d| %>
<%= d.input :billed_navn %>
<%= d.label :image, :label => 'Upload logo', :required => false %>
<%= d.file_field :image, :label => 'Image', :class => 'imagec', :required => 'false', :style => 'margin-bottom:2px;float:left;width:250px;' %>
<input type="button" value="Clear" id="clear" style="width:70px;float:left;margin-right:2px;">
<%= d.input :image_url, :label => 'Billed URL', :input_html => { :class => 'imagec'}, :required => false %>
<%= f.label :image, :label => 'Billed preview', :required => false %><div id="preview"></div>
<% end %>
This setup works as it should, I can upload 1 photo.
I users to be able to upload multiple photos at once.
Therefor I have changed the assocition in useres model to:
User model:
has_many :photos
accepts_nested_attributes_for :photos
But I how should the nested form then be? If it should be possible to upload mulitple images at once?
The accepts_nested_attributes_for thing only allows mass assignment to add multiple photos at once. (Beware of mass assignment security vulnerabilities! strong_parameters gem recommended). This means that the update action accepts multiple photos.
It will only add it if they are sent, which happens if there are fields in the form that a user fills out. This is mainly determined by the edit view.
Because you don't know how many photos a user will want to add, the best way to do this is to use javascript to dynamically add an extra set of fields for a photo when requested by the user. This can be a link, which when clicked, appends the fields to the form. This way the user can submit as many photos at once as they want.
You will also want to have some validation so that if a set of empty fields (for a photo) are submitted, it doesn't add a non-photo photo.
If you don't want to use javascript, the best you can do is to just assume the user will upload at most say 3 at a time, and include 3 sets of photo fields. Again, being careful to deal with empty fields appropriately.
Example:
<% (1..5).each do |I| %>
<%= fields_for "user[photo_attributes][]", nil, :index => I do |form| %>
<%= form.input :billed_navn %>
...
<% end %>
<% end %>
I need a simple form to add a range of phone numbers.
ActiveAdmin.register Did do
# ..
collection_action :add_range, :method => :get do
end
collection_action :add_range, :method => :post do
end
end
<%= semantic_form_for [:admin, :dids, :add_range] do |f| %>
<%= f.inputs :start, :end %>
<%= f.buttons :commit %>
<% end %>
The above fails with "undefined method `model_name' for Symbol:Class".
How can I define a form like this that doesn't use an object directly?
Just tried, this will work:
<%= semantic_form_for :range, :url => add_range_admin_dids_path do |f| %>
<%= f.inputs :start, :end %>
<%= f.buttons :commit %>
<% end %>
and then find the posted params in params[:range]
I had a similar situation where I need to customize the form action attribute. So, the best way I found to achieve this was by creating a partial form in the corresponding view's folder.
First tell your resource you are going to use a custom form, so add this line to your resource file:
# app/admin/organizations.rb
form partial: "form"
Now you can create your partial by using Arbre Components, like this example:
# app/views/admin/organizations/_form.html.arb
active_admin_form_for [:admin, resource] do |f|
tabs do
tab 'General Configuration' do
f.inputs 'Organization Details' do
admin_accounts = User.with_role(:admin).order('email ASC')
site_collection = Site.where("subdomain <> ''").map { |site| ["#{site.subdomain}", site.id ]}
f.input :name
f.input :kind, :as => :enum
f.input :carereceiver_kind, :as => :enum
f.input :account_manager, :as => :select ,:collection => admin_accounts
f.input :site_id, as: :select ,collection: site_collection
f.input :office_phone
f.input :office_fax
f.input :office_address
f.input :company_logo, :as => :file
f.input :letterhead
f.input :base_url, label: 'BASE URL'
f.input :dynamics_url, label: 'DYNAMICS URL'
f.input :genoa_site_id, label: 'GENOA SITE ID'
end
f.inputs 'Organization Settings' do
f.input :demo_account
f.input :appointment_not_started_notifications_enabled
f.input :erx_enabled
f.input :patients_can_book_appointments
f.input :new_providers_can_manage_their_own_availability_by_default
f.input :clarity_enabled
f.input :whitelist_enabled
f.input :bed_form_enabled
f.input :patient_email_required, label: 'Require patient email addresses'
f.input :patient_credit_card_required, label: 'Require patient credit card information'
f.input :enable_patient_survey, label: 'Enable patient survey'
f.input :enable_provider_survey, label: 'Enable provider survey'
f.input :rcopia4_enabled, label: 'Rcopia 4 enabled'
f.input :share_notes_across_providers_enabled
f.input :d2c_mode
f.input :sso_login_only
f.input :allow_invited_patients_to_complete_profile
f.input :allow_overlapping_appointments, as: :select
f.input :media_mode, :as => :enum
end
f.inputs('Organization Contacts', { class: 'organization_contacts_section' }) do
saved_contacts = f.object.organization_contacts.count
n = 5 - saved_contacts.to_i
n.times do
f.object.organization_contacts.build
end
contact_counter = 0
f.fields_for :organization_contacts do |m|
contact_counter = contact_counter + 1
m.inputs "Contact #{contact_counter}" do
m.input :name, placeholder: 'Name'
m.input :title, placeholder: 'Title'
m.input :email, placeholder: 'Email'
m.input :phone_number, placeholder: 'Phone Number'
end
end
end
end
tab 'Appointment Parser Configuration' do
f.inputs 'Appointment Parser Configuration' do
f.input :appointment_parsers, as: :select, input_html: { multiple: true }
end
end
tab 'EMR Settings' do
f.inputs 'Settings' do
f.input :emr_integrated, label: 'Enable EMR integration'
f.input :emr_processor_type, as: :select, collection: Organization::AVAILABLE_EMR_PROCESSORS
f.input :send_to_emr, label: 'Enable integration from 1DW to EMR'
f.input :receive_from_emr, label: 'Enable integration from EMR to 1DW'
end
end
tab 'Athena EMR Settings' do
f.inputs 'Settings' do
f.input :athena_practice_id, label: 'Athena Practice ID', input_html: { disabled: !f.object.has_athena_processor? }
f.input :athena_department_number, label: 'Athena Department ID', input_html: { disabled: !f.object.has_athena_processor? }
end
end
end
f.actions
end
As you can see with admin_organization_path you can point the URL to any other you want but also you can customize the method to send the form.
Also make sure you use resource for the active_admin_form_for block because you will get an error if you try to use something like #organization.
The form contains a possible way to add nested resources to the principal one, every time you had configured the corresponding model relationships.
And with this, it should be working fine.
I hope it could be useful for someone else.
I'm pretty sure you need to have a model in your call to semantic_form_for. Since your action is a collection action it's not acting on a specific DID, so what model are you trying to create? A Range model? If that is the case you should just have something like:
<%= semantic_form_for [:admin, #range] do |f| %>
<% ... %>
<%= f.buttons :commit
<% end %>
Of course #range should be initialized as Range.new in the controller.
Edit: Realized a bit late that you don't want to use an object. In the documentation it indicates that you can use semantic_form_for :login, but it might not work with nested / namespaced forms. You'd probably have to specify the url with :url => admin_add_range_dids_path or something similar. Just check rake routes to find the right naming. Not sure if the model is being called by ActiveAdmin or Formtastic, so that still might not work, but it's worth trying.
I am using ActiveAdmin and Rails 3.1 -- having problem understanding whether the following is a bug, or if there is some way to do it correctly that I am not understanding. I am trying to use a nested model with a has one relationship, so that I can create a page and fill out it's meta data in 1 step. --
(page has_one meta_data, accepts_nested_attributes_for meta_data)
Example 1)
in this example, when I click new page, meta data section is there but there are no input fields -- also, if I edit the record, it shows up correctly, however the fieldset is duplicated in the second section... and if I remove the f.inputs wrapping semantic_field_for (which would make sense), then it breaks completely and shows nothing in the meta data area...
form do |f|
f.inputs "Page Information" do
f.input :name
f.input :uri
f.input :view
f.input :body, :as => :text
f.input :active
end
f.inputs "Meta Data" do
f.semantic_fields_for :meta_data do |meta_form|
meta_form.inputs :title, :description, :keywords, :name => "Meta Information"
end
end
end
I understand the meta data probably isn't being instantiated, but I am not sure how I am supposed to do that in the form block? (or if I can even do it) -- The only way I am able to get this to work is by doing using a custom form, and building the meta data in the view, which looks like this
2) How I am working around it, but seems hacky
<%= semantic_form_for [:admin, #page] do |f| %>
<% #page.build_meta_data %>
<%= f.inputs :name => "Page Information" do %>
<%= f.input :name %>
<%= f.input :uri %>
<%= f.input :view %>
<%= f.input :body, :as => :text %>
<%= f.input :active %>
<% end %>
<%= f.semantic_fields_for :meta_data do |meta_form| %>
<%= meta_form.inputs :title, :description, :keywords, :name => "Meta Information" %>
<% end %>
<%= f.buttons %>
<% end %>
Thanks in advance for any help or clarification.
(note to moderators I started another thread on this but was not as clear and didn't have the workaround solution I do now yet, so if one of the questions should be deleted please delete the other)
I found a better solution for you. You can use :for option in inputs helper.
f.inputs "Meta Data", for: [:meta_data, f.object.meta_data || MetaData.new] do |meta_form|
meta_form.input :title
meta_form.input :description
meta_form.input :keywords
end
I think this might work too, but I didn't check
f.inputs :title, :desctiption, :keywords,
name: "Meta Data",
for: [:meta_data, f.object.meta_data || MetaData.new]
In rails 4, this is something that works, with a nice design
e.g.,
A customer has one account
model/customer.rb
accepts_nested_attributes_for :account
admin/customer.rb
form do |f|
f.inputs do
f.input :user, input_html: { disabled: true }
f.input :name
f.input :address
f.input :city
f.input :country, as: :string
end
f.buttons
f.inputs "Account Information", for: [:account, f.object.account] do |s|
s.input :active, as: :boolean
s.input :subscription, as: :boolean
s.input :expires_on, as: :datepicker
s.actions
end
end
controller do
def permitted_params
params.permit!
end
end
end
i was having the same problem, i worked in your hack and got it working.
i then moved <% #page.build_meta_data %> to a custom new method like this
controller do
def new
#tenant = Tenant.new
#tenant.build_tenant_configurable
end
end
hope this helps
using simple_form we can change class of a label using:
label_html => {:class => "myclass"}
but how do we do the same when dealing with checkboxes?
simple_form assigns the default class of collection_check_boxes
Is there a way to change this default class?
I wanted to give an update to this answer in case someone comes here looking for a way to do this as I did.
You can give the label a class with this option :item_wrapper_class => 'class_goes_here'
Here is a full example:
= user.input :resident,
:collection => [["In the U.S", true],["Outside the U.S.", false]],
:label_method => :first,
:value_method => :last,
:as => :radio_buttons,
:label => "Where is your principle residence?",
:item_wrapper_class => 'inline'
If you want you can pass new_class to the label doing something like:
<%= f.collection_check_boxes attribute, collection, value_method, text_method do |b|
b.label(class: 'new_class') {b.check_box + b.text}
end %>
You should be able to set :input_html on your form input.
Somthing like:
f.input :something, :as => :check_box, :input_html => { :class => "myclass" }
ian.
The easiest way to change the label class for a checkbox is to insert the following in /config/inititializers/simple_form.rb or /config/initializers/simple_form_bootstrap.rb:
config.boolean_label_class = 'form-check-label'
This should be pretty straight forward like mentioned above one should add :label_html => { :class => "myclass" } in order achieve this, for instance:
= f.input :remember_me, as: :boolean, :input_html => { :class => 'kt-checkbox kt-mock-span' }, :label_html => { :class => "kt-login-checkbox-label" }
will create and assign the attributes for the styles on the checkbox's label like this:
To get the label class I had to get rid of the auto-generated label and write my own.
this is in rails 3 with simple form 2.1 so YMMV....
before:
<%= f.input :remember_me, :as => :boolean if devise_mapping.rememberable? %>
after:
<%= f.label :remember_me, :class => 'remember-me' %>
<%= f.input :remember_me, :label => false, :as => :boolean if devise_mapping.rememberable? %>