Number & Currency Auto Formatting in Javascript

Hi Guys. Its been long since I have added a new post. But here I am with something that might be of use for you.
Its a very small Javascript library built by me which could be used to auto format the text that is being entered into a Textbox to correspond to American numeral system. It can be used to format the entered value on both onkeyup and onchange events.

Checkout the live working example
Enter any value here :-

The Code goes on something like this





var previousCurrencyValue;
var cursorPos;


/* Function that will reverse the given string 
        
input parameter  :- string to reverse
output parameter :- reversed string  
*/
function reverse(s) {
    var o = '';
    for (var i = s.length - 1; i >= 0; i--)
        o += s[i];
    return o;
}

function setInitialCursorPosition(textbox) {
    if (textbox.value == '0.0') {
        setCursorPosition(textbox, 1);
    }
}

/* Function that will be called onkeyup event of the textbox. It will split the entire string into
two parts. One before decimal point and other after decimal point. Process those two parts seperately
based on various validation criteria and finally join them into a complete string  
            
input parameter  :- Textbox object
output parameter :- Void    
*/

function removeIllegalChar(str) {
  
    var regex = /[^d,.]+/g;
    str = str.replace(regex, '');
  
    return str;
}

function checkFormat(textbox,type) {

  
    var e = window.event;
    if (e.keyCode == 8) {
        cursorPos++;
    }
    else if (e.keyCode >= 48 && e.keyCode <= 57) {
        cursorPos--;
    }
    cursorPos = getCursorPosition(textbox);
    var text = textbox.value;
    var orgLen = text.length;

    if (text == previousCurrencyValue) {
        return;
    }
    
    text = removeIllegalChar(text);
  
    var str2 = "";
    var decisplit = text.split('.');
    if (decisplit.length == 1) {
        str2 = "0";
        decisplit = decisplit.join('');
    }
  
    else {
        str2 = checkDecimal(decisplit[decisplit.length - 1]);
        decisplit[decisplit.length - 1] = '';
        decisplit = decisplit.join('');
    }
  
    if (type == "Currency") {
        var str1 = addCommas(decisplit);
        previousCurrencyValue = str1 + '.' + str2;
    }
    else if (type == "Number") {
        previousCurrencyValue = decisplit + '.' + str2;
    }
    else {
        previousCurrencyValue = "Error in Checking format";
    }
    textbox.value = previousCurrencyValue;
    var newLen = previousCurrencyValue.length;
    var offset = newLen - orgLen;
    cursorPos += offset;
    setCursorPosition(textbox, cursorPos);
    
}

/* Function to check and format Decimal part of the string  
        
input parameter  :- decimal part of the original string
output parameter :- formatted decimal part
*/
function checkDecimal(Decimaltext) {
    if (Decimaltext.length !== 0 && Decimaltext !== null) {
        Decimaltext = Decimaltext.replace(/[,]/g, '');
        Decimaltext = Decimaltext.slice(0, 2);
        return Decimaltext;
    }
    else
        return "0";
}

/* Function to get the set position of Cursor inside the Textbox 
            
input parameter  :- Textbox object , Position to set cursor to
output parameter :- Void
*/
function setCursorPosition(elem, caretPos) {
    if (elem !== null) {
        if (elem.createTextRange) {
            var range = elem.createTextRange();
            range.move('character', caretPos);
            range.select();
        }
        else {
            if (elem.selectionStart) {
                elem.focus();
                elem.setSelectionRange(caretPos, caretPos);
            }
            else
                elem.focus();
        }
    }
}

/* Function to get the current position of Cursor inside the Textbox 
        
input parameter  :- Textbox object
output parameter :- current position of cursor in the provided textbox
*/
function getCursorPosition(el) {

    if (el.selectionStart) {
        return el.selectionStart;
    } else if (document.selection) {
        el.focus();

        var r = document.selection.createRange();
        if (r === null) {
            return 0;
        }

        var re = el.createTextRange(),
                rc = re.duplicate();
        re.moveToBookmark(r.getBookmark());
        rc.setEndPoint('EndToStart', re);

        return rc.text.length;
    }
    return 0;

}

/* Function to format the string before the decimal point 
        
input parameter  :- string to the left of decimal point
output parameter :- formatted string to append with the string after decimal point
*/
function addCommas(text) {
    var i;
    var output = "";
    if (text.length > 0) {
        var filtertext = text.replace(/[,]/g, '');
        reversefiltertext = reverse(filtertext);
        var strippedArray = reversefiltertext.match(/.{1,3}/g);
        for (i = 0; i < strippedArray.length; i++) {
            if (strippedArray[i].length == 3 && i != strippedArray.length - 1)
                output += strippedArray[i] + ',';

            else
                output += strippedArray[i];

        }
        var reverseOutput = reverse(output);
        reverseOutput = reverseOutput.replace(/^0+(,)?/, '');
        if (reverseOutput === "")
            reverseOutput = "0";

        if (reverseOutput.length > 19) {
            reverseOutput = reverseOutput.substring(0, reverseOutput.length - 1);
            reverseOutput = addCommas(reverseOutput);
        }

        return reverseOutput;

    }
    else
        return '0';

}
Usage Just include the javascript into your code and have your markup look like this

<input id="ac" onkeyup="checkFormat(this,'Currency')" type="text" />
Here first argument is the textbox object itself and the second argument is the type of behaviour you want with the textbox. Behaviour could be either "Currency" which includes commas according to American number system or "Number"which could be the same thing without any commas.

You could change the event from "onkeyup" to "onchange" which will fire the script when the inuput element loses focus.

 I am doing the following things in the script
  • Adding Commas at appropriate places
  • Checking for proper decimal notation and consistency
  • Getting and setting the cursor position in every code trip to ease effort for user input
  • Removing all characters which are neither digits nor comma or dots to prevent user from entering illegal characters.
I have added in a bit of documentation into the code to help you understand what each function is doing.

0 comments:

Post a Comment