A set of flutter formatters for text and input fields

Overview

flutter_multi_formatter

pub.dev likes popularity pub points style: effective dart Awesome Flutter

Formatters Included

  1. Phone Formatter
  2. Credit / Debit Card Formatter
  3. Money Formatter
  4. Masked Formatter

Special utilities

  1. Bitcoin (BTC) wallet validator;
  2. Digit exctractor (allows to extract all digits out of a string)
  3. Phone number validator (the check is based on country phone codes and masks so it's a more serious and reliable validation than a simple regular expression)
  4. "Is digit" checker (Simply checks if an input string value a digit or not)
  5. Currency string formatter (allows to convert a number to a currency string representation e.g. this 10000 to this 10,000.00$)
  6. Unfocuser (a widget that is used to unfocus any text fields without any boilerplate code. Extremely simple to use)

Formatting a phone

PhoneInputFormatter.replacePhoneMask(
    countryCode: 'RU',
    newMask: '+0 (000) 000 00 00',
);
PhoneInputFormatter.addAlternativePhoneMasks(
    countryCode: 'BR',
    alternativeMasks: [
    '+00 (00) 0000-0000',
    '+(00) 00000',
    '+00 (00) 00-0000',
    ],
);
/// There is also a possibility to enter endless phones 
/// by setting allowEndlessPhone to true 
/// this means that you can enter a phone number of any length
/// its part that matches a mask will be formatted 
/// and the rest will be entered unformatted
/// is will allow you to support any phones (even those that are not supported by the formatter yet)
PhoneInputFormatter(
    onCountrySelected: _onCountrySelected,
    allowEndlessPhone: true,
)

Formatting a credit / debit card

Formatting currencies

Using:

import 'package:flutter_multi_formatter/flutter_multi_formatter.dart';

A list of formatters included

/// for phone numbers with a fully automated detection
PhoneInputFormatter

/// for anything that can be masked
MaskedInputFormatter

/// for credit / debit cards
CreditCardNumberInputFormatter
CreditCardCvcInputFormatter
CreditCardExpirationDateFormatter

/// for any inputs where you need to restrict or
/// allow some characters
RestrictingInputFormatter

/// for currencies
MoneyInputFormatter
PosInputFormatter

Utility methods and widgets

Validates Bitcoin wallets (also supports bech32)

You can use these example wallets to test the validator

P2PKH addresses start with the number 1 Example: 1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2

P2SH addresses start with the number 3 Example: 3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy

Bech32 addresses also known as "bc1 addresses" start with bc1 Example: bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq

/// a simple check if its a BTC wallet or not, regardless of its type
bool isBitcoinWalletValid(String value);

/// a bit more complicated check which can return the type of 
/// BTC wallet and return SegWit (Bech32), Regular, or None if 
/// the string is not a BTC address
BitcoinWalletType getBitcoinWalletType(String value);

/// Detailed check, for those who need to get more details 
/// of the wallet. Returns the address type, the network, and 
/// the wallet type along with its address. 
/// It always returns BitcoinWalletDetails object. To check if it's
/// valid or not use bitcoinWalletDetails.isValid getter
/// IMPORTANT The BitcoinWalletDetails class overrides an 
/// equality operators so two BitcoinWalletDetails objects can be 
/// compared simply like this bwd1 == bwd2
BitcoinWalletDetails getBitcoinWalletDetails(String? value);

Gets all numbers out of a string and joins them into a new string e.g. a string like fGgfjh456bb78 will be converted into this: 45678

import 'package:flutter_multi_formatter/flutter_multi_formatter.dart';

String toNumericString(String text);

returns 'true' if the checked character is a digit

import 'package:flutter_multi_formatter/flutter_multi_formatter.dart';

bool isDigit(String character);

toCurrencyString() is used by the MoneyInputFormatter internally but you can also use it directly

import 'package:flutter_multi_formatter/flutter_multi_formatter.dart';

String toCurrencyString(String value, {
    int mantissaLength = 2,
    /// in case you need a period as a thousand separator
    /// simply change ThousandSeparator.Comma to ThousandSeparator.Period
    /// and you will get 1.000.000,00 instead of 1,000,000.00
    ThousandSeparator thousandSeparator = ThousandSeparator.Comma,
    ShorteningPolicy shorteningPolicy = ShorteningPolicy.NoShortening,
    String leadingSymbol = '',
    String trailingSymbol = '',
    bool useSymbolPadding = false
});

print(toCurrencyString('123456', leadingSymbol: MoneySymbols.DOLLAR_SIGN)); // $123,456.00

/// the values can also be shortened to thousands, millions, billions... 
/// in this case a 1000 will be displayed as 1K, and 1250000 will turn to this 1.25M
var result = toCurrencyString(
    '125000', 
    leadingSymbol: MoneySymbols.DOLLAR_SIGN,
    shorteningPolicy: ShorteningPolicy.RoundToThousands
); // $125K

result = toCurrencyString(
    '1250000', 
    leadingSymbol: MoneySymbols.DOLLAR_SIGN,
    shorteningPolicy: ShorteningPolicy.RoundToMillions
); // 1.25M

There's also an "extension" version of this function which can be used on double, int and String.

import 'package:flutter_multi_formatter/flutter_multi_formatter.dart';

var someNumericValue = 123456;
print(someNumericValue.toCurrencyString(leadingSymbol: MoneySymbols.DOLLAR_SIGN)); // $123,456.00

var someNumericStringValue = '123456';
print(someNumericStringValue.toCurrencyString(trailingSymbol: MoneySymbols.EURO_SIGN)); // 123,456.00€
Unfocuser()

Unfocuser allows you to unfocus any text input and hide the onscreen keyboard when you tap outside of a text input. Use it like this:

@override
Widget build(BuildContext context) {
return Unfocuser(
    child: Scaffold(
    body: SingleChildScrollView(
        child: Padding(
        padding: const EdgeInsets.all(30.0),
        child: Form(
            key: _formKey,
            child: Column(
            children: <Widget>[
                TextFormField(
                keyboardType: TextInputType.phone,
                inputFormatters: [
                    PhoneInputFormatter()
                ],
                ),
            ],
            ),
        ),
        ),
    ),
    ),
);
}

More detailed description

PhoneInputFormatter()

Automatically detects the country the phone number belongs to and formats the number according to its mask. You don't have to care about keeping track of the list of countries or anything else. The whole process is completely automated. You simply add this formatter to the list of formatters like this:

TextFormField(
    keyboardType: TextInputType.phone,
    inputFormatters: [
        PhoneInputFormatter()
    ],
),

You can also get a country data for the selected phone number by simply passing a callback function to your formatter.

TextFormField(
    keyboardType: TextInputType.phone,
    inputFormatters: [
        PhoneInputFormatter(onCountrySelected:  (PhoneCountryData countryData) {
            print(countryData.country);
        });
    ],
),
CreditCardNumberInputFormatter()

CreditCardNumberInputFormatter automatically detects a type of a card based on a predefined list of card system and formats the number accordingly. This detection is pretty rough and may not work with many card system. All supported systems are available as string constants in

class CardSystem {
  static const String VISA = 'Visa';
  static const String MASTERCARD = 'Mastercard';
  static const String JCB = 'JCB';
  static const String DISCOVER = 'Discover';
  static const String MAESTRO = 'Maestro';
  static const String AMERICAN_EXPRESS= 'Amex';
}

Anyway, if the number is not supported it will just be returned as it is and your input will not break because of that

TextFormField(
    keyboardType: TextInputType.number,
    inputFormatters: [
        CreditCardNumberInputFormatter(onCardSystemSelected:  (CardSystemData cardSystemData) {
            print(cardSystemData.system);
        });
    ],
),

/// there's also a method to format a number as a card number
/// the method is located in a credit_card_number_input_formatter.dart file
String formatAsCardNumber(
String cardNumber, {
    bool useSeparators = true,
});

/// and a method to check is a card is valid
bool isCardValidNumber(String cardNumber);
/// but it will return true only if the card system is supported, 
/// so you should not really rely on that

Masked formatter

MaskedInputFormatter()

This formatter allows you to easily format a text by a mask This formatter processes current text selection very carefully so that input does not feel unnatural Use it like any other formatters

/// # matches any character and 0 matches digits
/// so, in order to format a string like this GHJ45GHJHN to GHJ-45-GHJHN
/// use a mask like this
TextFormField(
    keyboardType: TextInputType.phone,
    inputFormatters: [
        MaskedInputFormatter('###-00-#####')
    ],
),

But in case you want # (hash symbol) to match only some particular values, you can pass a regular expression to [anyCharMatcher] parameter

/// in this scenario, the # symbol will only match uppercase latin letters
TextFormField(
    keyboardType: TextInputType.phone,
    inputFormatters: [
        MaskedInputFormatter('###-00-#####', anyCharMatcher: RegExp(r'[A-Z]'))
    ],
),

Money Input formatter

MoneyInputFormatter()
TextFormField(
    keyboardType: TextInputType.number,
    inputFormatters: [
        MoneyInputFormatter(
            leadingSymbol: MoneySymbols.DOLLAR_SIGN
        )
    ],
),
...

TextFormField(
    keyboardType: TextInputType.number,
    inputFormatters: [
        MoneyInputFormatter(
            trailingSymbol: MoneySymbols.EURO_SIGN,
            useSymbolPadding: true,
            mantissaLength: 3 // the length of the fractional side
        )
    ],
),

Point of Sale input formatter

PosInputFormatter

Allows you to enter numbers like you would normally do on a sales terminal

TextFormField(
    keyboardType: TextInputType.number,
    inputFormatters: [
        PosInputFormatter(),
    ],
),
...


For more details see [example](https://github.com/caseyryan/flutter_multi_formatter/tree/master/example) project. And feel free to open an issue if you find any bugs of errors
Comments
  • fixing

    fixing "-" error in maskedInputFormatter

    In the current version, this code is not working correctly:

    return [MaskedInputFormatter('00/00/0000', allowedCharMatcher: RegExp(r'[0-9]')];

    Im able to write: "07/07/2--2, because the regex used by "isDigit" allows "-".

    Now, in this pull request, the user is able to do this:

    return [MaskedInputFormatter('00/00/0000', allowedCharMatcher: RegExp(r'[0-9]'), allowOnlyPositiveNumbers: true)];

    Then, im not allow to write "-" in my masks anymore.

    opened by PauloMolarinho 10
  • CurrencyInputFormatter automatically appends zeros

    CurrencyInputFormatter automatically appends zeros

    Upgraded from MoneyInputFormatter to CurrencyInput formatter, and discovered this issue:

    When the user enters a value into a field using CurrencyInputFormatter, the field automatically adds the decimal place and two zeros. Further input by the user does not change the field.

    Example: User wants to enter in 3.45. When they enter "3" the field changes to 3.00, and when they enter 4, nothing changes. They have to select into the string after the decimal place to enter in values.

    Using version 2.9.11

    opened by banderberg 9
  • Decimal inserted despite mantissaLength: 0

    Decimal inserted despite mantissaLength: 0

    Trying to display 400000 as $400,000.

    However, the following, print(400000.toCurrencyString(mantissaLength: 0, leadingSymbol: MoneySymbols.DOLLAR_SIGN, trailingSymbol: '')); displays as $400,000., displaying a period after the value.

    In a prior release, this wasn't happening (I just updated from 2.0.2) How do I avoid the . from being displayed? Or is this the expected behavior?

    Flutter (Channel stable, 3.3.8)

    Thank you!

    opened by ericbenwa 8
  • Currency input formatter empty value error

    Currency input formatter empty value error

    when i erase my currency value it becomes 0 and then if i type new numbers to that input field it doesn't erase the zero and leaves it at the start of the text

    opened by Sancene 8
  • Phone format while typing doesn't work Flutter stable 2.0.1

    Phone format while typing doesn't work Flutter stable 2.0.1

    Just got the flutter stable branch 2.0.1. The example app doesn't work for phone format while typing. Try to get the flutter team to merge the fix into stable.

    opened by sgehrman 8
  • Hungary phone mask incorrect

    Hungary phone mask incorrect

    Hey!

    I discovered a phone mask mismatch. The correct hungarian mask is +00 00 000 0000, so one more digit in the end (Current mask is +00 00 000 000). Everything else is correct.

    opened by Szabocsongi576 7
  • Using onValueChange, if you submit the number after pressing

    Using onValueChange, if you submit the number after pressing ".", it adds two 0s to the number before the "."

    Maybe this only happens in my specific case. If it wasn't clear in the title here is a more detailed explanation:

    On an app I'm creating, the user inputs a number (like € 20.00). If that user only taps the "2" + "0", the number will be "€ 20.00" which works.

    And if the user submits (I'm saving the onValueChange to a variable, and then the submit button calls a function that uses that variable to store it on the UI) that, it will work.

    However, if the user taps the "2" + "0" and then the ".", the displayed number on the UI textfield is still "€ 20.00". HOWEVER, if you submit after that (after tapping the "."), the number will be stored as "2000.00".

    Very strange, I wish I knew how to fix it but I'm quite a noob, to be honest. Dart is the language I know best and I don't know that much, this is my first app. Let me know if you need any more info, love this package!

    opened by pedez 7
  • If value loaded to TextFormField via

    If value loaded to TextFormField via "initialValue" property, formatting is not working

    I pass via "InitialValue" string '4141554455667898', or '0222', and it's not formatted. But when I trigger TextForm manually (add or delete symbol) formatting starts working. Please fix, your library is very useful

    Screenshot 2021-12-20 at 18 19 05

    opened by booooohdan 6
  • Fix _lastValue bug in formatEditUpdate

    Fix _lastValue bug in formatEditUpdate

    Before: If we type something into a TextField with disabled allowEndlessPhone after a phone number is filled and then try to get its value using PhoneInputFormatter masked on unmasked property we will get incorrect value with an excess digit. After the fix: all working as expected.

    opened by rodion-m 6
  • Invalid format on erase

    Invalid format on erase

    Using MoneyInputFormatter, if you remove a character with backspace key, it result easily to an invalid format input.

    For instance with 1 235€, if I backspace on the 3, it shows 1 25€.

    opened by Nico04 6
  • Unfocuser has a bug: recklicking in an already focused text field.

    Unfocuser has a bug: recklicking in an already focused text field.

    Hi,

    I tried to use your unfocouser for a website. If I click into a text filed. It get's focused. If I click into a white area next to it, it get's unfocused. But If I click again into a already focused textfield, it get's also unfocused. User did not expect that. Example use case: Open the website, oh, I need to copy and paste something in this text field. Click in it. Switch the window and copy something. Return and click again into the already selected text field. Press Ctrl V. Nothing get's pasted because the text field is now defocused.

    opened by Wissperwind 5
  • toCurrencyString() format negative amount incorrectly

    toCurrencyString() format negative amount incorrectly

    When using toCurrencyString() to format negative amount, an extra separator is appended in front.

    Version: ^2.10.0

    Expected behavior: Should produce -888.00 instead of -,888.00.

    Example to reproduce:

    import 'package:flutter/material.dart';
    import 'package:flutter_multi_formatter/flutter_multi_formatter.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        final positiveString = toCurrencyString(
          '888',
          mantissaLength: 2,
        );
        final negativeString = toCurrencyString(
          '-888',
          mantissaLength: 2,
        );
    
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(primarySwatch: Colors.blue),
          home: Scaffold(
            body: Center(
              child: Text('Positive: $positiveString\nNegative: $negativeString'),
            ),
          ),
        );
      }
    }
    

    Current Result: Screenshot_1672805071

    opened by yosemiteyss 0
