Merge pull request #876 from opf/fix/error_message_accessibility_4087
[FIX] Error message accessibility 4087pull/904/head
commit
1ecb3b620a
@ -0,0 +1,32 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2013 the OpenProject Foundation (OPF)
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License version 3.
|
||||||
|
//
|
||||||
|
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||||
|
// Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||||
|
// Copyright (C) 2010-2013 the ChiliProject Team
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
//
|
||||||
|
// See doc/COPYRIGHT.rdoc for more details.
|
||||||
|
//++
|
||||||
|
|
||||||
|
jQuery(document).ajaxComplete(function() { |
||||||
|
activateError(); |
||||||
|
}); |
||||||
|
|
@ -0,0 +1,35 @@ |
|||||||
|
/*-- copyright |
||||||
|
* OpenProject is a project management system. |
||||||
|
* Copyright (C) 2012-2013 the OpenProject Foundation (OPF) |
||||||
|
* |
||||||
|
* This program is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU General Public License version 3. |
||||||
|
* |
||||||
|
* OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||||
|
* Copyright (C) 2006-2013 Jean-Philippe Lang |
||||||
|
* Copyright (C) 2010-2013 the ChiliProject Team |
||||||
|
* |
||||||
|
* This program is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU General Public License |
||||||
|
* as published by the Free Software Foundation; either version 2 |
||||||
|
* of the License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program; if not, write to the Free Software |
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||||
|
* |
||||||
|
* See doc/COPYRIGHT.rdoc for more details. ++ |
||||||
|
*/ |
||||||
|
|
||||||
|
@mixin hidden_for_sighted |
||||||
|
position: absolute |
||||||
|
left: -10000px |
||||||
|
top: auto |
||||||
|
width: 1px |
||||||
|
height: 1px |
||||||
|
overflow: hidden |
@ -0,0 +1,38 @@ |
|||||||
|
<%#-- copyright |
||||||
|
OpenProject is a project management system. |
||||||
|
Copyright (C) 2012-2013 the OpenProject Foundation (OPF) |
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or |
||||||
|
modify it under the terms of the GNU General Public License version 3. |
||||||
|
|
||||||
|
OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||||
|
Copyright (C) 2006-2013 Jean-Philippe Lang |
||||||
|
Copyright (C) 2010-2013 the ChiliProject Team |
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or |
||||||
|
modify it under the terms of the GNU General Public License |
||||||
|
as published by the Free Software Foundation; either version 2 |
||||||
|
of the License, or (at your option) any later version. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License |
||||||
|
along with this program; if not, write to the Free Software |
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||||
|
|
||||||
|
See doc/COPYRIGHT.rdoc for more details. |
||||||
|
|
||||||
|
++#%> |
||||||
|
|
||||||
|
<div class="errorExplanation" id="errorExplanation"> |
||||||
|
<h2 role="alert"><%= l("activerecord.errors.template.header.#{(error_messages.count == 1) ? 'one' : 'other'}", count: error_messages.count, model: object_name) %></h2> |
||||||
|
<p><%= l("errors.header_invalid_fields") %></p> |
||||||
|
<ul> |
||||||
|
<% error_messages.each do |message| %> |
||||||
|
<li><%= message %></li> |
||||||
|
<% end %> |
||||||
|
</ul> |
||||||
|
</div> |
@ -1,20 +0,0 @@ |
|||||||
Copyright (c) 2010 David Heinemeier Hansson |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining |
|
||||||
a copy of this software and associated documentation files (the |
|
||||||
"Software"), to deal in the Software without restriction, including |
|
||||||
without limitation the rights to use, copy, modify, merge, publish, |
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to |
|
||||||
permit persons to whom the Software is furnished to do so, subject to |
|
||||||
the following conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be |
|
||||||
included in all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
|
||||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
@ -1,13 +0,0 @@ |
|||||||
DynamicForm |
|
||||||
=========== |
|
||||||
|
|
||||||
DynamicForm holds a few helpers method to help you deal with your models, they are: |
|
||||||
|
|
||||||
* input(record, method, options = {}) |
|
||||||
* form(record, options = {}) |
|
||||||
* error_message_on(object, method, options={}) |
|
||||||
* error_messages_for(record, options={}) |
|
||||||
|
|
||||||
It also adds f.error_messages and f.error_messages_on to your form builders. |
|
||||||
|
|
||||||
Copyright (c) 2010 David Heinemeier Hansson, released under the MIT license |
|
@ -1,10 +0,0 @@ |
|||||||
require 'rake/testtask' |
|
||||||
|
|
||||||
desc 'Default: run unit tests.' |
|
||||||
task :default => :test |
|
||||||
|
|
||||||
desc 'Test the active_model_helper plugin.' |
|
||||||
Rake::TestTask.new(:test) do |t| |
|
||||||
t.libs << 'test' |
|
||||||
t.pattern = 'test/**/*_test.rb' |
|
||||||
end |
|
@ -1,12 +0,0 @@ |
|||||||
Gem::Specification.new do |s| |
|
||||||
s.name = 'dynamic_form' |
|
||||||
s.version = '1.0.0' |
|
||||||
s.author = 'David Heinemeier Hansson' |
|
||||||
s.email = 'david@loudthinking.com' |
|
||||||
s.summary = 'Deprecated dynamic form helpers: input, form, error_messages_for, error_messages_on' |
|
||||||
|
|
||||||
s.add_dependency('rails', '>= 3.0.0') |
|
||||||
|
|
||||||
s.files = Dir['lib/**/*'] |
|
||||||
s.require_path = 'lib' |
|
||||||
end |
|
@ -1 +0,0 @@ |
|||||||
require 'dynamic_form' |
|
@ -1,300 +0,0 @@ |
|||||||
require 'action_view/helpers' |
|
||||||
require 'active_support/i18n' |
|
||||||
require 'active_support/core_ext/enumerable' |
|
||||||
require 'active_support/core_ext/object/blank' |
|
||||||
|
|
||||||
module ActionView |
|
||||||
module Helpers |
|
||||||
# The Active Record Helper makes it easier to create forms for records kept in instance variables. The most far-reaching is the +form+ |
|
||||||
# method that creates a complete form for all the basic content types of the record (not associations or aggregations, though). This |
|
||||||
# is a great way of making the record quickly available for editing, but likely to prove lackluster for a complicated real-world form. |
|
||||||
# In that case, it's better to use the +input+ method and the specialized +form+ methods in link:classes/ActionView/Helpers/FormHelper.html |
|
||||||
module DynamicForm |
|
||||||
# Returns a default input tag for the type of object returned by the method. For example, if <tt>@post</tt> |
|
||||||
# has an attribute +title+ mapped to a +VARCHAR+ column that holds "Hello World": |
|
||||||
# |
|
||||||
# input("post", "title") |
|
||||||
# # => <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /> |
|
||||||
def input(record_name, method, options = {}) |
|
||||||
InstanceTag.new(record_name, method, self).to_tag(options) |
|
||||||
end |
|
||||||
|
|
||||||
# Returns an entire form with all needed input tags for a specified Active Record object. For example, if <tt>@post</tt> |
|
||||||
# has attributes named +title+ of type +VARCHAR+ and +body+ of type +TEXT+ then |
|
||||||
# |
|
||||||
# form("post") |
|
||||||
# |
|
||||||
# would yield a form like the following (modulus formatting): |
|
||||||
# |
|
||||||
# <form action='/posts/create' method='post'> |
|
||||||
# <p> |
|
||||||
# <label for="post_title">Title</label><br /> |
|
||||||
# <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /> |
|
||||||
# </p> |
|
||||||
# <p> |
|
||||||
# <label for="post_body">Body</label><br /> |
|
||||||
# <textarea cols="40" id="post_body" name="post[body]" rows="20"></textarea> |
|
||||||
# </p> |
|
||||||
# <input name="commit" type="submit" value="Create" /> |
|
||||||
# </form> |
|
||||||
# |
|
||||||
# It's possible to specialize the form builder by using a different action name and by supplying another |
|
||||||
# block renderer. For example, if <tt>@entry</tt> has an attribute +message+ of type +VARCHAR+ then |
|
||||||
# |
|
||||||
# form("entry", |
|
||||||
# :action => "sign", |
|
||||||
# :input_block => Proc.new { |record, column| |
|
||||||
# "#{column.human_name}: #{input(record, column.name)}<br />" |
|
||||||
# }) |
|
||||||
# |
|
||||||
# would yield a form like the following (modulus formatting): |
|
||||||
# |
|
||||||
# <form action="/entries/sign" method="post"> |
|
||||||
# Message: |
|
||||||
# <input id="entry_message" name="entry[message]" size="30" type="text" /><br /> |
|
||||||
# <input name="commit" type="submit" value="Sign" /> |
|
||||||
# </form> |
|
||||||
# |
|
||||||
# It's also possible to add additional content to the form by giving it a block, such as: |
|
||||||
# |
|
||||||
# form("entry", :action => "sign") do |form| |
|
||||||
# form << content_tag("b", "Department") |
|
||||||
# form << collection_select("department", "id", @departments, "id", "name") |
|
||||||
# end |
|
||||||
# |
|
||||||
# The following options are available: |
|
||||||
# |
|
||||||
# * <tt>:action</tt> - The action used when submitting the form (default: +create+ if a new record, otherwise +update+). |
|
||||||
# * <tt>:input_block</tt> - Specialize the output using a different block, see above. |
|
||||||
# * <tt>:method</tt> - The method used when submitting the form (default: +post+). |
|
||||||
# * <tt>:multipart</tt> - Whether to change the enctype of the form to "multipart/form-data", used when uploading a file (default: +false+). |
|
||||||
# * <tt>:submit_value</tt> - The text of the submit button (default: "Create" if a new record, otherwise "Update"). |
|
||||||
def form(record_name, options = {}) |
|
||||||
record = instance_variable_get("@#{record_name}") |
|
||||||
record = convert_to_model(record) |
|
||||||
|
|
||||||
options = options.symbolize_keys |
|
||||||
options[:action] ||= record.persisted? ? "update" : "create" |
|
||||||
action = url_for(:action => options[:action], :id => record) |
|
||||||
|
|
||||||
submit_value = options[:submit_value] || options[:action].gsub(/[^\w]/, '').capitalize |
|
||||||
|
|
||||||
contents = form_tag({:action => action}, :method =>(options[:method] || 'post'), :enctype => options[:multipart] ? 'multipart/form-data': nil) |
|
||||||
contents.safe_concat hidden_field(record_name, :id) if record.persisted? |
|
||||||
contents.safe_concat all_input_tags(record, record_name, options) |
|
||||||
yield contents if block_given? |
|
||||||
contents.safe_concat submit_tag(submit_value) |
|
||||||
contents.safe_concat('</form>') |
|
||||||
end |
|
||||||
|
|
||||||
# Returns a string containing the error message attached to the +method+ on the +object+ if one exists. |
|
||||||
# This error message is wrapped in a <tt>DIV</tt> tag by default or with <tt>:html_tag</tt> if specified, |
|
||||||
# which can be extended to include a <tt>:prepend_text</tt> and/or <tt>:append_text</tt> (to properly explain |
|
||||||
# the error), and a <tt>:css_class</tt> to style it accordingly. +object+ should either be the name of an |
|
||||||
# instance variable or the actual object. The method can be passed in either as a string or a symbol. |
|
||||||
# As an example, let's say you have a model <tt>@post</tt> that has an error message on the +title+ attribute: |
|
||||||
# |
|
||||||
# <%= error_message_on "post", "title" %> |
|
||||||
# # => <div class="formError">can't be empty</div> |
|
||||||
# |
|
||||||
# <%= error_message_on @post, :title %> |
|
||||||
# # => <div class="formError">can't be empty</div> |
|
||||||
# |
|
||||||
# <%= error_message_on "post", "title", |
|
||||||
# :prepend_text => "Title simply ", |
|
||||||
# :append_text => " (or it won't work).", |
|
||||||
# :html_tag => "span", |
|
||||||
# :css_class => "inputError" %> |
|
||||||
# # => <span class="inputError">Title simply can't be empty (or it won't work).</span> |
|
||||||
def error_message_on(object, method, *args) |
|
||||||
options = args.extract_options! |
|
||||||
unless args.empty? |
|
||||||
ActiveSupport::Deprecation.warn('error_message_on takes an option hash instead of separate ' + |
|
||||||
'prepend_text, append_text, html_tag, and css_class arguments', caller) |
|
||||||
|
|
||||||
options[:prepend_text] = args[0] || '' |
|
||||||
options[:append_text] = args[1] || '' |
|
||||||
options[:html_tag] = args[2] || 'div' |
|
||||||
options[:css_class] = args[3] || 'formError' |
|
||||||
end |
|
||||||
options.reverse_merge!(:prepend_text => '', :append_text => '', :html_tag => 'div', :css_class => 'formError') |
|
||||||
|
|
||||||
object = convert_to_model(object) |
|
||||||
|
|
||||||
if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) && |
|
||||||
(errors = obj.errors[method]).presence |
|
||||||
content_tag(options[:html_tag], |
|
||||||
(options[:prepend_text].html_safe << errors.first).safe_concat(options[:append_text]), |
|
||||||
:class => options[:css_class] |
|
||||||
) |
|
||||||
else |
|
||||||
'' |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
# Returns a string with a <tt>DIV</tt> containing all of the error messages for the objects located as instance variables by the names |
|
||||||
# given. If more than one object is specified, the errors for the objects are displayed in the order that the object names are |
|
||||||
# provided. |
|
||||||
# |
|
||||||
# This <tt>DIV</tt> can be tailored by the following options: |
|
||||||
# |
|
||||||
# * <tt>:header_tag</tt> - Used for the header of the error div (default: "h2"). |
|
||||||
# * <tt>:id</tt> - The id of the error div (default: "errorExplanation"). |
|
||||||
# * <tt>:class</tt> - The class of the error div (default: "errorExplanation"). |
|
||||||
# * <tt>:object</tt> - The object (or array of objects) for which to display errors, |
|
||||||
# if you need to escape the instance variable convention. |
|
||||||
# * <tt>:object_name</tt> - The object name to use in the header, or any text that you prefer. |
|
||||||
# If <tt>:object_name</tt> is not set, the name of the first object will be used. |
|
||||||
# * <tt>:header_message</tt> - The message in the header of the error div. Pass +nil+ |
|
||||||
# or an empty string to avoid the header message altogether. (Default: "X errors |
|
||||||
# prohibited this object from being saved"). |
|
||||||
# * <tt>:message</tt> - The explanation message after the header message and before |
|
||||||
# the error list. Pass +nil+ or an empty string to avoid the explanation message |
|
||||||
# altogether. (Default: "There were problems with the following fields:"). |
|
||||||
# |
|
||||||
# To specify the display for one object, you simply provide its name as a parameter. |
|
||||||
# For example, for the <tt>@user</tt> model: |
|
||||||
# |
|
||||||
# error_messages_for 'user' |
|
||||||
# |
|
||||||
# You can also supply an object: |
|
||||||
# |
|
||||||
# error_messages_for @user |
|
||||||
# |
|
||||||
# This will use the last part of the model name in the presentation. For instance, if |
|
||||||
# this is a MyKlass::User object, this will use "user" as the name in the String. This |
|
||||||
# is taken from MyKlass::User.model_name.human, which can be overridden. |
|
||||||
# |
|
||||||
# To specify more than one object, you simply list them; optionally, you can add an extra <tt>:object_name</tt> parameter, which |
|
||||||
# will be the name used in the header message: |
|
||||||
# |
|
||||||
# error_messages_for 'user_common', 'user', :object_name => 'user' |
|
||||||
# |
|
||||||
# You can also use a number of objects, which will have the same naming semantics |
|
||||||
# as a single object. |
|
||||||
# |
|
||||||
# error_messages_for @user, @post |
|
||||||
# |
|
||||||
# If the objects cannot be located as instance variables, you can add an extra <tt>:object</tt> parameter which gives the actual |
|
||||||
# object (or array of objects to use): |
|
||||||
# |
|
||||||
# error_messages_for 'user', :object => @question.user |
|
||||||
# |
|
||||||
# NOTE: This is a pre-packaged presentation of the errors with embedded strings and a certain HTML structure. If what |
|
||||||
# you need is significantly different from the default presentation, it makes plenty of sense to access the <tt>object.errors</tt> |
|
||||||
# instance yourself and set it up. View the source of this method to see how easy it is. |
|
||||||
def error_messages_for(*params) |
|
||||||
options = params.extract_options!.symbolize_keys |
|
||||||
|
|
||||||
objects = Array.wrap(options.delete(:object) || params).map do |object| |
|
||||||
object = instance_variable_get("@#{object}") unless object.respond_to?(:to_model) |
|
||||||
object = convert_to_model(object) |
|
||||||
|
|
||||||
if object.class.respond_to?(:model_name) |
|
||||||
options[:object_name] ||= object.class.model_name.human.downcase |
|
||||||
end |
|
||||||
|
|
||||||
object |
|
||||||
end |
|
||||||
|
|
||||||
objects.compact! |
|
||||||
count = objects.inject(0) {|sum, object| sum + object.errors.count } |
|
||||||
|
|
||||||
unless count.zero? |
|
||||||
html = {} |
|
||||||
[:id, :class].each do |key| |
|
||||||
if options.include?(key) |
|
||||||
value = options[key] |
|
||||||
html[key] = value unless value.blank? |
|
||||||
else |
|
||||||
html[key] = 'errorExplanation' |
|
||||||
end |
|
||||||
end |
|
||||||
options[:object_name] ||= params.first |
|
||||||
|
|
||||||
I18n.with_options :locale => options[:locale], :scope => [:errors, :template] do |locale| |
|
||||||
header_message = if options.include?(:header_message) |
|
||||||
options[:header_message] |
|
||||||
else |
|
||||||
locale.t :header, :count => count, :model => options[:object_name].to_s.gsub('_', ' ') |
|
||||||
end |
|
||||||
|
|
||||||
message = options.include?(:message) ? options[:message] : locale.t(:body) |
|
||||||
|
|
||||||
error_messages = objects.sum do |object| |
|
||||||
object.errors.full_messages.map do |msg| |
|
||||||
content_tag(:li, msg) |
|
||||||
end |
|
||||||
end.join.html_safe |
|
||||||
|
|
||||||
contents = '' |
|
||||||
contents << content_tag(options[:header_tag] || :h2, header_message) unless header_message.blank? |
|
||||||
contents << content_tag(:p, message) unless message.blank? |
|
||||||
contents << content_tag(:ul, error_messages) |
|
||||||
|
|
||||||
content_tag(:div, contents.html_safe, html) |
|
||||||
end |
|
||||||
else |
|
||||||
'' |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
private |
|
||||||
|
|
||||||
def all_input_tags(record, record_name, options) |
|
||||||
input_block = options[:input_block] || default_input_block |
|
||||||
record.class.content_columns.collect{ |column| input_block.call(record_name, column) }.join("\n") |
|
||||||
end |
|
||||||
|
|
||||||
def default_input_block |
|
||||||
Proc.new { |record, column| %(<p><label for="#{record}_#{column.name}">#{column.human_name}</label><br />#{input(record, column.name)}</p>) } |
|
||||||
end |
|
||||||
|
|
||||||
module InstanceTagMethods |
|
||||||
def to_tag(options = {}) |
|
||||||
case column_type |
|
||||||
when :string |
|
||||||
field_type = @method_name.include?("password") ? "password" : "text" |
|
||||||
to_input_field_tag(field_type, options) |
|
||||||
when :text |
|
||||||
to_text_area_tag(options) |
|
||||||
when :integer, :float, :decimal |
|
||||||
to_input_field_tag("text", options) |
|
||||||
when :date |
|
||||||
to_date_select_tag(options) |
|
||||||
when :datetime, :timestamp |
|
||||||
to_datetime_select_tag(options) |
|
||||||
when :time |
|
||||||
to_time_select_tag(options) |
|
||||||
when :boolean |
|
||||||
to_boolean_select_tag(options) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def column_type |
|
||||||
object.send(:column_for_attribute, @method_name).type |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
module FormBuilderMethods |
|
||||||
def error_message_on(method, *args) |
|
||||||
@template.error_message_on(@object || @object_name, method, *args) |
|
||||||
end |
|
||||||
|
|
||||||
def error_messages(options = {}) |
|
||||||
@template.error_messages_for(@object_name, objectify_options(options)) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
class InstanceTag |
|
||||||
include DynamicForm::InstanceTagMethods |
|
||||||
end |
|
||||||
|
|
||||||
class FormBuilder |
|
||||||
include DynamicForm::FormBuilderMethods |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
I18n.load_path << File.expand_path("../../locale/en.yml", __FILE__) |
|
@ -1,36 +0,0 @@ |
|||||||
#-- copyright |
|
||||||
# OpenProject is a project management system. |
|
||||||
# Copyright (C) 2012-2013 the OpenProject Foundation (OPF) |
|
||||||
# |
|
||||||
# This program is free software; you can redistribute it and/or |
|
||||||
# modify it under the terms of the GNU General Public License version 3. |
|
||||||
# |
|
||||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
|
||||||
# Copyright (C) 2006-2013 Jean-Philippe Lang |
|
||||||
# Copyright (C) 2010-2013 the ChiliProject Team |
|
||||||
# |
|
||||||
# This program is free software; you can redistribute it and/or |
|
||||||
# modify it under the terms of the GNU General Public License |
|
||||||
# as published by the Free Software Foundation; either version 2 |
|
||||||
# of the License, or (at your option) any later version. |
|
||||||
# |
|
||||||
# This program is distributed in the hope that it will be useful, |
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
# GNU General Public License for more details. |
|
||||||
# |
|
||||||
# You should have received a copy of the GNU General Public License |
|
||||||
# along with this program; if not, write to the Free Software |
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
||||||
# |
|
||||||
# See doc/COPYRIGHT.rdoc for more details. |
|
||||||
#++ |
|
||||||
|
|
||||||
en: |
|
||||||
errors: |
|
||||||
template: |
|
||||||
header: |
|
||||||
one: "1 error prohibited this %{model} from being saved" |
|
||||||
other: "%{count} errors prohibited this %{model} from being saved" |
|
||||||
# The variable :count is also available |
|
||||||
body: "There were problems with the following fields:" |
|
@ -1,5 +0,0 @@ |
|||||||
require 'action_view/helpers/dynamic_form' |
|
||||||
|
|
||||||
class ActionView::Base |
|
||||||
include DynamicForm |
|
||||||
end |
|
@ -1,42 +0,0 @@ |
|||||||
require 'test_helper' |
|
||||||
|
|
||||||
class DynamicFormI18nTest < Test::Unit::TestCase |
|
||||||
include ActionView::Context |
|
||||||
include ActionView::Helpers::DynamicForm |
|
||||||
|
|
||||||
attr_reader :request |
|
||||||
|
|
||||||
def setup |
|
||||||
@object = stub :errors => stub(:count => 1, :full_messages => ['full_messages']) |
|
||||||
@object.stub :to_model => @object |
|
||||||
@object.stub :class => stub(:model_name => stub(:human => "")) |
|
||||||
|
|
||||||
@object_name = 'book_seller' |
|
||||||
@object_name_without_underscore = 'book seller' |
|
||||||
|
|
||||||
stub(:content_tag).and_return 'content_tag' |
|
||||||
|
|
||||||
I18n.stub(:t).with(:'header', :locale => 'en', :scope => [:errors, :template], :count => 1, :model => '').and_return "1 error prohibited this from being saved" |
|
||||||
I18n.stub(:t).with(:'body', :locale => 'en', :scope => [:errors, :template]).and_return 'There were problems with the following fields:' |
|
||||||
end |
|
||||||
|
|
||||||
def test_error_messages_for_given_a_header_option_it_does_not_translate_header_message |
|
||||||
I18n.should_receive(:t).with(:'header', :locale => 'en', :scope => [:errors, :template], :count => 1, :model => '').never |
|
||||||
error_messages_for(:object => @object, :header_message => 'header message', :locale => 'en') |
|
||||||
end |
|
||||||
|
|
||||||
def test_error_messages_for_given_no_header_option_it_translates_header_message |
|
||||||
I18n.should_receive(:t).with(:'header', :locale => 'en', :scope => [:errors, :template], :count => 1, :model => '').and_return 'header message' |
|
||||||
error_messages_for(:object => @object, :locale => 'en') |
|
||||||
end |
|
||||||
|
|
||||||
def test_error_messages_for_given_a_message_option_it_does_not_translate_message |
|
||||||
I18n.should_receive(:t).with(:'body', :locale => 'en', :scope => [:errors, :template]).never |
|
||||||
error_messages_for(:object => @object, :message => 'message', :locale => 'en') |
|
||||||
end |
|
||||||
|
|
||||||
def test_error_messages_for_given_no_message_option_it_translates_message |
|
||||||
I18n.should_receive(:t).with(:'body', :locale => 'en', :scope => [:errors, :template]).and_return 'There were problems with the following fields:' |
|
||||||
error_messages_for(:object => @object, :locale => 'en') |
|
||||||
end |
|
||||||
end |
|
File diff suppressed because one or more lines are too long
@ -1,9 +0,0 @@ |
|||||||
require 'rubygems' |
|
||||||
require 'test/unit' |
|
||||||
require 'active_support' |
|
||||||
require 'active_support/core_ext' |
|
||||||
require 'action_view' |
|
||||||
require 'action_controller' |
|
||||||
require 'action_controller/test_case' |
|
||||||
require 'active_model' |
|
||||||
require 'action_view/helpers/dynamic_form' |
|
Loading…
Reference in new issue