Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 101 additions & 51 deletions src/pat/validation/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,57 +127,107 @@ define(["pat-registry", "pat-validation"], function(registry, pattern) {
expect($el.find('em.warning').text()).toBe("Slegs heelgetalle");
});

// Unfortunately date validation cannot be tested using the Constraints
// API. ``ValidityState`` information is not updated after
// programmatically setting values.
// See whole discussion here: https://twitter.com/thetetet/status/1285239806205755393
// and: https://stackoverflow.com/questions/53226031/html-input-validity-not-checked-when-value-is-changed-by-javascript

//it("validates dates", function() {
// var $el = $(
// '<form class="pat-validation">'+
// '<input type="date" name="date">'+
// '</form>');
// var input = $el[0].querySelector('input');
// input.value = '2000-02-30';
// var pat = pattern.init($el);
// pat.validateForm();
// debugger;
// expect($el.find('em.warning').length).toBe(1);
// expect($el.find('em.warning').text()).toBe("This value must be a valid date");

// $el = $(
// '<form class="pat-validation">'+
// '<input type="date" name="date">'+
// '</form>');
// input = $el[0].querySelector('input');
// input.value = '2000-02-28';
// pat = pattern.init($el);
// pat.validateForm();
// expect($el.find('em.warning').length).toBe(0);
//});

//it("doesn't validate empty optional dates", function() {
// var $el = $(
// '<form class="pat-validation">'+
// '<input type="date" name="date">'+
// '</form>');
// var pat = pattern.init($el);
// pat.validateForm();
// expect($el.find('em.warning').length).toBe(0);
//});

//it("do require-validate non-empty required dates", function() {
// var $el = $(
// '<form class="pat-validation">'+
// '<input type="date" name="date" required>'+
// '<button type="submit" name="date" required>'+
// '</form>');
// var pat = pattern.init($el);
// pat.validateForm();
// expect($el.find('em.warning').length).toBe(1);
// expect($el.find('em.warning').text()).toBe("This field is required");
//});
// Using ``type="text"`` for date validation as Constraints API
// ``ValidityState`` information is not updated after programmatically
// setting values.
// See: https://twitter.com/thetetet/status/1285239806205755393

it("validates dates", function() {
var $el = $(
'<form class="pat-validation">'+
'<input type="text" name="date" data-pat-validation="type: date">'+
'</form>');

var $input = $el.find(':input');
$input.val('2000-02-30');
pattern.init($el);
$input.trigger('change');
expect($el.find('em.warning').length).toBe(1);
expect($el.find('em.warning').text()).toBe("This value must be a valid date");

$input.val('2000-02-28');
$input.trigger('change');
expect($el.find('em.warning').length).toBe(0);
});

it("validates dates with before/after constraints", function() {
var $el = $(
'<form class="pat-validation">'+
'<input type="text" id="start" name="start" data-pat-validation="type: date; not-after: #end; message-date: The start date must on or before the end date.">'+
'<input type="text" id="end" name="end" data-pat-validation="type: date; not-before: #start; message-date: The end date must on or before the start date.">'+
'</form>');
$('#lab').append($el);

pattern.init($el);

var $start = $el.find('#start');
var $end = $el.find('#end');

// Before/after constraints still allow for normal date validation
// (wasn't before this commit)
$start.val('2020-02-30');
$start.trigger('change');
expect($el.find('em.warning').length).toBe(1);
expect($el.find('em.warning').text()).toBe("The start date must on or before the end date.");

// Before/after without required allows for empty dates of the
// relation.
$start.val('2020-10-10');
$start.trigger('change');
expect($el.find('em.warning').length).toBe(0);

// Violate the before/after constraint
$end.val('2020-10-05');
$end.trigger('change');
expect($el.find('em.warning').length).toBe(2);
expect($el.find('em.warning').text().indexOf("The start date must on or before the end date.") !== -1).toBe(true);
expect($el.find('em.warning').text().indexOf("The end date must on or before the start date.") !== -1).toBe(true);

// Fulfill the before/after constraint - same date
$end.val('2020-10-10');
$end.trigger('change');
expect($el.find('em.warning').length).toBe(0);

// Fulfill the before/after constraint - start before end
$start.val('2020-10-01');
$start.trigger('change');
expect($el.find('em.warning').length).toBe(0);

// Before/after without required allows for empty dates of the
// relation.
$start.val('');
$start.trigger('change');
expect($el.find('em.warning').length).toBe(0);

});

