Skip to content

Commit 0cabb37

Browse files
committed
Added tests for :horizontal_form wrapper and made it pass
1 parent 923dfc6 commit 0cabb37

File tree

5 files changed

+142
-12
lines changed

5 files changed

+142
-12
lines changed

dist/simple-form.bootstrap4.esm.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,24 @@ ClientSideValidations.formBuilders['SimpleForm::FormBuilder'] = {
2020
wrappers: {
2121
"default": {
2222
add: function add(element, settings, message) {
23-
var wrapperElement = element.parent();
23+
var parentElement = element.parent();
24+
var wrapperElement = element.closest(settings.wrapper_tag + '.' + settings.wrapper_class.replace(/ /g, '.'));
2425
var errorElement = wrapperElement.find(settings.error_tag + '.invalid-feedback');
2526

2627
if (!errorElement.length) {
2728
errorElement = $('<' + settings.error_tag + '>', {
2829
"class": 'invalid-feedback',
2930
text: message
3031
});
31-
wrapperElement.append(errorElement);
32+
parentElement.append(errorElement);
3233
}
3334

3435
wrapperElement.addClass(settings.wrapper_error_class);
3536
element.addClass('is-invalid');
3637
errorElement.text(message);
3738
},
3839
remove: function remove(element, settings) {
39-
var wrapperElement = element.parent();
40+
var wrapperElement = element.closest(settings.wrapper_tag + '.' + settings.wrapper_class.replace(/ /g, '.'));
4041
var errorElement = wrapperElement.find(settings.error_tag + '.invalid-feedback');
4142
wrapperElement.removeClass(settings.wrapper_error_class);
4243
element.removeClass('is-invalid');

dist/simple-form.bootstrap4.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,24 @@
2626
wrappers: {
2727
"default": {
2828
add: function add(element, settings, message) {
29-
var wrapperElement = element.parent();
29+
var parentElement = element.parent();
30+
var wrapperElement = element.closest(settings.wrapper_tag + '.' + settings.wrapper_class.replace(/ /g, '.'));
3031
var errorElement = wrapperElement.find(settings.error_tag + '.invalid-feedback');
3132

3233
if (!errorElement.length) {
3334
errorElement = $('<' + settings.error_tag + '>', {
3435
"class": 'invalid-feedback',
3536
text: message
3637
});
37-
wrapperElement.append(errorElement);
38+
parentElement.append(errorElement);
3839
}
3940

4041
wrapperElement.addClass(settings.wrapper_error_class);
4142
element.addClass('is-invalid');
4243
errorElement.text(message);
4344
},
4445
remove: function remove(element, settings) {
45-
var wrapperElement = element.parent();
46+
var wrapperElement = element.closest(settings.wrapper_tag + '.' + settings.wrapper_class.replace(/ /g, '.'));
4647
var errorElement = wrapperElement.find(settings.error_tag + '.invalid-feedback');
4748
wrapperElement.removeClass(settings.wrapper_error_class);
4849
element.removeClass('is-invalid');

src/main.bootstrap4.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ ClientSideValidations.formBuilders['SimpleForm::FormBuilder'] = {
1515
wrappers: {
1616
default: {
1717
add (element, settings, message) {
18-
const wrapperElement = element.closest(settings.wrapper_tag + '.' + settings.wrapper_class.replace(/\ /g, '.'));
18+
const parentElement = element.parent()
19+
const wrapperElement = element.closest(settings.wrapper_tag + '.' + settings.wrapper_class.replace(/ /g, '.'))
20+
1921
let errorElement = wrapperElement.find(settings.error_tag + '.invalid-feedback')
2022

2123
if (!errorElement.length) {
2224
errorElement = $('<' + settings.error_tag + '>', { class: 'invalid-feedback', text: message })
23-
wrapperElement.append(errorElement)
25+
parentElement.append(errorElement)
2426
}
2527

2628
wrapperElement.addClass(settings.wrapper_error_class)
@@ -29,7 +31,7 @@ ClientSideValidations.formBuilders['SimpleForm::FormBuilder'] = {
2931
},
3032

3133
remove (element, settings) {
32-
const wrapperElement = settings.wrapper_tag + "." + settings.wrapper_class.replace(/\ /g, ".")
34+
const wrapperElement = element.closest(settings.wrapper_tag + '.' + settings.wrapper_class.replace(/ /g, '.'))
3335
const errorElement = wrapperElement.find(settings.error_tag + '.invalid-feedback')
3436

3537
wrapperElement.removeClass(settings.wrapper_error_class)
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
QUnit.module('Validate Horizontal wrapper SimpleForm Bootstrap 4', {
2+
before: function () {
3+
currentFormBuilder = window.ClientSideValidations.formBuilders['SimpleForm::FormBuilder']
4+
window.ClientSideValidations.formBuilders['SimpleForm::FormBuilder'] = BS4_FORM_BUILDER
5+
},
6+
7+
after: function () {
8+
window.ClientSideValidations.formBuilders['SimpleForm::FormBuilder'] = currentFormBuilder
9+
},
10+
11+
beforeEach: function () {
12+
dataCsv = {
13+
html_settings: {
14+
type: 'SimpleForm::FormBuilder',
15+
error_class: 'is-invalid',
16+
error_tag: 'div',
17+
wrapper_error_class: 'form-group-invalid',
18+
wrapper_tag: 'div',
19+
wrapper_class: 'form-group'
20+
},
21+
validators: {
22+
'user[name]': { presence: [{ message: 'must be present' }], format: [{ message: 'is invalid', 'with': { options: 'g', source: '\\d+' } }] },
23+
'user[username]': { presence: [{ message: 'must be present' }] }
24+
}
25+
}
26+
27+
$('#qunit-fixture')
28+
.append(
29+
$('<form>', {
30+
action: '/users',
31+
'data-client-side-validations': JSON.stringify(dataCsv),
32+
method: 'post',
33+
id: 'new_user'
34+
})
35+
.append(
36+
$('<div>', { 'class': 'form-group row' })
37+
.append(
38+
$('<label for="user_name" class="string col-sm-3 col-form-label">Name</label>'))
39+
.append(
40+
$('<div>', { 'class': 'col-sm-9' })
41+
.append(
42+
$('<input />', { 'class': 'form-control', name: 'user[name]', id: 'user_name', type: 'text' }))))
43+
// there isn't horizontal :input_group wrapper in simple_form's bootstrap 4 configuration by default
44+
// but if somebody would do it it would look like this
45+
.append(
46+
$('<div>', { 'class': 'form-group row' })
47+
.append(
48+
$('<label for="user_username" class="string col-sm-3 col-form-label">Username</label>'))
49+
.append(
50+
$('<div>', { 'class': 'col-sm-9' })
51+
.append(
52+
$('<div>', { 'class': 'input-group' })
53+
.append(
54+
$('<div>', { 'class': 'input-group-prepend' })
55+
.append(
56+
$('<span>', { 'class': 'input-group-text', text: '@' })))
57+
.append(
58+
$('<input />', { 'class': 'form-control', name: 'user[username]', id: 'user_username', type: 'text' }))))))
59+
60+
$('form#new_user').validate()
61+
}
62+
})
63+
64+
var wrappers = ['horizontal_form' ]
65+
66+
for (var i = 0; i < wrappers.length; i++) {
67+
var wrapper = wrappers[i]
68+
69+
QUnit.test(wrapper + ' - Validate error attaching and detaching', function (assert) {
70+
var form = $('form#new_user')
71+
var input = form.find('input#user_name')
72+
var label = $('label[for="user_name"]')
73+
form[0].ClientSideValidations.settings.html_settings.wrapper = wrapper
74+
75+
input.trigger('focusout')
76+
assert.ok(input.closest('.form-group').hasClass('form-group-invalid'))
77+
assert.ok(label.parent().hasClass('form-group-invalid'))
78+
assert.ok(input.parent().find('div.invalid-feedback:contains("must be present")')[0])
79+
80+
input.val('abc')
81+
input.trigger('change')
82+
input.trigger('focusout')
83+
assert.ok(input.closest('.form-group').hasClass('form-group-invalid'))
84+
assert.ok(input.parent().find('div.invalid-feedback:contains("is invalid")')[0])
85+
assert.ok(input.hasClass('is-invalid'))
86+
87+
input.val('123')
88+
input.trigger('change')
89+
input.trigger('focusout')
90+
assert.notOk(input.closest('.form-group').parent().hasClass('form-group-invalid'))
91+
assert.notOk(input.parent().parent().find('div.invalid-feedback:contains("is invalid")')[0])
92+
assert.notOk(input.hasClass('is-invalid'))
93+
})
94+
95+
QUnit.test(wrapper + ' - Validate pre-existing error blocks are re-used', function (assert) {
96+
var form = $('form#new_user'); var input = form.find('input#user_name')
97+
var label = $('label[for="user_name"]')
98+
form[0].ClientSideValidations.settings.html_settings.wrapper = wrapper
99+
100+
input.parent().append($('<div class="invalid-feedback">Error from Server</span>'))
101+
assert.ok(input.parent().find('div.invalid-feedback:contains("Error from Server")')[0])
102+
input.val('abc')
103+
input.trigger('change')
104+
input.trigger('focusout')
105+
assert.ok(input.closest('.form-group').hasClass('form-group-invalid'))
106+
assert.ok(label.parent().hasClass('form-group-invalid'))
107+
assert.ok(input.parent().find('div.invalid-feedback:contains("is invalid")').length === 1)
108+
assert.ok(form.find('div.invalid-feedback').length === 1)
109+
})
110+
111+
QUnit.test(wrapper + ' - Validate input-group', function (assert) {
112+
var form = $('form#new_user'); var input = form.find('input#user_username')
113+
form[0].ClientSideValidations.settings.html_settings.wrapper = wrapper
114+
115+
input.trigger('change')
116+
input.trigger('focusout')
117+
assert.ok(input.closest('.input-group-prepend').find('div.invalid-feedback').length === 0)
118+
assert.ok(input.closest('.input-group').find('div.invalid-feedback').length === 1)
119+
120+
input.val('abc')
121+
input.trigger('change')
122+
input.trigger('focusout')
123+
assert.ok(input.closest('.input-group').find('div.invalid-feedback').length === 0)
124+
})
125+
}

vendor/assets/javascripts/rails.validations.simple_form.bootstrap4.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,24 @@
2626
wrappers: {
2727
"default": {
2828
add: function add(element, settings, message) {
29-
var wrapperElement = element.parent();
29+
var parentElement = element.parent();
30+
var wrapperElement = element.closest(settings.wrapper_tag + '.' + settings.wrapper_class.replace(/ /g, '.'));
3031
var errorElement = wrapperElement.find(settings.error_tag + '.invalid-feedback');
3132

3233
if (!errorElement.length) {
3334
errorElement = $('<' + settings.error_tag + '>', {
3435
"class": 'invalid-feedback',
3536
text: message
3637
});
37-
wrapperElement.append(errorElement);
38+
parentElement.append(errorElement);
3839
}
3940

4041
wrapperElement.addClass(settings.wrapper_error_class);
4142
element.addClass('is-invalid');
4243
errorElement.text(message);
4344
},
4445
remove: function remove(element, settings) {
45-
var wrapperElement = element.parent();
46+
var wrapperElement = element.closest(settings.wrapper_tag + '.' + settings.wrapper_class.replace(/ /g, '.'));
4647
var errorElement = wrapperElement.find(settings.error_tag + '.invalid-feedback');
4748
wrapperElement.removeClass(settings.wrapper_error_class);
4849
element.removeClass('is-invalid');

0 commit comments

Comments
 (0)