How to force a specific input in text field in Rails? - ruby-on-rails

I need to set three different types of allowed inputs for my application like this:
running disciplines 00,00
long running disciplines 00:00,00
jumping disciplines 0,00
<%= f.text_field %> should force an input such as that, is there a way I could do it?

Yes you can do it with Model validation along with a Regular Expression. So if you are only allowing the given values i.e., '00,00', '00:00,00', '0,00' , you can do:
class ModelName < ActiveRecord::Base
validates_format_of :field_name, :with => /((\A[0]{2}(\,|\:)[0]{2}((\,)[0]{2})*\Z)|(\A[0]{1}(\,)[0]{2}\Z))/i, :message => " is Invalid"
end
Check it here http://rubular.com/r/7ZGo0ktlSe
Update as per the comment from Xeen:
If you allow all the digits [0-9], the you can go for the answer below:
class ModelName < ActiveRecord::Base
validates_format_of :field_name, :with => /((\A\d{2}(\,|\:)\d{2}((\,)\d{2})*\Z)|(\A\d{1}(\,)\d{2}\Z))/i, :message => " is Invalid"
end
Check http://rubular.com/r/c2Q5K3armn.
Hope it helps :)

One way can be to use JS functions, put all the validations in that, and show alerts when user tries to submit the form. Js function will be like this:
function validateForm()
{
var x=document.forms["myForm"]["fname"].value;
if (x==null || other conditions)
{
alert("Please enter in THAT format");
return false;
}
}
and using following HTML snippet, you can validate it on submit:
<input type="submit" value="Submit" onsubmit="return validateForm()">
Check this as well.

Related

globalize3 and easy_globalize3_accessors validation

