Number Textbox

As part of a new UI library, I have created a custom server control that creates the markup for a simple textbox using the new HTML5 input type of "number" and the pattern attribute. The URL Textbox supports the following features:

  • Native browser support, if available.
  • Instant character validation on keyup and blur.
  • Optional min and max allowed value range.
  • Optional setting to set an empty entry to zero (0).
  • Regular expression validation upon submit. The "pattern" attribute is set dynamically.
  • Dynamic maxlength assignment.
  • Fully integrates with the UI Library - Ajax Form feature.
  • UI Manifesto compliance:

The Demo

The Markup

Just a basic input element, with a normal type attribute of "number" and a RegExp pattern value. Once the Script stuff is in place on a website, any page can take advantage of this Number Textbox by simply setting an input's type attribute to "number" and setting the desired optional min and max attribute and the optional data-setEmptyToZero custom data attribute. If native browser support is available, then the browser implementation of the control will be used in addtion to the onkey up validation.

That sounds like a DRY solution to me (see UI Manifesto).

 
<div class="form legendLook horizontalFormLayout">
    <div id="hdivFormTest1ConfirmationMessage" class="confirmationMessageWrapper hide"></div>
            
    <label for="txtNumber">Number:</label>
    <input type="number" id="txtNumber" style="width:150px;" 
        required 
        placeholder="between 0 and 100"            
        min="0"
        max="100"
        data-setEmptyToZero="true"
        data-formGroup="formAuthenticate" 
        name="Value" />   
            
    <div class="formButtonWrapper clearFix">
        <input type="submit" class="ajaxFormPost buttonStrong" value="Submit"
            data-formGroup="formAuthenticate" 
            data-serviceRequestUrl="..." 
            data-successFunction="successFormTest1"
            data-confirmActionMessage=""
            data-processingMessage=""
            data-overlayWindowWhileProcessing="true" />
    </div>
</div>

The Script

//Abstracted Methods for Formatting
function makeNumeric(value, setEmptyToZero, minNumberAllowed, maxNumberAllowed) {
    var numericValue = "";
    for (var i = 0; i <= value.length; i++) {
        if (value.charAt(i) == "1" || value.charAt(i) == "2" || value.charAt(i) == "3" || value.charAt(i) == "4" || value.charAt(i) == "5" || value.charAt(i) == "6" || value.charAt(i) == "7" || value.charAt(i) == "8" || value.charAt(i) == "9" || value.charAt(i) == "0") {
            numericValue += value.charAt(i);
        }
    }

    if (setEmptyToZero) {
        if (numericValue == "") {
            numericValue = 0;
        }
    }

    if (minNumberAllowed != null && numericValue < minNumberAllowed) {
        numericValue = minNumberAllowed;
    }

    if (maxNumberAllowed != null && numericValue > maxNumberAllowed) {
        numericValue = maxNumberAllowed;
    }

    return numericValue;
}

//Enable Number Textbox(es)
$(parentElementSelector + " input[type='number']").each(function () {
    //Build and assign the "pattern", if not already there.
    if (!isAttrDefined($(this).attr("pattern")) || $(this).attr("pattern").length == 0) {
        var patternValue = "^\\d+$";
        $(this).attr("pattern", patternValue);
    }

    //Assign the "maxlength", if not already there.
    if (!isAttrDefined($(this).attr("maxlength")) || $(this).attr("maxlength").length == 0) {
        $(this).attr("maxlength", "11"); //safe int32 range
    }

    $(this).keyup(function () {
        var setEmptyToZero = (($(this).attr("data-setEmptyToZero") == "true") ? true : false);
        var min = ((!isAttrDefined($(this).attr("min"))) ? null : ((isNaN(parseInt($(this).attr("min"), 10))) ? null : eval($(this).attr("min"))));
        var max = ((!isAttrDefined($(this).attr("max"))) ? null : ((isNaN(parseInt($(this).attr("max"), 10))) ? null : eval($(this).attr("max"))));
        $(this).val(makeNumeric($(this).val(), setEmptyToZero, min, max));
    });
});

The CSS

 
    Not applicable.