Confirm 1 field (unobtrusive) when changing another field and check only 1 rule

Is there a way to run a specific jquery-non-intrusiveness rule in one field when the value in another field changes?

I have a form with two date fields (e.g. start / end), with confirmation that end must be greater than start . This works fine in the simple case of changing end after start already set. What he does not do is allow:

  • set end first and then set start
  • changing start after both are already set, and breaking the constraint

A server-side check will probably catch it, but it will be bad if the error in end remains fixed even after fixing start , or if there is no error that appears when changing the value in end to an invalid value. The reason for running a specific rule is that I do not want to run the required or date format rules in the same field before the user can enter a value. The form begins with "clean." However, if this is not possible, running all the rules is in order.

Sorry for the lack of code samples, but I don’t even know where to start.

Update:

What I have done so far is to delve into the model (since this is an asp.net mvc project), find the attribute and read its properties directly.

 var controllerCtx = ViewContext.Controller.ControllerContext; var da = ViewData.ModelMetadata.GetValidators(controllerCtx) .SelectMany(x => x.GetClientValidationRules()) .Where(x => x.ValidationType == "isdateafter") .FirstOrDefault(); var otherid = da == null ? "" : da.ValidationParameters["propertytested"]; 

Then, in the normal part of HTML, I run a start test and see if it is a date picker, then connect the basic validation and work out all the validation rules. Since there are not many rules, I just check to see if there is a value in the end field before running them. I would like to use the brilliant solution below, and this will give him time when I will have free time this week.

 @if (otherid != "") { <text> var other = $("#@otherid"); if (other && other.hasClass('hasDatepicker')) { // if the other box is a date/time picker other.datetimepicker('option', 'onSelect', function(dateText, instance) { var lowerTime = $(this).datetimepicker('getDate'); $("#@id").datetimepicker('option', 'minDate', new Date(lowerTime.getTime())); if ($("#@id").val()) { // if there is a value in the other $('form').data('validator').element('#@id'); } }); } </text> } 
+4
source share
1 answer

This might work for you ...

 $('form').data('validator').element('#Key') 

This grabs the validator from your form and forces a single element to be validated.

http://docs.jquery.com/Plugins/Validation/Validator/element#element

UPDATE

See if it helps!

 $.extend($.validator.prototype, { elementWithRule: function(element, rule) { element = this.clean(element); this.lastElement = element; this.prepareElement(element); this.currentElements = $(element); var result = this.checkSpecificRule(element, rule); if (result) { delete this.invalid[element.name]; } else { this.invalid[element.name] = true; } if (!this.numberOfInvalids()) { // Hide error containers on last error this.toHide = this.toHide.add(this.containers); } this.showErrors(); return result; }, checkSpecificRule: function(element, rule) { element = this.clean(element); // if radio/checkbox, validate first element in group instead if (this.checkable(element)) { element = this.findByName(element.name).not(this.settings.ignore)[0]; } var findRule = { }, checkRule = $(element).rules()[ rule ]; var rules; if (checkRule) { findRule[rule] = checkRule; rules = findRule; } if (!rules) { return; } var dependencyMismatch = false; for (var method in rules) { var rule = { method: method, parameters: rules[method] }; try { var result = $.validator.methods[method].call(this, element.value.replace( /\r/g , ""), element, rule.parameters); // if a method indicates that the field is optional and therefore valid, // don't mark it as valid when there are no other rules if (result == "dependency-mismatch") { dependencyMismatch = true; continue; } dependencyMismatch = false; if (result == "pending") { this.toHide = this.toHide.not(this.errorsFor(element)); return; } if (!result) { this.formatAndAdd(element, rule); return false; } } catch(e) { this.settings.debug && window.console && console.log("exception occured when checking element " + element.id + ", check the '" + rule.method + "' method", e); throw e; } } if (dependencyMismatch) return; if (this.objectLength(rules)) this.successList.push(element); return true; } }); // Then use it like this... $('form').data('validator').elementWithRule('#Key', 'required'); 

There seems to be no built-in way to do this, so I just hacked something! :)

+9
source

Source: https://habr.com/ru/post/1412802/


All Articles