I'm using gems: globalize3 and easy_globalize3_accessors.
I have a problem with validations. For example, I have Post model:
class Post
translates :title, :content
globalize_accessors :locales => [:en, :ru], :attributes => [:title, :content]
validates :title, :content, :presence => true
end
and form:
= form_for #post do |f|
-I18n.available_locales.each do |locale|
= f.text_field "title_#{locale}"
= f.text_area "content_#{locale}"
it looks like in view (if I18n.locale = :ru):
<form action="/ru/posts" method="post">
<input id="post_title_ru" name="post[title_ru]" type="text" />
<textarea cols="40" id="post_content_ru" name="vision[content_ru]"></textarea>
<input id="post_title_en" name="post[title_en]" type="text" />
<textarea cols="40" id="post_content_en" name="vision[content_en]"></textarea>
<input name="commit" type="submit" value="Создать Видение" />
</form>
If I fill in the fields only in Russian, the validation passes, if I wanted to post was in English only, and fill only the English field (when I18n.locale = :ru), the validation fails
Title can't be blank
Content can't be blank
As I understand it, there is a problem in the attributes, validation checks only the first attributes :title_ru and :content_ru. And to the rest of attributes (:content_en and :title_en) check does not reach.
how to make a second data validator to check if the validation of the first group of attributes is not passed?
thanks in advance
validate :titles_validation
def titles_validation
errors.add(:base, "your message") if [title_ru, title_en].all? { |value| value.blank? }
end
The problem is that globalize3 is validating the title for whatever locale you are currently in. If you want to validate for every locale (and not just the current locale), you have to explicitly add validators for the attribute in each locale (as #apneadiving pointed out).
You should be able to generate these validators automatically by cycling through I18n.available_locales:
class Post < ActiveRecord::Base
I18n.available_locales.each do |locale|
validates :"title_#{locale}", :presence => true
end
...
end

HAML - how to create form validation and display error messages?

I am able to render a form in HAML but I am not sure how to validate it.
Here is what I have so far:
#disclosure-form-container
= form_for([:mobile,#disclosure], :html => {:id => "disclosure-form", :remote => true}) do |f|
%p
=f.label :display_as, (t :select_disclosure_type)
=f.select :display_as, options_from_collection_for_select(Disclosure.basics, :display_as, :name, f.object.display_as)
%p
=f.label :notes, (t :notes)
=f.text_area :notes, :class => "#{validation_rules(:free_disclosure_notes)}", :rows => 5 , :id => "disclosure_notes_entry"
= buttonset({:submit_label => (t "buttons.influencers.disclosures.create"),:submit_css_class => "call-to-action",:cancel_url => "#",:direction => :left_to_right})
This renders a form with two fields and a button to click submit. But what if people just enter submit without doing much? Where do I put the validation code and how do I validate this form?
Thanks!
A user enters data that should be saved in your model and then stored in your DB. So it's naturally to implement validation on model-level. Rails allows you to create validation for models easy. Here you can read about it. In a few words: adding few lines to your model prevent it to be saved with inconsistent data.
But you can in addition to model-level validation use client-side validation: i.e., data will be checked before sending to server. This way user don't have to submit form to find out that he forgot to fill some required field. But of course this can't be any guaranty as it's easy to bypass. Here more about client-side validation.
So, as you see, Haml can't help you with validations. It's a great tool, but not for this purpose.
In your Disclosure model, you need:
class Disclosure < ActiveRecord::Base
validates_presence_of :display_as, :notes
...
end
Then you can include error messages at the top of your form with something like:
- if #disclosure.errors.any?
%ul.errors
- #disclosure.errors.full_messages.each do |msg|
%li= msg
Or if you use Simple Form you get automatic validation messages inline, and your form would just look like this:
= simple_form_for #disclosure do |f|
= f.input :display_as
= f.input :notes
= f.submit
And you're done.
Note, as Jdoe pointed out, HAML has nothing to do with detecting validations, it only displays what the server tells it. The server is what determines whether there are validation errors.
If you want to try and come up with the equivalent of something like this client side you could give your form an id and do something like this (in CoffeeScript):
jQuery ->
$('form#disclosures').submit (event) ->
unless $('input#display_as').val().length > 0 && $('input#notes').val().length > 0
event.preventDefault()
$(this).append('<div class="error">You must select 'display' and enter notes.</div>')

Validate field is unique compared to another field in same form

Say I have two fields in a new or edit form:
<%= f.text_field :email %>
<%= f.text_field :parent_email %>
How, in my model, can I validate that parent_email is different from email? The exclusion option seems like it might work, but I can't figure out how to access the email field's value within the model. Do I need to implement this in the controller instead?
validates :parent_email, exclusion: self.email # doesn't work, nor does :email
The following should work (but I guess there are cooler solutions out there):
class User
validate :email_differs_from_parent_email
private
def email_differs_from_parent_email
if email == parent_email
errors.add(:parent_email, "parent_email must differ from email")
end
end
end

Customize error message with simple_form

I'm using the simple_form gem. I want to customize the error message displayed when a user fails validations. How can I accomplish this?
You can declare the content of the
error message in your model:
validates_length_of :name, :minimum => 5, :message => "blah blah blah"
You can set id or class for your
error tag:
<%= f.input :name, :error_html => { :id => "name_error"} %>
Then you can use CSS for the styling.
And you can use
<%= f.error :name, :id => "name_error" %>
and you'll get
<span class="error" id="name_error">is too short (minimum is 5 characters)</span>
I dont know if it is any different for simple_form gem.
For content of error messages to be changed, you can use the :message attribute in the model.
class User < ActiveRecord::Base
validates :email, {:presence => true, :message => "is not filled up."}
end
Now the validation message will be Email is not filled up. If you want the field name also to be changed(Email to E-mail address something like that ), the approach now is to define it in locales.rb file like this
# config/locales/en.yml
en:
activerecord:
attributes:
user:
email: "E-mail address"
See link for details on locales. Another approach is to define in the model, humanized attributes like this:
class User < ActiveRecord::Base
validates :email, {:presence => true, :message => "is not filled up."}
HUMANIZED_ATTRIBUTES = {
:email => "E-mail address",
...(other fields and their humanized names)
...
}
def self.human_attribute_name(attr, options={})
HUMANIZED_ATTRIBUTES[attr.to_sym] || super
end
end
For customizing style of validation message we will have to edit the style for
#errorExplanation and .fieldWithErrors,in the scaffold.css stylesheet.
You can easily change the default error message comes in the translation file, which is found in config/locales/simple_form.en.yml.
In the specific initializer, config/initializers/simple_form.rb you can overrule the default options how the html is generated.
Hope this helps.
For completeness, I would like to add that formtastic is an easier choice to start with, because it has a default layout. I like simple_form a lot, but it does not offer any formatting out of the box, but that is their intention. With Formtastic it is very hard (impossible) to change the generated html, and with simple_form can you can completely mold the generated html to your liking. This is especially useful if you have a designer, and the forms you generate have to generate the same html. So if you are getting started, formtastic will give you nicer-looking results quicker. Also note that it is quite easy to switch, because the syntax is almost identical.
There is another solution explained here that wasn't mentioned in the answers. You can directly override the error messages from the views, in the form itself. For example:
<%= f.input :last_name,
placeholder: 'last_name',
error: 'This is a custom error message',
required: true,
class: 'form-field',
autofocus: true,
input_html: { autocomplete: "last_name" } %>
It is however not advised as it is not DRY, you would need to override it in every field.

Validating auto complete input for associations

Ok, so I'm probably missing something obvious here. I'm using rails3-jquery-autocomplete and formtastic to allow the user to select a Category when creating an Item:
class Category < ActiveRecord::Base
has_many :items
end
class Item < ActiveRecord::Base
belongs_to :category
validates :category_id, :presence => true
end
I got this working via:
semantic_form_for #item do |form|
form.inputs do
form.input :category_id, :as => :hidden
form.autocompleted_input :category,
:url => autocomplete_category_path,
:id_element => "#item_category_id"
end
end
That all works fine and dandy; when the user selects the category name, the category_id goes into the hidden field, and the item saves appropriately.
However i run into problems validating when the user doesn't input/select a valid category. What is the appropriate way to validate the following cases:
User types something in to the box that is not valid category. (this needs to fail. It fails now, but the inline errors are actually on the hidden field)
User makes a selection, then changes the value of the text field to an invalid category (resulting in the id in the hidden field becoming stale. This should also fail, but instead it uses the stale selected Id)
Thanks!
It seems like you are looking for jQuery Tokeninput.
You just serve your categories via REST or include the JSON into the initialization
$("#mytokeninputfield").tokenInput("/categories.json",
{
tokenLimit: 1 // allow at most 1 item
});
<input type="text" id="mytokeninputfield" name="item[category_tokens]" data-pre="<%= #user.category_id %>"/>
See railscast #258 on tokenfields and my gem tokenizes as well (although I currently don't use it feel free to report bugs and I'll take care of it. Or just get inspired and do it on your own :) )

Resources