Releases(2.9.0)
  • 2.9.0(Oct 31, 2022)

    • Added more pinyin utils + HanziUtils
    • Added to utility methods for currencies isCryptoCurrency(String currencyId) and isFiatCurrency(String currencyId)
    Source code(tar.gz)
    Source code(zip)
  • 2.7.4(Sep 15, 2022)

    • Removed "borderRadius" parameter from CountryDropdown to make it compatible with some older Flutter versions
    • Fixed https://github.com/caseyryan/flutter_multi_formatter/issues/92
    Source code(tar.gz)
    Source code(zip)
  • 2.6.1(Aug 20, 2022)

  • 2.5.4(May 19, 2022)

    • Added more card systems support
    • CreditCardCvvInputFormatter now accepts isAmericaExpress value if it's true, it will accept 4 digits, else 3 https://github.com/caseyryan/flutter_multi_formatter/issues/76
    • Merged flutter lint changes https://github.com/caseyryan/flutter_multi_formatter/pull/81
    • Rewritten MaskedInputFormatter. Now it's more robust and correct https://github.com/caseyryan/flutter_multi_formatter/issues/73
    Source code(tar.gz)
    Source code(zip)
  • 2.5.1(Dec 16, 2021)

  • 2.4.4(Dec 13, 2021)

    • https://github.com/caseyryan/flutter_multi_formatter/issues/68 fixed a typo in README section
    • Added alternative mask for Australean phone numbers
    • Added a correct phone mask for United Arab Emirates
    Source code(tar.gz)
    Source code(zip)
  • 2.4.0(Sep 30, 2021)

    Fixed https://github.com/caseyryan/flutter_multi_formatter/issues/61 Fixed orphan leading period formatting in strings like $.5. Now they are formatted correctly to $0.5, not $500.00

    Source code(tar.gz)
    Source code(zip)
  • 2.3.8(Sep 18, 2021)

  • 2.3.7(Sep 18, 2021)

    Fixed https://github.com/caseyryan/flutter_multi_formatter/issues/59 Fixed https://github.com/caseyryan/flutter_multi_formatter/issues/60

    Source code(tar.gz)
    Source code(zip)
  • 2.3.5(Aug 29, 2021)

    • Added correct Hungarian phone masks: +00 0 000 0000 for Budapest and +00 00 000 0000 for all other numbers. Hungarian phones now also support alternative country code +06 as well as +36
    • Changed the logic of MaskedInputFormatter. Now it can format the value correctly on erasing as well as on entering. BREAKING CHANGES: MaskedInputFormatter#applyMask() now returns FormattedValue object instead of String. To get a string value out of it simply call its .toString() method
    Source code(tar.gz)
    Source code(zip)
  • 2.3.3(Aug 11, 2021)

  • 2.3.2(Jul 24, 2021)

  • 2.3.1(Jul 6, 2021)

  • 2.3.0(Jul 6, 2021)

  • 2.2.1(Jul 5, 2021)

  • 2.2.0(Jun 5, 2021)

    BUG FIXES in MoneyInputFormatter Fixed a bug with ThousandSeparator.None described here https://github.com/caseyryan/flutter_multi_formatter/issues/50 Fixed a bug with wrong selection after several spaces have been added as thousand separators. The caret might have gone after the mantissa Fixed a bug that allowed to enter somthing like $02,500.00 where leading zero must not have beed allowed

    Source code(tar.gz)
    Source code(zip)
  • 2.1.3(May 26, 2021)

  • 2.1.2(May 26, 2021)

    Changed Kazakhstan phone code to 7 (which is correct) Fixed MaskedInputFormatter applyMask (merged this pull request https://github.com/caseyryan/flutter_multi_formatter/pull/46)

    Source code(tar.gz)
    Source code(zip)
  • 2.1.0(May 15, 2021)

  • 2.0.3(Apr 26, 2021)

    Added a support for Russian national payment system "МИР" (it's read as MEER, and literally means "The World" but it also means "Peace", this is just for those who are curious :) ) the number of the card is formatted just like Visa or Mastercard but it has a differen system code

    Source code(tar.gz)
    Source code(zip)
Owner
Konstantin Serov
Senior Flutter developer passionate for cool complex modern UI designs
Konstantin Serov
This project aims to basically listing crypto market prices and set alarms.

trader This project aims to basically listing crypto market prices and set alarms. Also, it is starting point of Flutter with GetX state management. B

Görkem Sarı 2 Oct 31, 2021
Quiver is a set of utility libraries for Dart that makes using many Dart libraries easier and more convenient, or adds additional functionality.

Quiver is a set of utility libraries for Dart that makes using many Dart libraries easier and more convenient, or adds additional functionality.

Google 905 Jan 2, 2023
🔥FlutterFire is a set of Flutter plugins that enable Flutter apps to use Firebase services.

FlutterFire is a set of Flutter plugins that enable Flutter apps to use Firebase services. You can follow an example that shows how to use these plugins in the Firebase for Flutter codelab.

null 7.4k Jan 2, 2023
A set of commands for coverage info files manipulation.

Coverage Utils A set of commands for coverage info files manipulation. Installing $ dart pub global activate

Karlo Verde 22 Oct 9, 2022
Rows lint contains a set of lint rules for dart projects used by projects at Rows GmbH

Rows lint contains a set of lint rules for dart projects used by projects at Rows GmbH

rows 6 Apr 12, 2022
🚀The Flutter dart code generator from zeplin. ex) Container, Text, Color, TextStyle, ... - Save your time.

Flutter Gen Zeplin Extension ?? The Flutter dart code generator from zeplin. ex) Container, Text, Color, TextStyle, ... - Save your time. ⬇ 1.1k Getti

