Skip to content

Commit a2126e9

Browse files
committed
Added support for date/time/datetime_select fields - to be included in validation hash and to have validations attached to selects
addSuportForDateAndTimeSelects remove unused test preparations
1 parent ab095f2 commit a2126e9

File tree

7 files changed

+207
-6
lines changed

7 files changed

+207
-6
lines changed

dist/client-side-validations.esm.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,8 @@ var cleanNestedElementName = function cleanNestedElementName(elementName, nested
625625
};
626626

627627
var cleanElementName = function cleanElementName(elementName, validators) {
628-
elementName = elementName.replace(/\[(\w+_attributes)\]\[[\da-z_]+\](?=\[(?:\w+_attributes)\])/g, '[$1][]');
628+
elementName = elementName.replace(/\[(\w+_attributes)\]\[[\da-z_]+\](?=\[(?:\w+_attributes)\])/g, '[$1][]').replace(/\(\di\)/g, ''); // date/time_select _1/2/3/4/5i fields
629+
629630
var nestedMatches = elementName.match(/\[(\w+_attributes)\].*\[(\w+)\]$/);
630631

631632
if (nestedMatches) {

dist/client-side-validations.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,8 @@
631631
};
632632

633633
var cleanElementName = function cleanElementName(elementName, validators) {
634-
elementName = elementName.replace(/\[(\w+_attributes)\]\[[\da-z_]+\](?=\[(?:\w+_attributes)\])/g, '[$1][]');
634+
elementName = elementName.replace(/\[(\w+_attributes)\]\[[\da-z_]+\](?=\[(?:\w+_attributes)\])/g, '[$1][]').replace(/\(\di\)/g, ''); // date/time_select _1/2/3/4/5i fields
635+
635636
var nestedMatches = elementName.match(/\[(\w+_attributes)\].*\[(\w+)\]$/);
636637

637638
if (nestedMatches) {

lib/client_side_validations/action_view/form_builder.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# frozen_string_literal: true
22

3+
# rubocop:disable Metrics/ModuleLength
34
module ClientSideValidations
45
module ActionView
56
module Helpers
@@ -103,6 +104,27 @@ def file_field(method, options = {})
103104
super(method, options)
104105
end
105106

107+
def date_select(method, options = {}, html_options = {})
108+
build_validation_options(method, options)
109+
options.delete(:validate)
110+
111+
super(method, options, html_options)
112+
end
113+
114+
def time_select(method, options = {}, html_options = {})
115+
build_validation_options(method, options)
116+
options.delete(:validate)
117+
118+
super(method, options, html_options)
119+
end
120+
121+
def datetime_select(method, options = {}, html_options = {})
122+
build_validation_options(method, options)
123+
options.delete(:validate)
124+
125+
super(method, options, html_options)
126+
end
127+
106128
private
107129

108130
def build_validation_options(method, options = {})
@@ -121,3 +143,4 @@ def build_validation_options(method, options = {})
121143
end
122144
end
123145
end
146+
# rubocop:enable Metrics/ModuleLength

src/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ $.fn.disableClientSideValidations = function () {
3232

3333
$.fn.enableClientSideValidations = function () {
3434
const selectors = { forms: 'form', inputs: 'input' }
35-
3635
for (var selector in selectors) {
3736
const enablers = selectors[selector]
3837

@@ -82,6 +81,7 @@ const cleanNestedElementName = (elementName, nestedMatches, validators) => {
8281

8382
const cleanElementName = (elementName, validators) => {
8483
elementName = elementName.replace(/\[(\w+_attributes)\]\[[\da-z_]+\](?=\[(?:\w+_attributes)\])/g, '[$1][]')
84+
.replace(/\(\di\)/g, '') // date/time_select _1/2/3/4/5i fields
8585

8686
const nestedMatches = elementName.match(/\[(\w+_attributes)\].*\[(\w+)\]$/)
8787

test/action_view/cases/test_form_for_helpers.rb

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,86 @@ def test_text_area
526526
assert_dom_equal expected, output_buffer
527527
end
528528

529+
def test_date_select
530+
input_html = ''
531+
532+
form_for(@post, validate: true) do |f|
533+
input_html = f.date_select(:cost)
534+
concat input_html
535+
end
536+
537+
validators = { 'post[cost]' => { presence: [{ message: "can't be blank" }] } }
538+
expected = whole_form_for('/posts', 'new_post', 'new_post', validators: validators) do
539+
input_html
540+
end
541+
542+
assert_dom_equal expected, output_buffer
543+
end
544+
545+
def test_time_select
546+
input_html = ''
547+
548+
form_for(@post, validate: true) do |f|
549+
input_html = f.time_select(:cost)
550+
concat input_html
551+
end
552+
553+
validators = { 'post[cost]' => { presence: [{ message: "can't be blank" }] } }
554+
expected = whole_form_for('/posts', 'new_post', 'new_post', validators: validators) do
555+
input_html
556+
end
557+
558+
assert_dom_equal expected, output_buffer
559+
end
560+
561+
def test_datetime_select
562+
input_html = ''
563+
564+
form_for(@post, validate: true) do |f|
565+
input_html = f.datetime_select(:cost)
566+
concat input_html
567+
end
568+
569+
validators = { 'post[cost]' => { presence: [{ message: "can't be blank" }] } }
570+
expected = whole_form_for('/posts', 'new_post', 'new_post', validators: validators) do
571+
input_html
572+
end
573+
574+
assert_dom_equal expected, output_buffer
575+
end
576+
577+
def test_date_field
578+
input_html = ''
579+
580+
form_for(@post, validate: true) do |f|
581+
input_html = f.date_field(:cost)
582+
concat input_html
583+
end
584+
585+
validators = { 'post[cost]' => { presence: [{ message: "can't be blank" }] } }
586+
expected = whole_form_for('/posts', 'new_post', 'new_post', validators: validators) do
587+
input_html
588+
end
589+
590+
assert_dom_equal expected, output_buffer
591+
end
592+
593+
def test_date_time_field
594+
input_html = ''
595+
596+
form_for(@post, validate: true) do |f|
597+
input_html = f.datetime_field(:cost)
598+
concat input_html
599+
end
600+
601+
validators = { 'post[cost]' => { presence: [{ message: "can't be blank" }] } }
602+
expected = whole_form_for('/posts', 'new_post', 'new_post', validators: validators) do
603+
input_html
604+
end
605+
606+
assert_dom_equal expected, output_buffer
607+
end
608+
529609
def test_as_form_option_with_new_record_rails
530610
form_for(@post, as: :article, validate: true) do
531611
concat content_tag(:span, 'Dummy Content')

test/javascript/public/test/validateElement.js

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ QUnit.module('Validate Element', {
1818
'user[phone_numbers_attributes][deeply][nested][][attribute]': { presence: [{ message: 'must be present' }] },
1919
'user[phone_numbers_attributes][][labels_attributes][][label]': { presence: [{ message: 'must be present' }] },
2020
'user[a_attributes][][b_attributes][][c_attributes][][d_attributes][][e]': { presence: [{ message: 'must be present' }] },
21-
customized_field: { length: [{ messages: { minimum: 'is too short (minimum is 4 characters)' }, minimum: 4 }] }
21+
customized_field: { length: [{ messages: { minimum: 'is too short (minimum is 4 characters)' }, minimum: 4 }] },
22+
'user[date_of_sign_up]': { presence: [{ message: 'must be present' }] },
23+
'user[date_of_birth]': { presence: [{ message: 'must be present' }] },
24+
'user[time_of_birth]': { presence: [{ message: 'must be present' }] },
2225
}
2326
}
2427

@@ -132,7 +135,47 @@ QUnit.module('Validate Element', {
132135
id: 'customized_field',
133136
type: 'text'
134137
}))
135-
138+
.append($(`
139+
<label for="user_date_of_sign_up">Date field</label>
140+
<input name="user[date_of_sign_up]"
141+
id="user_date_of_sign_up"
142+
type="date">
143+
`))
144+
.append($(`
145+
<label for="user_time_of_birth_1i">Time select</label>
146+
<input type="hidden" id="user_time_of_birth_1i" name="user[time_of_birth(1i)]" value="1">
147+
<input type="hidden" id="user_time_of_birth_2i" name="user[time_of_birth(2i)]" value="1">
148+
<input type="hidden" id="user_time_of_birth_3i" name="user[time_of_birth(3i)]" value="1">
149+
<select id="user_time_of_birth_4i" name="user[time_of_birth(4i)]" >
150+
<option value=""></option>
151+
<option value="00">00</option>
152+
<option value="01">01</option>
153+
</select>
154+
:
155+
<select id="user_time_of_birth_5i" name="user[time_of_birth(5i)]" >
156+
<option value=""></option>
157+
<option value="00">00</option>
158+
<option value="01">59</option>
159+
</select>
160+
`))
161+
.append($(`
162+
<label for="user_date_of_birth_1i">Date select</label>
163+
<select id="user_date_of_birth_1i" name="user[date_of_birth(1i)]">
164+
<option value=""></option>
165+
<option value="2015">2015</option>
166+
<option value="2016">2016</option>
167+
</select>
168+
<select id="user_date_of_birth_2i" name="user[date_of_birth(2i)]">
169+
<option value=""></option>
170+
<option value="1">January</option>
171+
<option value="2">February</option>
172+
</select>
173+
<select id="user_date_of_birth_3i" name="user[date_of_birth(3i)]">
174+
<option value=""></option>
175+
<option value="1">1</option>
176+
<option value="2">2</option>
177+
</select>
178+
`))
136179
$('form#new_user').validate()
137180
},
138181

@@ -152,6 +195,58 @@ QUnit.test('Validate when focusouting on customized_field', function (assert) {
152195
assert.ok(label.parent().hasClass('field_with_errors'))
153196
})
154197

198+
QUnit.test('Validate when focusouting on date_field', function (assert) {
199+
let form = $('form#new_user')
200+
let input = form.find('input#user_date_of_sign_up')
201+
let label = $('label[for="user_date_of_sign_up"]')
202+
203+
input.trigger('focusout')
204+
assert.ok(input.parent().hasClass('field_with_errors'))
205+
assert.ok(label.parent().hasClass('field_with_errors'))
206+
})
207+
208+
QUnit.test('Validate validations of date_select', function (assert) {
209+
let form = $('form#new_user')
210+
211+
//let label = $('label[for="user_date_of_birth_1i"]')
212+
let input_year = form.find('select#user_date_of_birth_1i')
213+
let input_month = form.find('select#user_date_of_birth_2i')
214+
let input_day = form.find('select#user_date_of_birth_3i')
215+
216+
input_year.trigger('focusout')
217+
assert.ok(input_year.parent().hasClass('field_with_errors'))
218+
219+
input_month.trigger('focusout')
220+
assert.ok(input_month.parent().hasClass('field_with_errors'))
221+
222+
input_day.trigger('focusout')
223+
assert.ok(input_day.parent().hasClass('field_with_errors'))
224+
225+
// showing validation messages doesnt work well with this.
226+
// JS Formbuilder must be customized for these types of fields
227+
// to share error message and hide error only when all 3 selects are valid
228+
229+
})
230+
231+
QUnit.test('Validate validations of time_select', function (assert) {
232+
let form = $('form#new_user')
233+
234+
//let label = $('label[for="user_time_of_birth_4i"]')
235+
let input_hour = form.find('select#user_time_of_birth_4i')
236+
let input_minute = form.find('select#user_time_of_birth_5i')
237+
238+
input_hour.trigger('focusout')
239+
assert.ok(input_hour.parent().hasClass('field_with_errors'))
240+
241+
input_minute.trigger('focusout')
242+
assert.ok(input_minute.parent().hasClass('field_with_errors'))
243+
244+
// showing validation messages doesnt work well with this.
245+
// JS Formbuilder must be customized for these types of fields
246+
// to share error message and hide error only when all 3 selects are valid
247+
})
248+
249+
155250
QUnit.test('Validate when focusouting', function (assert) {
156251
var form = $('form#new_user')
157252
var input = form.find('input#user_name')

vendor/assets/javascripts/rails.validations.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,8 @@
631631
};
632632

633633
var cleanElementName = function cleanElementName(elementName, validators) {
634-
elementName = elementName.replace(/\[(\w+_attributes)\]\[[\da-z_]+\](?=\[(?:\w+_attributes)\])/g, '[$1][]');
634+
elementName = elementName.replace(/\[(\w+_attributes)\]\[[\da-z_]+\](?=\[(?:\w+_attributes)\])/g, '[$1][]').replace(/\(\di\)/g, ''); // date/time_select _1/2/3/4/5i fields
635+
635636
var nestedMatches = elementName.match(/\[(\w+_attributes)\].*\[(\w+)\]$/);
636637

637638
if (nestedMatches) {

0 commit comments

Comments
 (0)