Integer Keypress Binding

by CodeRenaissance

HTML

<script src="http://cloud.github.com/downloads/coderenaissance/knockout.mapping/knockout-1.3.0beta.js"></script>
<script src="http://cloud.github.com/downloads/coderenaissance/knockout.mapping/knockout.mapping.js"></script>
<div id="test">
    <div>Max Length set to: <span data-bind="text: maxlength" /></div>
    <input data-bind="moneyKeypressValue:test, attr:{maxlength: maxlength}" type="input"/><br/>
<div>Stored Data: <span data-bind="text:test" /></div>
</div>

CSS

#test input{
 width:80px;
 text-align:right;   
}

JavaScript

(function () {//lets keep all of this out of the global namespace
     // format settings
    var prefix = '$ ';
    var thousandsSeparator = ',';
    var maxLimit =  13;
    var limit = maxLimit;

    function safeParse(val) {//accepts string, number, and all falsy values
        val = val || 0; //empty string and other falsy to 0;
        
        if (typeof val === 'string') {
            val = val.replace(/[^0-9]+/g, '');//replace all but numbers
            val = parseFloat(val, 10) || 0;//get float of string
        }
        
        //while val may have come in as either numeric or string it is now numeric
        //convert to fixed decimal string(stipping excess decimals) and parse again
        val = parseFloat(val.toFixed(0), 10) ;
        return val;
    }

    function getUnformattedText(val) {//removes all formatting: $0.00 becomes 000
        val = (typeof val === "number") ? val = val.toFixed(0) : val;
        val = val.replace(/[^0-9]+/g, '');//replace all but numbers
        
        //Remove leading zeros if needed
        while (val.length > 3 && val.indexOf('0',0) === 0 ) {
            val = val.substring(1);
        }
        
        return val;
    }

    // format as price
    function updateDisplayText(formattedText, options) {
        var unformattedText, reversedArray, spliceIndex, significantCharacters;
        options = options || {};//ensure options exist
        unformattedText = getUnformattedText(formattedText); 
        significantCharacters = (function(val){
            while (val.indexOf('0',0) === 0 ) {
                val = val.substring(1);    
            }
            return val.length;
        }(unformattedText));
        
        //add new char if limit not passed (subtact 1 for decimal point)
        if(options.newCharacter && significantCharacters < Math.min(limit, maxLimit)){
            unformattedText = unformattedText + (options.newCharacter || "");
        }
        
        //reversing allows for seperators to...