NAVER 49 Oct 12, 2022
An Android app to encrypt plain text notes

AndSafe AndSafe is an Android app that encrypts plain text notes. With version 3, AndSafe3 is re-implemented with Flutter and is now open source. FAQ

Clarence K.C. Ho 4 Jul 9, 2022
With this package you can display numbers or any other text more nicely

flutter_number_animation With this package you can display numbers or any other text more nicely Preview Works with text too! How to use Add this to y

idan ben shimon 8 Jun 7, 2022
The Dart Time Machine is a date and time library for Flutter, Web, and Server with support for timezones, calendars, cultures, formatting and parsing.

The Dart Time Machine is a date and time library for Flutter, Web, and Server with support for timezones, calendars, cultures, formatting and parsing.

null 2 Oct 8, 2021
Library for help you make userbot or bot telegram and support tdlib telegram database and only support nodejs dart and google-apps-script

To-Do telegram client dart ✅️ support multi token ( bot / userbot ) ✅️ support bot and userbot ✅️ support telegram-bot-api local server ✅️ support tel

Azka Full Snack Developer:) 73 Jan 7, 2023
Get Version - Get the Version Name, Version Code, Platform and OS Version, and App ID on iOS and Android. Maintainer: @rodydavis

Get Version - Get the Version Name, Version Code, Platform and OS Version, and App ID on iOS and Android.

