Question

We have a mask with ~400 input fields which are all loaded on the client. The mask is structured in several tabs and accordions to enable the users to see and edit directly all necessary fields. At the end of the editing, the mask is validated on the client.

We use jQuery UI for tabs and accordions and the jQuery Validation Plugin for on client validation. On the server we run ASP.NET MVC. To generate the HTML with necessary data-val-* attributes we use different techniques:

  • default EditorFor-helper function (@Html.EditorFor(model => model.property)

  • specific TextBoxFor, DropDownListFor helper functions (`@Html.EditorFor(model => model.property')

  • custom HTML tags, when we need specific formatting ex:

      <input 
          class="text-box single-line" 
          data-val="true" 
          data-val-number="The field @data.Title must be a number." 
          id="@data.Name" 
          name="@data.Name" 
          type="text" 
          value="@data.Value" @(data.IsDisabled ? "disabled='disabled'" : string.Empty ) />
    

However we don't use the extension function The generated fields look all pretty similar, ex:

<input name="fieldName" 
       class="text-box single-line valid" 
       id="fieldName" 
       type="text" 
       value="311969d" 
       data-val="true" 
       data-val-length-max="8" 
       data-val-length="The field fieldName must be a string with a maximum length of 8.">

If I modify the value of this input with more than 8 characters, the field is marked red, showing and error and everything works nicely.

However when I press submit, the validation takes ~12.5 seconds - this it what I get from the IE - profiler:

IE-profiler screenshot of one validation round executed

As many mentioned in the comments before I updated this question, DOM Manipulations make the execution extremely slow, but I don't understand why the jQuery-Validation plugin adds new elements to my HTML page. Here you can see the showLabel-function which performs the DOM Manipulation:

showLabel: function(element, message) {
    var label = this.errorsFor( element );
    if ( label.length ) {
        // refresh error/success class
        label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );

        // check if we have a generated label, replace the message then
        label.attr("generated") && label.html(message);
    } else {
        // create label
        label = $("<" + this.settings.errorElement + "/>")
            .attr({"for":  this.idOrName(element), generated: true})
            .addClass(this.settings.errorClass)
            .html(message || "");
        if ( this.settings.wrapper ) {
            // make sure the element is visible, even in IE
            // actually showing the wrapped element is handled elsewhere
            label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
        }
        if ( !this.labelContainer.append(label).length )
            this.settings.errorPlacement
                ? this.settings.errorPlacement(label, $(element) )
                : label.insertAfter(element);
    }
    if ( !message && this.settings.success ) {
        label.text("");
        typeof this.settings.success == "string"
            ? label.addClass( this.settings.success )
            : this.settings.success( label );
    }
    this.toShow = this.toShow.add(label);
},

Interestingly however, now error label or anything similar is displayed, or shows up on the DOM. Also we actually don't want to have any labels displayed, since there isn't any space for it on the mask. We'd rather use ToolTip texts where the error is shown, as it works with most modern browsers and HTML validation.

For a short term solution it would be good if we could somehow disable (for this mask only) the DOM Manipulation. Is it possible with some configuration?

A more sophisticated solution would be to use HTML validation instead of JavaScript since our customer already now uses IE 9 or 10 and if necessary they'll be able to upgrade to 10, which supports it. I've found a Stack Overflow question from last November about it: ASP.NET MVC 5 and HTML 5 form attributes according to the W3C specs. Maybe something has changed or is going to change in this manner? Since a manual implementation for all the fields will be too much work.

Was it helpful?

Solution

Which browsers do you need to support? For the newer browsers, you can use HTML5 form validation e.g:

<form>
  <label for="choose">Would you prefer a banana or a cherry?</label>
  <input id="choose" name="i_like" pattern="banana|cherry">
  <button>Submit</button>
</form>

And as fallback for older browsers you can include your validation script.

OTHER TIPS

I would validate one field set at a time.

Every time a user opens a pane and then enters some data into a field on that pane, this pane would be marked 'dirty'. Now when the user goes ahead and opens another pane, he won't be able to 'leave' until he fixed any validation requirements posed to the fields on the current pane.

This way, a validation would occur in descrete portions, avoiding unnessecary roundtrips to fields the user didn't even touch.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top