Ray
Ray

Reputation: 4929

Unobtrusive validation fails even before my javascript call to submit

I have an ASP.NET MVC application with a form defined as:

@using (Ajax.BeginForm("Identify", "Employee", new AjaxOptions()
{
    HttpMethod = "POST",
    OnSuccess = "Identify.OnSuccess(data, status, xhr)",
    OnFailure = "Identify.OnFailure(xhr, status, error)"
}, new { id = "identifyForm"}))
{
    <div id="employeeIdContainer">
        @Html.LabelFor(m => m.IdEmployee) : <br/>
        @Html.TextBoxFor(m => m.IdEmployee, new {@type = "number", @Id = "IdEmployee"})
        <span class="validation">
        @Html.ValidationMessageFor(m => m.IdEmployee)
    </span>
    </div>

    <div id="pinContainer">
        @Html.LabelFor(m => m.Pin) : <br/>
        @Html.PasswordFor(m => m.Pin, new {@type = "number", @maxlength = "4", @Id = "Pin"})
        <span class="validation">
        @Html.ValidationMessageFor(m => m.Pin)
    </span>
    </div>

    <div>
        <input class="validate" type="submit" value="Submit" name="identifyButton"/>
    </div>

    <div id="keyboardContainer">
        <ul id="keyboard">
            <li class="number">1</li>
            <li class="number">2</li>
            <li class="number">3</li>
            <li class="validate">Submit</li>
            <li class="number line">4</li>
            <li class="number">5</li>
            <li class="number">6</li>
            <li class="delete">Corriger</li>
            <li class="number line">7</li>
            <li class="number">8</li>
            <li class="number">9</li>
            <li class="number line hidden"></li>
            <li class="number">0</li>
            <li class="number hidden"></li>
        </ul>   
    </div>
}

Inside the form I have a ul that I styled as a keyboard and this keyboard has an li that I want to use as a submit button, the one with the validate class. This isn't a regular submit button, but how do I submit the form in this case? I tried the following in javascript:

 $("#keyboard li.validate").click(function () {
    if ($("#identifyForm").valid()) {
        $("#identifyForm").submit();
    }
});

...but for some reason, before this javascript code is even called, the @Html.PasswordFor textbox gets erased and the validation kicks in saying that I need to enter a valid pin number (even when I just entered a valid one).

I have jQuery code that updates the EmployeeId and Pin number as the user types in the keyboard. I'm starting to think that the Unobtrusive validation mechanism does not see that these values have been updated and so it thinks that the Pin number is still empty. Here is the jQuery code if it helps:

var keyboard = $(function () {

var currentInput = $("#IdEmployee");

$("#Pin").on("focusin", function() {
    currentInput = $("#Pin");
});

$("#IdEmployee").on("focusin", function() {
    currentInput = $("#IdEmployee");
});

$('#keyboard li').click(function () {
    var $this = $(this),
        character = $this.html();

    if ($this.hasClass('delete')) {
        var html = currentInput.val();
        currentInput.val(html.substr(0, html.length - 1));
        return false;
    }
    currentInput.val(currentInput.val() + character);
});

$("#keyboard li.validate").click(function () {
    if ($("#identifyForm").valid()) {
        $("#identifyForm").submit();
    }
});

$("#IdEmployee").focus();

});

Upvotes: 2

Views: 68

Answers (1)

user3559349
user3559349

Reputation:

Your $('#keyboard li').click(function () { is setting the current input to the text value of the associated li element.

In the case of <li class="validate">Submit</li> it is setting the value of the current numeric input to the value "Submit" which is not a valid number, so validation fails. And because its invalid, the contents are cleared (that is the default behavior of the HTML5 control)

You can make this work by modifying your script to

$('#keyboard li').click(function () {
  var $this = $(this),
      character = $this.html();
  if ($this.hasClass('validate')) {
    return;
  } else if ($this.hasClass('delete')) {
    var html = currentInput.val();
    currentInput.val(html.substr(0, html.length - 1));
    return false;
  }
  currentInput.val(currentInput.val() + character);
});

or modify the selector to exclude the li with class="validate" element

$('#keyboard li:not(.validate)') {

Side note: Its not necessary to add new { @Id = "IdEmployee"} to your controls. Your just overwriting the id attribute with the value that it already is.

Upvotes: 1

Related Questions