├── lib ├── client_side_validations │ ├── version.rb │ ├── core_ext.rb │ ├── engine.rb │ ├── active_model │ │ ├── presence.rb │ │ ├── acceptance.rb │ │ ├── inclusion.rb │ │ ├── exclusion.rb │ │ ├── format.rb │ │ ├── length.rb │ │ └── numericality.rb │ ├── core_ext │ │ ├── range.rb │ │ └── regexp.rb │ ├── generators.rb │ ├── config.rb │ ├── files.rb │ ├── generators │ │ └── rails_validations.rb │ ├── action_view │ │ ├── form_tag_helper.rb │ │ ├── form_builder.rb │ │ └── form_helper.rb │ ├── action_view.rb │ ├── active_record.rb │ ├── active_record │ │ ├── uniqueness.rb │ │ └── middleware.rb │ ├── active_model.rb │ └── middleware.rb ├── client_side_validations.rb └── generators │ ├── client_side_validations │ ├── install_generator.rb │ └── copy_assets_generator.rb │ └── templates │ └── client_side_validations │ └── initializer.rb ├── .travis.yml ├── test ├── javascript │ ├── config.ru │ ├── public │ │ ├── test │ │ │ ├── utilities.js │ │ │ ├── settings.js │ │ │ ├── validators │ │ │ │ ├── presence.js │ │ │ │ ├── confirmation.js │ │ │ │ ├── format.js │ │ │ │ ├── acceptance.js │ │ │ │ ├── exclusion.js │ │ │ │ ├── inclusion.js │ │ │ │ ├── length.js │ │ │ │ ├── uniqueness.js │ │ │ │ └── numericality.js │ │ │ ├── disableValidators.js │ │ │ ├── callbacks │ │ │ │ ├── formAfter.js │ │ │ │ ├── formBefore.js │ │ │ │ ├── formPass.js │ │ │ │ ├── formFail.js │ │ │ │ ├── elementBefore.js │ │ │ │ ├── elementAfter.js │ │ │ │ ├── elementPass.js │ │ │ │ └── elementFail.js │ │ │ ├── form_builders │ │ │ │ └── validateForm.js │ │ │ └── validateElement.js │ │ └── vendor │ │ │ ├── jquery.metadata.js │ │ │ └── qunit.css │ ├── views │ │ ├── layout.erb │ │ └── index.erb │ └── server.rb ├── active_model │ ├── cases │ │ ├── helper.rb │ │ ├── test_base.rb │ │ ├── test_presence_validator.rb │ │ ├── test_confirmation_validator.rb │ │ ├── test_acceptance_validator.rb │ │ ├── test_exclusion_validator.rb │ │ ├── test_inclusion_validator.rb │ │ ├── test_format_validator.rb │ │ ├── test_length_validator.rb │ │ ├── test_numericality_validator.rb │ │ └── test_validations.rb │ └── models │ │ └── person.rb ├── action_view │ ├── models.rb │ ├── models │ │ ├── comment.rb │ │ └── post.rb │ └── cases │ │ ├── helper.rb │ │ └── test_legacy_helpers.rb ├── active_record │ ├── models │ │ ├── guid.rb │ │ ├── thing.rb │ │ └── user.rb │ └── cases │ │ ├── test_base.rb │ │ ├── helper.rb │ │ ├── test_uniqueness_validator.rb │ │ └── test_middleware.rb ├── test_loader.rb ├── middleware │ └── cases │ │ ├── helper.rb │ │ └── test_middleware.rb ├── base_helper.rb ├── core_ext │ └── cases │ │ └── test_core_ext.rb └── generators │ └── cases │ └── test_generators.rb ├── .gitignore ├── Gemfile ├── coffeescript ├── processor.rb └── rails.validations.coffee ├── client_side_validations.gemspec ├── CONTRIBUTING.md ├── HISTORY.md └── Rakefile /lib/client_side_validations/version.rb: -------------------------------------------------------------------------------- 1 | module ClientSideValidations 2 | VERSION = '3.2.6' 3 | end 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | rvm: 2 | - 1.9.3 3 | before_install: 4 | - gem update --system 5 | - gem install bundler --pre 6 | -------------------------------------------------------------------------------- /test/javascript/config.ru: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path('..', __FILE__) 2 | require 'server' 3 | run Sinatra::Application 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | *.lock 4 | pkg/* 5 | tags 6 | test/generators/tmp/* 7 | *.swp 8 | .*rc 9 | bundler_stubs/* 10 | binstubs/* 11 | bin/* 12 | -------------------------------------------------------------------------------- /test/active_model/cases/helper.rb: -------------------------------------------------------------------------------- 1 | require 'base_helper' 2 | require 'active_model' 3 | require 'client_side_validations/active_model' 4 | require 'active_model/models/person' 5 | -------------------------------------------------------------------------------- /lib/client_side_validations/core_ext.rb: -------------------------------------------------------------------------------- 1 | require 'active_support/json' 2 | require 'client_side_validations/core_ext/range' 3 | require 'client_side_validations/core_ext/regexp' 4 | -------------------------------------------------------------------------------- /test/action_view/models.rb: -------------------------------------------------------------------------------- 1 | require 'active_model' 2 | require 'client_side_validations/active_model' 3 | require 'action_view/models/comment' 4 | require 'action_view/models/post' 5 | -------------------------------------------------------------------------------- /lib/client_side_validations/engine.rb: -------------------------------------------------------------------------------- 1 | module ClientSideValidations 2 | class Engine < ::Rails::Engine 3 | config.app_middleware.use ClientSideValidations::Middleware::Validators 4 | end 5 | end 6 | 7 | -------------------------------------------------------------------------------- /test/active_record/models/guid.rb: -------------------------------------------------------------------------------- 1 | guids_table = %{CREATE TABLE guids (id INTEGER PRIMARY KEY, key text);} 2 | ActiveRecord::Base.connection.execute(guids_table) 3 | 4 | class Guid < ActiveRecord::Base 5 | 6 | end 7 | 8 | -------------------------------------------------------------------------------- /lib/client_side_validations/active_model/presence.rb: -------------------------------------------------------------------------------- 1 | module ClientSideValidations::ActiveModel 2 | module Presence 3 | private 4 | 5 | def message_type 6 | :blank 7 | end 8 | end 9 | end 10 | 11 | -------------------------------------------------------------------------------- /lib/client_side_validations/core_ext/range.rb: -------------------------------------------------------------------------------- 1 | class Range 2 | def as_json(options = nil) 3 | [first, last] 4 | end 5 | 6 | def to_json(options = nil) 7 | as_json(options).inspect 8 | end 9 | end 10 | 11 | -------------------------------------------------------------------------------- /lib/client_side_validations/active_model/acceptance.rb: -------------------------------------------------------------------------------- 1 | module ClientSideValidations::ActiveModel 2 | module Acceptance 3 | private 4 | 5 | def message_type 6 | :accepted 7 | end 8 | end 9 | end 10 | 11 | -------------------------------------------------------------------------------- /test/test_loader.rb: -------------------------------------------------------------------------------- 1 | # Sanity check to make sure the entire library loads OK 2 | 3 | require 'base_helper' 4 | require 'client_side_validations' 5 | require 'client_side_validations/files' 6 | require 'client_side_validations/version' 7 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | # Specify your gem's dependencies in client_side_validations.gemspec 4 | gemspec 5 | 6 | if RUBY_VERSION >= '1.9.3' 7 | gem 'debugger' 8 | elsif RUBY_VERSION < '1.9' 9 | gem 'minitest' 10 | end 11 | -------------------------------------------------------------------------------- /test/active_model/cases/test_base.rb: -------------------------------------------------------------------------------- 1 | require 'active_model/cases/helper' 2 | 3 | class ClientSideValidations::ActiveModelTestBase < ActiveModel::TestCase 4 | include ActiveModel::Validations 5 | 6 | def setup 7 | @person = Person.new 8 | end 9 | 10 | end 11 | 12 | -------------------------------------------------------------------------------- /test/active_record/cases/test_base.rb: -------------------------------------------------------------------------------- 1 | require 'active_record/cases/helper' 2 | 3 | class ClientSideValidations::ActiveRecordTestBase < ActiveRecord::TestCase 4 | include ActiveRecord::Validations 5 | 6 | def setup 7 | @user = User.new 8 | end 9 | 10 | end 11 | 12 | -------------------------------------------------------------------------------- /test/middleware/cases/helper.rb: -------------------------------------------------------------------------------- 1 | require 'base_helper' 2 | require 'action_controller' 3 | require 'action_controller/railtie' 4 | require 'client_side_validations/middleware' 5 | require 'client_side_validations/engine' 6 | require 'active_record/cases/helper' 7 | 8 | TestApp::Application.initialize! 9 | -------------------------------------------------------------------------------- /lib/client_side_validations/generators.rb: -------------------------------------------------------------------------------- 1 | module ClientSideValidations 2 | module Generators 3 | Assets = [] 4 | 5 | def self.register_assets(klass) 6 | Assets.push(*klass.assets) 7 | end 8 | end 9 | end 10 | 11 | require 'client_side_validations/generators/rails_validations' 12 | 13 | -------------------------------------------------------------------------------- /test/active_record/models/thing.rb: -------------------------------------------------------------------------------- 1 | things_table = %{CREATE TABLE things (id INTEGER PRIMARY KEY, name text);} 2 | ActiveRecord::Base.connection.execute(things_table) 3 | 4 | class AbstractThing < ActiveRecord::Base 5 | self.abstract_class = true 6 | end 7 | 8 | class Thing < AbstractThing 9 | validates_uniqueness_of :name 10 | end 11 | -------------------------------------------------------------------------------- /lib/client_side_validations/config.rb: -------------------------------------------------------------------------------- 1 | module ClientSideValidations 2 | module Config 3 | class << self 4 | attr_accessor :disabled_validators 5 | attr_accessor :number_format_with_locale 6 | attr_accessor :root_path 7 | end 8 | 9 | self.disabled_validators = [] 10 | self.number_format_with_locale = false 11 | self.root_path = nil 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/client_side_validations/files.rb: -------------------------------------------------------------------------------- 1 | # This is only used by dependant libraries that need to find the files 2 | 3 | module ClientSideValidations 4 | module Files 5 | Initializer = File.expand_path(File.dirname(__FILE__) + '/../generators/templates/client_side_validations/initializer.rb') 6 | Javascript = File.expand_path(File.dirname(__FILE__) + '/../../vendor/assets/javascripts/rails.validations.js') 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /lib/client_side_validations/core_ext/regexp.rb: -------------------------------------------------------------------------------- 1 | class Regexp 2 | def as_json(options = nil) 3 | Regexp.new inspect.sub('\\A','^').sub('\\Z','$').sub('\\z','$').sub(/^\//,'').sub(/\/[a-z]*$/,'').gsub(/\(\?#.+\)/, '').gsub(/\(\?-\w+:/,'(').gsub(/\s/,''), self.options & 5 4 | end 5 | 6 | def to_json(options = nil) 7 | as_json(options).inspect 8 | end 9 | 10 | def encode_json(encoder) 11 | inspect 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/client_side_validations/generators/rails_validations.rb: -------------------------------------------------------------------------------- 1 | module ClientSideValidations 2 | module Generators 3 | class RailsValidations 4 | def self.assets 5 | [{ 6 | :path => File.expand_path('../../../../vendor/assets/javascripts', __FILE__), 7 | :file => 'rails.validations.js' 8 | }] 9 | end 10 | 11 | Generators.register_assets(self) 12 | end 13 | end 14 | end 15 | 16 | -------------------------------------------------------------------------------- /test/active_model/models/person.rb: -------------------------------------------------------------------------------- 1 | class PersonValidator < ActiveModel::Validator 2 | def validate(record) 3 | end 4 | end 5 | 6 | class Person 7 | include ActiveModel::Validations 8 | 9 | attr_accessor :first_name, :last_name, :email, :age 10 | 11 | validates_presence_of :first_name 12 | validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i 13 | 14 | def new_record? 15 | true 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /test/active_record/cases/helper.rb: -------------------------------------------------------------------------------- 1 | require 'base_helper' 2 | require 'active_record' 3 | require 'client_side_validations/active_record' 4 | 5 | # Connection must be establised before anything else 6 | ActiveRecord::Base.establish_connection( 7 | :adapter => defined?(JRUBY_VERSION) ? 'jdbcsqlite3' : 'sqlite3', 8 | :database => ':memory:' 9 | ) 10 | 11 | require 'active_record/models/user' 12 | require 'active_record/models/guid' 13 | require 'active_record/models/thing' 14 | -------------------------------------------------------------------------------- /test/action_view/models/comment.rb: -------------------------------------------------------------------------------- 1 | class Comment 2 | extend ActiveModel::Naming 3 | extend ActiveModel::Translation 4 | include ActiveModel::Validations 5 | include ActiveModel::Conversion 6 | 7 | attr_reader :id, :post_id, :title, :body 8 | validates :title, :body, :presence => true 9 | 10 | def initialize(params={}) 11 | params.each do |attr, value| 12 | self.public_send("#{attr}=", value) 13 | end if params 14 | end 15 | 16 | def persisted? 17 | false 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/client_side_validations/action_view/form_tag_helper.rb: -------------------------------------------------------------------------------- 1 | module ClientSideValidations::ActionView::Helpers 2 | module FormTagHelper 3 | private 4 | def html_options_for_form(url_for_options, options, *parameters_for_url) 5 | options.stringify_keys! 6 | html_options = {} 7 | html_options['data-validate'] = options.delete('validate') if options['validate'] 8 | html_options.merge!(super(url_for_options, options, *parameters_for_url)) 9 | end 10 | end 11 | end 12 | 13 | -------------------------------------------------------------------------------- /test/base_helper.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'bundler/setup' 3 | require 'test/unit' 4 | if RUBY_VERSION >= '1.9.3' 5 | require 'debugger' 6 | end 7 | require 'mocha/setup' 8 | require 'rails' 9 | require 'client_side_validations/config' 10 | 11 | module TestApp 12 | class Application < Rails::Application 13 | config.root = File.dirname(__FILE__) 14 | config.active_support.deprecation = :log 15 | config.logger = Logger.new(STDOUT) 16 | end 17 | end 18 | 19 | module ClientSideValidations; end 20 | -------------------------------------------------------------------------------- /lib/client_side_validations.rb: -------------------------------------------------------------------------------- 1 | module ClientSideValidations 2 | end 3 | 4 | require 'client_side_validations/config' 5 | require 'client_side_validations/active_model' if defined?(::ActiveModel) 6 | require 'client_side_validations/active_record' if defined?(::ActiveRecord) 7 | require 'client_side_validations/action_view' if defined?(::ActionView) 8 | if defined?(::Rails) 9 | require 'client_side_validations/generators' 10 | require 'client_side_validations/middleware' 11 | require 'client_side_validations/engine' 12 | end 13 | 14 | -------------------------------------------------------------------------------- /test/javascript/public/test/utilities.js: -------------------------------------------------------------------------------- 1 | module('Utilities'); 2 | 3 | test('Remote Validator Url without setting', function() { 4 | ClientSideValidations.remote_validators_prefix = undefined; 5 | equal(ClientSideValidations.remote_validators_url_for('test'), '//'+window.location.host+'/validators/test'); 6 | }); 7 | 8 | test('Remote Validator Url with setting', function() { 9 | ClientSideValidations.remote_validators_prefix = 'other'; 10 | equal(ClientSideValidations.remote_validators_url_for('test'), '//'+window.location.host+'/other/validators/test'); 11 | }); 12 | -------------------------------------------------------------------------------- /test/javascript/public/test/settings.js: -------------------------------------------------------------------------------- 1 | // hijacks normal form submit; lets it submit to an iframe to prevent 2 | // navigating away from the test suite 3 | $(document).bind('submit', function(e) { 4 | if (!e.isDefaultPrevented()) { 5 | var form = $(e.target), action = form.attr('action'), 6 | name = 'form-frame' + jQuery.guid++, 7 | iframe = $('