Skip to content

Remote validations with Promise

dinatih edited this page Jul 17, 2018 · 4 revisions

Maybe is not the best way, but I try help someone this method I change :

validateElement = function(element, validators) {
  var afterValidate, destroyInputName, executeValidators, executeRemoteValidators, failElement, local, passElement, remote;
  element.trigger('element:validate:before.ClientSideValidations');
  passElement = function() {
    return element.trigger('element:validate:pass.ClientSideValidations').data('valid', null);
  };
  failElement = function(message) {
    element.trigger('element:validate:fail.ClientSideValidations', message).data('valid', false);
    return false;
  };
  afterValidate = function() {
    return element.trigger('element:validate:after.ClientSideValidations').data('valid') !== false;
  };
  executeValidators = function(context) {
    var fn, i, kind, len, message, ref, valid, validator;
    valid = true;
    for (kind in context) {
      fn = context[kind];
      if (validators[kind]) {
        ref = validators[kind];
        for (i = 0, len = ref.length; i < len; i++) {
          validator = ref[i];
          message = fn.call(context, element, validator);
          if (message) {
            valid = failElement(message);
            break;
          }
        }
        if (!valid) {
          break;
        }
      }
    }
    return valid;
  };
  executeRemoteValidators = function(context) {
    var fn, i, kind, len, message, ref, valid, validator;
    valid = $.Deferred();
    for (kind in context) {
      fn = context[kind];
      if (validators[kind]) {
        ref = validators[kind];
        for (i = 0, len = ref.length; i < len; i++) {
          validator = ref[i];
          message = fn.call(context, element, validator);
          message.done(function(message_promise) {
            console.log(message_promise);
            valid.resolve(failElement(message_promise));
          });
        }
      }
    }
    return valid;
  };
  if (element.attr('name').search(/\[([^\]]*?)\]$/) >= 0) {
    destroyInputName = element.attr('name').replace(/\[([^\]]*?)\]$/, '[_destroy]');
    if ($("input[name='" + destroyInputName + "']").val() === '1') {
      passElement();
      return afterValidate();
    }
  }
  if (element.data('changed') === false) {
    return afterValidate();
  }
  element.data('changed', false);
  local = ClientSideValidations.validators.local;
  remote = ClientSideValidations.validators.remote;
  if (executeValidators(local) && executeRemoteValidators(remote).done(function(valid) {
      return valid
    })) {
    passElement();
  }
  return afterValidate();
};

And for call It

// This is my own method than call to ajax for validation remote
function checkValidatorEmailUnique(params) {
  var aDeferred = jQuery.Deferred();
  if (typeof params == 'undefined') {
    params = {};
  }
  params.success = function(data, status, jqXHR) {
    aDeferred.resolve(data);
  };
  params.error = function(jqXHR, textStatus, errorThrown) {
    aDeferred.reject(textStatus, errorThrown);
  };
  jQuery.ajax(params);
  return aDeferred.promise();
}

ClientSideValidations.validators.remote['uniqueness'] = function(element, options) {
  var promise_response = $.Deferred();
  var params = {
    url: '/validator/check_email',
    data: {
      id: element.val()
    },
  };
  checkValidatorEmailUnique(params).done(
    function(response) {
      promise_response.resolve(options.message);
    }
  );
  return promise_response
};

I hope It helps you!!

Ref: #728