undefined method `error_message_on' after implementing simple private messages [duplicate] - ruby-on-rails

I have a form with input fields/labels etc. How do I get the error message to show up next to the field? instead of clumped together at the top?
I am using devise, rails 3
I have this at the top of my form:
= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f|
- if resource.errors.any?
#errorExplanation
%h2
= pluralize(resource.errors.count, "error")
prevented this user from being saved:
%ul
- resource.errors.full_messages.each do |msg|
%li
= msg

You can use this
- if #resource.errors[:field_name]
...
Also useful link:
http://guides.rubyonrails.org/active_record_validations.html#working-with-validation-errors

Just create a file in your initializers folder.
config/initializers/inline_errors.rb
Place this code in it:
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
unless html_tag =~ /^<label/
%{<div class="has-error">#{html_tag}<span class="help-block">#{instance.error_message.first}</span></div>}.html_safe
else
%{#{html_tag}}.html_safe
end
end
PD: Sorry for my english.

How about this
if you want to put the error message just beneath the text field, you can do like this
.row.spacer20top
.col-sm-6.form-group
= f.label :first_name, "*Your First Name:"
= f.text_field :first_name, :required => true, class: "form-control"
= f.error_message_for(:first_name)
What is error_message_for?
--> Well, this is a beautiful hack to do some cool stuff
# Author Shiva Bhusal
# Aug 2016
# in config/initializers/modify_rails_form_builder.rb
# This will add a new method in the `f` object available in Rails forms
class ActionView::Helpers::FormBuilder
def error_message_for(field_name)
if self.object.errors[field_name].present?
model_name = self.object.class.name.downcase
id_of_element = "error_#{model_name}_#{field_name}"
target_elem_id = "#{model_name}_#{field_name}"
class_name = 'signup-error alert alert-danger'
error_declaration_class = 'has-signup-error'
"<div id=\"#{id_of_element}\" for=\"#{target_elem_id}\" class=\"#{class_name}\">"\
"#{self.object.errors[field_name].join(', ')}"\
"</div>"\
"<!-- Later JavaScript to add class to the parent element -->"\
"<script>"\
"document.onreadystatechange = function(){"\
"$('##{id_of_element}').parent()"\
".addClass('#{error_declaration_class}');"\
"}"\
"</script>".html_safe
end
rescue
nil
end
end
Result
Markup Generated after error
<div id="error_user_first_name" for="user_first_name" class="signup-error alert alert-danger">This field is required.</div>
<script>document.onreadystatechange = function(){$('#error_user_first_name').parent().addClass('has-signup-error');}</script>
Corresponding SCSS
.has-signup-error{
.signup-error{
background: transparent;
color: $brand-danger;
border: none;
}
input, select{
background-color: $bg-danger;
border-color: $brand-danger;
color: $gray-base;
font-weight: 500;
}
&.checkbox{
label{
&:before{
background-color: $bg-danger;
border-color: $brand-danger;
}
}
}
Note: Bootstrap variables used here
and, do not forget to Restart the server now and after any modification to the file in config dir.

You can use error_message_on
http://apidock.com/rails/ActionView/Helpers/ActiveRecordHelper/error_message_on
Update:
form.error_messages was removed from Rails and is now available as a plugin. Please install it with rails plugin install git://github.com/rails/dynamic_form.git.

If anyone is looking for a way how to display error messages for particular field in Rails 6:
a = Post.new
a.save # => false
a.errors.full_messages_for(:title)
["Title can't be blank"]
a.errors.full_messages_for(:title).join(', ')
"Title can't be blank, Title too short"

Related

Trix Rich Text Editor works in new.html.erb but renders code in show.html.erb view instead of styled text(display in browser)

I am having a weird problem.
I installed Trix to my Rails app recently. It all went smoothly until I tried to publish a blogpost and found that html elements like strong> and div> were being included as actual text(and no styling occurring as a result).
Has anyone else had this problem? I am pretty sure my setup was pretty similar to this
Here's a picture to describe my view:
To be clear, the picture is a zoomed in screenshot of one of the cards that a user would see(and hence it should be styled ... not outputting html in that actual view)
Here is my setup
actiontext.scss
#import "trix/dist/trix";
.trix-content {
.attachment-gallery {
> action-text-attachment,
> .attachment {
flex: 1 0 33%;
padding: 0 0.5em;
max-width: 33%;
}
&.attachment-gallery--2,
&.attachment-gallery--4 {
> action-text-attachment,
> .attachment {
flex-basis: 50%;
max-width: 50%;
}
}
}
action-text-attachment {
.attachment {
padding: 0 !important;
max-width: 100% !important;
}
}
}
application.scss
#import "actiontext";
The styling in my new.html.erb works but publishing is not showing styling as mentioned above.
Continuing
My form,
new.html.erb
<div class="page-content-area">
<h1>Create a Blogpost</h1>
<h2>Fill in the details below</h2>
<%= simple_form_for [#blogposts] do |f| %>
<%= f.input :blog_title,
required: true,
autofocus: true,
input_html: { autocomplete: "Blogpost Title" }%>
<%= f.input :blog_sub_heading,
required: true,
autofocus: true,
input_html: { autocomplete: "Blogpost Sub Heading" }%>
<%= f.input :blog_text,
as: :rich_text_area,
required: true,
autofocus: true,
input_html: { class: "text-area-blog", autocomplete: "Blog Text" }%>
<%= f.input :photo,
autofocus: true,
as: :file %>
<%= f.submit "CREATE", class: "btn btn-primary" %>
<% end %>
</div>
application.js
require("trix")
require("#rails/actiontext")
blogpost controller
def new
#blogposts = Blogpost.new
end
def create
#blogposts = Blogpost.new(blogpost_params)
#blogposts.user = current_user
if #blogposts.save!
redirect_to blogpost_path(#blogposts)
else
render 'new'
end
end
private
def blogpost_params
params.require(:blogpost).permit(:user_id, :blog_title, :blog_sub_heading, :blog_text, :photo, :content)
end
blogpost model
class Blogpost < ApplicationRecord
belongs_to :user
has_rich_text :content
end
If you need me to display anything else don't hesitate to let me know!
Thanks for your time!
How are you rendering the blog_text field in your view? Generally rendering of HTML from user-content is restricted (to avoid against XSS/etc). You can use .html_safe to tell rails to not escape the html tags. See raw vs. html_safe vs. h to unescape html
So I realised my error.
Instead of
class Blogpost < ApplicationRecord
belongs_to :user
has_rich_text :content
end
It should be
class Blogpost < ApplicationRecord
belongs_to :user
has_rich_text :blog_text
end
Because in my app, I have named that column in my schema and form as "blog_text".
I followed the tutorial too closely and didn't contextualise it to my schema.

How to use rich_text_area with simple_form in Ruby on Rails 6?

At the moment simple_form does not support ruby on rails 6 action_text with the rich_text_area input field.
So at the moment my input field can look like this in posts/_form.html.haml:
= f.label :description
= f.rich_text_area :description
= f.error :description, class: 'text-danger'
How to make it work as = f.input :description and have a rich text area?
create a file in app/inputs/rich_text_area_input.rb:
class RichTextAreaInput < SimpleForm::Inputs::Base
def input_html_classes
super.push('trix-content')
end
def input(wrapper_options = nil)
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
#builder.rich_text_area(attribute_name, merged_input_options)
end
end
in application.scss:
//simple_form input for rich_text_area hight
trix-editor.form-control {
height: auto;
}
Now in posts/_form.html.haml you can just do:
= f.input :description, as: :rich_text_area
Althrough hopefully at some point simple_form must add it to master
Source 1: https://github.com/heartcombo/simple_form/issues/1638
Source 2: https://github.com/heartcombo/simple_form/pull/1646

Rails, Gritter - remove default title

I use Gritter notifications in Rails 5 app and can't find a way to remove default title of the notification popup. I add Gritter as bellow:
<%= js add_gritter(flash[:notice], title: 'I dont need you', sticky: false) %>
Tried:
<%= js add_gritter(flash[:notice], title: false, sticky: false) %>
<%= js add_gritter(flash[:notice], title: nil, sticky: false) %>
<%= js add_gritter(flash[:notice], title: '', sticky: false) %>
<%= js add_gritter(flash[:notice], title: ' ', sticky: false) %>
And still popup appears with the default title - "Notification". Tried to search in the whole app's project "Notification" or "gritter", but nothing related was found.
How to get rid of it?
The add_gritter method in the gem sets the options[:title] as "Notification" if options[:title].blank? returns true.
The "dirty" option is to define it again, with a hash of options instead *args, and to render the title if it was passed as an option argument, like:
def add_gritter(text, options={})
if %w(success warning error notice progress).include?(options[:image].to_s)
options[:image] = image_path("#{options[:image]}#{options[:image].to_s == 'progress' ? '.gif' : '.png'}")
end
notification = Array.new
notification.push("jQuery(function(){") if options[:nodom_wrap].blank?
notification.push("jQuery.gritter.add({")
notification.push("image:'#{options[:image]}',") if options[:image].present?
notification.push("sticky:#{options[:sticky]},") if options[:sticky].present?
notification.push("time:#{options[:time]},") if options[:time].present?
notification.push("class_name:'#{options[:class_name]}',") if options[:class_name].present?
notification.push("before_open:function(e){#{options[:before_open]}},") if options[:before_open].present?
notification.push("after_open:function(e){#{options[:after_open]}},") if options[:after_open].present?
notification.push("before_close:function(e){#{options[:before_close]}},") if options[:before_close].present?
notification.push("after_close:function(e){#{options[:after_close]}},") if options[:after_close].present?
notification.push("on_click:function(e){#{options[:on_click]}},") if options[:on_click].present?
notification.push("title:'#{escape_javascript(options[:title])}',") if options[:title].blank? # Here
notification.push("text:'#{escape_javascript(text)}'")
notification.push("});")
notification.push("});") if options[:nodom_wrap].blank?
text.present? ? notification.join.html_safe : nil
end
But the gritter.js file has an if to check if the title has any content, so you should have to deal with your own and edit it, just to check for the text, like:
//We might have some issues if we don't have a title or text!
if (!params.text) {
throw 'You need to fill out the text parameter.';
}
Doesn't sound like a best way, but works. If any other solutions - please feel free :)
.gritter-title {
display: none;
}
Edit:
Since I use SCSS, this is better:
<%= js add_gritter(flash[:notice], sticky: false, :on_click => remove_gritter, :time => 100000, class_name: 'no-title') %>
.no-title {
.gritter-title {
display: none;
}
}

ruby on rails qr code implemetation

hi just trying to create a qr code in my rails website using sam vincents qr code generator https://github.com/samvincent/rqrcode-rails3....... first i added this code to a controller
class QrcodeController < ApplicationController
def qrcode
respond_to do |format|
format.html
format.svg { render:qrcode => #qrurl, :level => :l, :unit => 10, :color => black }
format.png { render :qrcode => #qrurl }
format.gif { render :qrcode => #qrurl }
format.jpeg { render :qrcode => #qrurl }
end
end
def options
{:qrcode => "http://helloworld.com", size => 4}
end
end
then i am not sure what to add in the view i tried this
<div class="Qrcode qr">
<h2>Qr code</h2>
<p><%= link_to "SVG", Qrcode_path("svg") %></p>
<p><%= link_to "PNG", Qrcode_path("png") %></p>
<p><%= link_to "JPEG", Qrcode_path("jpeg") %></p>
<p><%= link_to "GIF", Qrcode_path("gif") %></p>
would appreciate any help on how it works as their are not that many instructions online
im using ruby 1.9.3 and rails 4.0.1
I'm using rqrcode gem. It's pretty simple and you don't need to generate images for your qrcodes. The code is generated using tables and some css styles...
You can use this helper: /helpers/qrcode_helper.rb
module QrcodeHelper
require 'rqrcode'
def render_qr_code text, size = 3
return if text.to_s.empty?
qr = RQRCode::QRCode.new(text)
sizeStyle = "width: #{size}px; height: #{size}px;"
content_tag :table, class: "qrcode pull-right" do
qr.modules.each_index do |x|
concat(content_tag(:tr) do
qr.modules.each_index do |y|
color = qr.dark?(x, y) ? 'black' : 'white'
concat content_tag(:td, nil, class: color, style: sizeStyle)
end
end)
end
end
end
end
Into your view some_view.html.erb
<%= render_qr_code("MYCODE") %>
And you need to add style for your code qrcode.css.less
table.qrcode {
border-width: 0;
border-style: none;
border-color: #0000ff;
border-collapse: collapse;
margin-top: 100px;
margin-bottom: 12px;
td {
border-width: 0;
border-style: none;
border-color: #0000ff;
border-collapse: collapse;
padding: 0;
margin: 0;
width: 3px;
height: 3px;
&.black {
background-color: #000 !important
}
&.white {
background-color: #fff !important
}
}
}
My example it's working with Rails 3.
Here's a minimal example that avoids the need to write code to render each (x,y) "pixel" yourself.
In your controller:
def show
#qr = RQRCode::QRCode.new('https://stackoverflow.com/')
end
And then in your corresponding .html.erb view:
<p>
<%== #qr.as_svg %>
</p>
(Note that this uses <%==, not <%=; if you use the latter, you'll get the raw SVG XML source instead of a rendered SVG image.)
See the RQRCode docs for options that can be passed to .as_svg, and for other output options such as PNG.

ruby on rails add div on error messages join

current code for the ajax call:
#return = { :error => true, :response => #invitation.errors.full_messages.join("<br />") }
the errors now appear as
Email can't be blank
Email is invalid
how can i add a div before the error messages and a p tag in each line?
so it would become
<div>
<p>Email can't be blank</p>
<p>Email is invalid</p>
</div>
Something like this could work for you:
error_message = content_tag :div, #invitation.errors.full_messages.map {|error| "<p>#{error}</p>"}.join
#return = { :error => true, :response => error_message }

Resources