Rails: Two values for label_method (simple_form_for) - ruby-on-rails

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 %>

Related

How do I modify the form url with the ActiveAdmin Ruby gem?

I'm using the ActiveAdmin ruby gem, which uses formtastic.
I have a form like below:
ActiveAdmin.register User do
permit_params :first_name, :last_name, :age
form do |f|
input :first_name
input :last_name
input :age
actions
end
end
I want to modify the form URL to a custom URL which includes the user's ID (eg 7). Something like:
ActiveAdmin.register User do
permit_params :first_name, :last_name, :age
form url: "/api/customer/7/attempt", method: :post do |f|
input :first_name
input :last_name
input :age
actions
end
end
The above works (that is, the form url is changed). However, I'm hardcoding the user ID 7 in the URL. I need to do a variable interpolation. But I'm not sure I have access to the user object outside the block.
I have access to the user object within the block like
f.object.id
But not outside the block.
How do I overcome this problem?
Thank you.
I don't know if that's possible, I tried approaches like
resource.id
user.id
params[:id]
and they didn't work.
To solve this problem you can create custom form
form partial: 'form'
and specify url there.
I'm working with Rails 5 and ActiveAdmin with Arctic_Admin them and I found myself in a very 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. 😃
resource.id should work in your case

Simple form association label with image

I want to display the image on the gift on simple form association
I tried this code using label_method but it does not work:
<%=f.association :gift, :collection=> Gift.all, :label_method=>lambda { |gift| "#{gift.name} #{image_tag 'gift.photo.url(:small)'}" }, :value_method=> :id, :as=>:radio_buttons%>
This code can help you, show check boxes with images
<%= f.association :gift,
:as => :check_boxes,
item_wrapper_tag: :div,
item_wrapper_class: "image-select",
:collection => Gift.all,
:label => false,
:inline_label => false,
:include_blank => false,
:input_html => {multiple: true},
:label_method => lambda { |b| image_tag(b.photo.url) },
value_method: :id
%>
Don't forget to use html_safe if you are working with string

Creating a custom form in active admin

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.

Adding a custom input field in formtastic?

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

how to change class of a label for checkboxes in simple_form

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? %>

Resources