waiable 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Accessibility related issue for rails core.txt~ +11 -0
- data/Contributing.md +11 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +55 -0
- data/Rakefile +10 -0
- data/grid parameter details.txt~ +26 -0
- data/lib/action_view/check_box.rb +47 -0
- data/lib/action_view/common_methods.rb +67 -0
- data/lib/action_view/date_select.rb +31 -0
- data/lib/action_view/errors.rb +40 -0
- data/lib/action_view/form_helper.rb +19 -0
- data/lib/action_view/radio_button.rb +34 -0
- data/lib/action_view/select.rb +38 -0
- data/lib/action_view/text_aria.rb +45 -0
- data/lib/action_view/text_field.rb +43 -0
- data/lib/waiable.rb +16 -0
- data/lib/waiable/railtie.rb +10 -0
- data/lib/waiable/version.rb +3 -0
- data/test/action_view/helpers/form_helper_test.rb +137 -0
- data/test/support/person.rb +35 -0
- data/test/test_helper.rb +11 -0
- data/waiable.gemspec +27 -0
- metadata +144 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 824374e1dfe7e06fc06445a53abcf6da92ffc297
|
|
4
|
+
data.tar.gz: 9edfaa3d46e041dd9d0bb990f67986d3db15b217
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: eacb2f463ae390c22f70c1bcfadee6cff60bef1973141f344df3ad2d8549b8ab2c6dacd4c2df31943ffadf83a86616750bc02d94b4738b93c914fb9952a10719
|
|
7
|
+
data.tar.gz: 987662d4de67d1035de79d631b6ece9b406b9c8a188588dd2766cdf8b6240f6fb320613cb2e8f56a200bcf84e70632b5f7d280c34590c88de3434f752574cc99
|
data/.gitignore
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Accessibility related issues for devise gem.
|
|
2
|
+
Sign up page:
|
|
3
|
+
1) aria-required(property) is missing.
|
|
4
|
+
Email, Password, Password Confirmation are manditory fields.
|
|
5
|
+
aria-required: indecates that user input is required on the element before a form may be submitted.
|
|
6
|
+
Note: The fact that the element is required is often presented visually (such as a sign or symbol after the widget). Using the aria-required attribute allows the author to explicitly convey to assistive technologies that an element is required.
|
|
7
|
+
2) Validation Errors must be accessible. After submitting Sign Up form and validation error display then focouse was not shipt on the error list.
|
|
8
|
+
Sign In page:
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
data/Contributing.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Quick guide:
|
|
4
|
+
|
|
5
|
+
1. Fork the repo.
|
|
6
|
+
2. Run the tests. We only take pull requests with passing tests, and it's great to know that you have a clean slate: `bundle && rake`
|
|
7
|
+
3. Add a test for your change. Only styling, documentation and refactoring changes don't require any new tests. If you are adding functionality or fixing a bug, we need a test!
|
|
8
|
+
4. Make the test pass.
|
|
9
|
+
5. Commit, with a meaningul describing message. This is very important!
|
|
10
|
+
6. Push to your fork and submit a pull request.
|
|
11
|
+
7. Wait for comments or feedback.
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2015 Techvision Software Solutions http://techvision.net.in
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# WAIAble
|
|
2
|
+
|
|
3
|
+
WAIAble gem is the Rails **W**​eb **A**​ccessibility **I**​nitiative for differently **able**.
|
|
4
|
+
|
|
5
|
+
WAIAble gem will add accessibility features in rails form and will make rails form fully accessible to
|
|
6
|
+
screen reader users and keyboard users. This gem forces all the form fields to be compliant with WAI-ARIA standards.
|
|
7
|
+
If you are looking to contribute, please go through the contributing section below.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Add it to your Gemfile:
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
gem 'waiable'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Run the following command to install it:
|
|
18
|
+
|
|
19
|
+
```console
|
|
20
|
+
bundle install
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
WAIAble gem will add different accessibility features to make rails form accessible for screen reader users and keyboard users. Visually this will not remove or change any existing functionalities provided by rails core and will include aria-properties for form fields to enhance screen reader performance. To make form labels accessible, aria-labelledby property is added and default id attribute gets generated for label_for element. For mandatory form fields, aria-required property gets added when presence validator is added for that form field. For text field and text area, when maxlength option is provided, aria-describedby property is added to that form field which will announce about the size limitation of that field to the screen reader. On form submission, if there is any error then these error messages are linkable and clicking on that linkwill shift the focus to the form field for which the error gets generated. Additionally the error message id will be added to the aria-describedby property which will announce the error message to the screen reader when the focus is on errorneous input field. For search field, aria-label property is added to provide information about the search field to the screen reader.
|
|
26
|
+
|
|
27
|
+
## Bug Reports
|
|
28
|
+
|
|
29
|
+
If you discover any bugs, feel free to create an issue on github. Please provide sufficient information so that we can fix the possible bug.
|
|
30
|
+
|
|
31
|
+
https://github.com/techvision/waiable/issues
|
|
32
|
+
|
|
33
|
+
## Maintainers
|
|
34
|
+
|
|
35
|
+
* Sanghapal Bhowate sangha@techvision.net.in
|
|
36
|
+
* Shantanu Choudhury shantanu@techvision.net.in
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
## Contributing
|
|
40
|
+
###Fork the repository
|
|
41
|
+
1. Fork it
|
|
42
|
+
https://github.com/techvision/waiable/fork
|
|
43
|
+
2. Create your feature branch (�git checkout -b my-new-feature�)
|
|
44
|
+
###Contribute at Pune Ruby Meetups
|
|
45
|
+
|
|
46
|
+
Starting December 2014, we are taking up contributions to WAIable as part of PRUG Meetups. So we would recommend to have an account on [Meetup](http://www.meetup.com/) and be part of [Pune Ruby Users Group](http://www.meetup.com/PuneRailsMeetup/).
|
|
47
|
+
Meetup events are being posted out there and we call upon contributions from vibrant Ruby community for WAIable.
|
|
48
|
+
You can join us in the meetup to have more insight into what Accessibility is all about and what we are doing in WAIable.
|
|
49
|
+
###Then contribute online
|
|
50
|
+
1. Commit your changes (�git commit -am 'Add some feature'�)
|
|
51
|
+
2. Push to the branch (�git push origin my-new-feature�)
|
|
52
|
+
3. Create new Pull Request
|
|
53
|
+
###Follow us
|
|
54
|
+
Twitter: @techvision_ss
|
|
55
|
+
Blog: http://accessiblerails.wordpress.com
|
data/Rakefile
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
|
2
|
+
require 'rake/testtask'
|
|
3
|
+
|
|
4
|
+
Rake::TestTask.new do |t|
|
|
5
|
+
t.libs << 'test'
|
|
6
|
+
#add more <dir>/<file> patterns by adding params to the new method below
|
|
7
|
+
t.test_files = FileList.new('test/test_*.rb', 'test/action_view/helpers/*_test.rb')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
task :default => :test
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
grid_for() parameter list
|
|
2
|
+
|
|
3
|
+
1) :id
|
|
4
|
+
2) rows count
|
|
5
|
+
3) columns count
|
|
6
|
+
4) data{}
|
|
7
|
+
5) grid_option{:class, :width, :hight}
|
|
8
|
+
6) rows_option{:class, :width, :hight, :BG_color}
|
|
9
|
+
7) cell_option{:class, :width, :hight, BG_color}
|
|
10
|
+
8) focusable cell[r,c]
|
|
11
|
+
9) header columns[]
|
|
12
|
+
|
|
13
|
+
various types of calls for grid_for method.
|
|
14
|
+
|
|
15
|
+
grid_for(:id, :rows_count, :columns_count)
|
|
16
|
+
grid_for(:id, :data{})
|
|
17
|
+
grid_for(:id, :header['Sr No', 'Name', 'Email'], :data{})
|
|
18
|
+
grid_for(:id, :rows_count, :header['Id', 'Name', 'Role', "Email"], readonly false)
|
|
19
|
+
grid_for(:id, :rows_count, :columns_count, :data{}, , :focusable_cell[2,3])
|
|
20
|
+
grid_for(:id, :rows_count, :rows_option{}, :data())
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
We are design grid widget in three fazes
|
|
24
|
+
1) Basic plain accessible grid with data
|
|
25
|
+
2) Including css classes and design part
|
|
26
|
+
3) Including advance functionality. Add different types of elements, images.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'action_view/common_methods'
|
|
2
|
+
require 'active_support/concern'
|
|
3
|
+
|
|
4
|
+
module Waiable
|
|
5
|
+
module Base
|
|
6
|
+
module CheckBox
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
include CommonMethods
|
|
9
|
+
|
|
10
|
+
included do
|
|
11
|
+
def render
|
|
12
|
+
options = @options.stringify_keys
|
|
13
|
+
options["type"] = "checkbox"
|
|
14
|
+
options["value"] = @checked_value
|
|
15
|
+
options["checked"] = "checked" if input_checked?(object, options)
|
|
16
|
+
options["aria"] = {}
|
|
17
|
+
options["aria"]["required"] = true if required_field?(@method_name) == true
|
|
18
|
+
add_aria_labelledby_for_values(@checked_value, options)
|
|
19
|
+
add_aria_describedby_values(options)
|
|
20
|
+
if options["multiple"]
|
|
21
|
+
add_default_name_and_id_for_value(@checked_value, options)
|
|
22
|
+
options.delete("multiple")
|
|
23
|
+
else
|
|
24
|
+
add_default_name_and_id(options)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
include_hidden = options.delete("include_hidden") { true }
|
|
28
|
+
checkbox = tag("input", options)
|
|
29
|
+
|
|
30
|
+
if include_hidden
|
|
31
|
+
hidden = hidden_field_for_checkbox(options)
|
|
32
|
+
hidden + checkbox
|
|
33
|
+
else
|
|
34
|
+
checkbox
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
[
|
|
44
|
+
ActionView::Helpers::Tags::CheckBox
|
|
45
|
+
].each do |t|
|
|
46
|
+
t.send :include, Waiable::Base::CheckBox
|
|
47
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'active_support/concern'
|
|
2
|
+
|
|
3
|
+
module Waiable
|
|
4
|
+
module CommonMethods
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
TAG_PREFIXES = ['aria', 'data', :aria, :data].to_set
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def options_for_rendering
|
|
12
|
+
options = @options.stringify_keys
|
|
13
|
+
options["size"] = options["maxlength"] unless options.key?("size")
|
|
14
|
+
options["type"] ||= field_type
|
|
15
|
+
options["value"] = options.fetch("value") {value_before_type_cast(object) } unless field_type == "file"
|
|
16
|
+
options["aria"] ||= {}
|
|
17
|
+
options["aria"]["required"] = true if required_field?(@method_name)
|
|
18
|
+
options["aria"]["label"] = "search #{@method_name}" if field_type == "search"
|
|
19
|
+
@options = options
|
|
20
|
+
add_aria_describedby_values(@options)
|
|
21
|
+
add_default_name_and_id(@options)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def add_aria_labelledby_for_values(tag_value, options)
|
|
25
|
+
arr_labelledby= []
|
|
26
|
+
options["aria"] ||= {}
|
|
27
|
+
arr_labelledby << "label_#{add_default_name_and_id(options)}"
|
|
28
|
+
if tag_value.nil?
|
|
29
|
+
options["aria"]["labelledby"] = arr_labelledby.join(" ")
|
|
30
|
+
else
|
|
31
|
+
arr_labelledby << "label_#{add_default_name_and_id(options)}_#{sanitized_value(tag_value)}"
|
|
32
|
+
options["aria"]["labelledby"] = arr_labelledby.join(" ")
|
|
33
|
+
end
|
|
34
|
+
options["aria"]["labelledby"]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def add_aria_describedby_values(options)
|
|
38
|
+
arr_describedby = []
|
|
39
|
+
options['aria'] ||= {}
|
|
40
|
+
if options["maxlength"]
|
|
41
|
+
arr_describedby << "maxlength_#{add_default_name_and_id(options)}"
|
|
42
|
+
options["aria"]["describedby"] = arr_describedby.join(" ")
|
|
43
|
+
end
|
|
44
|
+
arr_describedby << "error_#{add_default_name_and_id(options)}" if object_has_errors?
|
|
45
|
+
options["aria"]["describedby"] = arr_describedby.join(" ")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def required_field?(field)
|
|
50
|
+
object_class = @object_name.classify.constantize
|
|
51
|
+
if object_class.respond_to?(:validators_on)
|
|
52
|
+
object_class.validators_on(field.intern).detect do |validator|
|
|
53
|
+
if validator.is_a? ActiveModel::Validations::PresenceValidator
|
|
54
|
+
validator.is_a? ActiveModel::Validations::PresenceValidator
|
|
55
|
+
elsif validator.is_a? Mongoid::Validatable::PresenceValidator
|
|
56
|
+
validator.is_a? Mongoid::Validatable::PresenceValidator
|
|
57
|
+
end
|
|
58
|
+
end.present?
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'action_view/common_methods'
|
|
2
|
+
require 'active_support/concern'
|
|
3
|
+
|
|
4
|
+
module Waiable
|
|
5
|
+
module Base
|
|
6
|
+
module DateSelect
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
include CommonMethods
|
|
9
|
+
|
|
10
|
+
included do
|
|
11
|
+
def render
|
|
12
|
+
html_options = @html_options.stringify_keys
|
|
13
|
+
html_options["aria"] ||= {}
|
|
14
|
+
html_options["aria"]["required"] = true if required_field?(@method_name) == true
|
|
15
|
+
html_options["aria"]["labelledby"] = "label_#{add_default_name_and_id(html_options)}"
|
|
16
|
+
add_aria_describedby_values(html_options)
|
|
17
|
+
@html_options = html_options
|
|
18
|
+
error_wrapping(datetime_selector(@options, @html_options).send("select_#{select_type}").html_safe)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
[
|
|
28
|
+
ActionView::Helpers::Tags::DateSelect
|
|
29
|
+
].each do |t|
|
|
30
|
+
t.send :include, Waiable::Base::DateSelect
|
|
31
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'action_view/helpers/tag_helper'
|
|
2
|
+
require 'action_view/context'
|
|
3
|
+
require 'active_support/concern'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
module Waiable
|
|
7
|
+
module Errors
|
|
8
|
+
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
include ActionView::Helpers::TagHelper
|
|
11
|
+
include ActionView::Context
|
|
12
|
+
|
|
13
|
+
included do
|
|
14
|
+
def full_messages
|
|
15
|
+
map { |attribute, message| error_full_message(attribute, message) }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def error_full_message(attribute, message)
|
|
20
|
+
return message if attribute == :base
|
|
21
|
+
attr_name = attribute.to_s.tr('.', '_').humanize
|
|
22
|
+
attr_name = @base.class.human_attribute_name(attribute, default: attr_name)
|
|
23
|
+
I18n.t(:"errors.format", {
|
|
24
|
+
default: "%{attribute} %{message}",
|
|
25
|
+
attribute: attr_name,
|
|
26
|
+
message: message
|
|
27
|
+
})
|
|
28
|
+
content_tag :div, id: "error_#{@base.class.to_s.downcase}_#{attribute}" do
|
|
29
|
+
"<a href=\"javascript:document.getElementsByName('#{@base.class.to_s.downcase}[#{attribute}]')[0].focus()\">#{attr_name + " " + message}</a>".html_safe
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
[
|
|
37
|
+
ActiveModel::Errors
|
|
38
|
+
].each do |t|
|
|
39
|
+
t.send :include, Waiable::Errors
|
|
40
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module ActionView
|
|
2
|
+
module Helpers
|
|
3
|
+
module FormTagHelper
|
|
4
|
+
|
|
5
|
+
def label_tag(name = nil, content_or_options = nil, options = nil, &block)
|
|
6
|
+
if block_given? && content_or_options.is_a?(Hash)
|
|
7
|
+
options = content_or_options = content_or_options.stringify_keys
|
|
8
|
+
else
|
|
9
|
+
options ||= {}
|
|
10
|
+
options = options.stringify_keys
|
|
11
|
+
end
|
|
12
|
+
options["for"] = sanitize_to_id(name) unless name.blank? || options.has_key?("for")
|
|
13
|
+
options["id"] = "label_#{options['for']}" if options.has_key?("for")
|
|
14
|
+
content_tag :label, content_or_options || name.to_s.humanize, options, &block
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'action_view/common_methods'
|
|
2
|
+
require 'active_support/concern'
|
|
3
|
+
|
|
4
|
+
module Waiable
|
|
5
|
+
module Base
|
|
6
|
+
module RadioButton
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
include CommonMethods
|
|
9
|
+
|
|
10
|
+
included do
|
|
11
|
+
def render
|
|
12
|
+
options = @options.stringify_keys
|
|
13
|
+
options["type"] = "radio"
|
|
14
|
+
options["value"] = @tag_value
|
|
15
|
+
options["checked"] = "checked" if input_checked?(object, options)
|
|
16
|
+
options["aria"] ||= {}
|
|
17
|
+
options["aria"]["required"] = true if required_field?(@method_name) == true
|
|
18
|
+
add_aria_labelledby_for_values(@tag_value, options)
|
|
19
|
+
add_aria_describedby_values(options)
|
|
20
|
+
|
|
21
|
+
add_default_name_and_id_for_value(@tag_value, options)
|
|
22
|
+
tag("input", options)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
[
|
|
31
|
+
ActionView::Helpers::Tags::RadioButton
|
|
32
|
+
].each do |t|
|
|
33
|
+
t.send :include, Waiable::Base::RadioButton
|
|
34
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'action_view/common_methods'
|
|
2
|
+
require 'active_support/concern'
|
|
3
|
+
|
|
4
|
+
module Waiable
|
|
5
|
+
module Base
|
|
6
|
+
module Select
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
include CommonMethods
|
|
9
|
+
|
|
10
|
+
included do
|
|
11
|
+
def select_content_tag(option_tags, options, html_options)
|
|
12
|
+
html_options = html_options.stringify_keys
|
|
13
|
+
html_options['aria'] = {}
|
|
14
|
+
html_options['aria']['required'] = true if required_field?(@method_name) == true
|
|
15
|
+
add_aria_describedby_values(html_options)
|
|
16
|
+
add_default_name_and_id(html_options)
|
|
17
|
+
options[:include_blank] ||= true unless options[:prompt] || select_not_required?(html_options)
|
|
18
|
+
value = options.fetch(:selected) { value(object) }
|
|
19
|
+
select = content_tag("select", add_options(option_tags, options, value), html_options)
|
|
20
|
+
if html_options["multiple"] && options.fetch(:include_hidden, true)
|
|
21
|
+
tag("input", :disabled => html_options["disabled"], :name => html_options["name"], :type => "hidden", :value => "") + select
|
|
22
|
+
else
|
|
23
|
+
select
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
[
|
|
33
|
+
ActionView::Helpers::Tags::CollectionSelect,
|
|
34
|
+
ActionView::Helpers::Tags::GroupedCollectionSelect,
|
|
35
|
+
ActionView::Helpers::Tags::Select
|
|
36
|
+
].each do |t|
|
|
37
|
+
t.send :include, Waiable::Base::Select
|
|
38
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'active_support/concern'
|
|
2
|
+
require 'action_view/common_methods'
|
|
3
|
+
|
|
4
|
+
module Waiable
|
|
5
|
+
module Base
|
|
6
|
+
module TextAria
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
include CommonMethods
|
|
9
|
+
|
|
10
|
+
included do
|
|
11
|
+
def render
|
|
12
|
+
options = @options.stringify_keys
|
|
13
|
+
add_default_name_and_id(options)
|
|
14
|
+
|
|
15
|
+
if size = options.delete("size")
|
|
16
|
+
options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
options["aria"] ||= {}
|
|
20
|
+
options["aria"]["required"] = true if required_field?(@method_name) == true
|
|
21
|
+
add_aria_describedby_values(options)
|
|
22
|
+
aria_content_tag(options)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def aria_content_tag(options)
|
|
27
|
+
aria= ""
|
|
28
|
+
if options["maxlength"]
|
|
29
|
+
aria= content_tag("textarea", options.delete("value") { value_before_type_cast(object) }, options) + content_tag(:div, "You can enter maximum " +options["maxlength"]+ " characters in this field.", id: "maxlength_#{options["id"]}", style: "display:none")
|
|
30
|
+
else
|
|
31
|
+
aria= content_tag("textarea", options.delete("value") { value_before_type_cast(object) }, options)
|
|
32
|
+
end
|
|
33
|
+
aria
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
[
|
|
42
|
+
ActionView::Helpers::Tags::TextArea
|
|
43
|
+
].each do |t|
|
|
44
|
+
t.send :include, Waiable::Base::TextAria
|
|
45
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'action_view/common_methods'
|
|
2
|
+
require 'active_support/concern'
|
|
3
|
+
|
|
4
|
+
module Waiable
|
|
5
|
+
module Base
|
|
6
|
+
module TextField
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
include CommonMethods
|
|
9
|
+
|
|
10
|
+
included do
|
|
11
|
+
def render
|
|
12
|
+
options_for_rendering
|
|
13
|
+
aria_content(@options)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def aria_content(options)
|
|
18
|
+
aria = ""
|
|
19
|
+
if options["maxlength"]
|
|
20
|
+
aria = tag("input", options) + content_tag(:div, "You can enter maximum " + options["maxlength"] + " characters in this field", id: "maxlength_#{options["id"]}", style: "display:none")
|
|
21
|
+
else
|
|
22
|
+
aria = tag("input", options)
|
|
23
|
+
end
|
|
24
|
+
aria
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
[
|
|
33
|
+
ActionView::Helpers::Tags::TextField,
|
|
34
|
+
ActionView::Helpers::Tags::EmailField,
|
|
35
|
+
ActionView::Helpers::Tags::PasswordField,
|
|
36
|
+
ActionView::Helpers::Tags::DatetimeField,
|
|
37
|
+
ActionView::Helpers::Tags::FileField,
|
|
38
|
+
ActionView::Helpers::Tags::NumberField,
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
].each do |t|
|
|
42
|
+
t.send :include, Waiable::Base::TextField
|
|
43
|
+
end
|
data/lib/waiable.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'action_view'
|
|
2
|
+
require 'action_view/base'
|
|
3
|
+
require 'action_view/form_helper'
|
|
4
|
+
require 'action_view/text_field'
|
|
5
|
+
require 'action_view/text_aria'
|
|
6
|
+
require 'action_view/select'
|
|
7
|
+
require 'action_view/date_select'
|
|
8
|
+
require 'action_view/check_box'
|
|
9
|
+
|
|
10
|
+
require 'action_view/radio_button'
|
|
11
|
+
require 'action_view/common_methods'
|
|
12
|
+
require 'action_view/errors'
|
|
13
|
+
require 'waiable/version'
|
|
14
|
+
require 'waiable/railtie' if defined?(Rails)
|
|
15
|
+
|
|
16
|
+
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
class WaiableFormBuilderTest < ActionView::TestCase
|
|
3
|
+
test "testing label with id attribute" do
|
|
4
|
+
expect = 'id="label_person_name"'
|
|
5
|
+
|
|
6
|
+
form_buffer = form_for :person, url: "dummy" do |f|
|
|
7
|
+
actual = f.label :name
|
|
8
|
+
assert_match(expect, actual)
|
|
9
|
+
end #form_for
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
test "testing text_field with aria-required attribute for mandatory fields " do
|
|
13
|
+
expect = 'aria-required="true"'
|
|
14
|
+
|
|
15
|
+
form_buffer = form_for :person, url: "dummy" do |f|
|
|
16
|
+
actual = f.text_field :name, :maxlength => "20"
|
|
17
|
+
assert_match(expect, actual)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
test "testing text_field with maxlength attribute" do
|
|
22
|
+
expect = 'aria-describedby="maxlength_person_name"'
|
|
23
|
+
extra_content = '<div id="maxlength_person_name"> You can enter maxmum 20 character in this field</div>'.html_safe
|
|
24
|
+
expect + extra_content
|
|
25
|
+
|
|
26
|
+
form_buffer = form_for :person, url: "dummy" do |f|
|
|
27
|
+
actual = f.text_field :name, :maxlength => "20"
|
|
28
|
+
assert_match(expect, actual)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
test "testing email_field with aria-required attribute for mandatory field" do
|
|
33
|
+
expect = 'aria-required="true"'
|
|
34
|
+
|
|
35
|
+
form_buffer = form_for :person, url: "dummy" do |f|
|
|
36
|
+
actual = f.email_field :email
|
|
37
|
+
assert_match(expect, actual)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
test "testing password_field with aria-required attribute" do
|
|
42
|
+
expect = 'aria-required="true"'
|
|
43
|
+
|
|
44
|
+
form_buffer = form_for :person, url: "dummy" do |f|
|
|
45
|
+
actual = f.password_field :password
|
|
46
|
+
assert_match(expect, actual)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
test "testing text_area with aria-required attribute for mandatory field" do
|
|
51
|
+
expect = 'aria-required="true"'
|
|
52
|
+
|
|
53
|
+
form_buffer = form_for :person, url: "dummy" do |f|
|
|
54
|
+
actual = f.text_area :address
|
|
55
|
+
assert_match(expect, actual)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
test "testing date_field with aria-required attribute for mandatory field" do
|
|
60
|
+
expect = 'aria-required="true"'
|
|
61
|
+
|
|
62
|
+
form_buffer = form_for :person, url: "dummy" do |f|
|
|
63
|
+
actual = f.date_field :joindate
|
|
64
|
+
assert_match(expect, actual)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
test "testing search_field with aria-label attribute" do
|
|
69
|
+
expect = 'aria-label="search name"'
|
|
70
|
+
|
|
71
|
+
form_buffer = form_for :person, url: "dummy" do |f|
|
|
72
|
+
actual = f.search_field :name
|
|
73
|
+
assert_match(expect, actual)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
test "testing datetime_field with aria-required attribute for mandatory field" do
|
|
78
|
+
expect = 'aria-required="true"'
|
|
79
|
+
|
|
80
|
+
form_buffer = form_for :person, url: "dummy" do |f|
|
|
81
|
+
actual = f.datetime_field :joindate
|
|
82
|
+
assert_match(expect, actual)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
test "testing phone_field with aria-required attribute for mandatory field" do
|
|
87
|
+
expect = 'aria-required="true"'
|
|
88
|
+
|
|
89
|
+
form_buffer = form_for :person, url: "dummy" do |f|
|
|
90
|
+
actual = f.phone_field :mobile_number
|
|
91
|
+
assert_match(expect, actual)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
test "testing select tag with aria-required attribute for manditary field" do
|
|
96
|
+
expect = 'aria-required="true"'
|
|
97
|
+
|
|
98
|
+
form_buffer = form_for :person, url: "dummy" do |f|
|
|
99
|
+
actual = f.select(:country, [["India", 1], ["Chaina", 2], ["Pakisthan", 3]])
|
|
100
|
+
assert_match(expect, actual)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
test "testing the error element with error object" do
|
|
106
|
+
person = ValidatePerson.new
|
|
107
|
+
person.valid?
|
|
108
|
+
|
|
109
|
+
form_buffer = form_for person, url: "dummy", as: "person_form" do |f|
|
|
110
|
+
person.errors.full_messages.each do |msg|
|
|
111
|
+
expect = "<div id=\"error_validateperson_name\"><a href=\"javascript:document.getElementsByName('validateperson[name]')[0].focus()\">Name can't be blank</a></div>"
|
|
112
|
+
actual = msg
|
|
113
|
+
assert_match(expect, actual)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
test "testing radio_button with aria-required attribute for mandatory field" do
|
|
119
|
+
expect = 'aria-required="true"'
|
|
120
|
+
|
|
121
|
+
form_buffer = form_for :person, url: "dummy" do |f|
|
|
122
|
+
actual = f.radio_button :gender, "male"
|
|
123
|
+
assert_match(expect, actual)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
test "testing date_select with aria-required attribute" do
|
|
128
|
+
expect = 'aria-required="true"'
|
|
129
|
+
|
|
130
|
+
form_buffer = form_for :person, url: "dummy" do |f|
|
|
131
|
+
actual = f.date_select :dateofbirth
|
|
132
|
+
assert_match(expect, actual)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
class Person
|
|
2
|
+
extend ActiveModel::Naming
|
|
3
|
+
include ActiveModel::Validations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
attr_accessor :attributes
|
|
7
|
+
attr_accessor :name, :email, :password, :address, :gender, :dateofbirth, :publish, :joindate, :created_at, :mobile_number, :country
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
validates :name, presence: true
|
|
11
|
+
validates :email, presence: true
|
|
12
|
+
validates :password, presence: true
|
|
13
|
+
validates :gender, presence: true
|
|
14
|
+
validates :joindate, presence: true
|
|
15
|
+
validates :mobile_number, presence: true
|
|
16
|
+
validates :country, presence: true
|
|
17
|
+
validates :address, presence: true
|
|
18
|
+
validates :dateofbirth, presence: true
|
|
19
|
+
|
|
20
|
+
def initialize(attributes = {})
|
|
21
|
+
@attributes = attributes
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def read_attribute_for_validation(key)
|
|
25
|
+
@attributes[key]
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class ValidatePerson
|
|
30
|
+
extend ActiveModel::Naming
|
|
31
|
+
include ActiveModel::Validations
|
|
32
|
+
|
|
33
|
+
attr_accessor :name
|
|
34
|
+
validates :name, Presence: true
|
|
35
|
+
end
|
data/test/test_helper.rb
ADDED
data/waiable.gemspec
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'waiable/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "waiable"
|
|
8
|
+
spec.version = Waiable::VERSION
|
|
9
|
+
spec.platform = Gem::Platform::RUBY
|
|
10
|
+
spec.authors = ["Sanghapal Bhowate", "Shantanu Choudhury"]
|
|
11
|
+
spec.email = ["sangha@techvision.net.in", "shantanu@techvision.net.in", "developer@techvision.net.in"]
|
|
12
|
+
spec.summary = %q{Making rails accessible !}
|
|
13
|
+
spec.description = %q{Details in the readme}
|
|
14
|
+
spec.homepage = "https://github.com/techvision/waiable"
|
|
15
|
+
spec.license = "MIT"
|
|
16
|
+
|
|
17
|
+
spec.files = `git ls-files`.split($/)
|
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
20
|
+
spec.require_paths = ["lib"]
|
|
21
|
+
|
|
22
|
+
spec.add_development_dependency "bundler"
|
|
23
|
+
spec.add_development_dependency "rake"
|
|
24
|
+
spec.add_development_dependency "minitest"
|
|
25
|
+
spec.add_development_dependency "xml-simple"
|
|
26
|
+
spec.add_dependency "rails"
|
|
27
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: waiable
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Sanghapal Bhowate
|
|
8
|
+
- Shantanu Choudhury
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2015-07-02 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: bundler
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
requirements:
|
|
18
|
+
- - ">="
|
|
19
|
+
- !ruby/object:Gem::Version
|
|
20
|
+
version: '0'
|
|
21
|
+
type: :development
|
|
22
|
+
prerelease: false
|
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
24
|
+
requirements:
|
|
25
|
+
- - ">="
|
|
26
|
+
- !ruby/object:Gem::Version
|
|
27
|
+
version: '0'
|
|
28
|
+
- !ruby/object:Gem::Dependency
|
|
29
|
+
name: rake
|
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
|
31
|
+
requirements:
|
|
32
|
+
- - ">="
|
|
33
|
+
- !ruby/object:Gem::Version
|
|
34
|
+
version: '0'
|
|
35
|
+
type: :development
|
|
36
|
+
prerelease: false
|
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - ">="
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '0'
|
|
42
|
+
- !ruby/object:Gem::Dependency
|
|
43
|
+
name: minitest
|
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '0'
|
|
49
|
+
type: :development
|
|
50
|
+
prerelease: false
|
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: '0'
|
|
56
|
+
- !ruby/object:Gem::Dependency
|
|
57
|
+
name: xml-simple
|
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - ">="
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '0'
|
|
63
|
+
type: :development
|
|
64
|
+
prerelease: false
|
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - ">="
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '0'
|
|
70
|
+
- !ruby/object:Gem::Dependency
|
|
71
|
+
name: rails
|
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - ">="
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '0'
|
|
77
|
+
type: :runtime
|
|
78
|
+
prerelease: false
|
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
80
|
+
requirements:
|
|
81
|
+
- - ">="
|
|
82
|
+
- !ruby/object:Gem::Version
|
|
83
|
+
version: '0'
|
|
84
|
+
description: Details in the readme
|
|
85
|
+
email:
|
|
86
|
+
- sangha@techvision.net.in
|
|
87
|
+
- shantanu@techvision.net.in
|
|
88
|
+
- developer@techvision.net.in
|
|
89
|
+
executables: []
|
|
90
|
+
extensions: []
|
|
91
|
+
extra_rdoc_files: []
|
|
92
|
+
files:
|
|
93
|
+
- ".gitignore"
|
|
94
|
+
- Accessibility related issue for rails core.txt~
|
|
95
|
+
- Contributing.md
|
|
96
|
+
- Gemfile
|
|
97
|
+
- LICENSE.txt
|
|
98
|
+
- README.md
|
|
99
|
+
- Rakefile
|
|
100
|
+
- grid parameter details.txt~
|
|
101
|
+
- lib/action_view/check_box.rb
|
|
102
|
+
- lib/action_view/common_methods.rb
|
|
103
|
+
- lib/action_view/date_select.rb
|
|
104
|
+
- lib/action_view/errors.rb
|
|
105
|
+
- lib/action_view/form_helper.rb
|
|
106
|
+
- lib/action_view/radio_button.rb
|
|
107
|
+
- lib/action_view/select.rb
|
|
108
|
+
- lib/action_view/text_aria.rb
|
|
109
|
+
- lib/action_view/text_field.rb
|
|
110
|
+
- lib/waiable.rb
|
|
111
|
+
- lib/waiable/railtie.rb
|
|
112
|
+
- lib/waiable/version.rb
|
|
113
|
+
- test/action_view/helpers/form_helper_test.rb
|
|
114
|
+
- test/support/person.rb
|
|
115
|
+
- test/test_helper.rb
|
|
116
|
+
- waiable.gemspec
|
|
117
|
+
homepage: https://github.com/techvision/waiable
|
|
118
|
+
licenses:
|
|
119
|
+
- MIT
|
|
120
|
+
metadata: {}
|
|
121
|
+
post_install_message:
|
|
122
|
+
rdoc_options: []
|
|
123
|
+
require_paths:
|
|
124
|
+
- lib
|
|
125
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
126
|
+
requirements:
|
|
127
|
+
- - ">="
|
|
128
|
+
- !ruby/object:Gem::Version
|
|
129
|
+
version: '0'
|
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
|
+
requirements:
|
|
132
|
+
- - ">="
|
|
133
|
+
- !ruby/object:Gem::Version
|
|
134
|
+
version: '0'
|
|
135
|
+
requirements: []
|
|
136
|
+
rubyforge_project:
|
|
137
|
+
rubygems_version: 2.4.5
|
|
138
|
+
signing_key:
|
|
139
|
+
specification_version: 4
|
|
140
|
+
summary: Making rails accessible !
|
|
141
|
+
test_files:
|
|
142
|
+
- test/action_view/helpers/form_helper_test.rb
|
|
143
|
+
- test/support/person.rb
|
|
144
|
+
- test/test_helper.rb
|