Skip to content

Commit

Permalink
feat(money): adding left and right symbols
Browse files Browse the repository at this point in the history
  • Loading branch information
Ben-hur Santos Ott committed Jun 17, 2018
1 parent 8ee0bcd commit 65f7eec
Show file tree
Hide file tree
Showing 6 changed files with 325 additions and 175 deletions.
352 changes: 216 additions & 136 deletions .idea/workspace.xml

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## [0.5.0] - 2018-jun-17.
* Adding left and right symbols.

## [0.4.1] - 2018-jun-11.
* Fixing not allowed characters on keyboard (thanks to [tobire](https://github.com/tobire)). Related: [issue#3](https://github.com/benhurott/flutter-masked-text/issues/3).

Expand Down
49 changes: 42 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Import the library
import 'package:flutter_masked_text/flutter_masked_text.dart';
```

## MaskedText

Create your mask controller:
```dart
var controller = new MaskedTextController(mask: '000.000.000-00');
Expand Down Expand Up @@ -44,21 +46,21 @@ This is the result:

![sample](doc/mask.mov.gif)

## Mask Options
#### Mask Options

In mask, you can use the following characters:
* `0`: accept numbers
* `A`: accept letters
* `@`: accept numbers and letters
* `*`: accept any character

## Initial Value
#### Initial Value
To start a mask with initial value, just use `text` property on constructor:
```dart
var controller = new MaskedTextController(mask: '000-000', text: '123456');
```

## Update text programaticaly
#### Update text programaticaly
If you want to set new text after controller initiatialization, use the `updateText` method:
```dart
var controller = new MaskedTextController(text: '', mask: '000-000');
Expand All @@ -67,7 +69,7 @@ controller.updateText('123456');
print(controller.text); //123-456
```

## Using custom translators
#### Using custom translators
If you want to use your custom regex to allow values, you can pass a custom translation dictionary:
```dart
const translator = {
Expand All @@ -88,9 +90,6 @@ controller.updateText('12345678');
print(controller.text); //1234 **** **** 5678
```

## Using default TextEditingController
The MaskedTextController extends TextEditingController. You can use all default native methods from this class.

## Money Mask
To use money mask, create a MoneyMaskedTextController:
```dart
Expand All @@ -100,21 +99,57 @@ var controller = new MoneyMaskedTextController();
new TextField(controller: controller, keyboardType: TextInputType.number)
```

#### Decimal and Thousand separator

It's possible to customize `decimal` and `thousand` separators:
```dart
var controller = new MoneyMaskedTextController(decimalSeparator: '.', thousandSeparator: ',');
```

#### Set value programaticaly

To set value programaticaly, use `updateValue`:
```dart
controller.updateValue(1234.0);
```


#### Get double value

To get the number value from masked text, use the `numberValue` property:
```dart
double val = controller.numberValue;
```


#### Using decoration symbols

You can use currency symbols if you want:
```dart
// left symbol
var controller = new MoneyMaskedTextController(leftSymbol: 'R\$ ');
controller.updateValue(123.45);
print(controller.text); //<-- R$ 123,45
// right symbol
var controller = new MoneyMaskedTextController(rightSymbol: ' US\$');
controller.updateValue(99.99);
print(controller.text); //<-- 99,99 US$
// both
var controller = new MoneyMaskedTextController(leftSymbol: 'to pay:', rightSymbol: ' US\$');
controller.updateValue(123.45);
print(controller.text); //<-- to pay: 123,45 US$
```

## Using default TextEditingController
The MaskedTextController and MoneyMaskedTextController extends TextEditingController. You can use all default native methods from this class.

## TODO
- [x] Custom translations
- [x] Money Mask
Expand Down
67 changes: 43 additions & 24 deletions lib/flutter_masked_text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,16 @@ class MaskedTextController extends TextEditingController {
}
}

/**
* Mask for monetary values.
*/
class MoneyMaskedTextController extends TextEditingController {
MoneyMaskedTextController(
{double initialValue = 0.0,
this.decimalSeparator = ',',
this.thousandSeparator = '.',
this.rightSymbol = ''}) {
this.decimalSeparator = ',',
this.thousandSeparator = '.',
this.rightSymbol = '',
this.leftSymbol = ''}) {
_validateConfig();

this.addListener(() {
Expand All @@ -108,36 +112,55 @@ class MoneyMaskedTextController extends TextEditingController {
final String decimalSeparator;
final String thousandSeparator;
final String rightSymbol;
final String leftSymbol;

/**
* this is the maximun double capacity.
*/
// this is the maximum supported for double values.
final int _maxLength = 19;

void updateValue(double value) {
String masked = this._applyMask(value);

if (masked != this.text) {
this.text = masked;
if (masked.length > _maxLength) {
masked = masked.substring(0, _maxLength);
}
}

double get numberValue => double.parse(_getSanitizedText(this.text)) / 100.0;
if (rightSymbol.length > 0) {
masked += rightSymbol;
}

@override
set text(String newText) {
if (newText.length <= this._maxLength) {
super.text = newText;
} else {
super.text = newText.substring(0, this._maxLength);
if (leftSymbol.length > 0) {
masked = leftSymbol + masked;
}

var cursorPosition = super.text.length - this.rightSymbol.length;
if (masked != this.text) {
this.text = masked;

this.selection = new TextSelection.fromPosition(
new TextPosition(offset: cursorPosition));
var cursorPosition = super.text.length - this.rightSymbol.length;
this.selection = new TextSelection.fromPosition(
new TextPosition(offset: cursorPosition));
}
}

double get numberValue => double.parse(_getSanitizedText(this.text)) / 100.0;

// @override
// set text(String newText) {
// String formattedText = "";
//
// if (newText.length <= _maxLengthForNumbers) {
// formattedText = newText;
// } else {
// formattedText = newText.substring(0, _maxLengthForNumbers);
// }
//
// super.text = formattedText + "${this.rightSymbol}";
//
// var cursorPosition = super.text.length - this.rightSymbol.length;
//
// this.selection = new TextSelection.fromPosition(
// new TextPosition(offset: cursorPosition));
// }

_validateConfig() {
bool rightSymbolHasNumbers = _getOnlyNumbers(this.rightSymbol).length > 0;

Expand Down Expand Up @@ -172,7 +195,7 @@ class MoneyMaskedTextController extends TextEditingController {

String _applyMask(double value) {
String textRepresentation =
value.toStringAsFixed(2).replaceAll('.', this.decimalSeparator);
value.toStringAsFixed(2).replaceAll('.', this.decimalSeparator);

List<String> numberParts = [];

Expand All @@ -194,10 +217,6 @@ class MoneyMaskedTextController extends TextEditingController {

String numberText = numberParts.join('');

if (this.rightSymbol.length > 0) {
numberText += "${this.rightSymbol}";
}

return numberText;
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: flutter_masked_text
description: Masked text input for flutter.
version: 0.4.1
version: 0.5.0
author: Ben-hur Santos Ott <ben-hur@outlook.com>
homepage: https://github.com/benhurott/flutter-masked-text

Expand Down
27 changes: 20 additions & 7 deletions test/flutter_masked_text_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,26 @@ void main() {
expect(controller.text, '99,99 US\$');
});

// todo: this test is failing due some uncaught reason
// test('rightSymbol with number must raises an error.', () {
// expect(
// new MoneyMaskedTextController(rightSymbol: ' U4'),
// throwsArgumentError
// );
// });
test('rightSymbol with number must raises an error.', () {
Function executor = () {
new MoneyMaskedTextController(rightSymbol: ' U4');
};

expect(executor, throwsArgumentError);
});

test('rightSymbol " US\$" with 12345678901234 must results in 123.456.789.012,34 US\$', () {
var controller = new MoneyMaskedTextController(rightSymbol: ' US\$');
controller.updateValue(123456789012.34);

expect(controller.text, '123.456.789.012,34 US\$');
});

test('leftSymbol "R\$ " and value 123.45 results in "R\$ 123,45"', () {
var controller = new MoneyMaskedTextController(leftSymbol: 'R\$ ');
controller.updateValue(123.45);

expect(controller.text, 'R\$ 123,45');
});
});
}

0 comments on commit 65f7eec

Please sign in to comment.