Simple Form behaving different than form_for - ruby-on-rails

Simple_form
<%= simple_form_for(#book, wrapper: :horizontal_form, wrapper_mappings: {
}, html: { class: 'form-horizontal' }) do |f| %>
<%= f.error_notification %>
<div class="image-upload">
<%= f.input :book_cover, as: :file , input_html: { class: 'fa fa-cloud-download'}%>
</div>
<%= f.input :category_id, collection: #categories, prompt: 'Select a category' %>
<%= f.input :author %>
<%= f.input :description %>
<div class="d-flex">
<div class="ml-auto">
<%= f.button :submit %>
<%= f.button :cancel, to: books_path %>
</div>
</div>
<% end %>
This is my simple_form form. I want the f.input :book_cover to be displayed as the icon fa fa-cloud-download without the normal download button.
CSS.
.image-upload > input {
display: none;
}
Ive got another form working with it (this is just a snippet of a regular form_for resource:
<%= f.form_group :avatar, class: "row" do |f| %>
<%= f.label :avatar, class: "col-sm-4 col-form-label" %>
<div class="col-md-8">
<label class="image-upload form-control">
<i class="fa fa-cloud-download"></i>
<% if #user.avatar.present? %> <%= #user.avatar_file_name %>
<% end %>
<%= f.file_field :avatar %>
<%= f.error_messages %>
</label>
</div>
<% end %>
Can't seem to get my simple_form working with just the icon.
Edit: Uploading a image to show what my problem is and what it should look like
picture
should look like this

SimpleForm has a input_field method that you can use instead input to render only the actual input element, without wrapper div and label. That helps if you want to build more complex structures manually.
<label class="col-sm-4 col-form-label">Book cover</label>
<div class="col-md-8">
<label class="image-upload form-control">
<i class="fa fa-cloud-download"></i>
<%= f.input_field :book_cover %>
<%= f.error_messages %>
</label>
</div>

Related

rails complex form simple_fields_for without loop | cocoon, simple_form |

I have a kind of complex form to build. I am using cocoon and simple-form for building it.
In that application there are contracts and for every contract a user should be able to create multiple distributions of a certain type via that form.
My model structure looks like the following (just so you can imagine it):
class Contract < ApplicationRecord
has_many distributions
accepts_nested_attributes_for :distributions
end
class Distribution
belongs_to :contract
# distribution_type :string // e.g. month or city
# percentage
# value
end
What I want to achieve is to let the user choose a distribution_type via a dropdown that lies inside the "_distribution_fields.html.erb" partial. If a user selects a certain type, for example "month", the predefined 'div' is loaded via javascript and builds multiple fields at once as follows:
<div class="nested-fields">
<div class="row">
<div class="row">
<%= f.input :distribution_type, wrapper_html: {class: 'col-xs-6 col-md-2'}, input_html: {data: {'toggle-select': 'distribution-type-0'}, class: 'distribution_type_select'}, required: true, disabled: #readonly %>
</div>
<div class="row">
<div id="distribution-type-0-event_type" class="distribution-type-selection">
<%= hidden_field_tag 'event_type', false, class: 'distribution_type_hidden_event_type' %>
<% #contract.event_types.each do |event_type| %>
<div class="col-xs-6 col-md-4">
<div class="field">
<%= f.input :distribution_type, as: 'hidden', input_html: { class: 'event_type_distribution_hidden', value: 'event_type' } %>
<%= f.input :value, input_html: { readonly: true, value: event_type } %>
<%= f.input :percentage, required: true, disabled: #readonly %>
</div>
</div>
<% end %>
</div>
</div>
<div class="row">
<div id="distribution-type-0-month" class="distribution-type-selection">
<%= hidden_field_tag 'month', false, class: 'distribution_type_hidden_month' %>
<% #contract.month_date_list.each do |month| %>
<div class="col-xs-6 col-md-4">
<div class="field">
<%= f.input :distribution_type, as: 'hidden', input_html: { class: 'month_distribution_hidden', value: 'month' } %>
<%= f.input :value, input_html: { readonly: true, value: month } %>
<%= f.input :percentage, required: true, disabled: #readonly %>
</div>
</div>
<% end %>
</div>
</div>
<div class="row">
<div id="distribution-type-0-city" class="distribution-type-selection">
<%= hidden_field_tag 'city', false, class: 'distribution_type_hidden_city' %>
<% #contract.location_cities.each do |city| %>
<div class="col-xs-6 col-md-4">
<div class="field">
<%= f.input :distribution_type, as: 'hidden', input_html: { class: 'city_distribution_hidden', value: 'city' } %>
<%= f.input :value, input_html: { readonly: true, value: city } %>
<%= f.input :percentage, required: true, disabled: #readonly %>
</div>
</div>
<% end %>
</div>
</div>
<div class="col-xs-6 col-md-1">
<div class="row">
<div class="col-xs-12">
<%= link_to_remove_association f, class: 'btn btn-danger delete-btn', disabled: #readonly, data: { confirm: 'You are about to delete the internet as well as to remove this kpi distribution? Are you sure?' } do %>
<i class="fa fa-trash"></i>
<% end %>
</div>
</div>
</div>
In the surrounding "_form.html.erb" it is as follows:
...
<%= field_set_tag 'KPI Distribution' do %>
<%= f.simple_fields_for :distributions do |distribution| %>
<%= render 'distribution_fields', f: distribution %>
<% end %>
<div class="links m-b-md">
<div class="text-left">
<%= link_to_add_association f, :kpi_distributions, class: 'btn btn-info btn-sm', disabled: #readonly do %>
<i class="fa fa-plus"></i>
<% end %>
</div>
</div>
<% end %>
...
As you might have already recognized in the above part, there is a "simple_fields_for" instruction looping the "_distribution_fields" partial. Usually only a single field including all its inputs is created inside such an partial, but I want to set multiple at once. Is there a certain way for doing something like this? Are there any best practices to achieve such a thing? Or can I set the ids produced by cocoon manually?
best regards

How to customize simple Form text area?

I want to customize input areas in this code
<%= simple_form_for #fuel_price, url: supplier_fuel_prices_path, class: "m-t" do |f| %>
<%= f.input :regular, label: "Regular" %>
<%= f.input :medium, label: "Medium"%>
<%= f.input :premium, label: "Premium" %>
<%= f.input :diesel, label: "Diesel" %>
to have styling like the image below
I dont want horizontol or anything. Just want that dollor in front.
Or even better, something like below but with $ instead of #
You can find solution here. He uses Bootstrap and SimpleForm
You have to add bootstrap css library into your application and try the below code
simple_form_for #fuel_price, url: supplier_fuel_prices_path, class: "m-t" do |f| %>
<div class="form-group">
<div class="input-group">
<div class="input-group-addon">$</div>
<%= f.text_field :regular, placeholder: "Regular", class:"form-control" %>
</div>
<div class="input-group">
<div class="input-group-addon">$</div>
<%= f.text_field :medium, placeholder: "Medium", class:"form-control"%>
</div
<div class="input-group">
<div class="input-group-addon">$</div>
<%= f.text_field :premium, placeholder: "Premium",class:"form-control" %>
</div
<div class="input-group">
<div class="input-group-addon">$</div>
<%= f.text_field :diesel, placeholder: "Diesel",class:"form-control" %>
</div
</div>
<%end%>

Accessing virtual attribute from params

ruby 2.1.5
rails 4.2.1
I am trying to figure out how to access a virtual attribute from params.
In my books_controller.rb, I have:
wrap_parameters :books_list
def product_params
params.require(:product).permit(:author_name, :book_name, :books_list)
end
Obviously, the books_list is the virtual attribute. I will be saving it to the books_list table
In my new.html.erb,I have:
<% #title = "Books" %>
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<%= form_for(#books, html: { class: 'form-horizontal' }) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.form_group :author_name do |f| %>
<%= f.label :author_name, class: 'control-label col-md-2' %>
<div class='col-md-8'>
<%= f.text_field :author_name, class: 'form-control' %>
<%= f.error_messages %>
</div>
<% end %>
<div class="form-inputs">
<%= f.form_group :book_name do |f| %>
<%= f.label :book_name, class: 'control-label col-md-2' %>
<div class='col-md-8'>
<%= f.text_field :book_name, class: 'form-control' %>
<%= f.error_messages %>
</div>
<% end %>
<%= f.form_group :books_list do |f| %>
<%= f.label :books_list, class: 'control-label col-md-2' %>
<div class='col-md-8'>
<%= f.text_area :books_list, class: 'form-control' %>
<%= f.error_messages %>
</div>
<% end %>
</div>
<div class="form-actions col-md-offset-2 col-md-10">
<%= f.submit class: 'btn btn-primary' %>
<%= link_to "Cancel", test_sets_path, class: 'btn' %>
</div>
<% end %>
</div>
</div>
</div>
When I submit the form, here's what I get for params:
Parameters: {
"utf8"=>"✓",
"authenticity_token"=>"5mxkibQHkwRnzVU31A6pe9uezsmaWeYbCUgU+gUZPLmiAZPnN6si+smdEePU0lfGITh7gmmyChf/bOY+YQQcQg==",
"books"=>{"author_name"=>"Some Author", "book_name"=>"Dwan Of The Dead"},
"books_list"=>{"{:class=>\"form-control\"}"=>"book1\r\nbook2"},
"commit"=>"Create Book List"
}
I am having trouble accessing the books_list in params. Any ideas?
If books_list column is not exist in #book, it raises error.
There is no method f.form_group in rails, I think you use gem that defines form_group method.
Maybe "books_list"=>{"{:class=>\"form-control\"}"=>"book1\r\nbook2"} parameter is made by some bootstrap gem. you check check name attribute in html source.

Rails 4 - Simple form arguments

Can anyone see what's wrong with this form of expression?
<%= simple_fields_for :article do |f| %>
<%=f.input :q, :nil, placeholder: "Search" %>
<% end %>
Error message says:
wrong number of arguments (3 for 1..2)
So- my wider code is:
articles#index.html.erb:
<div class="row">
<div class="col-md-10 col-md-offset-1">
<%= render 'articles/searchform' %>
</div>
<div class="col-md-10 col-md-offset-1">
<% Article.all.sort_by(&:created_at).in_groups_of(3) do |group| %>
</div>
<div class="row">
<% group.compact.each do |article| %>
<div class="col-md-4">
<div class="indexdisplay">
<%= image_tag article.image_url, width: '100%', height:
'200px' if article.image.present? %>
<div class="indexheading"> <%= link_to article.title, article %> </div>
<div class="indexsubtext"> <%= truncate(article.body, :ommission =>
"...", :length => 250) %></div>
</div>
</div>
<% end %>
</div>
<div class="row">
<%= link_to 'New Article', new_article_path %>
</div>
In my views articles#form.html.erb
<div class="col-xs-10 col-xs-offset-1">
<%= simple_form_for(#article) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :title, autofocus: true %>
<%= f.input :body, :label => "Post", :input_html => {:rows => 10} %>
<%= f.input :image, :label => "Add an image" %>
</div>
<div class="form-actions">
<%= f.button :submit, "Review a draft", :class =>
'formsubmit' %>
</div>
<% end %>
In articles#searchform.html.erb
<% f.simple_fields_for :article do |a| %>
<%=a.input :q, :nil, placeholder: "Search" %>
<% end %>
I get this error:
undefined local variable or method `f' for #<#<Class:0x007f874133c410>:0x007f8740448058>
You are missing your form variable, e.g. f.
For instance if you have simple_form_for ... do |f| you should then write
= f.simple_fields_for :article do |article|
= article.input :q, :nil, placeholder: 'search'
[EDIT] You seem confused. The simple_fields_for is a special command to iterate over nested items, inside a form (e.g. comments for a post). So simple_fields_for would require a surrounding form (simple_form_for). For your search-form you should just be using simple_form_for.

My submit button won't work in rails and I'm not sure why

I'm creating a simple form in rails and the submit button doesn't work. I think I'm missing something obvious here but the html seems to be fine (I'm far froma front end expert). Any advice or pointers?
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2>Apply</h2>
<hr class="star-primary">
</div>
</div>
<div class="row">
<div class="col-lg-8 col-lg-offset-2">
<div class="row control-group">
<% if #user.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(#user.errors.count, "error") %>.
</div>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="col-xs-12 floating-label-form-group controls">
<%= form_for #user, url: users_path(#user), :html => {:method => :post} do |f| %>
<%= f.label :name %>
<%= f.text_field :name, class: "form-control", placeholder: 'Name' %>
<%= f.label :email%>
<%= f.text_field :email, class: "form-control", placeholder: "Email" %>
<%= f.label :address%>
<%= f.text_field :address, class: "form-control", placeholder: "Address" %>
<%= f.label :phone %>
<%= f.text_field :phone, class: "form-control", placeholder: "Phone Number" %>
<%= f.submit "Apply"%>
<%end%>
</div>
</div>
</div>
</div>
</div>
Also, when the submit button fails, nothing happens. No error messages, no console errors. Nothing.
Take method out from the html hash?
form_for #user, url: users_path(#user), :method => :post do |f|
Try this:
<%= form_for #user, :url => {:controller => "your-controller-name", :action => "your-action-name"} do |f| %>
Can you try this one:
<%= form_for #user, url: {action: "create"} do |f| %>
...
...
<%= f.submit "Apply" %>
<% end %>
But I strongly suggest you to use simple_form gem.

Resources