Yii 1.1: moneymask

Just another money mask for your money-related fields
15 followers

This is wrapper for jQuery plugin jquery-maskmoney.

Requirements

Tested very quickly on Firefox 4 and Google Chrome on Windows 7

Usage

Extract the zip file to your extensions folder.

These are the variables you can change:

element: (required) the input field to be moneymasked (uses jQuery selector)

currency: (optional) used to set the symbol if config['symbol'] is not given

config: (optional) options for this extension.

The options that you can set are

symbol the symbol to be used before of the user values. default: 'US$'

showSymbol - set if the symbol must be displayed or not. default: false

symbolStay - set if the symbol will stay in the field after the user exists the field. default: false

thousands - the thousands separator. default: ','

decimal - the decimal separator. default: '.'

precision - how many decimal places are allowed. default: 2

defaultZero - when the user enters the field, it sets a default mask using zero. default: true

allowZero - use this setting to prevent users from inputing zero. default: false

allowNegative - use this setting to prevent users from inputing negative values. default: false

Use it like this:

<?php
$this->widget('application.extensions.moneymask.MMask',array(
    'element'=>'#testing',
    'currency'=>'PHP',
    'config'=>array(
        'showSymbol'=>true,
        'symbolStay'=>true,
    )
));
 
echo CHtml::textField('testing', '', array('id'=>'testing'));
?>

Resources

Total 10 comments

#16457 report it
Márcio Lordelo at 2014/02/25 01:55pm
Bug with CMaskedTextField

