Manually set unobtrusive validation error on a textbox
Asked Answered
C

5

22

I'm doing something similar to the remote validation, except that I already make my calls manually via jquery and setup whatever I had to setup.

Now my problem is, if I want to tell the validator that a particular textbox is not valid (and prevents the page from submitting, highlight the textbox, etc). How would I do this from code?

@Html.LabelFor(m => Model.Slug)
@Html.TextBoxFor(m => Model.Slug)
<span id="UrlMsg" class="field-validation-error" style="display: none;"></span>

 if (error) {
        $('#UrlMsg').html('This name is already in use.').fadeIn('fast');
        //what should I do here for the rest of the validation?
 }
Cusped answered 11/9, 2011 at 18:13 Comment(1)
Note to readers: the accepted answer probably doesn't do what you think it does. See my answer below for more detail.Crispin
V
50

First, you can add a validation summary:

@Html.ValidationMessageFor(m => m.Slug)

Then you can manually trigger jQuery validation / unobtrusive validation with the .showError method. Here is a sample:

var errorArray = {};
errorArray["Slug"] = 'Some error message for the Slug text box';
$('#SomeFormId').validate().showErrors(errorArray);
Vandalism answered 2/11, 2011 at 23:31 Comment(2)
But the form is valid if the errors are added manually like this $('#SomeFormId')= true?Mollee
Works great but can't get rid of the error afterwardsRoccoroch
A
8

You can also do:

@Html.ValidationMessageFor(m => m.Slug)

With this function in your code:

function setError(id, message) {
        var span = $("span[data-valmsg-for=\"" + id + "\"]");
        if (span && span.length > 0) {
            $(span).html(message);
            if (message && message != "") {
                $(span).removeClass("field-validation-valid");
                $(span).addClass("field-validation-no-valid");
            } else {
                $(span).removeClass("field-validation-no-valid");
                $(span).addClass("field-validation-valid");
            }
        }
    }

Then can set the error

setError("Slug", "errorMsg");
Alkyne answered 10/11, 2016 at 15:51 Comment(0)
K
5

Using showErrors did not allow the error to persist, so that running .valid() cleared the error. Instead, I added a "forcibleerror" rule and a javascript method to set the message.

function forceError(element, errorMessage) {
    $(element).rules("add", {
        forcibleerror: true,
        messages: {
            forcibleerror: function () { return errorMessage; }
        }
    });
    var isForced = false;
    if (errorMessage) {
        isForced = true;
    }
    $(element)[0].dataset.isForced = isForced;
    $(element).valid();
}
$.validator.addMethod("forcibleerror", function (value, element) {
    return $(element)[0].dataset.isForced !== "true";
});

Usage:

forceError($('#Slug'), 'my custom message');

To put it back in a valid state:

forceError($('#Slug'), '');
Karr answered 19/6, 2018 at 14:42 Comment(0)
P
3

This is an improvement on FRL's answer:

@Html.ValidationMessageFor(m => m.Slug)

JS Function

const span = $('span[data-valmsg-for="' + name + '"]');
function setError(name, message) {
    const span = $(`span[data-valmsg-for="${name}"]`);
    if (span && span.length > 0) {
        $(span).html(message);
        if (message) {
            $(`input[name="${name}"]`).addClass("input-validation-error");
            $(span).removeClass("field-validation-valid");
            $(span).addClass("field-validation-error");
        } else {
            $(`input[name="${name}"]`).removeClass("input-validation-error");
            $(span).removeClass("field-validation-error");
            $(span).addClass("field-validation-valid");
        }
    }
}

Call it like this:

setError("Slug", "errorMsg");
Promissory answered 21/12, 2018 at 8:25 Comment(0)
C
2

The accepted answer has two big problems that make it useless, in my opinion:

  1. It doesn't change the input's state to invalid. Therefore, the user is free to submit the form.
  2. It will be wiped out as soon as the input is validated next, such as on the input's next keyboard event.

kevinpo's answer addresses both of these problems and is probably what you should use if you need dynamically-generated error messages. But static error messages are usually good enough, so...

Let's make this really simple this with unobtrusive validation.

Add this to your site-wide javascript file:

$.fn.extend({
  toggleOk: function (value) {
    this[0].dataset.ok = value;
    this.valid();
  }
});

$.validator.addMethod("ok", function (value, element) {
  return this.optional(element) || $(element)[0].dataset.ok === "true";
});

$.validator.unobtrusive.adapters.addBool("ok");

Add this to the relevant input element in your HTML. The first attribute, data-val-ok, tells unobtrusive validation to activate this type of validation for this input and tells it what error message to show when it is invalid. The second attribute, data-ok, sets the initial state to valid.

data-val-ok="That item does not exist." data-ok="true"

Call this code in your page's Javascript to set the input to invalid, display the error and related formatting, and block page submission.

$('#myInput').toggleOk(false);

Call this to change it back to valid, hide the error and related formatting, and permit page submission:

$('#myInput').toggleOk(true);
Crispin answered 2/10, 2020 at 19:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.