Sfoglia il codice sorgente

Fix formatting on change and paste events.

Paulo Reis 10 anni fa
parent
commit
67290fd6a7
1 ha cambiato i file con 75 aggiunte e 1 eliminazioni
  1. 75 1
      services/web/public/coffee/directives/creditCards.coffee

+ 75 - 1
services/web/public/coffee/directives/creditCards.coffee

@@ -99,6 +99,30 @@ define [
 				groups = $.grep(groups, (n) -> n) # Filter empty groups
 				groups = $.grep(groups, (n) -> n) # Filter empty groups
 				groups.join(' ')
 				groups.join(' ')
 
 
+		formatExpiry = (expiry) ->
+			parts = expiry.match(/^\D*(\d{1,2})(\D+)?(\d{1,4})?/)
+			return '' unless parts
+
+			mon = parts[1] || ''
+			sep = parts[2] || ''
+			year = parts[3] || ''
+
+			if year.length > 0
+				sep = ' / '
+
+			else if sep is ' /'
+				mon = mon.substring(0, 1)
+				sep = ''
+
+			else if mon.length == 2 or sep.length > 0
+				sep = ' / '
+
+			else if mon.length == 1 and mon not in ['0', '1']
+				mon = "0#{mon}"
+				sep = ' / '
+
+			return mon + sep + year
+
 		parseExpiry = (value = "") ->
 		parseExpiry = (value = "") ->
 			[month, year] = value.split(/[\s\/]+/, 2)
 			[month, year] = value.split(/[\s\/]+/, 2)
 
 
@@ -119,6 +143,7 @@ define [
 			fromNumber: cardFromNumber
 			fromNumber: cardFromNumber
 			fromType: cardFromType
 			fromType: cardFromType
 			cardType: cardType 
 			cardType: cardType 
+			formatExpiry: formatExpiry
 			formatCardNumber: formatCardNumber  
 			formatCardNumber: formatCardNumber  
 			defaultFormat: defaultFormat
 			defaultFormat: defaultFormat
 			defaultInputFormat: defaultInputFormat
 			defaultInputFormat: defaultInputFormat
@@ -137,6 +162,45 @@ define [
 
 
 			false
 			false
 
 
+		safeVal = (value, $target) ->
+			try
+				cursor = $target.prop('selectionStart')
+			catch error
+				cursor = null
+			
+			last = $target.val()
+			$target.val(value)
+
+			if cursor != null && $target.is(":focus")
+				cursor = value.length if cursor is last.length
+
+				# This hack looks for scenarios where we are changing an input's value such
+				# that "X| " is replaced with " |X" (where "|" is the cursor). In those
+				# scenarios, we want " X|".
+				#
+				# For example:
+				# 1. Input field has value "4444| "
+				# 2. User types "1"
+				# 3. Input field has value "44441| "
+				# 4. Reformatter changes it to "4444 |1"
+				# 5. By incrementing the cursor, we make it "4444 1|"
+				#
+				# This is awful, and ideally doesn't go here, but given the current design
+				# of the system there does not appear to be a better solution.
+				#
+				# Note that we can't just detect when the cursor-1 is " ", because that
+				# would incorrectly increment the cursor when backspacing, e.g. pressing
+				# backspace in this scenario: "4444 1|234 5".
+				if last != value
+					prevPair = last[cursor-1..cursor]
+					currPair = value[cursor-1..cursor]
+					digit = value[cursor]
+					cursor = cursor + 1 if /\d/.test(digit) and
+						prevPair == "#{digit} " and currPair == " #{digit}"
+
+				$target.prop('selectionStart', cursor)
+				$target.prop('selectionEnd', cursor)
+
 		# Replace Full-Width Chars
 		# Replace Full-Width Chars
 		replaceFullWidthChars = (str = '') ->
 		replaceFullWidthChars = (str = '') ->
 			fullWidth = '\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19'
 			fullWidth = '\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19'
@@ -160,6 +224,7 @@ define [
 				value   = $target.val()
 				value   = $target.val()
 				value   = replaceFullWidthChars(value)
 				value   = replaceFullWidthChars(value)
 				value   = value.replace(/\D/g, '')
 				value   = value.replace(/\D/g, '')
+				safeVal(value, $target)
 
 
 		# Format Card Number
 		# Format Card Number
 		reFormatCardNumber = (e) ->
 		reFormatCardNumber = (e) ->
@@ -168,6 +233,7 @@ define [
 				value   = $target.val()
 				value   = $target.val()
 				value   = replaceFullWidthChars(value)
 				value   = replaceFullWidthChars(value)
 				value   = ccUtils.formatCardNumber(value)
 				value   = ccUtils.formatCardNumber(value)
+				safeVal(value, $target)
 
 
 		formatCardNumber = (e) ->
 		formatCardNumber = (e) ->
 			# Only format if input is a number
 			# Only format if input is a number
@@ -249,7 +315,9 @@ define [
 			setTimeout ->
 			setTimeout ->
 				value   = $target.val()
 				value   = $target.val()
 				value   = replaceFullWidthChars(value)
 				value   = replaceFullWidthChars(value)
-				value   = $.payment.formatExpiry(value)
+				value   = ccUtils.formatExpiry(value)
+				safeVal(value, $target)
+
 
 
 		formatExpiry = (e) ->
 		formatExpiry = (e) ->
 			# Only format if input is a number
 			# Only format if input is a number
@@ -328,6 +396,7 @@ define [
 				value   = $target.val()
 				value   = $target.val()
 				value   = replaceFullWidthChars(value)
 				value   = replaceFullWidthChars(value)
 				value   = value.replace(/\D/g, '')[0...4]
 				value   = value.replace(/\D/g, '')[0...4]
+				safeVal(value, $target)
 
 
 		# Restrictions
 		# Restrictions
 		restrictNumeric = (e) ->
 		restrictNumeric = (e) ->
@@ -429,11 +498,15 @@ define [
 		restrict: "A"
 		restrict: "A"
 		require: "ngModel"
 		require: "ngModel"
 		link: (scope, el, attrs, ngModel) ->
 		link: (scope, el, attrs, ngModel) ->
+			el.on "keypress", 	ccFormat.restrictNumeric
 			el.on "keypress", 	ccFormat.restrictExpiry
 			el.on "keypress", 	ccFormat.restrictExpiry
 			el.on "keypress", 	ccFormat.formatExpiry
 			el.on "keypress", 	ccFormat.formatExpiry
 			el.on "keypress", 	ccFormat.formatForwardSlash
 			el.on "keypress", 	ccFormat.formatForwardSlash
 			el.on "keypress", 	ccFormat.formatForwardExpiry
 			el.on "keypress", 	ccFormat.formatForwardExpiry
 			el.on "keydown", 	ccFormat.formatBackExpiry
 			el.on "keydown", 	ccFormat.formatBackExpiry
+			el.on "change", 	ccFormat.reFormatExpiry
+			el.on "input", 		ccFormat.reFormatExpiry
+			el.on "paste", 		ccFormat.reFormatExpiry
 
 
 			ngModel.$parsers.push ccFormat.parseExpiry
 			ngModel.$parsers.push ccFormat.parseExpiry
 			ngModel.$formatters.push ccFormat.parseExpiry
 			ngModel.$formatters.push ccFormat.parseExpiry
@@ -442,6 +515,7 @@ define [
 		restrict: "A"
 		restrict: "A"
 		require: "ngModel"
 		require: "ngModel"
 		link: (scope, el, attrs, ngModel) ->
 		link: (scope, el, attrs, ngModel) ->
+			el.on "keypress", 	ccFormat.restrictNumeric
 			el.on "keypress", 	ccFormat.restrictCardNumber
 			el.on "keypress", 	ccFormat.restrictCardNumber
 			el.on "keypress", 	ccFormat.formatCardNumber
 			el.on "keypress", 	ccFormat.formatCardNumber
 			el.on "keydown", 	ccFormat.formatBackCardNumber
 			el.on "keydown", 	ccFormat.formatBackCardNumber