Flutter Community 87 Jan 4, 2023
An android application built using Flutter that computes the Body Mass Index of person and suggestion to carry ,by taking Inputs (Weight, Height, and Age), Built using Flutter

BMI Calculator ?? Our Goal The objective of this tutorial is to look at how we can customise Flutter Widgets to achieve our own beautiful user interfa

dev_allauddin 7 Nov 2, 2022
Converts SVG icons to OTF font and generates Flutter-compatible class. Provides an API and a CLI tool.

Fontify The Fontify package provides an easy way to convert SVG icons to OpenType font and generate Flutter-compatible class that contains identifiers

Igor Kharakhordin 88 Oct 28, 2022
A flutter package provides controllers and editors for complex models and lists

This package provides controllers and editors for complex models and lists and is inspired by simplicity of TextEditingController. It encapsulates sta

null 2 Sep 1, 2022
Collects screen sizes and pixel densities for real iPhones, iPads, Google phones, Samsung phones, and more.

Device Sizes This package aggregates screen sizes and pixel densities for as many physical devices as possible. The purpose of this package is to help

Matt Carroll 16 Jan 8, 2023
A dart package to help you parse and evaluate infix mathematical expressions into their prefix and postfix notations.

A dart package to help you parse and evaluate infix mathematical expressions into their prefix and postfix notations.

Miguel Manjarres 2 Jan 28, 2022
Args simple - A simple argument parser and handler, integrated with JSON and dart

args_simple A simple argument parser and handler, integrated with JSON and dart:

Graciliano Monteiro Passos 1 Jan 22, 2022
Fluro is a Flutter routing library that adds flexible routing options like wildcards, named parameters and clear route definitions.

Fluro is a Flutter routing library that adds flexible routing options like wildcards, named parameters and clear route definitions.

Luke Pighetti 3.5k Jan 4, 2023