303 lines
10 KiB
JavaScript
Executable File
303 lines
10 KiB
JavaScript
Executable File
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
|
|
/* global BASE_URL, alertAlreadyDisplayed */
|
|
define([
|
|
'jquery',
|
|
'underscore',
|
|
'Magento_Ui/js/modal/alert',
|
|
'jquery/ui',
|
|
'jquery/validate',
|
|
'mage/translate',
|
|
'mage/validation'
|
|
], function ($, _, alert) {
|
|
'use strict';
|
|
|
|
$.extend(true, $.validator.prototype, {
|
|
/**
|
|
* Focus invalid fields
|
|
*/
|
|
focusInvalid: function () {
|
|
if (this.settings.focusInvalid) {
|
|
try {
|
|
$(this.errorList.length && this.errorList[0].element || [])
|
|
.trigger('focus')
|
|
.trigger('focusin');
|
|
} catch (e) {
|
|
// ignore IE throwing errors when focusing hidden elements
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Elements.
|
|
*/
|
|
elements: function () {
|
|
var validator = this,
|
|
rulesCache = {};
|
|
|
|
// select all valid inputs inside the form (no submit or reset buttons)
|
|
return $(this.currentForm)
|
|
.find('input, select, textarea')
|
|
.not(this.settings.forceIgnore)
|
|
.not(':submit, :reset, :image, [disabled]')
|
|
.not(this.settings.ignore)
|
|
.filter(function () {
|
|
if (!this.name && validator.settings.debug && window.console) {
|
|
console.error('%o has no name assigned', this);
|
|
}
|
|
|
|
// select only the first element for each name, and only those with rules specified
|
|
if (this.name in rulesCache || !validator.objectLength($(this).rules())) {
|
|
return false;
|
|
}
|
|
|
|
rulesCache[this.name] = true;
|
|
|
|
return true;
|
|
});
|
|
}
|
|
});
|
|
|
|
$.extend($.fn, {
|
|
/**
|
|
* ValidationDelegate overridden for those cases where the form is located in another form,
|
|
* to avoid not correct working of validate plug-in
|
|
* @override
|
|
* @param {String} delegate - selector, if event target matched against this selector,
|
|
* then event will be delegated
|
|
* @param {String} type - event type
|
|
* @param {Function} handler - event handler
|
|
* @return {Element}
|
|
*/
|
|
validateDelegate: function (delegate, type, handler) {
|
|
return this.on(type, $.proxy(function (event) {
|
|
var target = $(event.target),
|
|
form = target[0].form;
|
|
|
|
if (form && $(form).is(this) && $.data(form, 'validator') && target.is(delegate)) {
|
|
return handler.apply(target, arguments);
|
|
}
|
|
}, this));
|
|
}
|
|
});
|
|
|
|
$.widget('mage.validation', $.mage.validation, {
|
|
options: {
|
|
messagesId: 'messages',
|
|
forceIgnore: '',
|
|
ignore: ':disabled, .ignore-validate, .no-display.template, ' +
|
|
':disabled input, .ignore-validate input, .no-display.template input, ' +
|
|
':disabled select, .ignore-validate select, .no-display.template select, ' +
|
|
':disabled textarea, .ignore-validate textarea, .no-display.template textarea',
|
|
errorElement: 'label',
|
|
errorUrl: typeof BASE_URL !== 'undefined' ? BASE_URL : null,
|
|
|
|
/**
|
|
* @param {HTMLElement} element
|
|
*/
|
|
highlight: function (element) {
|
|
if ($.validator.defaults.highlight && typeof $.validator.defaults.highlight === 'function') {
|
|
$.validator.defaults.highlight.apply(this, arguments);
|
|
}
|
|
$(element).trigger('highlight.validate');
|
|
},
|
|
|
|
/**
|
|
* @param {HTMLElement} element
|
|
*/
|
|
unhighlight: function (element) {
|
|
if ($.validator.defaults.unhighlight && typeof $.validator.defaults.unhighlight === 'function') {
|
|
$.validator.defaults.unhighlight.apply(this, arguments);
|
|
}
|
|
$(element).trigger('unhighlight.validate');
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Validation creation
|
|
* @protected
|
|
*/
|
|
_create: function () {
|
|
if (!this.options.submitHandler && typeof this.options.submitHandler !== 'function') {
|
|
if (!this.options.frontendOnly && this.options.validationUrl) {
|
|
this.options.submitHandler = $.proxy(this._ajaxValidate, this);
|
|
} else {
|
|
this.options.submitHandler = $.proxy(this._submit, this);
|
|
}
|
|
}
|
|
this.element.on('resetElement', function (e) {
|
|
$(e.target).rules('remove');
|
|
});
|
|
this._super('_create');
|
|
},
|
|
|
|
/**
|
|
* ajax validation
|
|
* @protected
|
|
*/
|
|
_ajaxValidate: function () {
|
|
$.ajax({
|
|
url: this.options.validationUrl,
|
|
type: 'POST',
|
|
dataType: 'json',
|
|
data: this.element.serialize(),
|
|
context: $('body'),
|
|
success: $.proxy(this._onSuccess, this),
|
|
error: $.proxy(this._onError, this),
|
|
showLoader: true,
|
|
dontHide: false
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Process ajax success.
|
|
*
|
|
* @protected
|
|
* @param {Object} response
|
|
*/
|
|
_onSuccess: function (response) {
|
|
if (!response.error) {
|
|
this._submit();
|
|
} else {
|
|
this._showErrors(response);
|
|
$(this.element[0]).trigger('afterValidate.error');
|
|
$('body').trigger('processStop');
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Submitting a form.
|
|
* @private
|
|
*/
|
|
_submit: function () {
|
|
$(this.element[0]).trigger('afterValidate.beforeSubmit');
|
|
this.element[0].submit();
|
|
},
|
|
|
|
/**
|
|
* Displays errors after backend validation.
|
|
*
|
|
* @param {Object} data - Data that came from backend.
|
|
*/
|
|
_showErrors: function (data) {
|
|
$('body').notification('clear')
|
|
.notification('add', {
|
|
error: data.error,
|
|
message: data.message,
|
|
|
|
/**
|
|
* @param {*} message
|
|
*/
|
|
insertMethod: function (message) {
|
|
$('.messages:first').html(message);
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Tries to retrieve element either by id or by inputs' name property.
|
|
* @param {String} code - String to search by.
|
|
* @returns {jQuery} jQuery element.
|
|
*/
|
|
_getByCode: function (code) {
|
|
var parent = this.element[0],
|
|
element;
|
|
|
|
element = parent.querySelector('#' + code) || parent.querySelector('input[name=' + code + ']');
|
|
|
|
return $(element);
|
|
},
|
|
|
|
/**
|
|
* Process ajax error
|
|
* @protected
|
|
*/
|
|
_onError: function () {
|
|
$(this.element[0]).trigger('afterValidate.error');
|
|
$('body').trigger('processStop');
|
|
|
|
if (this.options.errorUrl) {
|
|
location.href = this.options.errorUrl;
|
|
}
|
|
}
|
|
});
|
|
|
|
_.each({
|
|
'validate-greater-zero-based-on-option': [
|
|
function (v, el) {
|
|
var optionType = $(el)
|
|
.closest('.form-list')
|
|
.prev('.fieldset-alt')
|
|
.find('select.select-product-option-type'),
|
|
optionTypeVal = optionType.val();
|
|
|
|
v = Number(v) || 0;
|
|
|
|
if (optionType && (optionTypeVal == 'checkbox' || optionTypeVal == 'multi') && v <= 0) { //eslint-disable-line
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
},
|
|
$.mage.__('Please enter a number greater 0 in this field.')
|
|
],
|
|
'validate-rating': [
|
|
function () {
|
|
var ratings = $('#detailed_rating').find('.field-rating'),
|
|
noError = true;
|
|
|
|
ratings.each(function (index, rating) {
|
|
noError = noError && $(rating).find('input:checked').length > 0;
|
|
});
|
|
|
|
return noError;
|
|
},
|
|
$.mage.__('Please select one of each ratings above.')
|
|
],
|
|
'validate-downloadable-file': [
|
|
function (v, element) {
|
|
var elmParent = $(element).parent(),
|
|
linkType = elmParent.find('input[value="file"]'),
|
|
newFileContainer;
|
|
|
|
if (linkType.is(':checked') && (v === '' || v === '[]')) {
|
|
newFileContainer = elmParent.find('.new-file');
|
|
|
|
if (!alertAlreadyDisplayed && (newFileContainer.empty() || newFileContainer.is(':visible'))) {
|
|
window.alertAlreadyDisplayed = true;
|
|
alert({
|
|
content: $.mage.__('There are files that were selected but not uploaded yet. ' +
|
|
'Please upload or remove them first')
|
|
});
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
},
|
|
'Please upload a file.'
|
|
],
|
|
'validate-downloadable-url': [
|
|
function (v, element) {
|
|
var linkType = $(element).parent().find('input[value="url"]');
|
|
|
|
if (linkType.is(':checked') && v === '') {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
},
|
|
$.mage.__('Please specify Url.')
|
|
]
|
|
}, function (rule, i) {
|
|
rule.unshift(i);
|
|
$.validator.addMethod.apply($.validator, rule);
|
|
});
|
|
|
|
return $.mage.validation;
|
|
});
|