diff --git a/.gitignore b/.gitignore index e0f4944c..001c7c38 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ node_modules/ .vscode/ npm-debug.log + +poc.js \ No newline at end of file diff --git a/README.md b/README.md index 3c4514e6..ccba3723 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,10 @@ export default class MyComponent extends Component { // Ex: if you input 40/02/1990 30:20:20, it will return false // because in this case, the day and the hour is invalid. let valid = this.refs['myDateText'].isValid(); + + // get converted value. Using type=datetime, it returns the moment object. + // If it's using type=money, it returns a Number object. + let rawValue = this.refs['myDateText'].getRawValue(); } render() { @@ -107,6 +111,10 @@ For `type={'custom'}`
* The function receives 2 parameters: * `value`: current value. * `settings`: current settings + * `getRawValue` (Function, default returns the current value): the function that's invoked when `getRawValue` method from component is called. + * The function receives 2 parameters: + * `value`: current value. + * `settings`: current settings For `type={'credit-card'}`
* *options={...}* @@ -126,6 +134,16 @@ For `type={'credit-card'}`
* *cel-phone*: return true if the mask is complete. * *datetime*: return true if the date value is valid for format. * *custom*: use custom validation, if it not exist, always returns true. +* `getRawValue()`: get the converted value of mask. + * *credit-card*: return the array with the value parts. Ex: `1234 1234 1234 1234` returns `[1234, 1234, 1234, 1234]`. + * *cpf*: return the value without mask. + * *cnpj*: return the value without mask. + * *zip-code*: return the value without mask. + * *only-numbers*: return the value without mask. + * *money*: return the Number value. Ex: `R$ 1.234,56` returns `1234.56`. + * *cel-phone*: return the value without mask. + * *datetime*: return the `moment` object for the date and format. + * *custom*: use custom method (passed in options). If it not exists, returns the current value. ## Usage (TextMask) @@ -198,6 +216,9 @@ var money = MaskService.toMask('money', '123', { # Changelog +## 1.2.0 +* Adding `getRawValue`. + ## 1.1.1 * Fixing toolbox-service reference (thanks to [ziftinpeki](https://github.com/ziftinpeki)). diff --git a/__tests__/cel-phone.mask.test.js b/__tests__/cel-phone.mask.test.js index 1bffddad..0cda0a6f 100644 --- a/__tests__/cel-phone.mask.test.js +++ b/__tests__/cel-phone.mask.test.js @@ -94,4 +94,32 @@ test('1237777777 dddMask=999 is not valid', () => { }); expect(isValid).toBe(false); +}); + +test('5188888888 results (51) 8888-8888 and raw value 5188888888', () => { + var mask = new CelPhoneMask(); + var expected = '(51) 8888-8888'; + var received = mask.getValue('5188888888'); + + var expectedRawValue = '5188888888'; + var receivedRawValue = mask.getRawValue(received); + + expect(received).toBe(expected); + expect(receivedRawValue).toBe(expectedRawValue); +}); + +test('123777777777 dddMask=999 results 123 77777-7777 and raw value 123777777777', () => { + var mask = new CelPhoneMask(); + var expected = '123 77777-7777'; + var received = mask.getValue('123777777777', { + dddMask: '999 ' + }); + + var expectedRawValue = '123777777777'; + var receivedRawValue = mask.getRawValue(received, { + dddMask: '999 ' + }); + + expect(received).toBe(expected); + expect(receivedRawValue).toBe(expectedRawValue); }); \ No newline at end of file diff --git a/__tests__/cnpj.mask.test.js b/__tests__/cnpj.mask.test.js index 4c49c4e1..9f9ccf2c 100644 --- a/__tests__/cnpj.mask.test.js +++ b/__tests__/cnpj.mask.test.js @@ -51,4 +51,16 @@ test('7988526200013 results 79.885.262/0001-3 and is not valid', () => { expect(received).toBe(expected); expect(isValid).toBe(false); +}); + +test('79885262000130 results 79.885.262/0001-30 and raw value 79885262000130', () => { + var mask = new CnpjMask(); + var expected = '79.885.262/0001-30'; + var received = mask.getValue('79885262000130'); + + var expectedRawValue = '79885262000130'; + var receivedRawValue = mask.getRawValue(received); + + expect(received).toBe(expected); + expect(receivedRawValue).toBe(expectedRawValue); }); \ No newline at end of file diff --git a/__tests__/cpf.mask.test.js b/__tests__/cpf.mask.test.js index 4b86dc3d..261a9666 100644 --- a/__tests__/cpf.mask.test.js +++ b/__tests__/cpf.mask.test.js @@ -51,4 +51,16 @@ test('1234567890 results 123.456.789-0 and is not valid', () => { expect(received).toBe(expected); expect(isValid).toBe(false); +}); + +test('12312312356 results 123.123.123-56 and raw value 12312312356', () => { + var mask = new CpfMask(); + var expected = '123.123.123-56'; + var received = mask.getValue('12312312356'); + + var expectedRawValue = '12312312356'; + var receivedRawValue = mask.getRawValue(received); + + expect(received).toBe(expected); + expect(receivedRawValue).toBe(expectedRawValue); }); \ No newline at end of file diff --git a/__tests__/credit-card.mask.test.js b/__tests__/credit-card.mask.test.js index 41117b0f..11725311 100644 --- a/__tests__/credit-card.mask.test.js +++ b/__tests__/credit-card.mask.test.js @@ -33,4 +33,42 @@ test('1234123412341234 obfuscated false results 1234 1234 1234 1234', () => { }); expect(received).toBe(expected); +}); + +test('1234123412341234 obfuscated false results 1234 1234 1234 1234 and raw value [1234, 1234, 1234, 1234]', () => { + var mask = new CreditCardMask(); + var options = { + obfuscated: false + }; + + var expected = '1234 1234 1234 1234'; + var received = mask.getValue('1234123412341234', options); + + var expectedRawValue = ['1234', '1234', '1234', '1234']; + var receivedRawValue = mask.getRawValue(received, options); + + expect(received).toBe(expected); + + expectedRawValue.forEach((val, index) => { + expect(val).toBe(receivedRawValue[index]); + }); +}); + +test('1234123412341234 obfuscated true results 1234 **** **** 1234 and raw value [1234, ****, ****, 1234]', () => { + var mask = new CreditCardMask(); + var options = { + obfuscated: true + }; + + var expected = '1234 **** **** 1234'; + var received = mask.getValue('1234123412341234', options); + + var expectedRawValue = ['1234', '****', '****', '1234']; + var receivedRawValue = mask.getRawValue(received, options); + + expect(received).toBe(expected); + + expectedRawValue.forEach((val, index) => { + expect(val).toBe(receivedRawValue[index]); + }); }); \ No newline at end of file diff --git a/__tests__/custom.mask.test.js b/__tests__/custom.mask.test.js index 633fd0a7..9fdcd98c 100644 --- a/__tests__/custom.mask.test.js +++ b/__tests__/custom.mask.test.js @@ -111,4 +111,23 @@ test('ELF with mask AAAAA and custom validator results DWARF and is invalid', () expect(expected).toBe(received); expect(isValid).toBe(true); +}); + +test('123 with mask 999 results 123 and raw value 123(type Number)', () => { + var mask = new CustomMask(); + var options = { + mask: '999', + getRawValue: function(maskedValue, settings) { + return Number(maskedValue); + } + }; + + var expected = '123'; + var received = mask.getValue('123', options); + + var expectedRawValue = 123; + var receivedRawValue = mask.getRawValue(received, options); + + expect(received).toBe(expected); + expect(receivedRawValue).toBe(expectedRawValue); }); \ No newline at end of file diff --git a/__tests__/datetime.mask.test.js b/__tests__/datetime.mask.test.js index 43bfcb5b..203987f5 100644 --- a/__tests__/datetime.mask.test.js +++ b/__tests__/datetime.mask.test.js @@ -1,4 +1,13 @@ import { DatetimeMask } from '../lib/masks'; +var moment = require('moment'); + +function compareMomentObj(dateTimeA, dateTimeB) { + var momentA = moment(dateTimeA,"DD/MM/YYYY"); + var momentB = moment(dateTimeB,"DD/MM/YYYY"); + if (momentA > momentB) return 1; + else if (momentA < momentB) return -1; + else return 0; +} test('getType results datetime', () => { var expected = 'datetime'; @@ -79,4 +88,16 @@ test('01011990174030 with format DD/MM/YYYY HH:mm:ss results 01/01/1990 17:40:30 expect(received).toBe(expected); expect(isValid).toBe(true); +}); + +test('01011990174030 with format DD/MM/YYYY HH:mm:ss results 01/01/1990 17:40:30 and raw value Date', () => { + var mask = new DatetimeMask(); + var expected = '01/01/1990 17:40:30'; + var received = mask.getValue('01011990174030'); + + var expectedRawValue = moment(received, 'DD/MM/YYYY HH:mm:ss', true); + var receivedRawValue = mask.getRawValue(received); + + expect(received).toBe(expected); + expect(compareMomentObj(receivedRawValue, expectedRawValue)).toBe(0); }); \ No newline at end of file diff --git a/__tests__/money.mask.test.js b/__tests__/money.mask.test.js index 33115b9d..450441ff 100644 --- a/__tests__/money.mask.test.js +++ b/__tests__/money.mask.test.js @@ -133,4 +133,56 @@ test('US$ config with value 1234567 results US$ 12,345.67', () => { }); expect(received).toBe(expected); -}) +}); + +test('1 results R$ 0,01 and raw value 0.01', () => { + var mask = new MoneyMask(); + var expected = 'R$ 0,01'; + var received = mask.getValue('1'); + + var expectedRawValue = 0.01; + var receivedRawValue = mask.getRawValue(received); + + expect(received).toBe(expected); + expect(receivedRawValue).toBe(expectedRawValue); +}); + +test('111111 results R$ 1.111,11 and raw value 1111.11', () => { + var mask = new MoneyMask(); + var expected = 'R$ 1.111,11'; + var received = mask.getValue('111111'); + + var expectedRawValue = 1111.11; + var receivedRawValue = mask.getRawValue(received); + + expect(received).toBe(expected); + expect(receivedRawValue).toBe(expectedRawValue); +}); + +test('1 zeroCents results R$ 1,00 and raw value 1', () => { + var mask = new MoneyMask(); + var expected = 'R$ 1,00'; + var received = mask.getValue('1', { + zeroCents: true + }); + + var expectedRawValue = 1; + var receivedRawValue = mask.getRawValue(received); + + expect(received).toBe(expected); + expect(receivedRawValue).toBe(expectedRawValue); +}); + +test('111111 delimiter , results R$ 1,111,11 and raw value 1111.11', () => { + var mask = new MoneyMask(); + var expected = 'R$ 1,111,11'; + var received = mask.getValue('111111', { + delimiter: ',' + }); + + var expectedRawValue = 1111.11; + var receivedRawValue = mask.getRawValue(received); + + expect(received).toBe(expected); + expect(receivedRawValue).toBe(expectedRawValue); +}); \ No newline at end of file diff --git a/__tests__/only-numbers.mask.js b/__tests__/only-numbers.mask.js index cc0fd2e6..798de3df 100644 --- a/__tests__/only-numbers.mask.js +++ b/__tests__/only-numbers.mask.js @@ -29,4 +29,16 @@ test('abc results ', () => { var received = mask.getValue('abc'); expect(received).toBe(expected); +}); + +test('1 results 1 and raw value 1', () => { + var mask = new OnlyNumbersMask(); + var expected = '1'; + var received = mask.getValue('1'); + + var expectedRawValue = '1'; + var receivedRawValue = mask.getRawValue(received); + + expect(received).toBe(expected); + expect(receivedRawValue).toBe(expectedRawValue); }); \ No newline at end of file diff --git a/__tests__/zip-code.mask.test.js b/__tests__/zip-code.mask.test.js index e87a046d..40da9ce1 100644 --- a/__tests__/zip-code.mask.test.js +++ b/__tests__/zip-code.mask.test.js @@ -39,4 +39,16 @@ test('11111111 results 11111-111 and is not valid', () => { var isValid = mask.validate(received); expect(isValid).toBe(true); +}); + +test('11111111 results 11111-111 and raw value 11111111', () => { + var mask = new ZipCodeMask(); + var expected = '11111-111'; + var received = mask.getValue('11111111'); + + var expectedRawValue = '11111111'; + var receivedRawValue = mask.getRawValue(received); + + expect(received).toBe(expected); + expect(receivedRawValue).toBe(expectedRawValue); }); \ No newline at end of file diff --git a/lib/base-text-component.js b/lib/base-text-component.js index 053c63ba..3648d57b 100644 --- a/lib/base-text-component.js +++ b/lib/base-text-component.js @@ -37,7 +37,15 @@ export default class BaseTextComponent extends Component { isValid() { return this._maskHandler.validate( this._getDefaultValue(this.state.value), - this.state.options); + this.state.options + ); + } + + getRawValue() { + return this._maskHandler.getRawValue( + this._getDefaultValue(this.state.value), + this.state.options + ); } _resolveMaskHandler() { diff --git a/lib/masks/_base.mask.js b/lib/masks/_base.mask.js index 1e357901..fc5c1200 100644 --- a/lib/masks/_base.mask.js +++ b/lib/masks/_base.mask.js @@ -16,6 +16,10 @@ export default class BaseMask { return obj3; } + getRawValue(maskedValue, settings) { + return maskedValue; + } + getDefaultValue(value) { if(value === undefined || value === null) { return ''; @@ -25,6 +29,6 @@ export default class BaseMask { } removeNotNumbers(text) { - return text.replace(/[^0-9\.]+/g, ''); + return text.replace(/[^0-9]+/g, ''); } } \ No newline at end of file diff --git a/lib/masks/cel-phone.mask.js b/lib/masks/cel-phone.mask.js index 1802f286..fca287b1 100644 --- a/lib/masks/cel-phone.mask.js +++ b/lib/masks/cel-phone.mask.js @@ -17,6 +17,10 @@ export default class CelPhoneMask extends BaseMask { return this.getVMasker().toPattern(value, mask); } + getRawValue(maskedValue, settings) { + return super.removeNotNumbers(maskedValue); + } + validate(value, settings) { let valueToValidate = super.getDefaultValue(value); valueToValidate = this.getValue(value, settings); diff --git a/lib/masks/cnpj.mask.js b/lib/masks/cnpj.mask.js index 7d01c029..ebfe725f 100644 --- a/lib/masks/cnpj.mask.js +++ b/lib/masks/cnpj.mask.js @@ -30,6 +30,10 @@ export default class CnpjMask extends BaseMask { return this.getVMasker().toPattern(value, CNPJ_MASK); } + getRawValue(maskedValue, settings) { + return super.removeNotNumbers(maskedValue); + } + validate(value, settings) { return validateCnpj(value); } diff --git a/lib/masks/cpf.mask.js b/lib/masks/cpf.mask.js index 10a8be65..ec4d7e7b 100644 --- a/lib/masks/cpf.mask.js +++ b/lib/masks/cpf.mask.js @@ -58,6 +58,10 @@ export default class CpfMask extends BaseMask { return this.getVMasker().toPattern(value, CPF_MASK); } + getRawValue(maskedValue, settings) { + return super.removeNotNumbers(maskedValue); + } + validate(value, settings) { return validateCPF(value); } diff --git a/lib/masks/credit-card.mask.js b/lib/masks/credit-card.mask.js index bf5b025e..33908604 100644 --- a/lib/masks/credit-card.mask.js +++ b/lib/masks/credit-card.mask.js @@ -25,6 +25,16 @@ export default class CreditCardMask extends BaseMask { return true; } + getRawValue(maskedValue, settings) { + if(!maskedValue) return []; + + return maskedValue.split(' ').map(val => { + if (!val) return ''; + + return val.trim(); + }); + } + _getMask(settings) { let mergedSettings = super.mergeSettings(CREDIT_CARD_SETTINGS, settings); let selectedMask = mergedSettings.obfuscated ? CREDIT_CARD_OBFUSCATED_MASK : CREDIT_CARD_MASK; diff --git a/lib/masks/custom.mask.js b/lib/masks/custom.mask.js index ecba6881..7471c048 100644 --- a/lib/masks/custom.mask.js +++ b/lib/masks/custom.mask.js @@ -13,6 +13,14 @@ export default class CustomMask extends BaseMask { return this.getVMasker().toPattern(value, settings.mask); } + getRawValue(maskedValue, settings) { + if(!!settings && settings.getRawValue) { + return settings.getRawValue(maskedValue, settings); + } + + return maskedValue; + } + validate(value, settings) { if(!!settings && settings.validator) { return settings.validator(value, settings); diff --git a/lib/masks/datetime.mask.js b/lib/masks/datetime.mask.js index e97c0715..cfda53ff 100644 --- a/lib/masks/datetime.mask.js +++ b/lib/masks/datetime.mask.js @@ -21,6 +21,11 @@ export default class DatetimeMask extends BaseMask { return this.getVMasker().toPattern(value, mask); } + getRawValue(maskedValue, settings) { + let mergedSettings = this._getMergedSettings(settings); + return moment(maskedValue, mergedSettings.format, true); + } + validate(value, settings) { var maskedValue = this.getValue(value, settings); let mergedSettings = this._getMergedSettings(settings); diff --git a/lib/masks/money.mask.js b/lib/masks/money.mask.js index 8a1c3d10..0d3d9108 100644 --- a/lib/masks/money.mask.js +++ b/lib/masks/money.mask.js @@ -1,12 +1,12 @@ import BaseMask from './_base.mask'; const MONEY_MASK_SETTINGS = { - precision: 2, - separator: ',', - delimiter: '.', - unit: 'R$', - suffixUnit: '', - zeroCents: false + precision: 2, + separator: ',', + delimiter: '.', + unit: 'R$', + suffixUnit: '', + zeroCents: false }; export default class MoneyMask extends BaseMask { @@ -16,10 +16,29 @@ export default class MoneyMask extends BaseMask { getValue(value, settings) { let mergedSettings = super.mergeSettings(MONEY_MASK_SETTINGS, settings); - return this.getVMasker().toMoney(value, mergedSettings); + return this.getVMasker().toMoney(value, mergedSettings); + } + + getRawValue(maskedValue, settings) { + let mergedSettings = super.mergeSettings(MONEY_MASK_SETTINGS, settings); + let normalized = super.removeNotNumbers(maskedValue); + + let dotPosition = normalized.length - mergedSettings.precision; + normalized = this._insert(normalized, dotPosition, '.'); + + return Number(normalized); } validate(value, settings) { return true; } + + _insert(text, index, string) { + if (index > 0) { + return text.substring(0, index) + string + text.substring(index, text.length); + } + else { + return string + text; + } + }; } \ No newline at end of file diff --git a/lib/masks/only-numbers.mask.js b/lib/masks/only-numbers.mask.js index 4101359e..c5819733 100644 --- a/lib/masks/only-numbers.mask.js +++ b/lib/masks/only-numbers.mask.js @@ -9,6 +9,10 @@ export default class OnlyNumbersMask extends BaseMask { return this.getVMasker().toNumber(value); } + getRawValue(maskedValue, settings) { + return super.removeNotNumbers(maskedValue); + } + validate(value, settings) { return true; } diff --git a/lib/masks/zip-code.mask.js b/lib/masks/zip-code.mask.js index ad4d65aa..28c9c192 100644 --- a/lib/masks/zip-code.mask.js +++ b/lib/masks/zip-code.mask.js @@ -10,6 +10,10 @@ export default class ZipCodeMask extends BaseMask { return this.getVMasker().toPattern(value, ZIP_CODE_MASK); } + getRawValue(maskedValue, settings) { + return super.removeNotNumbers(maskedValue); + } + validate(value, settings) { if(!!value) { return value.length === ZIP_CODE_MASK.length; diff --git a/package.json b/package.json index e9a22685..ea214619 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-masked-text", - "version": "1.1.1", + "version": "1.2.0", "description": "Text and TextInput with mask for React Native applications", "main": "index.js", "scripts": {