AngularJS Formatted Input Fields

currency percentage phone

by Amy L

HTML

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=PT+Sans+Narrow:400,700#.css">
<div ng-controller="MyController">
     <h1>Formatted fields. Try 'em out.</h1>
     
     <h2>Mock Form</h2>
     
     <form name="moneyForm">
        <quick-input>
            <input field id="accountBalance" title="Balance" ng-model="account.balance" format="currency" />
        </quick-input>
        <quick-input>
            <input field id="accountPercent" title="Percentage" ng-model="account.percentage" format="percent" />
        </quick-input>
        <quick-input>
            <input field id="accountPhone" title="Phone" ng-model="account.phone" format="phone" />
        </quick-input>
        <quick-input>
            <select field id="accountManager" title="Manager" ng-model="account.manager" ng-options="m.name as m.name for m in managers">
                <option value>Choose a Manager</option>
            </select>
        </quick-input>
        <div class="form-actions">
            <button ng-disabled="moneyForm.$invalid">Save</button> <a href="#0">Cancel</a>
        </div>
    </form>
    <h2>The resulting model value:</h2>
    
    <p>
      <pre>{{account | json}}</pre>
    </p>
</div>

CSS

* {
    box-sizing:border-box;
}
:focus {
    outline: 0;
    box-shadow: 0 0 1em -.333em #369;
}
html {
    font-size: 1em;
}
body {
    background-color: white;
    font-family:'PT Sans Narrow', serif;
    font-weight: 400;
    line-height: 1.45;
    color: #333;
    padding: 0 1.414em;
}
p, input, select, ul {
    margin-bottom: 1.3em;
}
h1, h2, h3, h4 {
    margin: 1.414em 0 0.5em;
    font-weight: inherit;
    line-height: 1.2;
}
h1 {
    margin-top: 0;
    font-size: 3.157em;
}
h2 {
    font-size: 2.369em;
}
h3 {
    font-size: 1.777em;
}
h4 {
    font-size: 1.333em;
}
small {
    font-size: 0.75em;
}
label {
    display: block;
    font-size: 1.333em;
}
input, button, select {
    border:1px solid #aaa;
    padding:.666em;
}
.error {
    color: red;
}
button {
    background: #E3E3E3;
    cursor: pointer;
}
button:hover {
    background: #f5f5f5;
    box-shadow: 0 0 1.777em -.333em #369;
}
:disabled {
    cursor:not-allowed;
}
button + a {
    padding-left: 1.333em;
}
.ng-touched.ng-invalid {
    border:1px solid red;
    box-shadow: 0 0 1.333em -.5em red;
    outline:0;
}
select {
    -webkit-appearance:none;
    padding-right: 1.777em;
    border-radius: 0;
    background: url("data:image/png;base64,R0lGODlhDwAUAIABAAAAAP///yH5BAEAAAEALAAAAAAPABQAAAIXjI+py+0Po5wH2HsXzmw//lHiSJZmUAAAOw==") 98% 50% no-repeat;
}
input, select {
    background-color:#fff;
    width:17em;
}

JavaScript

'use strict';

angular.module('app', [])
    .controller('MyController', function ($scope) {
    $scope.managers = [{
        name: 'John'
    }, {
        name: 'Susie'
    }];
    $scope.account = {
        balance: -456,
        percentage: 12,
        phone: 1234567890
    };
}).constant('formatFactory', {
    currency: {
        pattern: /^[\(\-\+]?\d*,?\d*\.?\d+[\)]?$/,
        patternError: 'This field must be formatted as Currency.<br/>A sample valid input looks like: 1000.00',
        replace: /[,\$]/g,
        symbol: '$'
    },
    percent: {
        pattern: /^\d+(\.\d+)?$/,
        patternError: 'The value you entered is not a valid percentage.',
        replace: /[,%]/g,
        symbol: '%'
    },
    phone: {
        pattern: /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/,
        patternError: 'This field must be formatted as a Phone Number.<br/>A sample valid input looks like 123-456-7890',
        replace: /[-\.\(\)\sa-zA-Z]/g
    }
})
    .filter('percent', function () {
    return function (input) {
        if (!input || isNaN(input)) {
            return;
        } else {
            return input + '%';
        }
    };
})
    .filter('phone', function () {
    'use strict';

    return function (input, parens, separator) {
        var out,
        arrOut,
        i;

        if (!input) {
            return;
        } else {
            if (!isNaN(input)) {
                input = input.toString();
            }
            separator = separator || '-';
            input = input.replace(' ', '');
            input = input.replace('(', '');
            input = input.replace(')', '');
            input = input.replace('.', '');

            arrOut = input.split('');

            // Loop through the array and remove anything that's NaN
            for (i = 0; i < arrOut.length; i++) {
                if (isNaN(parseInt(arrOut[i], 10))) {
                    arrOut.splice(i, 1);
                }
            }

            // Put all the...