/** * remote validator * * @link http://formvalidation.io/validators/remote/ * @author https://twitter.com/nghuuphuoc * @copyright (c) 2013 - 2015 Nguyen Huu Phuoc * @license http://formvalidation.io/license/ */ (function(root, factory) { "use strict"; // AMD module is defined if (typeof define === "function" && define.amd) { define("validator/remote", ["jquery", "base"], factory); } else { // planted over the root! factory(root.jQuery, root.FormValidation); } }(this, function ($, FormValidation) { FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, { 'en_US': { remote: { 'default': 'Please enter a valid value' } } }); FormValidation.Validator.remote = { html5Attributes: { message: 'message', name: 'name', type: 'type', url: 'url', data: 'data', delay: 'delay' }, /** * Destroy the timer when destroying the bootstrapValidator (using validator.destroy() method) */ destroy: function(validator, $field, options) { var ns = validator.getNamespace(), timer = $field.data(ns + '.remote.timer'); if (timer) { clearTimeout(timer); $field.removeData(ns + '.remote.timer'); } }, /** * Request a remote server to check the input value * * @param {FormValidation.Base} validator Plugin instance * @param {jQuery} $field Field element * @param {Object} options Can consist of the following keys: * - url {String|Function} * - type {String} [optional] Can be GET or POST (default) * - data {Object|Function} [optional]: By default, it will take the value * { * : * } * - delay * - name {String} [optional]: Override the field name for the request. * - message: The invalid message * - headers: Additional headers * @returns {Deferred} */ validate: function(validator, $field, options) { var ns = validator.getNamespace(), value = validator.getFieldValue($field, 'remote'), dfd = new $.Deferred(); if (value === '') { dfd.resolve($field, 'remote', { valid: true }); return dfd; } var name = $field.attr('data-' + ns + '-field'), data = options.data || {}, url = options.url, type = options.type || 'GET', headers = options.headers || {}; // Support dynamic data if ('function' === typeof data) { data = data.call(this, validator); } // Parse string data from HTML5 attribute if ('string' === typeof data) { data = JSON.parse(data); } // Support dynamic url if ('function' === typeof url) { url = url.call(this, validator); } data[options.name || name] = value; function runCallback() { var xhr = $.ajax({ type: type, headers: headers, url: url, dataType: 'json', data: data }); xhr .success(function(response) { response.valid = response.valid === true || response.valid === 'true'; dfd.resolve($field, 'remote', response); }) .error(function(response) { dfd.resolve($field, 'remote', { valid: false }); }); dfd.fail(function() { xhr.abort(); }); return dfd; } if (options.delay) { // Since the form might have multiple fields with the same name // I have to attach the timer to the field element if ($field.data(ns + '.remote.timer')) { clearTimeout($field.data(ns + '.remote.timer')); } $field.data(ns + '.remote.timer', setTimeout(runCallback, options.delay)); return dfd; } else { return runCallback(); } } }; return FormValidation.Validator.remote; }));