it("doesn't validate empty optional dates", function() {
var $el = $(
'<form class="pat-validation">'+
'<input type="text" name="date" data-pat-validation="type: date">'+
'</form>');

var $input = $el.find(':input');
$input.val('');
pattern.init($el);
$input.trigger('change');
expect($el.find('em.warning').length).toBe(0);
});

it("do require-validate non-empty required dates", function() {
var $el = $(
'<form class="pat-validation">'+
'<input type="text" name="date" required="required" data-pat-validation="type: date">'+
'</form>');

var $input = $el.find(':input');
$input.val('');
pattern.init($el);
$input.trigger('change');

expect($el.find('em.warning').length).toBe(1);
expect($el.find('em.warning').text()).toBe("This field is required");
});

it("doesn't validate disabled elements", function() {
var $el = $(
Expand Down
47 changes: 23 additions & 24 deletions src/pat/validation/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,40 +93,37 @@ define([
setLocalDateConstraints: function (input, opts, constraints) {
/* Set the relative date constraints, i.e. not-after and not-before, as well as custom messages.
*/
var name = input.getAttribute('name').replace(/\./g, '\\.'),
type = this.getFieldType(input),
c = constraints[name][type];
var name = input.getAttribute('name').replace(/\./g, '\\.');
var type = this.getFieldType(input);
var c = constraints[name][type];

if (!c || typeof opts == "undefined") {
return constraints;
}

_.each(['before', 'after'], function (relation) {
var isDate = validate.moment.isDate,
relative = opts.not && opts.not[relation] || undefined,
arr, constraint, $ref;
var relative = opts.not ? opts.not[relation] : undefined;
var $ref;
if (typeof relative === "undefined") {
return;
}
constraint = relation === "before" ? 'earliest' : 'latest';
if (isDate(relative)) {
c[constraint] = relative;
var relative_constraint = relation === "before" ? 'earliest' : 'latest';
if (validate.moment.isDate(relative)) {
c[relative_constraint] = relative;
} else {
try {
$ref = $(relative);
} catch (e) {
console.log(e);
}
arr = $ref.data('pat-validation-refs') || [];
var arr = $ref.data('pat-validation-refs') || [];
if (!_.contains(arr, input)) {
arr.unshift(input);
$ref.data('pat-validation-refs', arr);
}
c[constraint] = $ref.val();
if (! $ref.val()) {
// do not validate empty reference dates
constraints[name][type] = false;
return;
if ($ref && $ref.val()) {
// relative constraint validation
c[relative_constraint] = $ref.val();
}
}
});
Expand Down Expand Up @@ -211,16 +208,18 @@ define([
// Returns true if a date check should be done.
// Don't check if there is no input - this should be handled by
// the ``required`` attribute.
// In case of HTML5 ``date``/``datetime-local`` support we
// implicitly check this if the input is ``badInput``, which is
// only set in case of an invalid date but not on empty values.
// Note that in case of HTML5 ``date``/``datetime-local`` support
// the value is empty on invalid input.
// In case of HTML5 date/datetime-local support we also have to
// check for ``badInput`` as invalid date input will result in an
// empty ``value``.
var type = input.getAttribute('type'); // we need the raw type here
if (Modernizr.inputtypes.date && type.indexOf('date') === 0) {
// Do the date check if the input is invalid (actually
// double-checking here - HTML5 and validate.js).
return input.validity.badInput;
if (
Modernizr.inputtypes.date &&
type.indexOf('date') === 0 &&
typeof input.validity.badInput !== "undefined"
) {
// Do the date check if the input is invalid or not missing
// (actually double-checking here - HTML5 and validate.js).
return input.validity.badInput || !!input.value;
} else {
// Do the date check if input is not empty (Safari has yet no
// date support at all)
Expand Down