I solved this problem changing jquery.maskMoney.js in assets folder. Both (CMaskedTextField and mask money) declare a function with same name (mask), I changed this name in maskMoney (and where it's called ) to solve the problem.

(function($) {
    $.fn.maskMoney = function(settings) {
        settings = $.extend({
            symbol: 'US$',
            showSymbol: false,
            symbolStay: false,
            thousands: ',',
            decimal: '.',
            precision: 2,
            defaultZero: true,
            allowZero: false,
            allowNegative: false
        }, settings);
 
        return this.each(function() {
            var input = $(this);
 
            function keypressEvent(e) {
                e = e||window.event;
                var k = e.charCode||e.keyCode||e.which;
                if (k == undefined) return false; //needed to handle an IE "special" event
                if (input.attr('readonly') && (k!=13&&k!=9)) return false; // don't allow editing of readonly fields but allow tab/enter
 
                if (k<48||k>57) { // any key except the numbers 0-9
                    if (k==45) { // -(minus) key
                        input.val(changeSign(input));
                        return false;
                    }
                    if (k==43) { // +(plus) key
                        input.val(input.val().replace('-',''));
                        return false;
                    } else if (k==13||k==9) { // enter key or tab key
                        return true;
                    } else if (k==37||k==39) { // left arrow key or right arrow key
                        return true;
                    } else { // any other key with keycode less than 48 and greater than 57
                        preventDefault(e);
                        return true;
                    }
                } else if (input.val().length==input.attr('maxlength')) {
                    return false;
                } else {
                    preventDefault(e);
 
                    var key = String.fromCharCode(k);
                    var x = input.get(0);
                    var selection = input.getInputSelection(x);
                    var startPos = selection.start;
                    var endPos = selection.end;
                    x.value = x.value.substring(0, startPos) + key + x.value.substring(endPos, x.value.length);
                    maskAndPosition(x, startPos + 1);
                    return false;
                }
            }
 
            function keydownEvent(e) {
                e = e||window.event;
                var k = e.charCode||e.keyCode||e.which;
                if (k == undefined) return false; //needed to handle an IE "special" event
                if (input.attr('readonly') && (k!=13&&k!=9)) return false; // don't allow editing of readonly fields but allow tab/enter
 
                var x = input.get(0);
                var selection = input.getInputSelection(x);
                var startPos = selection.start;
                var endPos = selection.end;
 
                if (k==8) { // backspace key
                    preventDefault(e);
 
                    if(startPos == endPos){
                        // Remove single character
                        x.value = x.value.substring(0, startPos - 1) + x.value.substring(endPos, x.value.length);
                        startPos = startPos - 1;
                    } else {
                        // Remove multiple characters
                        x.value = x.value.substring(0, startPos) + x.value.substring(endPos, x.value.length);
                    }
                    maskAndPosition(x, startPos);
                    return false;
                } else if (k==9) { // tab key
                    return true;
                } else if (k==46||k==63272) { // delete key (with special case for safari)
                    preventDefault(e);
                    if(x.selectionStart == x.selectionEnd){
                        // Remove single character
                        x.value = x.value.substring(0, startPos) + x.value.substring(endPos + 1, x.value.length);
                    } else {
                        //Remove multiple characters
                        x.value = x.value.substring(0, startPos) + x.value.substring(endPos, x.value.length);
                    }
                    maskAndPosition(x, startPos);
                    return false;
                } else { // any other key
                    return true;
                }
            }
 
            function focusEvent(e) {
                var mask = getDefaultMask();
                if (input.val()==mask) {
                    input.val('');
                } else if (input.val()==''&&settings.defaultZero) {
                    input.val(setSymbol(mask));
                } else {
                    input.val(setSymbol(input.val()));
                }
                if (this.createTextRange) {
                    var textRange = this.createTextRange();
                    textRange.collapse(false); // set the cursor at the end of the input
                    textRange.select();
                }
            }
 
            function blurEvent(e) {
                if ($.browser.msie) {
                    keypressEvent(e);
                }
 
                if (input.val()==''||input.val()==setSymbol(getDefaultMask())||input.val()==settings.symbol) {
                    if(!settings.allowZero) input.val('');
                    else if (!settings.symbolStay) input.val(getDefaultMask());
                    else input.val(setSymbol(getDefaultMask()));
                } else {
                    if (!settings.symbolStay) input.val(input.val().replace(settings.symbol,''));
                    else if (settings.symbolStay&&input.val()==settings.symbol) input.val(setSymbol(getDefaultMask()));
                }
            }
 
            function preventDefault(e) {
                if (e.preventDefault) { //standard browsers
                    e.preventDefault();
                } else { // internet explorer
                    e.returnValue = false
                }
            }
 
            function maskAndPosition(x, startPos) {
                var originalLen = input.val().length;
                input.val(maskMoneyValue(x.value));
                var newLen = input.val().length;
                startPos = startPos - (originalLen - newLen);
                input.setCursorPosition(startPos);
            }
 
            function maskMoneyValue(v) {
                v = v.replace(settings.symbol,'');
 
                var strCheck = '0123456789';
                var len = v.length;
                var a = '', t = '', neg='';
 
                if(len!=0 && v.charAt(0)=='-'){
                    v = v.replace('-','');
                    if(settings.allowNegative){
                        neg = '-';
                    }
                }
 
                if (len==0) {
                    if (!settings.defaultZero) return t;
                    t = '0.00';
                }
 
                for (var i = 0; i<len; i++) {
                    if ((v.charAt(i)!='0') && (v.charAt(i)!=settings.decimal)) break;
                }
 
                for (; i<len; i++) {
                    if (strCheck.indexOf(v.charAt(i))!=-1) a+= v.charAt(i);
                }
 
                var n = parseFloat(a);
                n = isNaN(n) ? 0 : n/Math.pow(10,settings.precision);
                t = n.toFixed(settings.precision);
 
                i = settings.precision == 0 ? 0 : 1;
                var p, d = (t=t.split('.'))[i].substr(0,settings.precision);
                for (p = (t=t[0]).length; (p-=3)>=1;) {
                    t = t.substr(0,p)+settings.thousands+t.substr(p);
                }
 
                return (settings.precision>0)
                    ? setSymbol(neg+t+settings.decimal+d+Array((settings.precision+1)-d.length).join(0))
                    : setSymbol(neg+t);
            }
 
            function maskMoneyMask() {
 
                var value = input.val();
                input.val(maskMoneyValue(value));
            }
 
            function getDefaultMask() {
                var n = parseFloat('0')/Math.pow(10,settings.precision);
                return (n.toFixed(settings.precision)).replace(new RegExp('\\.','g'),settings.decimal);
            }
 
            function setSymbol(v) {
                if (settings.showSymbol) {
                    if (v.substr(0, settings.symbol.length) != settings.symbol) return settings.symbol+v;
                }
                return v;
            }
 
            function changeSign(i){
                if (settings.allowNegative) {
                    var vic = i.val();
                    if (i.val()!='' && i.val().charAt(0)=='-'){
                        return i.val().replace('-','');
                    } else{
                        return '-'+i.val();
                    }
                } else {
                    return i.val();
                }
            }
 
            input.bind('keypress.maskMoney',keypressEvent);
            input.bind('keydown.maskMoney',keydownEvent);
            input.bind('blur.maskMoney',blurEvent);
            input.bind('focus.maskMoney',focusEvent);
            input.bind('mask', maskMoneyMask);
 
            input.one('unmaskMoney',function() {
                input.unbind('.maskMoney');
 
                if ($.browser.msie) {
                    this.onpaste= null;
                } else if ($.browser.mozilla) {
                    this.removeEventListener('input',blurEvent,false);
                }
            });
        });
    }
 
    $.fn.unmaskMoney=function() {
        return this.trigger('unmaskMoney');
    };
 
    $.fn.maskMoneyMask=function() {
        return this.trigger('maskMoneyMask');
    };
 
    $.fn.setCursorPosition = function(pos) {
        this.each(function(index, elem) {
            if (elem.setSelectionRange) {
                elem.focus();
                elem.setSelectionRange(pos, pos);
            } else if (elem.createTextRange) {
                var range = elem.createTextRange();
                range.collapse(true);
                range.moveEnd('character', pos);
                range.moveStart('character', pos);
                range.select();
            }
        });
        return this;
    };
 
    $.fn.getInputSelection = function(el) {
        var start = 0, end = 0, normalizedValue, range, textInputRange, len, endRange;
 
        if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
            start = el.selectionStart;
            end = el.selectionEnd;
        } else {
            range = document.selection.createRange();
 
            if (range && range.parentElement() == el) {
                len = el.value.length;
                normalizedValue = el.value.replace(/\r\n/g, "\n");
 
                // Create a working TextRange that lives only in the input
                textInputRange = el.createTextRange();
                textInputRange.moveToBookmark(range.getBookmark());
 
                // Check if the start and end of the selection are at the very end
                // of the input, since moveStart/moveEnd doesn't return what we want
                // in those cases
                endRange = el.createTextRange();
                endRange.collapse(false);
 
                if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
                    start = end = len;
                } else {
                    start = -textInputRange.moveStart("character", -len);
                    start += normalizedValue.slice(0, start).split("\n").length - 1;
 
                    if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
                        end = len;
                    } else {
                        end = -textInputRange.moveEnd("character", -len);
                        end += normalizedValue.slice(0, end).split("\n").length - 1;
                    }
                }
            }
        }
 
        return {
            start: start,
            end: end
        };
    }
})(jQuery);
#15951 report it
bodyfarmer at 2014/01/02 09:05pm
More options?

