2013-04-29 18:49:05 -07:00
/ * *
* autoNumeric . js
* @ author : Bob Knothe
* @ author : Sokolov Yura aka funny _falcon
* @ version : 1.9 . 6 - 2013 - 04 - 20 GMT 3 : 00 PM
*
* Created by Robert J . Knothe on 2010 - 10 - 25. Please report any bug at http : //www.decorplanit.com/plugin/
* Created by Sokolov Yura on 2010 - 11 - 07. http : //github.com/funny_falcon
*
* Copyright ( c ) 2011 Robert J . Knothe http : //www.decorplanit.com/plugin/
* Copyright ( c ) 2011 Sokolov Yura aka funny _falcon
*
* The MIT License ( http : //www.opensource.org/licenses/mit-license.php)
*
* Permission is hereby granted , free of charge , to any person
* obtaining a copy of this software and associated documentation
* files ( the "Software" ) , to deal in the Software without
* restriction , including without limitation the rights to use ,
* copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following
* conditions :
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND ,
* EXPRESS OR IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY , FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT . IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER LIABILITY ,
* WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING
* FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE .
* /
( function ( $ ) {
"use strict" ;
/**jslint browser: true*/
/**global jQuery*/
/ * *
* Cross browser routine for getting selected range / cursor position
* /
function getElementSelection ( that ) {
var position = { } ;
if ( that . selectionStart === undefined ) {
that . focus ( ) ;
var select = document . selection . createRange ( ) ;
position . length = select . text . length ;
select . moveStart ( 'character' , - that . value . length ) ;
position . end = select . text . length ;
position . start = position . end - position . length ;
} else {
position . start = that . selectionStart ;
position . end = that . selectionEnd ;
position . length = position . end - position . start ;
}
return position ;
}
/ * *
* Cross browser routine for setting selected range / cursor position
* /
function setElementSelection ( that , start , end ) {
if ( that . selectionStart === undefined ) {
that . focus ( ) ;
var r = that . createTextRange ( ) ;
r . collapse ( true ) ;
r . moveEnd ( 'character' , end ) ;
r . moveStart ( 'character' , start ) ;
r . select ( ) ;
} else {
that . selectionStart = start ;
that . selectionEnd = end ;
}
}
/ * *
* run callbacks in parameters if any
* any parameter could be a callback :
* - a function , which invoked with jQuery element , parameters and this parameter name and returns parameter value
* - a name of function , attached to $ ( selector ) . autoNumeric . functionName ( ) { } - which was called previously
* /
function runCallbacks ( $this , settings ) {
/ * *
* loops through the settings object ( option array ) to find the following
* k = option name example k = aNum
* val = option value example val = 0123456789
* /
$ . each ( settings , function ( k , val ) {
if ( typeof val === 'function' ) {
settings [ k ] = val ( $this , settings , k ) ;
} else if ( typeof $this . autoNumeric [ val ] === 'function' ) {
/ * *
* calls the attached function from the html5 data example : data - a - sign = "functionName"
* /
settings [ k ] = $this . autoNumeric [ val ] ( $this , settings , k ) ;
}
} ) ;
}
function convertKeyToNumber ( settings , key ) {
if ( typeof ( settings [ key ] ) === 'string' ) {
settings [ key ] *= 1 ;
}
}
/ * *
* Preparing user defined options for further usage
* merge them with defaults appropriatly
* /
function autoCode ( $this , settings ) {
runCallbacks ( $this , settings ) ;
settings . oEvent = null ;
settings . tagList = [ 'DD' , 'DT' , 'H1' , 'H2' , 'H3' , 'H4' , 'H5' , 'H6' , 'LABEL' , 'P' , 'SPAN' , 'TD' , 'TH' ] ;
var vmax = settings . vMax . toString ( ) . split ( '.' ) ,
vmin = ( ! settings . vMin && settings . vMin !== 0 ) ? [ ] : settings . vMin . toString ( ) . split ( '.' ) ;
convertKeyToNumber ( settings , 'vMax' ) ;
convertKeyToNumber ( settings , 'vMin' ) ;
convertKeyToNumber ( settings , 'mDec' ) ; /** set mDec if not defained by user */
settings . allowLeading = true ;
settings . aNeg = settings . vMin < 0 ? '-' : '' ;
vmax [ 0 ] = vmax [ 0 ] . replace ( '-' , '' ) ;
vmin [ 0 ] = vmin [ 0 ] . replace ( '-' , '' ) ;
settings . mInt = Math . max ( vmax [ 0 ] . length , vmin [ 0 ] . length , 1 ) ;
if ( settings . mDec === null ) {
var vmaxLength = 0 ,
vminLength = 0 ;
if ( vmax [ 1 ] ) {
vmaxLength = vmax [ 1 ] . length ;
}
if ( vmin [ 1 ] ) {
vminLength = vmin [ 1 ] . length ;
}
settings . mDec = Math . max ( vmaxLength , vminLength ) ;
} /** set alternative decimal separator key */
if ( settings . altDec === null && settings . mDec > 0 ) {
if ( settings . aDec === '.' && settings . aSep !== ',' ) {
settings . altDec = ',' ;
} else if ( settings . aDec === ',' && settings . aSep !== '.' ) {
settings . altDec = '.' ;
}
}
/** cache regexps for autoStrip */
var aNegReg = settings . aNeg ? '([-\\' + settings . aNeg + ']?)' : '(-?)' ;
settings . aNegRegAutoStrip = aNegReg ;
settings . skipFirstAutoStrip = new RegExp ( aNegReg + '[^-' + ( settings . aNeg ? '\\' + settings . aNeg : '' ) + '\\' + settings . aDec + '\\d]' + '.*?(\\d|\\' + settings . aDec + '\\d)' ) ;
settings . skipLastAutoStrip = new RegExp ( '(\\d\\' + settings . aDec + '?)[^\\' + settings . aDec + '\\d]\\D*$' ) ;
var allowed = '-' + settings . aNum + '\\' + settings . aDec ;
settings . allowedAutoStrip = new RegExp ( '[^' + allowed + ']' , 'gi' ) ;
settings . numRegAutoStrip = new RegExp ( aNegReg + '(?:\\' + settings . aDec + '?(\\d+\\' + settings . aDec + '\\d+)|(\\d*(?:\\' + settings . aDec + '\\d*)?))' ) ;
return settings ;
}
/ * *
* strip all unwanted characters and leave only a number alert
* /
function autoStrip ( s , settings , strip _zero ) {
if ( settings . aSign ) { /** remove currency sign */
while ( s . indexOf ( settings . aSign ) > - 1 ) {
s = s . replace ( settings . aSign , '' ) ;
}
}
s = s . replace ( settings . skipFirstAutoStrip , '$1$2' ) ; /** first replace anything before digits */
s = s . replace ( settings . skipLastAutoStrip , '$1' ) ; /** then replace anything after digits */
s = s . replace ( settings . allowedAutoStrip , '' ) ; /** then remove any uninterested characters */
if ( settings . altDec ) {
s = s . replace ( settings . altDec , settings . aDec ) ;
} /** get only number string */
var m = s . match ( settings . numRegAutoStrip ) ;
s = m ? [ m [ 1 ] , m [ 2 ] , m [ 3 ] ] . join ( '' ) : '' ;
if ( ( settings . lZero === 'allow' || settings . lZero === 'keep' ) && strip _zero !== 'strip' ) {
var parts = [ ] ,
nSign = '' ;
parts = s . split ( settings . aDec ) ;
if ( parts [ 0 ] . indexOf ( '-' ) !== - 1 ) {
nSign = '-' ;
parts [ 0 ] = parts [ 0 ] . replace ( '-' , '' ) ;
}
if ( parts [ 0 ] . length > settings . mInt && parts [ 0 ] . charAt ( 0 ) === '0' ) { /** strip leading zero if need */
parts [ 0 ] = parts [ 0 ] . slice ( 1 ) ;
}
s = nSign + parts . join ( settings . aDec ) ;
}
if ( ( strip _zero && settings . lZero === 'deny' ) || ( strip _zero && settings . lZero === 'allow' && settings . allowLeading === false ) ) {
var strip _reg = '^' + settings . aNegRegAutoStrip + '0*(\\d' + ( strip _zero === 'leading' ? ')' : '|$)' ) ;
strip _reg = new RegExp ( strip _reg ) ;
s = s . replace ( strip _reg , '$1$2' ) ;
}
return s ;
}
/ * *
* places or removes brackets on negative values
* /
function negativeBracket ( s , nBracket , oEvent ) { /** oEvent = settings.oEvent */
nBracket = nBracket . split ( ',' ) ;
if ( oEvent === 'set' || oEvent === 'focusout' ) {
s = s . replace ( '-' , '' ) ;
s = nBracket [ 0 ] + s + nBracket [ 1 ] ;
} else if ( ( oEvent === 'get' || oEvent === 'focusin' || oEvent === 'pageLoad' ) && s . charAt ( 0 ) === nBracket [ 0 ] ) {
s = s . replace ( nBracket [ 0 ] , '-' ) ;
s = s . replace ( nBracket [ 1 ] , '' ) ;
}
return s ;
}
/ * *
* truncate decimal part of a number
* /
function truncateDecimal ( s , aDec , mDec ) {
if ( aDec && mDec ) {
var parts = s . split ( aDec ) ;
/ * * t r u n c a t e d e c i m a l p a r t t o s a t i s f y i n g l e n g t h
* cause we would round it anyway * /
if ( parts [ 1 ] && parts [ 1 ] . length > mDec ) {
if ( mDec > 0 ) {
parts [ 1 ] = parts [ 1 ] . substring ( 0 , mDec ) ;
s = parts . join ( aDec ) ;
} else {
s = parts [ 0 ] ;
}
}
}
return s ;
}
/ * *
* prepare number string to be converted to real number
* /
function fixNumber ( s , aDec , aNeg ) {
if ( aDec && aDec !== '.' ) {
s = s . replace ( aDec , '.' ) ;
}
if ( aNeg && aNeg !== '-' ) {
s = s . replace ( aNeg , '-' ) ;
}
if ( ! s . match ( /\d/ ) ) {
s += '0' ;
}
return s ;
}
/ * *
* function to handle numbers less than 0 that are stored in Exponential notaion ex : . 0000001 stored as 1e-7
* /
function checkValue ( value ) {
var decimal = value . indexOf ( '.' ) ;
if ( decimal !== - 1 ) {
if ( decimal === 1 && value . charAt ( 0 ) === '0' ) {
value = + value ;
if ( value < 0.000001 && value > 0 ) {
value = ( value + 1 ) . toString ( ) ;
value = value . substring ( 1 ) ;
}
if ( value < 0 && value > - 1 ) {
value = ( value - 1 ) . toString ( ) ;
value = '-' + value . substring ( 2 ) ;
}
value = value . toString ( ) ;
} else {
var parts = value . split ( '.' ) ;
if ( parts [ 1 ] !== undefined ) {
if ( + parts [ 1 ] === 0 ) {
value = parts [ 0 ] ;
} else {
parts [ 1 ] = parts [ 1 ] . replace ( /0*$/ , '' ) ;
value = parts . join ( '.' ) ;
}
}
}
}
return value . replace ( /^0*(\d)/ , '$1' ) ;
}
/ * *
* prepare real number to be converted to our format
* /
function presentNumber ( s , aDec , aNeg ) {
if ( aNeg && aNeg !== '-' ) {
s = s . replace ( '-' , aNeg ) ;
}
if ( aDec && aDec !== '.' ) {
s = s . replace ( '.' , aDec ) ;
}
return s ;
}
/ * *
* checking that number satisfy format conditions
* and lays between settings . vMin and settings . vMax
* and the string length does not exceed the digits in settings . vMin and settings . vMax
* /
function autoCheck ( s , settings ) {
s = autoStrip ( s , settings ) ;
s = truncateDecimal ( s , settings . aDec , settings . mDec ) ;
s = fixNumber ( s , settings . aDec , settings . aNeg ) ;
var value = + s ;
if ( settings . oEvent === 'set' && ( value < settings . vMin || value > settings . vMax ) ) {
$ . error ( "The value (" + value + ") from the 'set' method falls outside of the vMin / vMax range" ) ;
}
return value >= settings . vMin && value <= settings . vMax ;
}
/ * *
* private function to check for empty value
* /
function checkEmpty ( iv , settings , signOnEmpty ) {
if ( iv === '' || iv === settings . aNeg ) {
if ( settings . wEmpty === 'zero' ) {
return iv + '0' ;
}
if ( settings . wEmpty === 'sign' || signOnEmpty ) {
return iv + settings . aSign ;
}
return iv ;
}
return null ;
}
/ * *
* private function that formats our number
* /
function autoGroup ( iv , settings ) {
iv = autoStrip ( iv , settings ) ;
var testNeg = iv ,
empty = checkEmpty ( iv , settings , true ) ;
if ( empty !== null ) {
return empty ;
}
var digitalGroup = '' ;
if ( settings . dGroup === 2 ) {
digitalGroup = /(\d)((\d)(\d{2}?)+)$/ ;
} else if ( settings . dGroup === 4 ) {
digitalGroup = /(\d)((\d{4}?)+)$/ ;
} else {
digitalGroup = /(\d)((\d{3}?)+)$/ ;
} /** splits the string at the decimal string */
var ivSplit = iv . split ( settings . aDec ) ;
if ( settings . altDec && ivSplit . length === 1 ) {
ivSplit = iv . split ( settings . altDec ) ;
} /** assigns the whole number to the a varibale (s) */
var s = ivSplit [ 0 ] ;
if ( settings . aSep ) {
while ( digitalGroup . test ( s ) ) { /** re-inserts the thousand sepparator via a regualer expression */
s = s . replace ( digitalGroup , '$1' + settings . aSep + '$2' ) ;
}
}
if ( settings . mDec !== 0 && ivSplit . length > 1 ) {
if ( ivSplit [ 1 ] . length > settings . mDec ) {
ivSplit [ 1 ] = ivSplit [ 1 ] . substring ( 0 , settings . mDec ) ;
} /** joins the whole number with the deciaml value */
iv = s + settings . aDec + ivSplit [ 1 ] ;
} else { /** if whole numers only */
iv = s ;
}
if ( settings . aSign ) {
var has _aNeg = iv . indexOf ( settings . aNeg ) !== - 1 ;
iv = iv . replace ( settings . aNeg , '' ) ;
iv = settings . pSign === 'p' ? settings . aSign + iv : iv + settings . aSign ;
if ( has _aNeg ) {
iv = settings . aNeg + iv ;
}
}
if ( settings . oEvent === 'set' && testNeg < 0 && settings . nBracket !== null ) { /** removes the negative sign and places brackets */
iv = negativeBracket ( iv , settings . nBracket , settings . oEvent ) ;
}
return iv ;
}
/ * *
* round number after setting by pasting or $ ( ) . autoNumericSet ( )
* private function for round the number
* please note this handled as text - Javascript math function can return inaccurate values
* also this offers multiple rounding metods that are not easily accomplished in javascript
* /
function autoRound ( iv , settings ) { /** value to string */
iv = ( iv === '' ) ? '0' : iv . toString ( ) ;
convertKeyToNumber ( settings , 'mDec' ) ; /** set mDec to number needed when mDec set by 'update method */
var ivRounded = '' ,
i = 0 ,
nSign = '' ,
rDec = ( typeof ( settings . aPad ) === 'boolean' || settings . aPad === null ) ? ( settings . aPad ? settings . mDec : 0 ) : + settings . aPad ;
var truncateZeros = function ( ivRounded ) { /** truncate not needed zeros */
var regex = rDec === 0 ? ( /(\.[1-9]*)0*$/ ) : rDec === 1 ? ( /(\.\d[1-9]*)0*$/ ) : new RegExp ( '(\\.\\d{' + rDec + '}[1-9]*)0*$' ) ;
ivRounded = ivRounded . replace ( regex , '$1' ) ; /** If there are no decimal places, we don't need a decimal point at the end */
if ( rDec === 0 ) {
ivRounded = ivRounded . replace ( /\.$/ , '' ) ;
}
return ivRounded ;
} ;
if ( iv . charAt ( 0 ) === '-' ) { /** Checks if the iv (input Value)is a negative value */
nSign = '-' ; /** removes the negative sign will be added back later if required */
iv = iv . replace ( '-' , '' ) ;
} /** prepend a zero if first character is not a digit (then it is likely to be a dot)*/
if ( ! iv . match ( /^\d/ ) ) {
iv = '0' + iv ;
} /** determines if the value is zero - if zero no negative sign */
if ( nSign === '-' && + iv === 0 ) {
nSign = '' ;
}
if ( ( + iv > 0 && settings . lZero !== 'keep' ) || ( iv . length > 0 && settings . lZero === 'allow' ) ) { /** trims leading zero's if needed */
iv = iv . replace ( /^0*(\d)/ , '$1' ) ;
}
var dPos = iv . lastIndexOf ( '.' ) ; /** virtual decimal position */
var vdPos = dPos === - 1 ? iv . length - 1 : dPos ; /** checks decimal places to determine if rounding is required */
var cDec = ( iv . length - 1 ) - vdPos ; /** check if no rounding is required */
if ( cDec <= settings . mDec ) {
ivRounded = iv ; /** check if we need to pad with zeros */
if ( cDec < rDec ) {
if ( dPos === - 1 ) {
ivRounded += '.' ;
}
while ( cDec < rDec ) {
var zeros = '000000' . substring ( 0 , rDec - cDec ) ;
ivRounded += zeros ;
cDec += zeros . length ;
}
} else if ( cDec > rDec ) {
ivRounded = truncateZeros ( ivRounded ) ;
} else if ( cDec === 0 && rDec === 0 ) {
ivRounded = ivRounded . replace ( /\.$/ , '' ) ;
}
return nSign + ivRounded ;
} /** rounded length of the string after rounding */
var rLength = dPos + settings . mDec ; /** test round */
var tRound = + iv . charAt ( rLength + 1 ) ;
var ivArray = iv . substring ( 0 , rLength + 1 ) . split ( '' ) ;
var odd = ( iv . charAt ( rLength ) === '.' ) ? ( iv . charAt ( rLength - 1 ) % 2 ) : ( iv . charAt ( rLength ) % 2 ) ;
if ( ( tRound > 4 && settings . mRound === 'S' ) || ( tRound > 4 && settings . mRound === 'A' && nSign === '' ) || ( tRound > 5 && settings . mRound === 'A' && nSign === '-' ) || ( tRound > 5 && settings . mRound === 's' ) || ( tRound > 5 && settings . mRound === 'a' && nSign === '' ) || ( tRound > 4 && settings . mRound === 'a' && nSign === '-' ) || ( tRound > 5 && settings . mRound === 'B' ) || ( tRound === 5 && settings . mRound === 'B' && odd === 1 ) || ( tRound > 0 && settings . mRound === 'C' && nSign === '' ) || ( tRound > 0 && settings . mRound === 'F' && nSign === '-' ) || ( tRound > 0 && settings . mRound === 'U' ) ) {
/** Round up the last digit if required, and continue until no more 9's are found */
for ( i = ( ivArray . length - 1 ) ; i >= 0 ; i -= 1 ) {
if ( ivArray [ i ] !== '.' ) {
ivArray [ i ] = + ivArray [ i ] + 1 ;
if ( ivArray [ i ] < 10 ) {
break ;
} else if ( i > 0 ) {
ivArray [ i ] = '0' ;
}
}
}
} /** Reconstruct the string, converting any 10's to 0's */
ivArray = ivArray . slice ( 0 , rLength + 1 ) ;
ivRounded = truncateZeros ( ivArray . join ( '' ) ) ; /** return rounded value */
return nSign + ivRounded ;
}
/ * *
* Holder object for field properties
* /
function AutoNumericHolder ( that , settings ) {
this . settings = settings ;
this . that = that ;
this . $that = $ ( that ) ;
this . formatted = false ;
this . settingsClone = autoCode ( this . $that , this . settings ) ;
this . value = that . value ;
}
AutoNumericHolder . prototype = {
init : function ( e ) {
this . value = this . that . value ;
this . settingsClone = autoCode ( this . $that , this . settings ) ;
this . ctrlKey = e . ctrlKey ;
this . cmdKey = e . metaKey ;
this . shiftKey = e . shiftKey ;
this . selection = getElementSelection ( this . that ) ; /** keypress event overwrites meaningfull value of e.keyCode */
if ( e . type === 'keydown' || e . type === 'keyup' ) {
this . kdCode = e . keyCode ;
}
this . which = e . which ;
this . processed = false ;
this . formatted = false ;
} ,
setSelection : function ( start , end , setReal ) {
start = Math . max ( start , 0 ) ;
end = Math . min ( end , this . that . value . length ) ;
this . selection = {
start : start ,
end : end ,
length : end - start
} ;
if ( setReal === undefined || setReal ) {
setElementSelection ( this . that , start , end ) ;
}
} ,
setPosition : function ( pos , setReal ) {
this . setSelection ( pos , pos , setReal ) ;
} ,
getBeforeAfter : function ( ) {
var value = this . value ;
var left = value . substring ( 0 , this . selection . start ) ;
var right = value . substring ( this . selection . end , value . length ) ;
return [ left , right ] ;
} ,
getBeforeAfterStriped : function ( ) {
var parts = this . getBeforeAfter ( ) ;
parts [ 0 ] = autoStrip ( parts [ 0 ] , this . settingsClone ) ;
parts [ 1 ] = autoStrip ( parts [ 1 ] , this . settingsClone ) ;
return parts ;
} ,
/ * *
* strip parts from excess characters and leading zeroes
* /
normalizeParts : function ( left , right ) {
var settingsClone = this . settingsClone ;
right = autoStrip ( right , settingsClone ) ; /** if right is not empty and first character is not aDec, */
/** we could strip all zeros, otherwise only leading */
var strip = right . match ( /^\d/ ) ? true : 'leading' ;
left = autoStrip ( left , settingsClone , strip ) ; /** prevents multiple leading zeros from being entered */
if ( ( left === '' || left === settingsClone . aNeg ) && settingsClone . lZero === 'deny' ) {
if ( right > '' ) {
right = right . replace ( /^0*(\d)/ , '$1' ) ;
}
}
var new _value = left + right ; /** insert zero if has leading dot */
if ( settingsClone . aDec ) {
var m = new _value . match ( new RegExp ( '^' + settingsClone . aNegRegAutoStrip + '\\' + settingsClone . aDec ) ) ;
if ( m ) {
left = left . replace ( m [ 1 ] , m [ 1 ] + '0' ) ;
new _value = left + right ;
}
} /** insert zero if number is empty and io.wEmpty == 'zero' */
if ( settingsClone . wEmpty === 'zero' && ( new _value === settingsClone . aNeg || new _value === '' ) ) {
left += '0' ;
}
return [ left , right ] ;
} ,
/ * *
* set part of number to value keeping position of cursor
* /
setValueParts : function ( left , right ) {
var settingsClone = this . settingsClone ;
var parts = this . normalizeParts ( left , right ) ;
var new _value = parts . join ( '' ) ;
var position = parts [ 0 ] . length ;
if ( autoCheck ( new _value , settingsClone ) ) {
new _value = truncateDecimal ( new _value , settingsClone . aDec , settingsClone . mDec ) ;
if ( position > new _value . length ) {
position = new _value . length ;
}
this . value = new _value ;
this . setPosition ( position , false ) ;
return true ;
}
return false ;
} ,
/ * *
* helper function for expandSelectionOnSign
* returns sign position of a formatted value
* /
signPosition : function ( ) {
var settingsClone = this . settingsClone ,
aSign = settingsClone . aSign ,
that = this . that ;
if ( aSign ) {
var aSignLen = aSign . length ;
if ( settingsClone . pSign === 'p' ) {
var hasNeg = settingsClone . aNeg && that . value && that . value . charAt ( 0 ) === settingsClone . aNeg ;
return hasNeg ? [ 1 , aSignLen + 1 ] : [ 0 , aSignLen ] ;
}
var valueLen = that . value . length ;
return [ valueLen - aSignLen , valueLen ] ;
}
return [ 1000 , - 1 ] ;
} ,
/ * *
* expands selection to cover whole sign
* prevents partial deletion / copying / overwritting of a sign
* /
expandSelectionOnSign : function ( setReal ) {
var sign _position = this . signPosition ( ) ;
var selection = this . selection ;
if ( selection . start < sign _position [ 1 ] && selection . end > sign _position [ 0 ] ) { /** if selection catches something except sign and catches only space from sign */
if ( ( selection . start < sign _position [ 0 ] || selection . end > sign _position [ 1 ] ) && this . value . substring ( Math . max ( selection . start , sign _position [ 0 ] ) , Math . min ( selection . end , sign _position [ 1 ] ) ) . match ( /^\s*$/ ) ) { /** then select without empty space */
if ( selection . start < sign _position [ 0 ] ) {
this . setSelection ( selection . start , sign _position [ 0 ] , setReal ) ;
} else {
this . setSelection ( sign _position [ 1 ] , selection . end , setReal ) ;
}
} else { /** else select with whole sign */
this . setSelection ( Math . min ( selection . start , sign _position [ 0 ] ) , Math . max ( selection . end , sign _position [ 1 ] ) , setReal ) ;
}
}
} ,
/ * *
* try to strip pasted value to digits
* /
checkPaste : function ( ) {
if ( this . valuePartsBeforePaste !== undefined ) {
var parts = this . getBeforeAfter ( ) ;
var oldParts = this . valuePartsBeforePaste ;
delete this . valuePartsBeforePaste ; /** try to strip pasted value first */
parts [ 0 ] = parts [ 0 ] . substr ( 0 , oldParts [ 0 ] . length ) + autoStrip ( parts [ 0 ] . substr ( oldParts [ 0 ] . length ) , this . settingsClone ) ;
if ( ! this . setValueParts ( parts [ 0 ] , parts [ 1 ] ) ) {
this . value = oldParts . join ( '' ) ;
this . setPosition ( oldParts [ 0 ] . length , false ) ;
}
}
} ,
/ * *
* process pasting , cursor moving and skipping of not interesting keys
* if returns true , futher processing is not performed
* /
skipAllways : function ( e ) {
var kdCode = this . kdCode , which = this . which , ctrlKey = this . ctrlKey , cmdKey = this . cmdKey , shiftKey = this . shiftKey ; /** catch the ctrl up on ctrl-v */
if ( ( ( ctrlKey || cmdKey ) && e . type === 'keyup' && this . valuePartsBeforePaste !== undefined ) || ( shiftKey && kdCode === 45 ) ) {
this . checkPaste ( ) ;
return false ;
}
/** codes are taken from http:/ / www . cambiaresearch . com / c4 / 702 b8cd1 - e5b0 - 42e6 - 83 ac - 25 f0306e3e25 / Javascript - Char - Codes - Key - Codes . aspx
* skip Fx keys , windows keys , other special keys
* /
if ( ( kdCode >= 112 && kdCode <= 123 ) || ( kdCode >= 91 && kdCode <= 93 ) || ( kdCode >= 9 && kdCode <= 31 ) || ( kdCode < 8 && ( which === 0 || which === kdCode ) ) || kdCode === 144 || kdCode === 145 || kdCode === 45 ) {
return true ;
}
if ( ( ctrlKey || cmdKey ) && kdCode === 65 ) { /** if select all (a=65)*/
return true ;
}
if ( ( ctrlKey || cmdKey ) && ( kdCode === 67 || kdCode === 86 || kdCode === 88 ) ) { /** if copy (c=67) paste (v=86) or cut (x=88) */
if ( e . type === 'keydown' ) {
this . expandSelectionOnSign ( ) ;
}
if ( kdCode === 86 || kdCode === 45 ) { /** try to prevent wrong paste */
if ( e . type === 'keydown' || e . type === 'keypress' ) {
if ( this . valuePartsBeforePaste === undefined ) {
this . valuePartsBeforePaste = this . getBeforeAfter ( ) ;
}
} else {
this . checkPaste ( ) ;
}
}
return e . type === 'keydown' || e . type === 'keypress' || kdCode === 67 ;
}
if ( ctrlKey || cmdKey ) {
return true ;
}
if ( kdCode === 37 || kdCode === 39 ) { /** jump over thousand separator */
var aSep = this . settingsClone . aSep ,
start = this . selection . start ,
value = this . that . value ;
if ( e . type === 'keydown' && aSep && ! this . shiftKey ) {
if ( kdCode === 37 && value . charAt ( start - 2 ) === aSep ) {
this . setPosition ( start - 1 ) ;
} else if ( kdCode === 39 && value . charAt ( start ) === aSep ) {
this . setPosition ( start + 1 ) ;
}
}
return true ;
}
if ( kdCode >= 34 && kdCode <= 40 ) {
return true ;
}
return false ;
} ,
/ * *
* process deletion of characters
* returns true if processing performed
* /
processAllways : function ( ) {
var parts ; /** process backspace or delete */
if ( this . kdCode === 8 || this . kdCode === 46 ) {
if ( ! this . selection . length ) {
parts = this . getBeforeAfterStriped ( ) ;
if ( this . kdCode === 8 ) {
parts [ 0 ] = parts [ 0 ] . substring ( 0 , parts [ 0 ] . length - 1 ) ;
} else {
parts [ 1 ] = parts [ 1 ] . substring ( 1 , parts [ 1 ] . length ) ;
}
this . setValueParts ( parts [ 0 ] , parts [ 1 ] ) ;
} else {
this . expandSelectionOnSign ( false ) ;
parts = this . getBeforeAfterStriped ( ) ;
this . setValueParts ( parts [ 0 ] , parts [ 1 ] ) ;
}
return true ;
}
return false ;
} ,
/ * *
* process insertion of characters
* returns true if processing performed
* /
processKeypress : function ( ) {
var settingsClone = this . settingsClone ;
var cCode = String . fromCharCode ( this . which ) ;
var parts = this . getBeforeAfterStriped ( ) ;
var left = parts [ 0 ] ,
right = parts [ 1 ] ; /** start rules when the decimal charactor key is pressed */
/** always use numeric pad dot to insert decimal separator */
if ( cCode === settingsClone . aDec || ( settingsClone . altDec && cCode === settingsClone . altDec ) || ( ( cCode === '.' || cCode === ',' ) && this . kdCode === 110 ) ) { /** do not allow decimal character if no decimal part allowed */
if ( ! settingsClone . mDec || ! settingsClone . aDec ) {
return true ;
} /** do not allow decimal character before aNeg character */
if ( settingsClone . aNeg && right . indexOf ( settingsClone . aNeg ) > - 1 ) {
return true ;
} /** do not allow decimal character if other decimal character present */
if ( left . indexOf ( settingsClone . aDec ) > - 1 ) {
return true ;
}
if ( right . indexOf ( settingsClone . aDec ) > 0 ) {
return true ;
}
if ( right . indexOf ( settingsClone . aDec ) === 0 ) {
right = right . substr ( 1 ) ;
}
this . setValueParts ( left + settingsClone . aDec , right ) ;
return true ;
} /** start rule on negative sign */
if ( cCode === '-' || cCode === '+' ) { /** prevent minus if not allowed */
if ( ! settingsClone . aNeg ) {
return true ;
} /** carret is always after minus */
if ( left === '' && right . indexOf ( settingsClone . aNeg ) > - 1 ) {
left = settingsClone . aNeg ;
right = right . substring ( 1 , right . length ) ;
} /** change sign of number, remove part if should */
if ( left . charAt ( 0 ) === settingsClone . aNeg ) {
left = left . substring ( 1 , left . length ) ;
} else {
left = ( cCode === '-' ) ? settingsClone . aNeg + left : left ;
}
this . setValueParts ( left , right ) ;
return true ;
} /** digits */
if ( cCode >= '0' && cCode <= '9' ) { /** if try to insert digit before minus */
if ( settingsClone . aNeg && left === '' && right . indexOf ( settingsClone . aNeg ) > - 1 ) {
left = settingsClone . aNeg ;
right = right . substring ( 1 , right . length ) ;
}
if ( settingsClone . vMax <= 0 && settingsClone . vMin < settingsClone . vMax && this . value . indexOf ( settingsClone . aNeg ) === - 1 && cCode !== '0' ) {
left = settingsClone . aNeg + left ;
}
this . setValueParts ( left + cCode , right ) ;
return true ;
} /** prevent any other character */
return true ;
} ,
/ * *
* formatting of just processed value with keeping of cursor position
* /
formatQuick : function ( ) {
var settingsClone = this . settingsClone ;
var parts = this . getBeforeAfterStriped ( ) ;
var leftLength = this . value ;
if ( ( settingsClone . aSep === '' || ( settingsClone . aSep !== '' && leftLength . indexOf ( settingsClone . aSep ) === - 1 ) ) && ( settingsClone . aSign === '' || ( settingsClone . aSign !== '' && leftLength . indexOf ( settingsClone . aSign ) === - 1 ) ) ) {
var subParts = [ ] ,
nSign = '' ;
subParts = leftLength . split ( settingsClone . aDec ) ;
if ( subParts [ 0 ] . indexOf ( '-' ) > - 1 ) {
nSign = '-' ;
subParts [ 0 ] = subParts [ 0 ] . replace ( '-' , '' ) ;
parts [ 0 ] = parts [ 0 ] . replace ( '-' , '' ) ;
}
if ( subParts [ 0 ] . length > settingsClone . mInt && parts [ 0 ] . charAt ( 0 ) === '0' ) { /** strip leading zero if need */
parts [ 0 ] = parts [ 0 ] . slice ( 1 ) ;
}
parts [ 0 ] = nSign + parts [ 0 ] ;
}
var value = autoGroup ( this . value , this . settingsClone ) ;
var position = value . length ;
if ( value ) {
/** prepare regexp which searches for cursor position from unformatted left part */
var left _ar = parts [ 0 ] . split ( '' ) ;
var i = 0 ;
for ( i ; i < left _ar . length ; i += 1 ) { /** thanks Peter Kovari */
if ( ! left _ar [ i ] . match ( '\\d' ) ) {
left _ar [ i ] = '\\' + left _ar [ i ] ;
}
}
var leftReg = new RegExp ( '^.*?' + left _ar . join ( '.*?' ) ) ;
/** search cursor position in formatted value */
var newLeft = value . match ( leftReg ) ;
if ( newLeft ) {
position = newLeft [ 0 ] . length ;
/** if we are just before sign which is in prefix position */
if ( ( ( position === 0 && value . charAt ( 0 ) !== settingsClone . aNeg ) || ( position === 1 && value . charAt ( 0 ) === settingsClone . aNeg ) ) && settingsClone . aSign && settingsClone . pSign === 'p' ) {
/** place carret after prefix sign */
position = this . settingsClone . aSign . length + ( value . charAt ( 0 ) === '-' ? 1 : 0 ) ;
}
} else if ( settingsClone . aSign && settingsClone . pSign === 's' ) {
/** if we could not find a place for cursor and have a sign as a suffix */
/** place carret before suffix currency sign */
position -= settingsClone . aSign . length ;
}
}
this . that . value = value ;
this . setPosition ( position ) ;
this . formatted = true ;
}
} ;
/** thanks to Anthony & Evan C */
function autoGet ( obj ) {
if ( typeof obj === 'string' ) {
obj = obj . replace ( /\[/g , "\\[" ) . replace ( /\]/g , "\\]" ) ;
obj = '#' + obj . replace ( /(:|\.)/g , '\\$1' ) ;
/** obj = '#' + obj.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1'); */
/** possible modification to replace the above 2 lines */
}
return $ ( obj ) ;
}
function getHolder ( $that , settings , update ) {
var data = $that . data ( 'autoNumeric' ) ;
if ( ! data ) {
data = { } ;
$that . data ( 'autoNumeric' , data ) ;
}
var holder = data . holder ;
if ( ( holder === undefined && settings ) || update ) {
holder = new AutoNumericHolder ( $that . get ( 0 ) , settings ) ;
data . holder = holder ;
}
return holder ;
}
var methods = {
init : function ( options ) {
return this . each ( function ( ) {
var $this = $ ( this ) ;
var settings = $this . data ( 'autoNumeric' ) ; /** attempt to grab 'autoNumeric' settings, if they don't exist returns "undefined". */
var tagData = $this . data ( ) ; /** attempt to grab HTML5 data, if they don't exist we'll get "undefined".*/
if ( typeof settings !== 'object' ) { /** If we could't grab settings, create them from defaults and passed options. */
var defaults = {
/ * * a l l o w e d n u m e r i c v a l u e s
* please do not modify
* /
aNum : '0123456789' ,
/ * * a l l o w e d t h o u s a n d s e p a r a t o r c h a r a c t e r s
* comma = ','
* period "full stop" = '.'
* apostrophe is escaped = '\''
* space = ' '
* none = ''
* NOTE : do not use numeric characters
* /
aSep : ',' ,
/ * * d i g i t a l g r o u p i n g f o r t h e t h o u s a n d s e p a r a t o r u s e d i n F o r m a t
* dGroup : '2' , results in 99 , 99 , 99 , 999 common in India for values less than 1 billion and greater than - 1 billion
* dGroup : '3' , results in 999 , 999 , 999 default
* dGroup : '4' , results in 9999 , 9999 , 9999 used in some Asian countries
* /
dGroup : '3' ,
/ * * a l l o w e d d e c i m a l s e p a r a t o r c h a r a c t e r s
* period "full stop" = '.'
* comma = ','
* /
aDec : '.' ,
/ * * a l l o w t o d e c l a r e a l t e r n a t i v e d e c i m a l s e p a r a t o r w h i c h i s a u t o m a t i c a l l y r e p l a c e d b y a D e c
* developed for countries the use a comma ',' as the decimal character
* and have keyboards \ numeric pads that have a period 'full stop' as the decimal characters ( Spain is an example )
* /
altDec : null ,
/ * * a l l o w e d c u r r e n c y s y m b o l
* Must be in quotes aSign : '$' , a space is allowed aSign : '$ '
* /
aSign : '' ,
/ * * p l a c e m e n t o f c u r r e n c y s i g n
* for prefix pSign : 'p' ,
* for suffix pSign : 's' ,
* /
pSign : 'p' ,
/ * * m a x i m u m p o s s i b l e v a l u e
* value must be enclosed in quotes and use the period for the decimal point
* value must be larger than vMin
* /
2013-07-21 15:21:09 -04:00
vMax : '999999999999.99' ,
2013-04-29 18:49:05 -07:00
/ * * m i n i m u m p o s s i b l e v a l u e
* value must be enclosed in quotes and use the period for the decimal point
* value must be smaller than vMax
* /
vMin : '0.00' ,
/ * * m a x n u m b e r o f d e c i m a l p l a c e s = u s e d t o o v e r i d e d e c i a m l p l a c e s s e t b y t h e v M i n & v M a x v a l u e s
* value must be enclosed in quotes example mDec : '3' ,
* This can also set the value via a call back function mDec : ' css : #
* /
mDec : null ,
/ * * m e t h o d u s e d f o r r o u n d i n g
* mRound : 'S' , Round - Half - Up Symmetric ( default )
* mRound : 'A' , Round - Half - Up Asymmetric
* mRound : 's' , Round - Half - Down Symmetric ( lower case s )
* mRound : 'a' , Round - Half - Down Asymmetric ( lower case a )
* mRound : 'B' , Round - Half - Even "Bankers Rounding"
* mRound : 'U' , Round Up "Round-Away-From-Zero"
* mRound : 'D' , Round Down "Round-Toward-Zero" - same as trancate
* mRound : 'C' , Round to Ceiling "Toward Positive Infinity"
* mRound : 'F' , Round to Floor "Toward Negative Infinity"
* /
mRound : 'S' ,
/ * * c o n t r o l s d e c i m a l p a d d i n g
* aPad : true - always Pad decimals with zeros
* aPad : false - does not pad with zeros .
* aPad : ` some number ` - pad decimals with zero to number different from mDec
* thanks to Jonas Johansson for the suggestion
* /
aPad : true ,
/ * * p l a c e s b r a c k e t s o n n e g a t i v e v a l u e - $ 9 9 9 . 9 9 t o ( 9 9 9 . 9 9 )
* visible only when the field does NOT have focus the left and right symbols should be enclosed in quotes and seperated by a comma
* nBracket : null , nBracket : '(,)' , nBracket : '[,]' , nBracket : '<,>' or nBracket : '{,}'
* /
nBracket : null ,
/ * * D i s p l a y e d o n e m p t y s t r i n g
* wEmpty : 'empty' , - input can be blank
* wEmpty : 'zero' , - displays zero
* wEmpty : 'sign' , - displays the currency sign
* /
wEmpty : 'empty' ,
/ * * c o n t r o l s l e a d i n g z e r o b e h a v i o r
* lZero : 'allow' , - allows leading zeros to be entered . Zeros will be truncated when entering additional digits . On focusout zeros will be deleted .
* lZero : 'deny' , - allows only one leading zero on values less than one
* lZero : 'keep' , - allows leading zeros to be entered . on fousout zeros will be retained .
* /
lZero : 'allow' ,
/ * * d e t e r m i n e i f t h e d e f a u l t v a l u e w i l l b e f o r m a t t e d o n p a g e r e a d y .
* true = atomatically formats the default value on page ready
* false = will not format the default value
* /
aForm : true ,
/** future use */
onSomeEvent : function ( ) { }
} ;
settings = $ . extend ( { } , defaults , tagData , options ) ; /** Merge defaults, tagData and options */
if ( settings . aDec === settings . aSep ) {
$ . error ( "autoNumeric will not function properly when the decimal character aDec: '" + settings . aDec + "' and thousand seperater aSep: '" + settings . aSep + "' are the same character" ) ;
return this ;
}
if ( $ . inArray ( $this . prop ( 'tagName' ) , settings . tagList ) !== - 1 ) {
$ . error ( "The <" + $this . prop ( 'tagName' ) + "> is not supported by autoNumeric()" ) ;
return this ;
}
$this . data ( 'autoNumeric' , settings ) ; /** Save our new settings */
} else {
return this ;
}
var holder = getHolder ( $this , settings ) ;
if ( settings . runOnce === undefined && settings . aForm && ( $this [ 0 ] . value || $this . text ( ) !== '' ) ) {
if ( $this . is ( 'input[type=text], input[type=hidden], input:not([type])' ) ) { /**added hidden type */
if ( settings . nBracket !== null && ( $this [ 0 ] . value || settings . wEmpty !== 'empty' ) ) { /** routine to handle page refresh */
settings . oEvent = "pageLoad" ;
$this [ 0 ] . value = negativeBracket ( $this [ 0 ] . value , settings . nBracket , settings . oEvent ) ;
$this [ 0 ] . value = autoStrip ( $this [ 0 ] . value , settings ) ;
}
if ( $this [ 0 ] . value !== $ ( $this [ 0 ] ) . attr ( "value" ) ) {
$this . autoNumeric ( 'set' , autoStrip ( $this . val ( ) , settings ) ) ;
} else {
$this . autoNumeric ( 'set' , $this . val ( ) ) ;
}
}
if ( $ . inArray ( $this . prop ( 'tagName' ) , settings . tagList ) !== - 1 ) {
$this . autoNumeric ( 'set' , $this . text ( ) ) ;
}
}
settings . runOnce = true ;
if ( $this . is ( 'input[type=text], input[type=hidden], input:not([type])' ) ) { /**added hidden type */
$this . bind ( 'keydown.autoNumeric' , function ( e ) {
holder = getHolder ( $this ) ;
if ( holder . settings . aDec === holder . settings . aSep ) {
$ . error ( "autoNumeric will not function properly when the decimal character aDec: '" + holder . settings . aDec + "' and thousand seperater aSep: '" + holder . settings . aSep + "' are the same character" ) ;
return this ;
}
if ( holder . that . readOnly ) {
holder . processed = true ;
return true ;
}
/** The below streamed code / comment allows the "enter" keydown to throw a change() event */
/ * * i f ( e . k e y C o d e = = = 1 3 & & h o l d e r . i n V a l ! = = $ t h i s . v a l ( ) ) {
$this . change ( ) ;
holder . inVal = $this . val ( ) ;
} * /
holder . init ( e ) ;
holder . settings . oEvent = 'keydown' ;
if ( holder . skipAllways ( e ) ) {
holder . processed = true ;
return true ;
}
if ( holder . processAllways ( ) ) {
holder . processed = true ;
holder . formatQuick ( ) ;
e . preventDefault ( ) ;
return false ;
}
holder . formatted = false ;
return true ;
} ) ;
$this . bind ( 'keypress.autoNumeric' , function ( e ) {
var holder = getHolder ( $this ) , processed = holder . processed ;
holder . init ( e ) ;
holder . settings . oEvent = 'keypress' ;
if ( holder . skipAllways ( e ) ) {
return true ;
}
if ( processed ) {
e . preventDefault ( ) ;
return false ;
}
if ( holder . processAllways ( ) || holder . processKeypress ( ) ) {
holder . formatQuick ( ) ;
e . preventDefault ( ) ;
return false ;
}
holder . formatted = false ;
} ) ;
$this . bind ( 'keyup.autoNumeric' , function ( e ) {
var holder = getHolder ( $this ) ;
holder . init ( e ) ;
holder . settings . oEvent = 'keyup' ;
var skip = holder . skipAllways ( e ) ;
holder . kdCode = 0 ;
delete holder . valuePartsBeforePaste ;
if ( skip ) {
return true ;
}
if ( this . value === '' ) {
return true ;
}
if ( ! holder . formatted ) {
holder . formatQuick ( ) ;
}
} ) ;
$this . bind ( 'focusin.autoNumeric' , function ( ) {
var holder = getHolder ( $this ) ;
holder . settingsClone . oEvent = 'focusin' ;
if ( holder . settingsClone . nBracket !== null ) {
var checkVal = $this . val ( ) ;
$this . val ( negativeBracket ( checkVal , holder . settingsClone . nBracket , holder . settingsClone . oEvent ) ) ;
}
holder . inVal = $this . val ( ) ;
var onempty = checkEmpty ( holder . inVal , holder . settingsClone , true ) ;
if ( onempty !== null ) {
$this . val ( onempty ) ;
}
} ) ;
$this . bind ( 'focusout.autoNumeric' , function ( ) {
var holder = getHolder ( $this ) ,
settingsClone = holder . settingsClone ,
value = $this . val ( ) ,
origValue = value ;
holder . settingsClone . oEvent = 'focusout' ;
var strip _zero = '' ; /** added to control leading zero */
if ( settingsClone . lZero === 'allow' ) { /** added to control leading zero */
settingsClone . allowLeading = false ;
strip _zero = 'leading' ;
}
if ( value !== '' ) {
value = autoStrip ( value , settingsClone , strip _zero ) ;
if ( checkEmpty ( value , settingsClone ) === null && autoCheck ( value , settingsClone , $this [ 0 ] ) ) {
value = fixNumber ( value , settingsClone . aDec , settingsClone . aNeg ) ;
value = autoRound ( value , settingsClone ) ;
value = presentNumber ( value , settingsClone . aDec , settingsClone . aNeg ) ;
} else {
value = '' ;
}
}
var groupedValue = checkEmpty ( value , settingsClone , false ) ;
if ( groupedValue === null ) {
groupedValue = autoGroup ( value , settingsClone ) ;
}
if ( groupedValue !== origValue ) {
$this . val ( groupedValue ) ;
}
if ( groupedValue !== holder . inVal ) {
$this . change ( ) ;
delete holder . inVal ;
}
if ( settingsClone . nBracket !== null && $this . autoNumeric ( 'get' ) < 0 ) {
holder . settingsClone . oEvent = 'focusout' ;
$this . val ( negativeBracket ( $this . val ( ) , settingsClone . nBracket , settingsClone . oEvent ) ) ;
}
} ) ;
}
} ) ;
} ,
/** method to remove settings and stop autoNumeric() */
destroy : function ( ) {
return $ ( this ) . each ( function ( ) {
var $this = $ ( this ) ;
$this . unbind ( '.autoNumeric' ) ;
$this . removeData ( 'autoNumeric' ) ;
} ) ;
} ,
/** method to update settings - can call as many times */
update : function ( options ) {
return $ ( this ) . each ( function ( ) {
var $this = autoGet ( $ ( this ) ) ,
settings = $this . data ( 'autoNumeric' ) ;
if ( typeof settings !== 'object' ) {
$ . error ( "You must initialize autoNumeric('init', {options}) prior to calling the 'update' method" ) ;
return this ;
}
var strip = $this . autoNumeric ( 'get' ) ;
settings = $ . extend ( settings , options ) ;
getHolder ( $this , settings , true ) ;
if ( settings . aDec === settings . aSep ) {
$ . error ( "autoNumeric will not function properly when the decimal character aDec: '" + settings . aDec + "' and thousand seperater aSep: '" + settings . aSep + "' are the same character" ) ;
return this ;
}
$this . data ( 'autoNumeric' , settings ) ;
if ( $this . val ( ) !== '' || $this . text ( ) !== '' ) {
return $this . autoNumeric ( 'set' , strip ) ;
}
return ;
} ) ;
} ,
/** returns a formated strings for "input:text" fields Uses jQuery's .val() method*/
set : function ( valueIn ) {
return $ ( this ) . each ( function ( ) {
var $this = autoGet ( $ ( this ) ) , settings = $this . data ( 'autoNumeric' ) , value = valueIn . toString ( ) ;
if ( typeof settings !== 'object' ) {
$ . error ( "You must initialize autoNumeric('init', {options}) prior to calling the 'set' method" ) ;
return this ;
}
/** returns a empty string if the value being 'set' contains non-numeric characters and or more than decimal point (full stop) and will not be formatted */
if ( ! $ . isNumeric ( + value ) ) {
return '' ;
}
value = checkValue ( value ) ;
settings . oEvent = 'set' ;
value . toString ( ) ;
if ( value !== '' ) {
value = autoRound ( value , settings ) ;
}
value = presentNumber ( value , settings . aDec , settings . aNeg ) ;
if ( ! autoCheck ( value , settings ) ) {
value = autoRound ( '' , settings ) ;
}
value = autoGroup ( value , settings ) ;
if ( $this . is ( 'input[type=text], input[type=hidden], input:not([type])' ) ) { /**added hidden type */
return $this . val ( value ) ;
}
if ( $ . inArray ( $this . prop ( 'tagName' ) , settings . tagList ) !== - 1 ) {
return $this . text ( value ) ;
}
$ . error ( "The <" + $this . prop ( 'tagName' ) + "> is not supported by autoNumeric()" ) ;
return false ;
} ) ;
} ,
/** method to get the unformated value from a specific input field, returns a numeric value */
get : function ( ) {
var $this = autoGet ( $ ( this ) ) ,
settings = $this . data ( 'autoNumeric' ) ;
if ( typeof settings !== 'object' ) {
$ . error ( "You must initialize autoNumeric('init', {options}) prior to calling the 'get' method" ) ;
return this ;
}
settings . oEvent = 'get' ;
var getValue = '' ;
/** determine the element type then use .eq(0) selector to grab the value of the first element in selector */
if ( $this . is ( 'input[type=text], input[type=hidden], input:not([type])' ) ) { /**added hidden type */
getValue = $this . eq ( 0 ) . val ( ) ;
} else if ( $ . inArray ( $this . prop ( 'tagName' ) , settings . tagList ) !== - 1 ) {
getValue = $this . eq ( 0 ) . text ( ) ;
} else {
$ . error ( "The <" + $this . prop ( 'tagName' ) + "> is not supported by autoNumeric()" ) ;
return false ;
}
if ( ( getValue === '' && settings . wEmpty === 'empty' ) || ( getValue === settings . aSign && settings . wEmpty === 'sign' ) ) {
return '' ;
}
if ( settings . nBracket !== null && getValue !== '' ) {
getValue = negativeBracket ( getValue , settings . nBracket , settings . oEvent ) ;
}
if ( settings . runOnce || settings . aForm === false ) {
getValue = autoStrip ( getValue , settings ) ;
}
getValue = fixNumber ( getValue , settings . aDec , settings . aNeg ) ;
if ( + getValue === 0 && settings . lZero !== 'keep' ) {
getValue = '0' ;
}
if ( settings . lZero === 'keep' ) {
return getValue ;
}
getValue = checkValue ( getValue ) ;
return getValue ; /** returned Numeric String */
} ,
/** method to get the unformated value from multiple fields */
getString : function ( ) {
var isAutoNumeric = false ,
$this = autoGet ( $ ( this ) ) ,
str = $this . serialize ( ) ,
parts = str . split ( '&' ) ,
i = 0 ;
for ( i ; i < parts . length ; i += 1 ) {
var miniParts = parts [ i ] . split ( '=' ) ;
var settings = $ ( '*[name="' + decodeURIComponent ( miniParts [ 0 ] ) + '"]' ) . data ( 'autoNumeric' ) ;
if ( typeof settings === 'object' ) {
if ( miniParts [ 1 ] !== null && $ ( '*[name="' + decodeURIComponent ( miniParts [ 0 ] ) + '"]' ) . data ( 'autoNumeric' ) !== undefined ) {
miniParts [ 1 ] = $ ( 'input[name="' + decodeURIComponent ( miniParts [ 0 ] ) + '"]' ) . autoNumeric ( 'get' ) ;
parts [ i ] = miniParts . join ( '=' ) ;
isAutoNumeric = true ;
}
}
}
if ( isAutoNumeric === true ) {
return parts . join ( '&' ) ;
}
$ . error ( "You must initialize autoNumeric('init', {options}) prior to calling the 'getString' method" ) ;
return this ;
} ,
/** method to get the unformated value from multiple fields */
getArray : function ( ) {
var isAutoNumeric = false ,
$this = autoGet ( $ ( this ) ) ,
formFields = $this . serializeArray ( ) ;
$ . each ( formFields , function ( i , field ) {
var settings = $ ( '*[name="' + decodeURIComponent ( field . name ) + '"]' ) . data ( 'autoNumeric' ) ;
if ( typeof settings === 'object' ) {
if ( field . value !== '' && $ ( '*[name="' + decodeURIComponent ( field . name ) + '"]' ) . data ( 'autoNumeric' ) !== undefined ) {
field . value = $ ( 'input[name="' + decodeURIComponent ( field . name ) + '"]' ) . autoNumeric ( 'get' ) . toString ( ) ;
}
isAutoNumeric = true ;
}
} ) ;
if ( isAutoNumeric === true ) {
return formFields ;
}
$ . error ( "You must initialize autoNumeric('init', {options}) prior to calling the 'getArray' method" ) ;
return this ;
} ,
/** returns the settings object for those who need to look under the hood */
getSettings : function ( ) {
var $this = autoGet ( $ ( this ) ) ;
return $this . eq ( 0 ) . data ( 'autoNumeric' ) ;
}
} ;
$ . fn . autoNumeric = function ( method ) {
if ( methods [ method ] ) {
return methods [ method ] . apply ( this , Array . prototype . slice . call ( arguments , 1 ) ) ;
}
if ( typeof method === 'object' || ! method ) {
return methods . init . apply ( this , arguments ) ;
}
$ . error ( 'Method "' + method + '" is not supported by autoNumeric()' ) ;
} ;
} ( jQuery ) ) ;