I have a structure that looks like this :
modifications
_form
_miniform
index
My index shows something like :
%span.right
= render "modifications/form", modification: modification
Form and Miniform are almost identical:
.modification-forms
- if can? :reject, modification.model
= form_tag modification_rejections_url, class: "inline", remote: true do |f|
= hidden_field_tag :id, modification.model.id
= submit_button "Reject", class: 'btn btn-danger'
- if can? :approve, modification.model
= form_tag modification_approvals_url, class: "inline", remote: true do |f|
= hidden_field_tag :id, modification.model.id
= submit_button "Approve" , class: 'btn btn-success'
vs miniform
.modification-device-forms
- if can? :reject, modification.model
= form_tag modification_rejections_url, class: "inline", remote: true do |f|
= hidden_field_tag :id, modification.model.id
= submit_button "<i class='icon-remove'> </i>".html_safe
- if can? :approve, modification.model
= form_tag modification_approvals_url, class: "inline", remote: true do |f|
= hidden_field_tag :id, modification.model.id
= submit_button "<i class='icon-ok'> </i>".html_safe
When i render the _form partial, ajax performs how you would expect. After clicking a button, the row disappears.
However, when I swap in miniform, it no longer works. The ajax runs, but it doesn't delete the row.
I assume this is rails conventions getting mixed up, but im not so good with rails magic, and have no idea where to start in deciphering this.
Is there a way to make this work?
Related
I have a recipe website made with rails and some haml on c9.io. On the show page, I'd like to display the price that the user inputted in a simple form with a dollar sign next to it. I tried using a <p> tag, however the dollar sign appears on another line.
Here is my show.html.haml file:
#post_show
%h1= #post.title
%p.username
Shared by
= #post.user.name
about
= time_ago_in_words(#post.created_at)
.clearfix
.post_image_description
= image_tag #post.image.url(:medium)
.description= simple_format(#post.description)
%h6 Notes:
.notes= simple_format(#post.notes)
%h6 Price:
%p
.price= (#post.price)
.post_data
= link_to "Visit Link", #post.link, class: "button", target: "_blank"
= link_to like_post_path(#post), method: :get, class: "data" do
%i.fa.fa-thumbs-o-up
= pluralize(#post.get_upvotes.size, "Like")
= link_to dislike_post_path(#post), method: :get, class: "data" do
%i.fa.fa-thumbs-o-down
= pluralize(#post.get_downvotes.size, "Dislike")
%p.data
%i.fa.fa-comments-o
= pluralize(#post.comments.count, "Comment")
- if #post.user == current_user
= link_to "Edit", edit_post_path(#post), class: "data"
= link_to "Delete", post_path(#post), method: :delete, data: { confirm: "Are you sure?" }, class: "data"
#random_post
%h3 Check this out
.post
.post_image
= link_to (image_tag #random_post.image.url(:small)), post_path(#random_post)
.post_content
.title
%h2= link_to #random_post.title, post_path(#random_post)
.data.clearfix
%p.username
Share by
= #random_post.user.name
%p.buttons
%span
%i.fa.fa-comments-o
= #random_post.comments.count
%span
%i.fa.fa-thumbs-o-up
= #random_post.get_likes.size
#comments
%h2.comment_count= pluralize(#post.comments.count, "Comment")
- #comments.each do |comment|
.comment
%p.username= comment.user.name
%p.content= comment.content
%h2 Share your opinion:
= render "comments/form"
And here is my posts' form.html.haml:
%div.container
= simple_form_for #post do |f|
= f.input :image
= f.input :title
= f.input :link
= f.input :description
= f.input :notes
= f.input :price
%br
= f.button :submit, class: "btn btn-info"
Help would be greatly appreciated.
EDIT:
So now, I have added the following:
%span .input-group-addon $ .price= (#post.price)
However, the dollar sign is on the top line, and the price is on the bottom.
p is block content so will cause a new line by default in html. You can either handle this with CSS or use something that is inline like a span tag
Haml input with preceding dollar sign just include in your code as you want to:
Or just use classes:
.input-group
%span.input-group-addon $
%input.form-control{:placeholder => "Price", :type => "text"}/
Looks like: http://jsfiddle.net/s6Xu6/1/
I'm attempting to a create a simple form that allows me to run a new search on the existing 'results' page using simple form.
The exact same code works fine when performing the search from another (landing) page. However, when I try to insert it into the results page I'm getting
undefined method 'vtype' for #
<Venue::ActiveRecord_Relation:0x007fd6860eb730>
vtype is both a table column and also the name of the param i'm passing to search on.
The simple_form looks like this:
<%= simple_form_for :results, html: { class: "form-inline justify-content-center" } do |f| %>
<%= f.error_notification %>
<%= f.select :vtype, options_for_select([['Happy Hours Anywhere','Anywhere'],['After Work Drinks','After Work Drinks'],['Somewhere to Relax with Friends', 'Relaxing with Friends'], ['A Club Night','Club Night'], ['Somewhere for Date Night','Date Night'], ['A Place to Watch Sports', 'Watching Sports']]),{} ,:class => "form-control select-box font-lightweight" %>
starting
<%= f.select :date, options_for_select(dates_for_search_select.each_with_index.map{|d, i| [d[1],d[0]]}), {}, :class => "form-control select-box font-lightweight" %>
at
<%= f.select :time, options_for_select(times_for_search_select.each_with_index.map{|d, i| [d[1],d[0]]}), {}, :class => "form-control select-box font-lightweight" %>
</h4>
<%= f.button :submit, 'Discover', :class => 'btn btn-block btn-danger btn-embossed top-margin ' %>
<%end%>
My controller looks like this:
def results
if params.has_key?(:results)
##results = Venue.joins(:offers).where("offers.offertype = '2-4-1'")
#finddate = (params[:results][:date]).to_date
#findtime = (params[:results][:time]).to_time
#resultsdate = DateTime.new(#finddate.year,#finddate.month,#finddate.day,#findtime.hour)
#results = Venue.joins(:offers).where(["venues.vtype = ? and offers.start >= ?", params[:results][:vtype], #resultsdate])
else
#results = Venue.joins(:offers).where(["offers.start = ?", Date.today])
end
end
What's wrong with this form running on the 'results' page?
In Rails, when you have a form like this:
<% form_for #post do |f| %>
<%= f.submit %>
<% end %>
You can have a specific translation like this for when the button is clicked:
en:
helpers:
submit:
create: "Create a {{model}}"
update: "Confirm changes to {{model}}"
But I have a form_tag, which submits a GET to an index path to set a filter:
= form_tag admin_dashboard_index_path, method: :get, class: "table_filter" do
= select_tag :company, options_for_select(#filter_companies.map{ |c| [c.name, c.id] }, params[:company]), include_blank: true, class: "selected"
= submit_tag :submit, value: I18n.t('.general.filter'), class: 'btn'
How can I get a specific translation for this situation?
Add this to the method so that the button label stays the same after pressing it.
= submit_tag :submit, value: t('.general.filter'), class: 'btn', data: { disable_with: t('.general.filter') }
submit_tag method
I've just started a new app where I want to take a postcode in a form and save it to the database. My problem is that the create action doesn't seem to be being called no matter what I try.
Routes:
root 'postcodes#new'
resources :postcodes, only: [:new ,:create]
Controller: postcodes_controller.rb
class PostcodesController < ApplicationController
def new
#postcode = Postcode.new
end
def create
#postcode = Postcode.new(postcode_params)
if #postcode.save
flash[:success] = 'Success'
else
flash[:error] = 'Error'
end
end
private
def postcode_params
params.require(:postcode).permit(:code)
end
end
Model: postcode.rb
class Postcode < ApplicationRecord
validates :code, presence: true, uniqueness: true
end
View: postcodes/new.haml
.container
%form
%fieldset.form-group
= form_for #postcode do |f|
= f.label :postcode
= f.text_field :code, placeholder: 'Example Postcode', class: 'form-control'
= f.submit 'Submit', class: 'btn btn-primary'
I've attempted to pass more options in the form_for such as the method and action and now I have a feeling it's a routing error.
Any help will be appreciated.
Thanks.
I believe the problem you are experiencing is a result of your HAML.
You do not need to use, nor should you use, a form HTML element outside the form_for method call.
The form_for method will handle generating this HTML element/tag for you.
You have:
.container
%form
%fieldset.form-group
= form_for #postcode do |f|
= f.label :postcode
= f.text_field :code, placeholder: 'Example Postcode', class: 'form-control'
= f.submit 'Submit', class: 'btn ban-primary'
Which outputs an empty <form> element.
You should have:
.container
= form_for #postcode do |f|
%fieldset.form-group
= f.label :postcode
= f.text_field :code, placeholder: 'Example Postcode', class: 'form-control'
= f.submit 'Submit', class: 'btn ban-primary'
That should generate a proper <form> tag with the required action and method attributes populated with the right URL and 'post' so that your create action is called.
The project which I am working in, is developed on Rails using haml markup to views. There is a view with a simple form like this:
= simple_form_for #message, url: [:admin, #request, #message], html: { class: 'form vertical-form} do |f|
= f.input :text, as: :text, input_html: { class: 'form-control', rows: 5 }
%br
= f.input :link_url, input_html: { class: 'form-control'}
%br
- if #message.has_picture_image?
= f.label :image
=link_to #message.picture_image, target: "_blank" do
= image_tag #message.picture_image(:thumb)
= f.file_field :image, class:'imagen-button'
= f.input_field :remove_picture, as: :boolean, inline_label: 'Remove'
%br
.form-actions
= f.submit(t('accept'), class: 'btn btn-large btn-primary')
= link_to(t('cancel'), [:admin, #message.request, #message], class: 'btn btn-large btn-danger')
and in Message model there is the bellow method:
def remove_picture
self.picture.destroy
end
The input_field is used to check if I want to remove the message image if it exists. I understood that input_filed gives me the option to check it so that when I click on accept button, it call the method remove_picture in the Message model. But, before the browser deploys the form, it rise the next error:
undefined method `to_i' for #<Picture:0x007f7675162b58>
Extracted source (around line #39):
37: = image_tag #message.picture_image(:thumb)
38: = f.file_field :image, class:'imagen-button'
39: = f.input_field :remove_picture, as: :boolean, inline_label: 'Remove'
40: %br
41: .form-actions
42: = f.submit(t('accept'), class: 'btn btn-large btn-primary')
and if I reload the page, this time the form is deployed. I guess this is because in the first time, as the picture exists then immediatly the remove_picture is called and the picture removed, and when I reload the form, as the picture already does not exist, the form is shown.
Obviously I am undestanding wrongly the input_field usage.
SimpleForms input_field is a helper which binds an input to a model attribute. It does not create a box which calls your method when the box is ticked! But rather it will call your remove_picture method when it rendering the form.
In some cases like checkboxes you will want to bind inputs to attributes that are not saved in the database. We call these virtual attributes. They are just like any old Ruby attributes:
class Message < ActiveRecord::Base
attr_accessor :remove_picture
# since this method is destructive it should have a bang (!)
def remove_picture!
self.picture.destroy
end
end
You could use it like this:
class MessagesController < ApplicationController
def update
#message.update(update_params)
#message.remove_picture! if message.remove_picture
# ...
end
def update_params
params.require(:message).allow(:remove_picture)
end
end
But there is a better way:
class Message < ActiveRecord::Base
has_one :picture_image
accepts_nested_attributes_for :picture_image, allow_destroy: true
end
accepts_nested_attributes_for lets us create an image with picture_image_attributes and destroy an image with:
#picture.update(picture_image_attributes: { _destroy: true })
This is how we would set up the form:
= simple_form_for #message, url: [:admin, #request, #message], html: { class: 'form vertical-form} do |f|
= f.input :text, as: :text, input_html: { class: 'form-control', rows: 5 }
%br
= f.input :link_url, input_html: { class: 'form-control'}
%br
- if #message.has_picture_image?
f.simple_fields_for :picture_image do |pif|
= pif.label :image
= link_to #message.picture_image, target: "_blank" do
= image_tag #message.picture_image(:thumb)
= pif.file_field :image, class:'imagen-button'
= pif.input_field :_destroy, as: :boolean, inline_label: 'Remove'
%br
.form-actions
= f.submit(t('accept'), class: 'btn btn-large btn-primary')
= link_to(t('cancel'), [:admin, #message.request, #message], class: 'btn btn-large btn-danger')
And your strong parameters whitelist:
def update_attributes
params.require(:message).allow(
:text,
:link_url,
picture_image_attributes: [:image, :_destroy]
)
end