Is there an option to unmask?

#11123 report it
cruzeta51 at 2012/12/18 04:52pm
CMaskedTextField

Why after using the moneymask, the core CMaskedTextField stops working on the same form? Didn't find solution on the forums...

#8098 report it
banamlehsb at 2012/05/10 12:01am
MoneyMask isn't masking when it already has value

Like @macinville comment. MoneyMask isn't masking when the text field already has a value. When that field validated failed, you must type something on that text field to mask again. Any solution?

#8094 report it
natb19 at 2012/05/09 12:27pm
More than one...

Ahh, yes, element! show's how good my memory is! ;)

BTW, you don't have to use #id, your could use the same class name for all of the inputs you want to affect. That could make things easier when creating multiple forms... e.g.

class="dollars" class="gbp"

and use different widget configs to affect them.

#8093 report it
banamlehsb at 2012/05/09 12:09pm
More than one moneymask (solved)

@natb19: Thanks very much. I solved my problem. In 'element' option (not 'selector' option), I added selector jquery like you.

<?php
                $this->widget('application.extensions.moneymask.MMask',array(
                    'element'=>'#price,#total',
                    'currency'=>'PHP',
                    'config'=>array(
                        'symbolStay'=>true,
                        'thousands'=>'.',
                        'decimal'=>',',
                        'precision'=>0,
                    )
                ));
 
                echo CHtml::textField('price', '', array('id'=>'price'));
                ?>

Note: In other text field you should change id of textfield exactly.

#8092 report it
natb19 at 2012/05/09 11:41am
More than one...

@banamlehsb yeh I had the same problem until I did the following:

1) only include one widget 2) in the 'selector' option, specify both (or as many) text inputs as you like in the normal $ way. (e.g. '#input1, #input 2')

#8091 report it
banamlehsb at 2012/05/09 11:34am
More than one moneymask

When I use more than one moneymask in my view page, only one field works. any solution?

#5151 report it
Peter JK at 2011/09/19 04:52am
wonderful.. thx for a great extension

Thank you for this extension. I'm using this effectively...

may I ask you to make another handphone masking?.. like the script on this page

http://www.kodyaz.com/articles/javascript-phone-format-phone-number-format.aspx

i just dont know how to modify from your moneymask to handphonemask... thank you, once again..

#4095 report it
macinville at 2011/06/05 10:15pm
Bugs bugs bugs

I noticed just now that it is not masking the text field if it already has a value. There's still a need to type something for it be masked...

Leave a comment

Please to leave your comment.

Create extension
Downloads