I have the following model:
public class Customer
{
public string FirstName {get;set;}
public string LastName {get; set;}
[Remote(\"CardExistin
if you don't like to create client scripts:
public class Customer
{
[Remote("CardExisting", "Validation", AdditionalFields = "CardNumber,LastName")]
public string FirstName { get; set; }
[Remote("CardExisting", "Validation", AdditionalFields = "FirstName,CardNumber")]
public string LastName { get; set; }
[Remote("CardExisting", "Validation", AdditionalFields = "FirstName,LastName")]
public string CardNumber { get; set; }
}
And validate in CardExisting all fields are filled or not
The way I have got this working is by adding some JavaScript.
$("#FirstName").change(function () {
$('#CardNumber').removeData('previousValue');
$('#CardNumber').valid();
});
So when the first name is changed you clear any previous values from the card number and re-validate the card number.
Expanding on Jaluka's answer, I wrote this helper method that finds each remotely validating element that has "additional fields," and then causes validation on said element to fire each time one of those fields changes.
// I hate naming things
function initializeRemotelyValidatingElementsWithAdditionalFields($form) {
var remotelyValidatingElements = $form.find("[data-val-remote]");
$.each(remotelyValidatingElements, function (i, element) {
var $element = $(element);
var additionalFields = $element.attr("data-val-remote-additionalfields");
if (additionalFields.length == 0) return;
var rawFieldNames = additionalFields.split(",");
var fieldNames = $.map(rawFieldNames, function (fieldName) { return fieldName.replace("*.", ""); });
$.each(fieldNames, function (i, fieldName) {
$form.find("#" + fieldName).change(function () {
// force re-validation to occur
$element.removeData("previousValue");
$element.valid();
});
});
});
}
Call the function like so:
$(document).ready(function() {
initializeRemotelyValidatingElementsWithAdditionalFields($("#myFormId"));
});
Following on from Chris's helper method above. This works great in most instances, but if your model has a prefix at all e.g. 'Custom.Address.Line1' . The additional fields are not found correctly. I have updated the helper with some additional logic from the jquery.validate.unobstructive lib which will lookup the fields correctly.
function getModelPrefix(fieldName) {
return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
}
function appendModelPrefix(value, prefix) {
if (value.indexOf("*.") === 0) {
value = value.replace("*.", prefix);
}
return value;
}
function escapeAttributeValue(value) {
// As mentioned on http://api.jquery.com/category/selectors/
return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
}
function initializeRemotelyValidatingElementsWithAdditionalFields($form) {
const remotelyValidatingElements = $form.find("[data-val-remote]");
$.each(remotelyValidatingElements, function (i, element) {
var $element = $(element);
const additionalFields = $element.attr("data-val-remote-additionalfields");
if (additionalFields.length === 0) return;
const rawFieldNames = additionalFields.split(",");
const prefix = getModelPrefix(element.name);
const fieldNames = $.map(rawFieldNames, function(fieldName) {
return appendModelPrefix(fieldName, prefix);
});
$.each(fieldNames, function (i, fieldName) {
$form.find(":input").filter("[name='" + escapeAttributeValue(fieldName) + "']").change(function () {
// force re-validation to occur
$element.removeData("previousValue");
$element.valid();
});
});
});
}