├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── bower.json
├── dist
├── angular-keypad.css
├── angular-keypad.js
├── angular-keypad.js.map
├── angular-keypad.min.css
├── angular-keypad.min.js
└── angular-keypad.min.js.map
├── karma.conf.js
├── package.json
├── src
├── angular-keypad.scss
├── backspace.svg
├── index.js
├── keypad.controller.js
├── keypad.controller.spec.js
├── keypad.directive.js
├── keypad.provider.js
├── submit.svg
└── templates
│ ├── backspace-left.html
│ ├── backspace-right.html
│ ├── keypad.html
│ ├── submit-left.html
│ └── submit-right.html
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015"],
3 | "plugins": ["babel-plugin-add-module-exports"]
4 | }
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | webpack.config.js
2 | package.json
3 | bower.json
4 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./node_modules/eslint-config-moment/index.js",
3 |
4 | "plugins": ["angular"],
5 |
6 | "ecmaFeatures": {
7 | "globalReturn": true,
8 | "jsx": true,
9 | "modules": true
10 | },
11 |
12 | "env": {
13 | "browser": true,
14 | "es6": true,
15 | "node": true
16 | },
17 |
18 | "globals": {
19 | "document": false,
20 | "escape": false,
21 | "navigator": false,
22 | "unescape": false,
23 | "window": false,
24 | "describe": true,
25 | "before": true,
26 | "it": true,
27 | "expect": true,
28 | "sinon": true,
29 | "angular": true
30 | },
31 |
32 | "parser": "babel-eslint",
33 |
34 | "rules": {
35 | // Needed for angular
36 | "no-use-before-define": 0,
37 | // Needed for angular
38 | "no-unused-vars": 0,
39 | "angular/log": 0,
40 | // Disabled this since we uses classes for services
41 | // http://www.michaelbromley.co.uk/blog/350/exploring-es6-classes-in-angularjs-1-x%20nice
42 | "angular/no-service-method": 0
43 | }
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Directory for instrumented libs generated by jscoverage/JSCover
11 | lib-cov
12 |
13 | # Coverage directory used by tools like istanbul
14 | coverage
15 | .coveralls.yml
16 |
17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
18 | .grunt
19 |
20 | # node-waf configuration
21 | .lock-wscript
22 |
23 | # Compiled binary addons (http://nodejs.org/api/addons.html)
24 | build/Release
25 |
26 | # Dependency directory
27 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
28 | node_modules
29 | bower_components
30 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, gender identity and expression, level of experience,
9 | nationality, personal appearance, race, religion, or sexual identity and
10 | orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at ben@benjamincharity.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at [http://contributor-covenant.org/version/1/4][version]
72 |
73 | [homepage]: http://contributor-covenant.org
74 | [version]: http://contributor-covenant.org/version/1/4/
75 |
76 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Benjamin Charity
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # angular-keypad
2 |
3 |
4 |
5 | [![MIT License][license_image]][license_url] [![Coverage Status][coveralls_badge]][coveralls_link] [![NPM version][npm_version_image]][npm_url]
6 |
7 | :iphone::1234: An Angular directive that creates a numeric keypad.
8 |
9 | > [:tv: **All Demos**][demo_collection]
10 |
11 | _[Comments and Pull Requests welcome!][issues]_
12 |
13 | ## Contents
14 |
15 | - [Installation](#installation)
16 | - [Dependencies](#dependencies)
17 | - [Usage](#usage)
18 | - [Directive](#directive)
19 | - [Attributes](#attributes)
20 | - [`bc-number-model`](#bc-number-model)
21 | - [`bc-max-length`](#bc-max-length)
22 | - [`bc-right-button`](#bc-right-button)
23 | - [`bc-left-button`](#bc-left-button)
24 | - [Custom Methods](#custom-methods)
25 | - [`bc-right-button-method`](#bc-right-button-method)
26 | - [`bc-left-button-method`](#bc-left-button-method)
27 | - [`bc-empty-backspace-method`](#bc-empty-backspace-method)
28 | - [Plug'n'Play Buttons](#plug-n-play-buttons)
29 | - [`bcKeypadConfigProvider`](#bckeypadconfigprovider)
30 | - [`setBackspaceTemplate`](#setbackspacetemplate)
31 | - [`setSubmitTemplate`](#setsubmittemplate)
32 | - [`setMaxLength`](#setmaxlength)
33 | - [Styles](#styles)
34 | - [angular-ripple](#angular-ripple)
35 | - [Development](#development)
36 |
37 |
38 |
39 | ---
40 |
41 |
42 | ## Installation
43 |
44 | #### NPM
45 |
46 | ```bash
47 | npm install angular-keypad --save
48 | ```
49 |
50 | #### Bower
51 |
52 | ```bash
53 | bower install angular-keypad --save
54 | ```
55 |
56 | #### Manually
57 |
58 | Add the script and styles to your HTML:
59 |
60 | ```html
61 |
62 |
63 | ```
64 |
65 |
66 | ## Dependencies
67 |
68 | - Angular.js (>=1.4.0)
69 |
70 |
71 | ## Usage
72 |
73 | Include `bc.AngularKeypad` as a dependency in your project:
74 |
75 | ```javascript
76 | angular.module('YourModule', ['bc.AngularKeypad']);
77 | ```
78 |
79 | Use the directive anywhere in your HTML. The keypad will expand to fill the width of it's container
80 | while maintaining the aspect ratio of the keypad buttons.
81 |
82 | ```html
83 |
84 | {{ vm.numbers }}
85 |
86 |
87 |
88 | ```
89 |
90 | > [:tv: Simple demo][demo_basic]
91 |
92 | #### `bc-number-model`
93 |
94 | **Required**: `String`
95 |
96 | The directive will store the current string of numbers here. This is the **only** required
97 | attribute.
98 |
99 | ```html
100 |
101 | ```
102 |
103 | #### `bc-max-length`
104 |
105 | **Optional**: `Integer`
106 |
107 | The directive will use this number to set a hard limit on how many characters are allowed in the
108 | number model (`vm.numbers` in the example below).
109 |
110 | > [:tv: Demo for `max-length`][demo_length]
111 |
112 | ```html
113 |
114 |
118 | ```
119 |
120 | #### `bc-left-button`
121 |
122 | **Optional**: `String`
123 |
124 | You can define a custom [Plug'n'Play button](#plug-n-play-buttons) type by passing in the name of
125 | any [valid (PnP) button](#availablepnpbuttontypes).
126 |
127 | > [:tv: Demo for Plug'n'Play button types with custom methods][demo_pnp_with_methods]
128 |
129 | ```html
130 |
131 |
135 | ```
136 |
137 | #### `bc-right-button`
138 |
139 | **Optional**: `String`
140 |
141 | You can define a custom [Plug'n'Play button](#plug-n-play-buttons) type by passing in the name of
142 | any [valid (PnP) button](#availablepnpbuttontypes).
143 |
144 | > [:tv: Demo for Plug'n'Play button types with custom methods][demo_pnp_with_methods]
145 |
146 | ```html
147 |
148 |
152 | ```
153 |
154 |
155 | ### Custom Methods
156 |
157 | #### `bc-left-button-method`
158 |
159 | **Optional**: `method`
160 |
161 | You can pass in a custom method that will be called each time the button is interacted with. This
162 | allows you to track interaction or handle custom validation in your controller.
163 |
164 | ##### Available Parameters:
165 |
166 | | Param | Type | Details |
167 | |-------|------|---------|
168 | | `$event` | Object | The original [event object][angular_event] from the `ng-click` |
169 | | `numbers` | String | The current value of [`bc-number-model`](#bc-number-model) |
170 |
171 | > [:tv: Demo for Plug'n'Play button types with custom methods][demo_pnp_with_methods]
172 |
173 | ```html
174 |
175 |
180 | ```
181 |
182 | ```javascript
183 | export class YourController {
184 |
185 | constructor() {
186 | this.numbers = '';
187 | }
188 |
189 | // I will be called each time the left (backspace) button is interacted with
190 | doSomething($event, numbers) {
191 | console.log('The backspace button on the left was clicked!');
192 | console.log('Original click event object: ', $event);
193 | console.log('Current number model value: ', numbers);
194 | }
195 |
196 | }
197 | ```
198 |
199 |
200 | #### `bc-right-button-method`
201 |
202 | **Optional**: `method`
203 |
204 | You can pass in a custom method that will be called each time the button is interacted with. This
205 | allows you to track interaction or handle custom validation in your controller.
206 |
207 | ##### Available Parameters:
208 |
209 | | Param | Type | Details |
210 | |-------|------|---------|
211 | | `$event` | Object | The original [event object][angular_event] from the `ng-click` |
212 | | `numbers` | String | The current value of [`bc-number-model`](#bc-number-model) |
213 |
214 | > [:tv: Demo for Plug'n'Play button types with custom methods][demo_pnp_with_methods]
215 |
216 | ```html
217 |
218 |
223 | ```
224 |
225 | ```javascript
226 | export class YourController {
227 |
228 | constructor() {
229 | this.numbers = '';
230 | }
231 |
232 | // I will be called each time the right (submit) button is interacted with
233 | doSomething($event, numbers) {
234 | console.log('The submit button on the right was clicked!');
235 | console.log('Original click event object: ', $event);
236 | console.log('Current number model value: ', numbers);
237 | }
238 |
239 | }
240 | ```
241 |
242 |
243 | #### `bc-empty-backspace-method`
244 |
245 | **Optional**: `method`
246 |
247 | You can pass in a custom method that will be called when the [backspace](#backspace) button is
248 | interacted with **and** [`bc-number-model`](#bc-number-model) is already empty. This can be useful
249 | for allowing users to step backwards through a multi-part form.
250 |
251 | > [:tv: Demo for bc-empty-backspace-method][demo_backspace_empty]
252 |
253 | ```html
254 |
259 | ```
260 |
261 | ```javascript
262 | export class YourController {
263 |
264 | constructor() {
265 | this.numbers = '';
266 | }
267 |
268 | // I will be called when the backspace button is clicked and the numbers
269 | // model is empty
270 | backspaceWhenEmpty() {
271 | console.log('Backspace clicked, but "vm.numbers" is empty!');
272 | }
273 |
274 | }
275 | ```
276 |
277 |
278 |
279 | ## Plug'n'Play Buttons
280 |
281 |
282 |
283 | This directive now supports Plug'n'Play (PnP) button types to the
284 | left and right of the final digit. These button types can be used on either side (or both if you
285 | really wanted to).
286 |
287 | > [:tv: Demo for Plug'n'Play button types with custom methods][demo_pnp_with_methods]
288 |
289 | ##### Available (PnP) Button Types
290 |
291 | - [backspace](#backspace)
292 | - [submit](#submit)
293 |
294 | Even when using a (PnP) button, any defined [custom
295 | methods](#custom-methods) will still be called.
296 |
297 | Any (PnP) button template can be overwritten using methods exposed
298 | via the [provider](#bckeypadconfigprovider).
299 |
300 | ---
301 |
302 | ```html
303 |
304 |
310 | ```
311 |
312 |
313 | ### Backspace
314 |
315 | ```html
316 |
317 |
321 | ```
322 |
323 | This will create a backspace button with styles and functionality already wired together.
324 |
325 | #### Functionality
326 |
327 | Each time a backspace button instance is interacted with, the last number will be removed from
328 | [`bc-number-model`](#bc-number-model).
329 |
330 | If a custom method was passed to [`bc-empty-backspace-method`](#bc-empty-backspace-method) it will
331 | be called when the backspace button is interacted with **and** [`bc-number-model`](#bc-number-model)
332 | is already empty. This can be useful for allowing users to step backwards through a multi-part form.
333 |
334 | Any defined [custom methods](#custom-methods) will still be called.
335 |
336 | #### Style
337 |
338 | By default the button is using a raw SVG version of [`ion-backspace-outline`][ionicons_backspace]
339 | from [ionicons][ionicons] since this allows you to customize the SVG styles with your project's CSS.
340 |
341 | > [:tv: Demo for custom button CSS][demo_custom_theme]
342 |
343 | ![Ionicons backspace icon][backspace]
344 |
345 | A special class is added to the backspace button which can be used to target specific styles:
346 |
347 | ```scss
348 | .bc-keypad__key-button--backspace {
349 | fill: #DE1E7E;
350 | }
351 | ```
352 |
353 |
354 | ### Submit
355 |
356 | ```html
357 |
361 | ```
362 |
363 | This is a purely aesthetic (PnP) button type. No functionality is
364 | attached, but any defined [custom methods](#custom-methods) will still be called.
365 |
366 | #### Style
367 |
368 | By default the button is using a raw SVG version of [`ion-log-in`][ionicons_submit] from
369 | [ionicons][ionicons] since this allows you to customize the SVG styles with your project's CSS.
370 |
371 | > [:tv: Demo for custom button CSS][demo_custom_theme]
372 |
373 | ![Ionicons submit icon][submit]
374 |
375 | A special class is added to the submit button which can be used to target specific styles:
376 |
377 | ```scss
378 | .bc-keypad__key-button--submit {
379 | fill: #101CA7;
380 | }
381 | ```
382 |
383 |
384 | ## `bcKeypadConfigProvider`
385 |
386 | This module exposes `bcKeypadConfigProvider` which can be used to set custom defaults for the
387 | directive. Setting options here will overwrite the directive's default options for all instances
388 | within your module.
389 |
390 | > [:tv: Demo for `bcKeypadConfigProvider`][demo_provider]
391 |
392 | ```javascript
393 | // ES6 Config Example
394 | export function config(bcKeypadConfigProvider) {
395 | 'ngInject';
396 |
397 | // Set a default of '7' for the max length of all keypads within your module
398 | bcKeypadConfigProvider.setMaxLength(7);
399 |
400 | }
401 |
402 | // ES5 Config Example
403 | angular.module('myModule')
404 | .config((bcKeypadConfigProvider) => {
405 | 'ngInject';
406 |
407 | bcKeypadConfigProvider.setMaxLength(7);
408 |
409 | })
410 | ;
411 | ```
412 |
413 |
414 | ### `setBackspaceTemplate`
415 |
416 | This allows you to specify a custom template for the [backspace](#backspace) key.
417 |
418 | By default it is using a raw SVG version of [`ion-backspace-outline`][ionicons_backspace] from
419 | [ionicons][ionicons] since this allows you to overwrite the SVG styles with CSS.
420 |
421 | > [:tv: Demo for `bcKeypadConfigProvider`][demo_provider]
422 |
423 | ![Ionicons backspace icon][backspace]
424 |
425 | ```javascript
426 | bcKeypadConfigProvider.setBackspaceTemplate('↩ ');
427 | ```
428 |
429 | ### `setSubmitTemplate`
430 |
431 | This allows you to specify a custom template for the [submit](#submit) key.
432 |
433 | By default it is using a raw SVG version of [`ion-log-in`][ionicons_submit] from
434 | [ionicons][ionicons] since this allows you to overwrite the SVG styles with CSS.
435 |
436 | > [:tv: Demo for `bcKeypadConfigProvider`][demo_provider]
437 |
438 | ![Ionicons log in icon][submit]
439 |
440 | ```javascript
441 | bcKeypadConfigProvider.setSubmitTemplate('Go');
442 | ```
443 |
444 | ### `setMaxLength`
445 |
446 | The directive will use this number to impose a hard limit on how many characters the model can hold.
447 | This is useful for specific data items such as a phone number:
448 |
449 | > [:tv: Demo for `bcKeypadConfigProvider`][demo_provider]
450 |
451 | ![max-length demo][max_length_gif]
452 |
453 | ```javascript
454 | bcKeypadConfigProvider.setMaxLength(10);
455 | ```
456 |
457 |
458 | ## Styles
459 |
460 | The included styles are 99% layout with _just_ enough style to work out of the box. The true
461 | styles should be written at your project level using the associated classes.
462 |
463 | Your project CSS should always be included after any library CSS files. This makes it easy for you
464 | to override or add to any styles defined by this module. Below are the classes available for
465 | styling.
466 |
467 | | Class | Element | Details |
468 | |-------|---------|---------|
469 | | `.bc-keypad` | `` | Primary container (`
`) around the keypad. |
470 | | `.bc-keypad__key` | `
` | Individual wrapper for each key. |
471 | | `.bc-keypad__key--left` | `
` | Target the **left** customizable key. |
472 | | `.bc-keypad__key--center` | `
` | Target the last number key (between the two customizable keys). |
473 | | `.bc-keypad__key--right` | `
` | Target the **right** customizable key. |
474 | | `.bc-keypad__key-button` | `
` | The button inside each key. |
475 | | `.bc-keypad__key-button--backspace` | `` | Target the [backspace key](#backspace) (if used) |
476 | | `.bc-keypad__key-button--submit` | `` | Target the [submit key](#submit) (if used) |
477 |
478 | > [:tv: Demo for custom theming][demo_custom_theme]
479 |
480 | ## angular-ripple
481 |
482 | The `bc-keypad` directive was written primarily for mobile so it supports the [Google Material
483 | 'ripple' style feedback][material_ripple] via a module called [angular-ripple][angular_ripple]. As
484 | not everyone may want that style of interaction, this project does not automatically install the
485 | `angular-ripple` library, but is however built to support it out of the box.
486 |
487 | > [:tv: Demo for `angular-ripple` integration][demo_ripple]
488 |
489 | Just install the `angular-ripple` library:
490 |
491 | ```bash
492 | $ npm install nelsoncash/angular-ripple --save
493 | # or
494 | $ bower install angular-ripple --save
495 | ```
496 |
497 | Include it as a dependency in your primary project:
498 |
499 | ```javascript
500 | angular.module('YourModule', ['bc.AngularKeypad', 'angularRipple']);
501 | ```
502 |
503 | And you should see it working!
504 |
505 | - [angular-ripple][angular_ripple]: The `angular-ripple` library.
506 | - [KL-Moment/angular-ripple][angular_ripple_fork]: A custom fork of `angular-ripple` library with
507 | better mobile support.
508 |
509 |
510 | ## Development
511 |
512 | - `npm run build` - Build JS/CSS/HTML/SVG
513 | - `npm run build:js` - Build JS
514 | - `npm run build:css` - Build CSS
515 | - `npm run watch:css` - Watch CSS and rebuild on change
516 | - `npm run watch:js` - Watch JS/HTML and rebuild on change
517 | - `npm run watch` - Watch JS/CSS/HTML and rebuild on change
518 |
519 |
520 |
521 |
522 | [issues]: https://github.com/benjamincharity/angular-keypad/issues
523 | [angular_ripple]: https://github.com/nelsoncash/angular-ripple
524 | [angular_ripple_fork]: https://github.com/KL-Moment/angular-ripple
525 | [ripple_changes]: https://github.com/KL-Moment/angular-ripple/commit/09374947e6cc986ebe7e2629b48edb0885ca842b
526 | [backspace]: http://cdn.benjamincharity.com/codepen/angular-keypad/backspace.svg
527 | [submit]: http://cdn.benjamincharity.com/open_source/angular-keypad/log-in.svg
528 | [ionicons]: http://ionicons.com/
529 | [ionicons_backspace]: https://github.com/driftyco/ionicons/blob/master/src/backspace-outline.svg
530 | [ionicons_submit]: https://github.com/driftyco/ionicons/blob/master/src/log-in.svg
531 | [max_length_gif]: http://cdn.benjamincharity.com/codepen/angular-keypad/rippleDemo.gif
532 | [angular_event]: https://docs.angularjs.org/guide/expression#-event-
533 | [material_ripple]: https://material.google.com/motion/material-motion.html#material-motion-how-does-material-move
534 |
535 | [demo_basic]: https://codepen.io/benjamincharity/pen/dpdpNo?editors=0010
536 | [demo_length]: http://codepen.io/benjamincharity/pen/EgQgKr?editors=0010
537 | [demo_ripple]: https://codepen.io/benjamincharity/pen/ozExBZ?editors=0010
538 | [demo_pnp_with_methods]: https://codepen.io/benjamincharity/pen/VKQjZV?editors=0010
539 | [demo_backspace_empty]: http://codepen.io/benjamincharity/pen/WGrGpr?editors=0010
540 | [demo_provider]: https://codepen.io/benjamincharity/pen/YGZGPX?editors=0010
541 | [demo_custom_theme]: https://codepen.io/benjamincharity/pen/mAXPzz?editors=0010
542 | [demo_collection]: https://codepen.io/collection/DkEqLr/
543 |
544 | [coveralls_badge]: https://coveralls.io/repos/github/benjamincharity/angular-keypad/badge.svg?branch=master
545 | [coveralls_link]: https://coveralls.io/github/benjamincharity/angular-keypad?branch=master
546 | [license_image]: http://img.shields.io/badge/license-MIT-blue.svg
547 | [license_url]: LICENSE
548 | [npm_url]: https://npmjs.org/package/angular-keypad
549 | [npm_version_image]: http://img.shields.io/npm/v/angular-keypad.svg
550 |
551 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-keypad",
3 | "description": "An Angular directive that creates a numeric keypad.",
4 | "homepage": "https://github.com/benjamincharity/angular-keypad",
5 | "authors": [
6 | "Benjamin Charity "
7 | ],
8 | "license": "MIT",
9 | "main": [
10 | "dist/angular-keypad.js",
11 | "dist/angular-keypad.css"
12 | ],
13 | "keywords": [
14 | "angular",
15 | "keypad",
16 | "numeric",
17 | "keyboard",
18 | "numberpad",
19 | "numbers"
20 | ],
21 | "dependencies": {
22 | "angular": ">=1.4.0"
23 | },
24 | "ignore": [
25 | "**/.*",
26 | "src",
27 | "node_modules",
28 | "package.json",
29 | "webpack.config.js"
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/dist/angular-keypad.css:
--------------------------------------------------------------------------------
1 | .bc-keypad {
2 | display: -webkit-box;
3 | display: -ms-flexbox;
4 | display: flex;
5 | -ms-flex-flow: row wrap;
6 | flex-flow: row wrap;
7 | overflow: hidden;
8 | padding-bottom: .375em;
9 | text-align: center;
10 | }
11 |
12 | @-webkit-keyframes ripple {
13 | 100% {
14 | opacity: 0;
15 | -webkit-transform: scale(2.5);
16 | transform: scale(2.5);
17 | }
18 | }
19 |
20 | @keyframes ripple {
21 | 100% {
22 | opacity: 0;
23 | -webkit-transform: scale(2.5);
24 | transform: scale(2.5);
25 | }
26 | }
27 |
28 | .bc-keypad .angular-ripple {
29 | background-color: rgba(0, 0, 0, 0.1);
30 | border-radius: 50%;
31 | display: block;
32 | position: absolute;
33 | -webkit-transform: scale(0);
34 | transform: scale(0);
35 | }
36 |
37 | .bc-keypad .angular-ripple.animate {
38 | -webkit-animation: ripple .3s linear;
39 | animation: ripple .3s linear;
40 | }
41 |
42 | .bc-keypad__key {
43 | position: relative;
44 | text-align: center;
45 | width: calc(100% / 3);
46 | }
47 |
48 | .bc-keypad__key::before {
49 | display: block;
50 | content: '';
51 | padding-top: 50%;
52 | width: 100%;
53 | }
54 |
55 | .bc-keypad__key-button {
56 | background: none;
57 | background-color: transparent;
58 | border: 0;
59 | color: inherit;
60 | cursor: pointer;
61 | font-size: 1.4rem;
62 | line-height: 1.5em;
63 | outline: 0;
64 | padding: 2%;
65 | position: absolute;
66 | bottom: 0;
67 | left: 0;
68 | right: 0;
69 | top: 0;
70 | text-align: center;
71 | width: 100%;
72 | }
73 |
74 | .bc-keypad__key-button:focus {
75 | outline: 0;
76 | }
77 |
78 | .bc-keypad__key-button::after {
79 | background-color: #ccc;
80 | content: '';
81 | display: block;
82 | height: 1px;
83 | position: absolute;
84 | left: 10%;
85 | right: 10%;
86 | bottom: 0;
87 | }
88 |
89 | .bc-keypad__key-button svg {
90 | height: 44px;
91 | position: absolute;
92 | left: 50%;
93 | top: 50%;
94 | -webkit-transform: translate(-50%, -50%);
95 | transform: translate(-50%, -50%);
96 | width: 50px;
97 | }
98 |
99 | .bc-keypad__key-button--icon {
100 | background-size: 50%;
101 | background-position: 45% 50%;
102 | background-repeat: no-repeat;
103 | border: 0;
104 | position: relative;
105 | }
106 |
107 | .bc-keypad__key-button--backspace {
108 | fill: inherit;
109 | }
110 |
111 | .bc-keypad__key-button--submit {
112 | fill: inherit;
113 | }
114 |
115 | .bc-keypad [angular-ripple] {
116 | overflow: hidden;
117 | position: relative;
118 | }
119 |
120 | .bc-keypad [angular-ripple].bc-keypad__key-button {
121 | position: absolute;
122 | }
123 |
--------------------------------------------------------------------------------
/dist/angular-keypad.js:
--------------------------------------------------------------------------------
1 | (function webpackUniversalModuleDefinition(root, factory) {
2 | if(typeof exports === 'object' && typeof module === 'object')
3 | module.exports = factory();
4 | else if(typeof define === 'function' && define.amd)
5 | define("angular-keypad", [], factory);
6 | else if(typeof exports === 'object')
7 | exports["angular-keypad"] = factory();
8 | else
9 | root["angular-keypad"] = factory();
10 | })(this, function() {
11 | return /******/ (function(modules) { // webpackBootstrap
12 | /******/ // The module cache
13 | /******/ var installedModules = {};
14 | /******/
15 | /******/ // The require function
16 | /******/ function __webpack_require__(moduleId) {
17 | /******/
18 | /******/ // Check if module is in cache
19 | /******/ if(installedModules[moduleId])
20 | /******/ return installedModules[moduleId].exports;
21 | /******/
22 | /******/ // Create a new module (and put it into the cache)
23 | /******/ var module = installedModules[moduleId] = {
24 | /******/ exports: {},
25 | /******/ id: moduleId,
26 | /******/ loaded: false
27 | /******/ };
28 | /******/
29 | /******/ // Execute the module function
30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
31 | /******/
32 | /******/ // Flag the module as loaded
33 | /******/ module.loaded = true;
34 | /******/
35 | /******/ // Return the exports of the module
36 | /******/ return module.exports;
37 | /******/ }
38 | /******/
39 | /******/
40 | /******/ // expose the modules object (__webpack_modules__)
41 | /******/ __webpack_require__.m = modules;
42 | /******/
43 | /******/ // expose the module cache
44 | /******/ __webpack_require__.c = installedModules;
45 | /******/
46 | /******/ // __webpack_public_path__
47 | /******/ __webpack_require__.p = "";
48 | /******/
49 | /******/ // Load entry module and return exports
50 | /******/ return __webpack_require__(0);
51 | /******/ })
52 | /************************************************************************/
53 | /******/ ([
54 | /* 0 */
55 | /***/ function(module, exports, __webpack_require__) {
56 |
57 | 'use strict';
58 |
59 | var _keypad = __webpack_require__(1);
60 |
61 | var _keypad2 = __webpack_require__(4);
62 |
63 | angular.module('bc.AngularKeypad', []).provider('bcKeypadConfig', _keypad.KeypadConfig).directive('bcKeypad', _keypad2.KeypadDirective);
64 |
65 | /***/ },
66 | /* 1 */
67 | /***/ function(module, exports, __webpack_require__) {
68 |
69 | 'use strict';
70 |
71 | Object.defineProperty(exports, "__esModule", {
72 | value: true
73 | });
74 | exports.KeypadConfig = undefined;
75 |
76 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
77 |
78 | var _backspace = __webpack_require__(2);
79 |
80 | var _backspace2 = _interopRequireDefault(_backspace);
81 |
82 | var _submit = __webpack_require__(3);
83 |
84 | var _submit2 = _interopRequireDefault(_submit);
85 |
86 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
87 |
88 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
89 |
90 | var KeypadConfig = exports.KeypadConfig = function () {
91 |
92 | // Define defaults
93 | function KeypadConfig() {
94 | _classCallCheck(this, KeypadConfig);
95 |
96 | this.keypadDefaults = {
97 |
98 | // The array of numbers that makes up the keypad
99 | numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], // eslint-disable-line no-magic-numbers
100 |
101 | // By default there is no max length
102 | // Integer
103 | maxLength: null,
104 |
105 | // Plug'N'Play button types
106 | types: ['backspace', 'submit'],
107 |
108 | backspaceTemplate: _backspace2.default,
109 | submitTemplate: _submit2.default
110 |
111 | };
112 | }
113 |
114 | _createClass(KeypadConfig, [{
115 | key: '$get',
116 | value: function $get() {
117 | return this.keypadDefaults;
118 | }
119 |
120 | /**
121 | * Set a custom backspace button template
122 | * NOTE: $templateCache is not available yet so we save the template and the controller will
123 | * handle overwriting the default template
124 | *
125 | * @param {String} template
126 | */
127 |
128 | }, {
129 | key: 'setBackspaceTemplate',
130 | value: function setBackspaceTemplate(template) {
131 | this.keypadDefaults.customBackspaceTemplate = template;
132 | }
133 |
134 | /**
135 | * Set a custom submit button template
136 | * NOTE: $templateCache is not available yet so we save the template and the controller will
137 | * handle overwriting the default template
138 | *
139 | * @param {String} template
140 | */
141 |
142 | }, {
143 | key: 'setSubmitTemplate',
144 | value: function setSubmitTemplate(template) {
145 | this.keypadDefaults.customSubmitTemplate = template;
146 | }
147 |
148 | /**
149 | * Overwrite the max length
150 | *
151 | * @param {Integer} length
152 | */
153 |
154 | }, {
155 | key: 'setMaxLength',
156 | value: function setMaxLength(length) {
157 | this.keypadDefaults.maxLength = parseInt(length, 10);
158 | }
159 | }]);
160 |
161 | return KeypadConfig;
162 | }();
163 |
164 | /***/ },
165 | /* 2 */
166 | /***/ function(module, exports) {
167 |
168 | var path = '/Users/bc/Code/open-source/angular-keypad/src/backspace.svg';
169 | var html = " delete ";
170 | window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
171 | module.exports = path;
172 |
173 | /***/ },
174 | /* 3 */
175 | /***/ function(module, exports) {
176 |
177 | var path = '/Users/bc/Code/open-source/angular-keypad/src/submit.svg';
178 | var html = " Submit ";
179 | window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
180 | module.exports = path;
181 |
182 | /***/ },
183 | /* 4 */
184 | /***/ function(module, exports, __webpack_require__) {
185 |
186 | 'use strict';
187 |
188 | Object.defineProperty(exports, "__esModule", {
189 | value: true
190 | });
191 | exports.KeypadDirective = KeypadDirective;
192 |
193 | var _keypad = __webpack_require__(5);
194 |
195 | var _keypad2 = __webpack_require__(10);
196 |
197 | var _keypad3 = _interopRequireDefault(_keypad2);
198 |
199 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
200 |
201 | /**
202 | * Creates a keypad
203 | *
204 | * @param {String} numberModel : '77043'
205 | * @param {Integer} maxLength : 10
206 | * @return {Element}
207 | */
208 | function KeypadDirective() {
209 | 'ngInject';
210 |
211 | var directive = {
212 | restrict: 'E',
213 | replace: true,
214 | scope: {},
215 | bindToController: {
216 | bcNumberModel: '=',
217 | bcMaxLength: '@',
218 | bcLeftButton: '@',
219 | bcRightButton: '@',
220 | bcLeftButtonMethod: '&',
221 | bcRightButtonMethod: '&',
222 | bcEmptyBackspaceMethod: '&'
223 | },
224 | templateUrl: _keypad3.default,
225 | controller: _keypad.KeypadController,
226 | controllerAs: 'vm'
227 | };
228 |
229 | return directive;
230 | }
231 |
232 | /***/ },
233 | /* 5 */
234 | /***/ function(module, exports, __webpack_require__) {
235 |
236 | 'use strict';
237 |
238 | Object.defineProperty(exports, "__esModule", {
239 | value: true
240 | });
241 | exports.KeypadController = undefined;
242 |
243 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
244 |
245 | var _backspaceLeft = __webpack_require__(6);
246 |
247 | var _backspaceLeft2 = _interopRequireDefault(_backspaceLeft);
248 |
249 | var _backspaceRight = __webpack_require__(7);
250 |
251 | var _backspaceRight2 = _interopRequireDefault(_backspaceRight);
252 |
253 | var _submitLeft = __webpack_require__(8);
254 |
255 | var _submitLeft2 = _interopRequireDefault(_submitLeft);
256 |
257 | var _submitRight = __webpack_require__(9);
258 |
259 | var _submitRight2 = _interopRequireDefault(_submitRight);
260 |
261 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
262 |
263 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
264 |
265 | var KeypadController = exports.KeypadController = function () {
266 | KeypadController.$inject = ["$rootScope", "$templateCache", "bcKeypadConfig"];
267 | function KeypadController($rootScope, $templateCache, bcKeypadConfig) {
268 | 'ngInject';
269 |
270 | _classCallCheck(this, KeypadController);
271 |
272 | this.$rootScope = $rootScope;
273 | this.$templateCache = $templateCache;
274 | this.bcKeypadConfig = bcKeypadConfig;
275 |
276 | this._activate();
277 | }
278 |
279 | _createClass(KeypadController, [{
280 | key: '_activate',
281 | value: function _activate() {
282 | // If anything other than a string was bound, overwrite with an empty string
283 | if (!angular.isString(this.bcNumberModel)) {
284 | this.bcNumberModel = '';
285 | }
286 |
287 | this.templates = {
288 | backspaceRight: _backspaceRight2.default,
289 | backspaceLeft: _backspaceLeft2.default,
290 | submitRight: _submitRight2.default,
291 | submitLeft: _submitLeft2.default
292 | };
293 |
294 | // The numbers that make up the keypad
295 | this.numbers = this.bcKeypadConfig.numbers.slice();
296 |
297 | // Pull the last number off of the array so that we can inject it outside of the ng-repeat
298 | this.lastNumber = this.numbers.splice(this.numbers.length - 1, 1)[0];
299 |
300 | // Set the max length
301 | this.bcMaxLength = this.bcMaxLength || this.bcKeypadConfig.maxLength;
302 |
303 | this._setCustomTemplates();
304 | }
305 |
306 | /**
307 | * Add the selected number to the number string
308 | *
309 | * @param {String} number
310 | */
311 |
312 | }, {
313 | key: 'setNumber',
314 | value: function setNumber(number) {
315 | // If a max length is defined, verify we have not yet reached it
316 | if (!this.bcMaxLength || this.bcNumberModel.length < this.bcMaxLength) {
317 | this.bcNumberModel += number;
318 | }
319 | }
320 |
321 | /**
322 | * Delete the last number from the number model
323 | */
324 |
325 | }, {
326 | key: 'backspace',
327 | value: function backspace() {
328 | // If at least one number exists
329 | if (this.bcNumberModel.length > 0) {
330 | this.bcNumberModel = this.bcNumberModel.substring(0, this.bcNumberModel.length - 1);
331 | } else {
332 | // If backspace was hit when the model is already empty
333 | this.bcEmptyBackspaceMethod();
334 | }
335 | }
336 |
337 | /**
338 | * Actions for the LEFT button
339 | *
340 | * @param {Object} $event
341 | * @param {String} type
342 | */
343 |
344 | }, {
345 | key: 'leftButtonTrigger',
346 | value: function leftButtonTrigger($event, type) {
347 | if (type && type === 'backspace') {
348 | this.backspace();
349 | }
350 |
351 | // Call the bound method
352 | this.bcLeftButtonMethod({ '$event': $event, 'numbers': this.bcNumberModel });
353 | }
354 |
355 | /**
356 | * Actions for the RIGHT button
357 | *
358 | * @param {Object} $event
359 | * @param {String} type
360 | */
361 |
362 | }, {
363 | key: 'rightButtonTrigger',
364 | value: function rightButtonTrigger($event, type) {
365 | if (type && type === 'backspace') {
366 | this.backspace();
367 | }
368 |
369 | // Call the bound method
370 | this.bcRightButtonMethod({ '$event': $event, 'numbers': this.bcNumberModel });
371 | }
372 |
373 | /**
374 | * Determine the correct template for the left button
375 | *
376 | * @param {String} side
377 | * @return {String} template
378 | */
379 |
380 | }, {
381 | key: 'keyTemplate',
382 | value: function keyTemplate(type, side) {
383 | // If the button type matches one of the plug'n'play types
384 | if (this.bcKeypadConfig.types.indexOf(type) >= 0) {
385 | return this.templates[type + side];
386 | } else {
387 | return;
388 | }
389 | }
390 |
391 | /**
392 | * Overwrite templates if any custom templates were set in the provider
393 | */
394 |
395 | }, {
396 | key: '_setCustomTemplates',
397 | value: function _setCustomTemplates() {
398 |
399 | if (this.bcKeypadConfig.customSubmitTemplate) {
400 | var path = this.bcKeypadConfig.submitTemplate;
401 | this.$templateCache.put(path, this.bcKeypadConfig.customSubmitTemplate);
402 | }
403 |
404 | if (this.bcKeypadConfig.customBackspaceTemplate) {
405 | var _path = this.bcKeypadConfig.backspaceTemplate;
406 | this.$templateCache.put(_path, this.bcKeypadConfig.customBackspaceTemplate);
407 | }
408 | }
409 | }]);
410 |
411 | return KeypadController;
412 | }();
413 |
414 | /***/ },
415 | /* 6 */
416 | /***/ function(module, exports) {
417 |
418 | var path = '/Users/bc/Code/open-source/angular-keypad/src/templates/backspace-left.html';
419 | var html = " ";
420 | window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
421 | module.exports = path;
422 |
423 | /***/ },
424 | /* 7 */
425 | /***/ function(module, exports) {
426 |
427 | var path = '/Users/bc/Code/open-source/angular-keypad/src/templates/backspace-right.html';
428 | var html = " ";
429 | window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
430 | module.exports = path;
431 |
432 | /***/ },
433 | /* 8 */
434 | /***/ function(module, exports) {
435 |
436 | var path = '/Users/bc/Code/open-source/angular-keypad/src/templates/submit-left.html';
437 | var html = " ";
438 | window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
439 | module.exports = path;
440 |
441 | /***/ },
442 | /* 9 */
443 | /***/ function(module, exports) {
444 |
445 | var path = '/Users/bc/Code/open-source/angular-keypad/src/templates/submit-right.html';
446 | var html = " ";
447 | window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
448 | module.exports = path;
449 |
450 | /***/ },
451 | /* 10 */
452 | /***/ function(module, exports) {
453 |
454 | var path = '/Users/bc/Code/open-source/angular-keypad/src/templates/keypad.html';
455 | var html = " {{ ::number }}
{{ ::vm.lastNumber }}
";
456 | window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
457 | module.exports = path;
458 |
459 | /***/ }
460 | /******/ ])
461 | });
462 | ;
463 | //# sourceMappingURL=angular-keypad.js.map
--------------------------------------------------------------------------------
/dist/angular-keypad.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 38f5539e36a988387935","webpack:///./src/index.js","webpack:///./src/index.js?1f39","webpack:///./src/keypad.provider.js","webpack:///./src/keypad.provider.js?72eb","webpack:///./src/backspace.svg","webpack:///./src/submit.svg","webpack:///./src/keypad.directive.js","webpack:///./src/keypad.directive.js?576d","webpack:///./src/keypad.controller.js","webpack:///./src/keypad.controller.js?4dc6","webpack:///./src/templates/backspace-left.html","webpack:///./src/templates/backspace-right.html","webpack:///./src/templates/submit-left.html","webpack:///./src/templates/submit-right.html","webpack:///./src/templates/keypad.html"],"names":["angular","module","provider","directive","KeypadConfig","keypadDefaults","numbers","maxLength","types","backspaceTemplate","submitTemplate","template","customBackspaceTemplate","customSubmitTemplate","length","parseInt","KeypadDirective","restrict","replace","scope","bindToController","bcNumberModel","bcMaxLength","bcLeftButton","bcRightButton","bcLeftButtonMethod","bcRightButtonMethod","bcEmptyBackspaceMethod","templateUrl","controller","controllerAs","$rootScope","$templateCache","bcKeypadConfig","_activate","isString","templates","backspaceRight","backspaceLeft","submitRight","submitLeft","slice","lastNumber","splice","_setCustomTemplates","number","substring","$event","type","backspace","side","indexOf","path","put"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;;ACAA;;AACA;;AAEAA,SAAQC,OAAO,oBAAoB,IAC9BC,SAAS,kBADd,sBAEKC,UAAU,YAFf,0B;;;;;;ACHA;;AAEA,QAAO,eAAe,SAAS,cAAc;KACzC,OAAO;;AAEX,SAAQ,eAAe;;AAEvB,KAAI,eAAe,YAAY,EAAE,SAAS,iBAAiB,QAAQ,OAAO,EAAE,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,EAAE,IAAI,aAAa,MAAM,IAAI,WAAW,aAAa,WAAW,cAAc,OAAO,WAAW,eAAe,MAAM,IAAI,WAAW,YAAY,WAAW,WAAW,MAAM,OAAO,eAAe,QAAQ,WAAW,KAAK,iBAAiB,OAAO,UAAU,aAAa,YAAY,aAAa,EAAE,IAAI,YAAY,iBAAiB,YAAY,WAAW,aAAa,IAAI,aAAa,iBAAiB,aAAa,cAAc,OAAO;;ACPhiB;;ADWA,KAAI,cAAc,uBAAuB;;ACVzC;;ADcA,KAAI,WAAW,uBAAuB;;AAEtC,UAAS,uBAAuB,KAAK,EAAE,OAAO,OAAO,IAAI,aAAa,MAAM,EAAE,SAAS;;AAEvF,UAAS,gBAAgB,UAAU,aAAa,EAAE,IAAI,EAAE,oBAAoB,cAAc,EAAE,MAAM,IAAI,UAAU;;AAEhH,KClBaC,eDkBM,QClBNA,eDkB6B,YAAY;;;KCflD,wBAAc;SAAA;;SAEV,KAAKC,iBAAiB;;;aAGlBC,SAAS,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;;;;aAIrCC,WAAW;;;aAGXC,OAAO,CACH,aACA;;aAGJC;aACAC;;;;;KDqBR,aAAa,cAAc,CAAC;SACxB,KAAK;SACL,OAAO,SAAS,OCbb;aACH,OAAO,KAAKL;;;;;;;;;;;QDwBb;SACC,KAAK;SACL,OAAO,SAAS,qBCfCM,UAAU;aAC3B,KAAKN,eAAeO,0BAA0BD;;;;;;;;;;;QD0B/C;SACC,KAAK;SACL,OAAO,SAAS,kBCjBFA,UAAU;aACxB,KAAKN,eAAeQ,uBAAuBF;;;;;;;;;QD0B5C;SACC,KAAK;SACL,OAAO,SAAS,aCnBPG,QAAQ;aACjB,KAAKT,eAAeE,YAAYQ,SAASD,QAAQ;;;;KDuBrD,OAAO;;;;;;;AE5FX;AACA;AACA,iEAAgE,oBAAoB;AACpF,uB;;;;;;ACHA;AACA;AACA,iEAAgE,oBAAoB;AACpF,uB;;;;;;ACHA;;AAEA,QAAO,eAAe,SAAS,cAAc;KACzC,OAAO;;AAEX,SCKgBE;;AAVhB;;AACA;;ADUA,KAAI,WAAW,uBAAuB;;AAEtC,UAAS,uBAAuB,KAAK,EAAE,OAAO,OAAO,IAAI,aAAa,MAAM,EAAE,SAAS;;;;;;;;;ACHhF,UAASA,kBAAkB;KAC9B;;KAEA,IAAMb,YAAY;SACdc,UAAU;SACVC,SAAS;SACTC,OAAO;SACPC,kBAAkB;aACdC,eAAe;aACfC,aAAa;aACbC,cAAc;aACdC,eAAe;aACfC,oBAAoB;aACpBC,qBAAqB;aACrBC,wBAAwB;;SAE5BC;SACAC;SACAC,cAAc;;;KAGlB,OAAO3B;;;;;;;AC/BX;;AAEA,QAAO,eAAe,SAAS,cAAc;KACzC,OAAO;;AAEX,SAAQ,mBAAmB;;AAE3B,KAAI,eAAe,YAAY,EAAE,SAAS,iBAAiB,QAAQ,OAAO,EAAE,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,EAAE,IAAI,aAAa,MAAM,IAAI,WAAW,aAAa,WAAW,cAAc,OAAO,WAAW,eAAe,MAAM,IAAI,WAAW,YAAY,WAAW,WAAW,MAAM,OAAO,eAAe,QAAQ,WAAW,KAAK,iBAAiB,OAAO,UAAU,aAAa,YAAY,aAAa,EAAE,IAAI,YAAY,iBAAiB,YAAY,WAAW,aAAa,IAAI,aAAa,iBAAiB,aAAa,cAAc,OAAO;;ACPhiB;;ADWA,KAAI,kBAAkB,uBAAuB;;ACV7C;;ADcA,KAAI,mBAAmB,uBAAuB;;ACb9C;;ADiBA,KAAI,eAAe,uBAAuB;;AChB1C;;ADoBA,KAAI,gBAAgB,uBAAuB;;AAE3C,UAAS,uBAAuB,KAAK,EAAE,OAAO,OAAO,IAAI,aAAa,MAAM,EAAE,SAAS;;AAEvF,UAAS,gBAAgB,UAAU,aAAa,EAAE,IAAI,EAAE,oBAAoB,cAAc,EAAE,MAAM,IAAI,UAAU;;;mFAElD;KCtB1D,0BACI4B,YAAYC,gBACZC,gBACF;SACE;;SADF;;SAGE,KAAKF,aAAaA;SAClB,KAAKC,iBAAiBA;SACtB,KAAKC,iBAAiBA;;SAGtB,KAAKC;;;KDwBT,aAAa,kBAAkB,CAAC;SAC5B,KAAK;SACL,OAAO,SAAS,YCnBR;;aAER,IAAI,CAAClC,QAAQmC,SAAS,KAAKd,gBAAgB;iBACvC,KAAKA,gBAAgB;;;aAGzB,KAAKe,YAAY;iBACbC;iBACAC;iBACAC;iBACAC;;;;aAIJ,KAAKlC,UAAU,KAAK2B,eAAe3B,QAAQmC;;;aAG3C,KAAKC,aAAa,KAAKpC,QAAQqC,OAAO,KAAKrC,QAAQQ,SAAS,GAAG,GAAG;;;aAGlE,KAAKQ,cAAc,KAAKA,eAAe,KAAKW,eAAe1B;;aAE3D,KAAKqC;;;;;;;;;QD4BN;SACC,KAAK;SACL,OAAO,SAAS,UCrBVC,QAAQ;;aAEd,IAAI,CAAC,KAAKvB,eAAe,KAAKD,cAAcP,SAAS,KAAKQ,aAAa;iBACnE,KAAKD,iBAAiBwB;;;;;;;;QD6B3B;SACC,KAAK;SACL,OAAO,SAAS,YCvBR;;aAER,IAAI,KAAKxB,cAAcP,SAAS,GAAG;iBAC/B,KAAKO,gBAAgB,KAAKA,cAAcyB,UAAU,GAAG,KAAKzB,cAAcP,SAAS;oBAC9E;;iBAEH,KAAKa;;;;;;;;;;;QDkCV;SACC,KAAK;SACL,OAAO,SAAS,kBCzBFoB,QAAQC,MAAM;aAC5B,IAAIA,QAAQA,SAAS,aAAa;iBAC9B,KAAKC;;;;aAIT,KAAKxB,mBAAmB,EAAE,UAAUsB,QAAQ,WAAW,KAAK1B;;;;;;;;;;QDmC7D;SACC,KAAK;SACL,OAAO,SAAS,mBC3BD0B,QAAQC,MAAM;aAC7B,IAAIA,QAAQA,SAAS,aAAa;iBAC9B,KAAKC;;;;aAIT,KAAKvB,oBAAoB,EAAE,UAAUqB,QAAQ,WAAW,KAAK1B;;;;;;;;;;QDqC9D;SACC,KAAK;SACL,OAAO,SAAS,YC7BR2B,MAAME,MAAM;;aAEpB,IAAI,KAAKjB,eAAezB,MAAM2C,QAAQH,SAAS,GAAG;iBAC9C,OAAO,KAAKZ,UAAUY,OAAOE;oBAC1B;iBACH;;;;;;;;QDqCL;SACC,KAAK;SACL,OAAO,SAAS,sBC/BE;;aAElB,IAAI,KAAKjB,eAAepB,sBAAsB;iBAC1C,IAAMuC,OAAO,KAAKnB,eAAevB;iBACjC,KAAKsB,eAAeqB,IAAID,MAAM,KAAKnB,eAAepB;;;aAGtD,IAAI,KAAKoB,eAAerB,yBAAyB;iBAC7C,IAAMwC,QAAO,KAAKnB,eAAexB;iBACjC,KAAKuB,eAAeqB,IAAID,OAAM,KAAKnB,eAAerB;;;;;KDoC1D,OAAO;;;;;;;AE9KX;AACA;AACA,iEAAgE,oBAAoB;AACpF,uB;;;;;;ACHA;AACA;AACA,iEAAgE,oBAAoB;AACpF,uB;;;;;;ACHA;AACA;AACA,iEAAgE,oBAAoB;AACpF,uB;;;;;;ACHA;AACA;AACA,iEAAgE,oBAAoB;AACpF,uB;;;;;;ACHA;AACA,4NAA2N,YAAY,MAAM,YAAY,6SAA6S,mBAAmB;AACzjB,iEAAgE,oBAAoB;AACpF,uB","file":"angular-keypad.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"angular-keypad\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"angular-keypad\"] = factory();\n\telse\n\t\troot[\"angular-keypad\"] = factory();\n})(this, function() {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 38f5539e36a988387935\n **/","'use strict';\n\nvar _keypad = require('./keypad.provider');\n\nvar _keypad2 = require('./keypad.directive');\n\nangular.module('bc.AngularKeypad', []).provider('bcKeypadConfig', _keypad.KeypadConfig).directive('bcKeypad', _keypad2.KeypadDirective);\n\n\n/** WEBPACK FOOTER **\n ** ./src/index.js\n **/","import { KeypadConfig } from './keypad.provider';\nimport { KeypadDirective } from './keypad.directive';\n\nangular.module('bc.AngularKeypad', [])\n .provider('bcKeypadConfig', KeypadConfig)\n .directive('bcKeypad', KeypadDirective)\n;\n\n\n\n\n/** WEBPACK FOOTER **\n ** ./~/eslint-loader!./src/index.js\n **/","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.KeypadConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _backspace = require('./backspace.svg');\n\nvar _backspace2 = _interopRequireDefault(_backspace);\n\nvar _submit = require('./submit.svg');\n\nvar _submit2 = _interopRequireDefault(_submit);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar KeypadConfig = exports.KeypadConfig = function () {\n\n // Define defaults\n function KeypadConfig() {\n _classCallCheck(this, KeypadConfig);\n\n this.keypadDefaults = {\n\n // The array of numbers that makes up the keypad\n numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], // eslint-disable-line no-magic-numbers\n\n // By default there is no max length\n // Integer\n maxLength: null,\n\n // Plug'N'Play button types\n types: ['backspace', 'submit'],\n\n backspaceTemplate: _backspace2.default,\n submitTemplate: _submit2.default\n\n };\n }\n\n _createClass(KeypadConfig, [{\n key: '$get',\n value: function $get() {\n return this.keypadDefaults;\n }\n\n /**\n * Set a custom backspace button template\n * NOTE: $templateCache is not available yet so we save the template and the controller will\n * handle overwriting the default template\n *\n * @param {String} template\n */\n\n }, {\n key: 'setBackspaceTemplate',\n value: function setBackspaceTemplate(template) {\n this.keypadDefaults.customBackspaceTemplate = template;\n }\n\n /**\n * Set a custom submit button template\n * NOTE: $templateCache is not available yet so we save the template and the controller will\n * handle overwriting the default template\n *\n * @param {String} template\n */\n\n }, {\n key: 'setSubmitTemplate',\n value: function setSubmitTemplate(template) {\n this.keypadDefaults.customSubmitTemplate = template;\n }\n\n /**\n * Overwrite the max length\n *\n * @param {Integer} length\n */\n\n }, {\n key: 'setMaxLength',\n value: function setMaxLength(length) {\n this.keypadDefaults.maxLength = parseInt(length, 10);\n }\n }]);\n\n return KeypadConfig;\n}();\n\n\n/** WEBPACK FOOTER **\n ** ./src/keypad.provider.js\n **/","import backspaceTemplate from './backspace.svg';\nimport submitTemplate from './submit.svg';\n\nexport class KeypadConfig {\n\n // Define defaults\n constructor() {\n\n this.keypadDefaults = {\n\n // The array of numbers that makes up the keypad\n numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], // eslint-disable-line no-magic-numbers\n\n // By default there is no max length\n // Integer\n maxLength: null,\n\n // Plug'N'Play button types\n types: [\n 'backspace',\n 'submit',\n ],\n\n backspaceTemplate: backspaceTemplate,\n submitTemplate: submitTemplate,\n\n };\n\n }\n\n\n\n\n\n $get() {\n return this.keypadDefaults;\n }\n\n\n /**\n * Set a custom backspace button template\n * NOTE: $templateCache is not available yet so we save the template and the controller will\n * handle overwriting the default template\n *\n * @param {String} template\n */\n setBackspaceTemplate(template) {\n this.keypadDefaults.customBackspaceTemplate = template;\n }\n\n\n /**\n * Set a custom submit button template\n * NOTE: $templateCache is not available yet so we save the template and the controller will\n * handle overwriting the default template\n *\n * @param {String} template\n */\n setSubmitTemplate(template) {\n this.keypadDefaults.customSubmitTemplate = template;\n }\n\n\n /**\n * Overwrite the max length\n *\n * @param {Integer} length\n */\n setMaxLength(length) {\n this.keypadDefaults.maxLength = parseInt(length, 10);\n }\n\n\n}\n\n\n\n\n/** WEBPACK FOOTER **\n ** ./~/eslint-loader!./src/keypad.provider.js\n **/","var path = '/Users/bc/Code/open-source/angular-keypad/src/backspace.svg';\nvar html = \" delete \";\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/backspace.svg\n ** module id = 2\n ** module chunks = 0 1\n **/","var path = '/Users/bc/Code/open-source/angular-keypad/src/submit.svg';\nvar html = \" Submit \";\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/submit.svg\n ** module id = 3\n ** module chunks = 0 1\n **/","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.KeypadDirective = KeypadDirective;\n\nvar _keypad = require('./keypad.controller');\n\nvar _keypad2 = require('./templates/keypad.html');\n\nvar _keypad3 = _interopRequireDefault(_keypad2);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Creates a keypad\n *\n * @param {String} numberModel : '77043'\n * @param {Integer} maxLength : 10\n * @return {Element} \n */\nfunction KeypadDirective() {\n 'ngInject';\n\n var directive = {\n restrict: 'E',\n replace: true,\n scope: {},\n bindToController: {\n bcNumberModel: '=',\n bcMaxLength: '@',\n bcLeftButton: '@',\n bcRightButton: '@',\n bcLeftButtonMethod: '&',\n bcRightButtonMethod: '&',\n bcEmptyBackspaceMethod: '&'\n },\n templateUrl: _keypad3.default,\n controller: _keypad.KeypadController,\n controllerAs: 'vm'\n };\n\n return directive;\n}\n\n\n/** WEBPACK FOOTER **\n ** ./src/keypad.directive.js\n **/","import { KeypadController } from './keypad.controller';\nimport template from './templates/keypad.html';\n\n/**\n * Creates a keypad\n *\n * @param {String} numberModel : '77043'\n * @param {Integer} maxLength : 10\n * @return {Element} \n */\nexport function KeypadDirective() {\n 'ngInject';\n\n const directive = {\n restrict: 'E',\n replace: true,\n scope: {},\n bindToController: {\n bcNumberModel: '=',\n bcMaxLength: '@',\n bcLeftButton: '@',\n bcRightButton: '@',\n bcLeftButtonMethod: '&',\n bcRightButtonMethod: '&',\n bcEmptyBackspaceMethod: '&',\n },\n templateUrl: template,\n controller: KeypadController,\n controllerAs: 'vm',\n };\n\n return directive;\n\n}\n\n\n\n\n/** WEBPACK FOOTER **\n ** ./~/eslint-loader!./src/keypad.directive.js\n **/","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.KeypadController = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _backspaceLeft = require('./templates/backspace-left.html');\n\nvar _backspaceLeft2 = _interopRequireDefault(_backspaceLeft);\n\nvar _backspaceRight = require('./templates/backspace-right.html');\n\nvar _backspaceRight2 = _interopRequireDefault(_backspaceRight);\n\nvar _submitLeft = require('./templates/submit-left.html');\n\nvar _submitLeft2 = _interopRequireDefault(_submitLeft);\n\nvar _submitRight = require('./templates/submit-right.html');\n\nvar _submitRight2 = _interopRequireDefault(_submitRight);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar KeypadController = exports.KeypadController = function () {\n function KeypadController($rootScope, $templateCache, bcKeypadConfig) {\n 'ngInject';\n\n _classCallCheck(this, KeypadController);\n\n this.$rootScope = $rootScope;\n this.$templateCache = $templateCache;\n this.bcKeypadConfig = bcKeypadConfig;\n\n this._activate();\n }\n\n _createClass(KeypadController, [{\n key: '_activate',\n value: function _activate() {\n // If anything other than a string was bound, overwrite with an empty string\n if (!angular.isString(this.bcNumberModel)) {\n this.bcNumberModel = '';\n }\n\n this.templates = {\n backspaceRight: _backspaceRight2.default,\n backspaceLeft: _backspaceLeft2.default,\n submitRight: _submitRight2.default,\n submitLeft: _submitLeft2.default\n };\n\n // The numbers that make up the keypad\n this.numbers = this.bcKeypadConfig.numbers.slice();\n\n // Pull the last number off of the array so that we can inject it outside of the ng-repeat\n this.lastNumber = this.numbers.splice(this.numbers.length - 1, 1)[0];\n\n // Set the max length\n this.bcMaxLength = this.bcMaxLength || this.bcKeypadConfig.maxLength;\n\n this._setCustomTemplates();\n }\n\n /**\n * Add the selected number to the number string\n *\n * @param {String} number\n */\n\n }, {\n key: 'setNumber',\n value: function setNumber(number) {\n // If a max length is defined, verify we have not yet reached it\n if (!this.bcMaxLength || this.bcNumberModel.length < this.bcMaxLength) {\n this.bcNumberModel += number;\n }\n }\n\n /**\n * Delete the last number from the number model\n */\n\n }, {\n key: 'backspace',\n value: function backspace() {\n // If at least one number exists\n if (this.bcNumberModel.length > 0) {\n this.bcNumberModel = this.bcNumberModel.substring(0, this.bcNumberModel.length - 1);\n } else {\n // If backspace was hit when the model is already empty\n this.bcEmptyBackspaceMethod();\n }\n }\n\n /**\n * Actions for the LEFT button\n *\n * @param {Object} $event\n * @param {String} type\n */\n\n }, {\n key: 'leftButtonTrigger',\n value: function leftButtonTrigger($event, type) {\n if (type && type === 'backspace') {\n this.backspace();\n }\n\n // Call the bound method\n this.bcLeftButtonMethod({ '$event': $event, 'numbers': this.bcNumberModel });\n }\n\n /**\n * Actions for the RIGHT button\n *\n * @param {Object} $event\n * @param {String} type\n */\n\n }, {\n key: 'rightButtonTrigger',\n value: function rightButtonTrigger($event, type) {\n if (type && type === 'backspace') {\n this.backspace();\n }\n\n // Call the bound method\n this.bcRightButtonMethod({ '$event': $event, 'numbers': this.bcNumberModel });\n }\n\n /**\n * Determine the correct template for the left button\n *\n * @param {String} side\n * @return {String} template\n */\n\n }, {\n key: 'keyTemplate',\n value: function keyTemplate(type, side) {\n // If the button type matches one of the plug'n'play types\n if (this.bcKeypadConfig.types.indexOf(type) >= 0) {\n return this.templates[type + side];\n } else {\n return;\n }\n }\n\n /**\n * Overwrite templates if any custom templates were set in the provider\n */\n\n }, {\n key: '_setCustomTemplates',\n value: function _setCustomTemplates() {\n\n if (this.bcKeypadConfig.customSubmitTemplate) {\n var path = this.bcKeypadConfig.submitTemplate;\n this.$templateCache.put(path, this.bcKeypadConfig.customSubmitTemplate);\n }\n\n if (this.bcKeypadConfig.customBackspaceTemplate) {\n var _path = this.bcKeypadConfig.backspaceTemplate;\n this.$templateCache.put(_path, this.bcKeypadConfig.customBackspaceTemplate);\n }\n }\n }]);\n\n return KeypadController;\n}();\n\n\n/** WEBPACK FOOTER **\n ** ./src/keypad.controller.js\n **/","import backspaceLeftTemplate from './templates/backspace-left.html';\nimport backspaceRightTemplate from './templates/backspace-right.html';\nimport submitLeftTemplate from './templates/submit-left.html';\nimport submitRightTemplate from './templates/submit-right.html';\n\nexport class KeypadController {\n\n constructor(\n $rootScope, $templateCache,\n bcKeypadConfig\n ) {\n 'ngInject';\n\n this.$rootScope = $rootScope;\n this.$templateCache = $templateCache;\n this.bcKeypadConfig = bcKeypadConfig;\n\n\n this._activate();\n\n }\n\n\n\n\n _activate() {\n // If anything other than a string was bound, overwrite with an empty string\n if (!angular.isString(this.bcNumberModel)) {\n this.bcNumberModel = '';\n }\n\n this.templates = {\n backspaceRight: backspaceRightTemplate,\n backspaceLeft: backspaceLeftTemplate,\n submitRight: submitRightTemplate,\n submitLeft: submitLeftTemplate,\n };\n\n // The numbers that make up the keypad\n this.numbers = this.bcKeypadConfig.numbers.slice();\n\n // Pull the last number off of the array so that we can inject it outside of the ng-repeat\n this.lastNumber = this.numbers.splice(this.numbers.length - 1, 1)[0];\n\n // Set the max length\n this.bcMaxLength = this.bcMaxLength || this.bcKeypadConfig.maxLength;\n\n this._setCustomTemplates();\n }\n\n\n /**\n * Add the selected number to the number string\n *\n * @param {String} number\n */\n setNumber(number) {\n // If a max length is defined, verify we have not yet reached it\n if (!this.bcMaxLength || this.bcNumberModel.length < this.bcMaxLength) {\n this.bcNumberModel += number;\n }\n }\n\n\n /**\n * Delete the last number from the number model\n */\n backspace() {\n // If at least one number exists\n if (this.bcNumberModel.length > 0) {\n this.bcNumberModel = this.bcNumberModel.substring(0, this.bcNumberModel.length - 1);\n } else {\n // If backspace was hit when the model is already empty\n this.bcEmptyBackspaceMethod();\n }\n }\n\n\n /**\n * Actions for the LEFT button\n *\n * @param {Object} $event\n * @param {String} type\n */\n leftButtonTrigger($event, type) {\n if (type && type === 'backspace') {\n this.backspace();\n }\n\n // Call the bound method\n this.bcLeftButtonMethod({ '$event': $event, 'numbers': this.bcNumberModel });\n }\n\n\n /**\n * Actions for the RIGHT button\n *\n * @param {Object} $event\n * @param {String} type\n */\n rightButtonTrigger($event, type) {\n if (type && type === 'backspace') {\n this.backspace();\n }\n\n // Call the bound method\n this.bcRightButtonMethod({ '$event': $event, 'numbers': this.bcNumberModel });\n }\n\n\n /**\n * Determine the correct template for the left button\n *\n * @param {String} side\n * @return {String} template\n */\n keyTemplate(type, side) {\n // If the button type matches one of the plug'n'play types\n if (this.bcKeypadConfig.types.indexOf(type) >= 0) {\n return this.templates[type + side];\n } else {\n return;\n }\n }\n\n\n /**\n * Overwrite templates if any custom templates were set in the provider\n */\n _setCustomTemplates() {\n\n if (this.bcKeypadConfig.customSubmitTemplate) {\n const path = this.bcKeypadConfig.submitTemplate;\n this.$templateCache.put(path, this.bcKeypadConfig.customSubmitTemplate);\n }\n\n if (this.bcKeypadConfig.customBackspaceTemplate) {\n const path = this.bcKeypadConfig.backspaceTemplate;\n this.$templateCache.put(path, this.bcKeypadConfig.customBackspaceTemplate);\n }\n\n }\n\n\n}\n\n\n\n\n/** WEBPACK FOOTER **\n ** ./~/eslint-loader!./src/keypad.controller.js\n **/","var path = '/Users/bc/Code/open-source/angular-keypad/src/templates/backspace-left.html';\nvar html = \" \";\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/templates/backspace-left.html\n ** module id = 6\n ** module chunks = 0 1\n **/","var path = '/Users/bc/Code/open-source/angular-keypad/src/templates/backspace-right.html';\nvar html = \" \";\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/templates/backspace-right.html\n ** module id = 7\n ** module chunks = 0 1\n **/","var path = '/Users/bc/Code/open-source/angular-keypad/src/templates/submit-left.html';\nvar html = \" \";\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/templates/submit-left.html\n ** module id = 8\n ** module chunks = 0 1\n **/","var path = '/Users/bc/Code/open-source/angular-keypad/src/templates/submit-right.html';\nvar html = \" \";\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/templates/submit-right.html\n ** module id = 9\n ** module chunks = 0 1\n **/","var path = '/Users/bc/Code/open-source/angular-keypad/src/templates/keypad.html';\nvar html = \" {{ ::number }}
{{ ::vm.lastNumber }}
\";\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/templates/keypad.html\n ** module id = 10\n ** module chunks = 0 1\n **/"],"sourceRoot":""}
--------------------------------------------------------------------------------
/dist/angular-keypad.min.css:
--------------------------------------------------------------------------------
1 | .bc-keypad{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;overflow:hidden;padding-bottom:.375em;text-align:center}@-webkit-keyframes ripple{100%{opacity:0;-webkit-transform:scale(2.5);transform:scale(2.5)}}@keyframes ripple{100%{opacity:0;-webkit-transform:scale(2.5);transform:scale(2.5)}}.bc-keypad .angular-ripple{background-color:rgba(0,0,0,0.1);border-radius:50%;display:block;position:absolute;-webkit-transform:scale(0);transform:scale(0)}.bc-keypad .angular-ripple.animate{-webkit-animation:ripple .3s linear;animation:ripple .3s linear}.bc-keypad__key{position:relative;text-align:center;width:calc(100% / 3)}.bc-keypad__key::before{display:block;content:'';padding-top:50%;width:100%}.bc-keypad__key-button{background:none;background-color:transparent;border:0;color:inherit;cursor:pointer;font-size:1.4rem;line-height:1.5em;outline:0;padding:2%;position:absolute;bottom:0;left:0;right:0;top:0;text-align:center;width:100%}.bc-keypad__key-button:focus{outline:0}.bc-keypad__key-button::after{background-color:#ccc;content:'';display:block;height:1px;position:absolute;left:10%;right:10%;bottom:0}.bc-keypad__key-button svg{height:44px;position:absolute;left:50%;top:50%;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);width:50px}.bc-keypad__key-button--icon{background-size:50%;background-position:45% 50%;background-repeat:no-repeat;border:0;position:relative}.bc-keypad__key-button--backspace{fill:inherit}.bc-keypad__key-button--submit{fill:inherit}.bc-keypad [angular-ripple]{overflow:hidden;position:relative}.bc-keypad [angular-ripple].bc-keypad__key-button{position:absolute}
2 |
--------------------------------------------------------------------------------
/dist/angular-keypad.min.js:
--------------------------------------------------------------------------------
1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("angular-keypad",[],t):"object"==typeof exports?exports["angular-keypad"]=t():e["angular-keypad"]=t()}(this,function(){return function(e){function t(a){if(n[a])return n[a].exports;var c=n[a]={exports:{},id:a,loaded:!1};return e[a].call(c.exports,c,c.exports,t),c.loaded=!0,c.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";var a=n(1),c=n(4);angular.module("bc.AngularKeypad",[]).provider("bcKeypadConfig",a.KeypadConfig).directive("bcKeypad",c.KeypadDirective)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{"default":e}}function c(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0}),t.KeypadConfig=void 0;var u=function(){function e(e,t){for(var n=0;n delete ';window.angular.module("ng").run(["$templateCache",function(e){e.put(n,a)}]),e.exports=n},function(e,t){var n="/Users/bc/Code/open-source/angular-keypad/src/submit.svg",a=' Submit ';window.angular.module("ng").run(["$templateCache",function(e){e.put(n,a)}]),e.exports=n},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{"default":e}}function c(){"ngInject";var e={restrict:"E",replace:!0,scope:{},bindToController:{bcNumberModel:"=",bcMaxLength:"@",bcLeftButton:"@",bcRightButton:"@",bcLeftButtonMethod:"&",bcRightButtonMethod:"&",bcEmptyBackspaceMethod:"&"},templateUrl:o["default"],controller:u.KeypadController,controllerAs:"vm"};return e}Object.defineProperty(t,"__esModule",{value:!0}),t.KeypadDirective=c;var u=n(5),i=n(10),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{"default":e}}function c(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0}),t.KeypadController=void 0;var u=function(){function e(e,t){for(var n=0;n0?this.bcNumberModel=this.bcNumberModel.substring(0,this.bcNumberModel.length-1):this.bcEmptyBackspaceMethod()}},{key:"leftButtonTrigger",value:function(e,t){t&&"backspace"===t&&this.backspace(),this.bcLeftButtonMethod({$event:e,numbers:this.bcNumberModel})}},{key:"rightButtonTrigger",value:function(e,t){t&&"backspace"===t&&this.backspace(),this.bcRightButtonMethod({$event:e,numbers:this.bcNumberModel})}},{key:"keyTemplate",value:function(e,t){return this.bcKeypadConfig.types.indexOf(e)>=0?this.templates[e+t]:void 0}},{key:"_setCustomTemplates",value:function(){if(this.bcKeypadConfig.customSubmitTemplate){var e=this.bcKeypadConfig.submitTemplate;this.$templateCache.put(e,this.bcKeypadConfig.customSubmitTemplate)}if(this.bcKeypadConfig.customBackspaceTemplate){var t=this.bcKeypadConfig.backspaceTemplate;this.$templateCache.put(t,this.bcKeypadConfig.customBackspaceTemplate)}}}]),e}()},function(e,t){var n="/Users/bc/Code/open-source/angular-keypad/src/templates/backspace-left.html",a=' ';window.angular.module("ng").run(["$templateCache",function(e){e.put(n,a)}]),e.exports=n},function(e,t){var n="/Users/bc/Code/open-source/angular-keypad/src/templates/backspace-right.html",a=' ';window.angular.module("ng").run(["$templateCache",function(e){e.put(n,a)}]),e.exports=n},function(e,t){var n="/Users/bc/Code/open-source/angular-keypad/src/templates/submit-left.html",a=' ';window.angular.module("ng").run(["$templateCache",function(e){e.put(n,a)}]),e.exports=n},function(e,t){var n="/Users/bc/Code/open-source/angular-keypad/src/templates/submit-right.html",a=' ';window.angular.module("ng").run(["$templateCache",function(e){e.put(n,a)}]),e.exports=n},function(e,t){var n="/Users/bc/Code/open-source/angular-keypad/src/templates/keypad.html",a=' {{ ::number }}
{{ ::vm.lastNumber }}
';window.angular.module("ng").run(["$templateCache",function(e){e.put(n,a)}]),e.exports=n}])});
2 | //# sourceMappingURL=angular-keypad.min.js.map
--------------------------------------------------------------------------------
/dist/angular-keypad.min.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///webpack/universalModuleDefinition?5ca6","webpack:///angular-keypad.min.js","webpack:///webpack/bootstrap 38f5539e36a988387935?6eab","webpack:///./src/index.js?9552","webpack:///./src/index.js?1f39*","webpack:///./src/keypad.provider.js?01a0","webpack:///./src/keypad.provider.js?72eb*","webpack:///./src/backspace.svg?c07b","webpack:///./src/submit.svg?f383","webpack:///./src/keypad.directive.js?13bc","webpack:///./src/keypad.directive.js?576d*","webpack:///./src/keypad.controller.js?3c91","webpack:///./src/keypad.controller.js?4dc6*","webpack:///./src/templates/backspace-left.html?9748","webpack:///./src/templates/backspace-right.html?4f12","webpack:///./src/templates/submit-left.html?b77f","webpack:///./src/templates/submit-right.html?ab3e","webpack:///./src/templates/keypad.html?d4eb"],"names":["root","factory","exports","module","define","amd","this","modules","__webpack_require__","moduleId","installedModules","id","loaded","call","m","c","p","_keypad","_keypad2","angular","provider","KeypadConfig","directive","KeypadDirective","_interopRequireDefault","obj","__esModule","default","_classCallCheck","instance","Constructor","TypeError","Object","defineProperty","value","undefined","_createClass","defineProperties","target","props","i","length","descriptor","enumerable","configurable","writable","key","protoProps","staticProps","prototype","_backspace","_backspace2","_submit","_submit2","keypadDefaults","numbers","maxLength","types","backspaceTemplate","submitTemplate","template","customBackspaceTemplate","customSubmitTemplate","parseInt","path","html","window","run","put","restrict","replace","scope","bindToController","bcNumberModel","bcMaxLength","bcLeftButton","bcRightButton","bcLeftButtonMethod","bcRightButtonMethod","bcEmptyBackspaceMethod","templateUrl","controller","controllerAs","_keypad3","KeypadController","_backspaceLeft","_backspaceLeft2","_backspaceRight","_backspaceRight2","_submitLeft","_submitLeft2","_submitRight","_submitRight2","$rootScope","$templateCache","bcKeypadConfig","_activate","$inject","isString","templates","backspaceRight","backspaceLeft","submitRight","submitLeft","slice","lastNumber","splice","_setCustomTemplates","number","substring","$event","type","backspace","side","indexOf"],"mappings":"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","file":"angular-keypad.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"angular-keypad\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"angular-keypad\"] = factory();\n\telse\n\t\troot[\"angular-keypad\"] = factory();\n})(this, function() {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/","(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"angular-keypad\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"angular-keypad\"] = factory();\n\telse\n\t\troot[\"angular-keypad\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar _keypad = __webpack_require__(1);\n\t\n\tvar _keypad2 = __webpack_require__(4);\n\t\n\tangular.module('bc.AngularKeypad', []).provider('bcKeypadConfig', _keypad.KeypadConfig).directive('bcKeypad', _keypad2.KeypadDirective);\n\n/***/ },\n/* 1 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.KeypadConfig = undefined;\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\tvar _backspace = __webpack_require__(2);\n\t\n\tvar _backspace2 = _interopRequireDefault(_backspace);\n\t\n\tvar _submit = __webpack_require__(3);\n\t\n\tvar _submit2 = _interopRequireDefault(_submit);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar KeypadConfig = exports.KeypadConfig = function () {\n\t\n\t // Define defaults\n\t function KeypadConfig() {\n\t _classCallCheck(this, KeypadConfig);\n\t\n\t this.keypadDefaults = {\n\t\n\t // The array of numbers that makes up the keypad\n\t numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], // eslint-disable-line no-magic-numbers\n\t\n\t // By default there is no max length\n\t // Integer\n\t maxLength: null,\n\t\n\t // Plug'N'Play button types\n\t types: ['backspace', 'submit'],\n\t\n\t backspaceTemplate: _backspace2.default,\n\t submitTemplate: _submit2.default\n\t\n\t };\n\t }\n\t\n\t _createClass(KeypadConfig, [{\n\t key: '$get',\n\t value: function $get() {\n\t return this.keypadDefaults;\n\t }\n\t\n\t /**\n\t * Set a custom backspace button template\n\t * NOTE: $templateCache is not available yet so we save the template and the controller will\n\t * handle overwriting the default template\n\t *\n\t * @param {String} template\n\t */\n\t\n\t }, {\n\t key: 'setBackspaceTemplate',\n\t value: function setBackspaceTemplate(template) {\n\t this.keypadDefaults.customBackspaceTemplate = template;\n\t }\n\t\n\t /**\n\t * Set a custom submit button template\n\t * NOTE: $templateCache is not available yet so we save the template and the controller will\n\t * handle overwriting the default template\n\t *\n\t * @param {String} template\n\t */\n\t\n\t }, {\n\t key: 'setSubmitTemplate',\n\t value: function setSubmitTemplate(template) {\n\t this.keypadDefaults.customSubmitTemplate = template;\n\t }\n\t\n\t /**\n\t * Overwrite the max length\n\t *\n\t * @param {Integer} length\n\t */\n\t\n\t }, {\n\t key: 'setMaxLength',\n\t value: function setMaxLength(length) {\n\t this.keypadDefaults.maxLength = parseInt(length, 10);\n\t }\n\t }]);\n\t\n\t return KeypadConfig;\n\t}();\n\n/***/ },\n/* 2 */\n/***/ function(module, exports) {\n\n\tvar path = '/Users/bc/Code/open-source/angular-keypad/src/backspace.svg';\n\tvar html = \" delete \";\n\twindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\n\tmodule.exports = path;\n\n/***/ },\n/* 3 */\n/***/ function(module, exports) {\n\n\tvar path = '/Users/bc/Code/open-source/angular-keypad/src/submit.svg';\n\tvar html = \" Submit \";\n\twindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\n\tmodule.exports = path;\n\n/***/ },\n/* 4 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.KeypadDirective = KeypadDirective;\n\t\n\tvar _keypad = __webpack_require__(5);\n\t\n\tvar _keypad2 = __webpack_require__(10);\n\t\n\tvar _keypad3 = _interopRequireDefault(_keypad2);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\t/**\n\t * Creates a keypad\n\t *\n\t * @param {String} numberModel : '77043'\n\t * @param {Integer} maxLength : 10\n\t * @return {Element} \n\t */\n\tfunction KeypadDirective() {\n\t 'ngInject';\n\t\n\t var directive = {\n\t restrict: 'E',\n\t replace: true,\n\t scope: {},\n\t bindToController: {\n\t bcNumberModel: '=',\n\t bcMaxLength: '@',\n\t bcLeftButton: '@',\n\t bcRightButton: '@',\n\t bcLeftButtonMethod: '&',\n\t bcRightButtonMethod: '&',\n\t bcEmptyBackspaceMethod: '&'\n\t },\n\t templateUrl: _keypad3.default,\n\t controller: _keypad.KeypadController,\n\t controllerAs: 'vm'\n\t };\n\t\n\t return directive;\n\t}\n\n/***/ },\n/* 5 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports.KeypadController = undefined;\n\t\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\t\n\tvar _backspaceLeft = __webpack_require__(6);\n\t\n\tvar _backspaceLeft2 = _interopRequireDefault(_backspaceLeft);\n\t\n\tvar _backspaceRight = __webpack_require__(7);\n\t\n\tvar _backspaceRight2 = _interopRequireDefault(_backspaceRight);\n\t\n\tvar _submitLeft = __webpack_require__(8);\n\t\n\tvar _submitLeft2 = _interopRequireDefault(_submitLeft);\n\t\n\tvar _submitRight = __webpack_require__(9);\n\t\n\tvar _submitRight2 = _interopRequireDefault(_submitRight);\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\tvar KeypadController = exports.KeypadController = function () {\n\t KeypadController.$inject = [\"$rootScope\", \"$templateCache\", \"bcKeypadConfig\"];\n\t function KeypadController($rootScope, $templateCache, bcKeypadConfig) {\n\t 'ngInject';\n\t\n\t _classCallCheck(this, KeypadController);\n\t\n\t this.$rootScope = $rootScope;\n\t this.$templateCache = $templateCache;\n\t this.bcKeypadConfig = bcKeypadConfig;\n\t\n\t this._activate();\n\t }\n\t\n\t _createClass(KeypadController, [{\n\t key: '_activate',\n\t value: function _activate() {\n\t // If anything other than a string was bound, overwrite with an empty string\n\t if (!angular.isString(this.bcNumberModel)) {\n\t this.bcNumberModel = '';\n\t }\n\t\n\t this.templates = {\n\t backspaceRight: _backspaceRight2.default,\n\t backspaceLeft: _backspaceLeft2.default,\n\t submitRight: _submitRight2.default,\n\t submitLeft: _submitLeft2.default\n\t };\n\t\n\t // The numbers that make up the keypad\n\t this.numbers = this.bcKeypadConfig.numbers.slice();\n\t\n\t // Pull the last number off of the array so that we can inject it outside of the ng-repeat\n\t this.lastNumber = this.numbers.splice(this.numbers.length - 1, 1)[0];\n\t\n\t // Set the max length\n\t this.bcMaxLength = this.bcMaxLength || this.bcKeypadConfig.maxLength;\n\t\n\t this._setCustomTemplates();\n\t }\n\t\n\t /**\n\t * Add the selected number to the number string\n\t *\n\t * @param {String} number\n\t */\n\t\n\t }, {\n\t key: 'setNumber',\n\t value: function setNumber(number) {\n\t // If a max length is defined, verify we have not yet reached it\n\t if (!this.bcMaxLength || this.bcNumberModel.length < this.bcMaxLength) {\n\t this.bcNumberModel += number;\n\t }\n\t }\n\t\n\t /**\n\t * Delete the last number from the number model\n\t */\n\t\n\t }, {\n\t key: 'backspace',\n\t value: function backspace() {\n\t // If at least one number exists\n\t if (this.bcNumberModel.length > 0) {\n\t this.bcNumberModel = this.bcNumberModel.substring(0, this.bcNumberModel.length - 1);\n\t } else {\n\t // If backspace was hit when the model is already empty\n\t this.bcEmptyBackspaceMethod();\n\t }\n\t }\n\t\n\t /**\n\t * Actions for the LEFT button\n\t *\n\t * @param {Object} $event\n\t * @param {String} type\n\t */\n\t\n\t }, {\n\t key: 'leftButtonTrigger',\n\t value: function leftButtonTrigger($event, type) {\n\t if (type && type === 'backspace') {\n\t this.backspace();\n\t }\n\t\n\t // Call the bound method\n\t this.bcLeftButtonMethod({ '$event': $event, 'numbers': this.bcNumberModel });\n\t }\n\t\n\t /**\n\t * Actions for the RIGHT button\n\t *\n\t * @param {Object} $event\n\t * @param {String} type\n\t */\n\t\n\t }, {\n\t key: 'rightButtonTrigger',\n\t value: function rightButtonTrigger($event, type) {\n\t if (type && type === 'backspace') {\n\t this.backspace();\n\t }\n\t\n\t // Call the bound method\n\t this.bcRightButtonMethod({ '$event': $event, 'numbers': this.bcNumberModel });\n\t }\n\t\n\t /**\n\t * Determine the correct template for the left button\n\t *\n\t * @param {String} side\n\t * @return {String} template\n\t */\n\t\n\t }, {\n\t key: 'keyTemplate',\n\t value: function keyTemplate(type, side) {\n\t // If the button type matches one of the plug'n'play types\n\t if (this.bcKeypadConfig.types.indexOf(type) >= 0) {\n\t return this.templates[type + side];\n\t } else {\n\t return;\n\t }\n\t }\n\t\n\t /**\n\t * Overwrite templates if any custom templates were set in the provider\n\t */\n\t\n\t }, {\n\t key: '_setCustomTemplates',\n\t value: function _setCustomTemplates() {\n\t\n\t if (this.bcKeypadConfig.customSubmitTemplate) {\n\t var path = this.bcKeypadConfig.submitTemplate;\n\t this.$templateCache.put(path, this.bcKeypadConfig.customSubmitTemplate);\n\t }\n\t\n\t if (this.bcKeypadConfig.customBackspaceTemplate) {\n\t var _path = this.bcKeypadConfig.backspaceTemplate;\n\t this.$templateCache.put(_path, this.bcKeypadConfig.customBackspaceTemplate);\n\t }\n\t }\n\t }]);\n\t\n\t return KeypadController;\n\t}();\n\n/***/ },\n/* 6 */\n/***/ function(module, exports) {\n\n\tvar path = '/Users/bc/Code/open-source/angular-keypad/src/templates/backspace-left.html';\n\tvar html = \" \";\n\twindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\n\tmodule.exports = path;\n\n/***/ },\n/* 7 */\n/***/ function(module, exports) {\n\n\tvar path = '/Users/bc/Code/open-source/angular-keypad/src/templates/backspace-right.html';\n\tvar html = \" \";\n\twindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\n\tmodule.exports = path;\n\n/***/ },\n/* 8 */\n/***/ function(module, exports) {\n\n\tvar path = '/Users/bc/Code/open-source/angular-keypad/src/templates/submit-left.html';\n\tvar html = \" \";\n\twindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\n\tmodule.exports = path;\n\n/***/ },\n/* 9 */\n/***/ function(module, exports) {\n\n\tvar path = '/Users/bc/Code/open-source/angular-keypad/src/templates/submit-right.html';\n\tvar html = \" \";\n\twindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\n\tmodule.exports = path;\n\n/***/ },\n/* 10 */\n/***/ function(module, exports) {\n\n\tvar path = '/Users/bc/Code/open-source/angular-keypad/src/templates/keypad.html';\n\tvar html = \" {{ ::number }}
{{ ::vm.lastNumber }}
\";\n\twindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\n\tmodule.exports = path;\n\n/***/ }\n/******/ ])\n});\n;\n\n\n/** WEBPACK FOOTER **\n ** angular-keypad.min.js\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 38f5539e36a988387935\n **/","'use strict';\n\nvar _keypad = require('./keypad.provider');\n\nvar _keypad2 = require('./keypad.directive');\n\nangular.module('bc.AngularKeypad', []).provider('bcKeypadConfig', _keypad.KeypadConfig).directive('bcKeypad', _keypad2.KeypadDirective);\n\n\n/** WEBPACK FOOTER **\n ** ./src/index.js\n **/","import { KeypadConfig } from './keypad.provider';\nimport { KeypadDirective } from './keypad.directive';\n\nangular.module('bc.AngularKeypad', [])\n .provider('bcKeypadConfig', KeypadConfig)\n .directive('bcKeypad', KeypadDirective)\n;\n\n\n\n\n/** WEBPACK FOOTER **\n ** ./~/eslint-loader!./src/index.js\n **/","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.KeypadConfig = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _backspace = require('./backspace.svg');\n\nvar _backspace2 = _interopRequireDefault(_backspace);\n\nvar _submit = require('./submit.svg');\n\nvar _submit2 = _interopRequireDefault(_submit);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar KeypadConfig = exports.KeypadConfig = function () {\n\n // Define defaults\n function KeypadConfig() {\n _classCallCheck(this, KeypadConfig);\n\n this.keypadDefaults = {\n\n // The array of numbers that makes up the keypad\n numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], // eslint-disable-line no-magic-numbers\n\n // By default there is no max length\n // Integer\n maxLength: null,\n\n // Plug'N'Play button types\n types: ['backspace', 'submit'],\n\n backspaceTemplate: _backspace2.default,\n submitTemplate: _submit2.default\n\n };\n }\n\n _createClass(KeypadConfig, [{\n key: '$get',\n value: function $get() {\n return this.keypadDefaults;\n }\n\n /**\n * Set a custom backspace button template\n * NOTE: $templateCache is not available yet so we save the template and the controller will\n * handle overwriting the default template\n *\n * @param {String} template\n */\n\n }, {\n key: 'setBackspaceTemplate',\n value: function setBackspaceTemplate(template) {\n this.keypadDefaults.customBackspaceTemplate = template;\n }\n\n /**\n * Set a custom submit button template\n * NOTE: $templateCache is not available yet so we save the template and the controller will\n * handle overwriting the default template\n *\n * @param {String} template\n */\n\n }, {\n key: 'setSubmitTemplate',\n value: function setSubmitTemplate(template) {\n this.keypadDefaults.customSubmitTemplate = template;\n }\n\n /**\n * Overwrite the max length\n *\n * @param {Integer} length\n */\n\n }, {\n key: 'setMaxLength',\n value: function setMaxLength(length) {\n this.keypadDefaults.maxLength = parseInt(length, 10);\n }\n }]);\n\n return KeypadConfig;\n}();\n\n\n/** WEBPACK FOOTER **\n ** ./src/keypad.provider.js\n **/","import backspaceTemplate from './backspace.svg';\nimport submitTemplate from './submit.svg';\n\nexport class KeypadConfig {\n\n // Define defaults\n constructor() {\n\n this.keypadDefaults = {\n\n // The array of numbers that makes up the keypad\n numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], // eslint-disable-line no-magic-numbers\n\n // By default there is no max length\n // Integer\n maxLength: null,\n\n // Plug'N'Play button types\n types: [\n 'backspace',\n 'submit',\n ],\n\n backspaceTemplate: backspaceTemplate,\n submitTemplate: submitTemplate,\n\n };\n\n }\n\n\n\n\n\n $get() {\n return this.keypadDefaults;\n }\n\n\n /**\n * Set a custom backspace button template\n * NOTE: $templateCache is not available yet so we save the template and the controller will\n * handle overwriting the default template\n *\n * @param {String} template\n */\n setBackspaceTemplate(template) {\n this.keypadDefaults.customBackspaceTemplate = template;\n }\n\n\n /**\n * Set a custom submit button template\n * NOTE: $templateCache is not available yet so we save the template and the controller will\n * handle overwriting the default template\n *\n * @param {String} template\n */\n setSubmitTemplate(template) {\n this.keypadDefaults.customSubmitTemplate = template;\n }\n\n\n /**\n * Overwrite the max length\n *\n * @param {Integer} length\n */\n setMaxLength(length) {\n this.keypadDefaults.maxLength = parseInt(length, 10);\n }\n\n\n}\n\n\n\n\n/** WEBPACK FOOTER **\n ** ./~/eslint-loader!./src/keypad.provider.js\n **/","var path = '/Users/bc/Code/open-source/angular-keypad/src/backspace.svg';\nvar html = \" delete \";\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/backspace.svg\n ** module id = 2\n ** module chunks = 0 1\n **/","var path = '/Users/bc/Code/open-source/angular-keypad/src/submit.svg';\nvar html = \" Submit \";\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/submit.svg\n ** module id = 3\n ** module chunks = 0 1\n **/","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.KeypadDirective = KeypadDirective;\n\nvar _keypad = require('./keypad.controller');\n\nvar _keypad2 = require('./templates/keypad.html');\n\nvar _keypad3 = _interopRequireDefault(_keypad2);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Creates a keypad\n *\n * @param {String} numberModel : '77043'\n * @param {Integer} maxLength : 10\n * @return {Element} \n */\nfunction KeypadDirective() {\n 'ngInject';\n\n var directive = {\n restrict: 'E',\n replace: true,\n scope: {},\n bindToController: {\n bcNumberModel: '=',\n bcMaxLength: '@',\n bcLeftButton: '@',\n bcRightButton: '@',\n bcLeftButtonMethod: '&',\n bcRightButtonMethod: '&',\n bcEmptyBackspaceMethod: '&'\n },\n templateUrl: _keypad3.default,\n controller: _keypad.KeypadController,\n controllerAs: 'vm'\n };\n\n return directive;\n}\n\n\n/** WEBPACK FOOTER **\n ** ./src/keypad.directive.js\n **/","import { KeypadController } from './keypad.controller';\nimport template from './templates/keypad.html';\n\n/**\n * Creates a keypad\n *\n * @param {String} numberModel : '77043'\n * @param {Integer} maxLength : 10\n * @return {Element} \n */\nexport function KeypadDirective() {\n 'ngInject';\n\n const directive = {\n restrict: 'E',\n replace: true,\n scope: {},\n bindToController: {\n bcNumberModel: '=',\n bcMaxLength: '@',\n bcLeftButton: '@',\n bcRightButton: '@',\n bcLeftButtonMethod: '&',\n bcRightButtonMethod: '&',\n bcEmptyBackspaceMethod: '&',\n },\n templateUrl: template,\n controller: KeypadController,\n controllerAs: 'vm',\n };\n\n return directive;\n\n}\n\n\n\n\n/** WEBPACK FOOTER **\n ** ./~/eslint-loader!./src/keypad.directive.js\n **/","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.KeypadController = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _backspaceLeft = require('./templates/backspace-left.html');\n\nvar _backspaceLeft2 = _interopRequireDefault(_backspaceLeft);\n\nvar _backspaceRight = require('./templates/backspace-right.html');\n\nvar _backspaceRight2 = _interopRequireDefault(_backspaceRight);\n\nvar _submitLeft = require('./templates/submit-left.html');\n\nvar _submitLeft2 = _interopRequireDefault(_submitLeft);\n\nvar _submitRight = require('./templates/submit-right.html');\n\nvar _submitRight2 = _interopRequireDefault(_submitRight);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar KeypadController = exports.KeypadController = function () {\n function KeypadController($rootScope, $templateCache, bcKeypadConfig) {\n 'ngInject';\n\n _classCallCheck(this, KeypadController);\n\n this.$rootScope = $rootScope;\n this.$templateCache = $templateCache;\n this.bcKeypadConfig = bcKeypadConfig;\n\n this._activate();\n }\n\n _createClass(KeypadController, [{\n key: '_activate',\n value: function _activate() {\n // If anything other than a string was bound, overwrite with an empty string\n if (!angular.isString(this.bcNumberModel)) {\n this.bcNumberModel = '';\n }\n\n this.templates = {\n backspaceRight: _backspaceRight2.default,\n backspaceLeft: _backspaceLeft2.default,\n submitRight: _submitRight2.default,\n submitLeft: _submitLeft2.default\n };\n\n // The numbers that make up the keypad\n this.numbers = this.bcKeypadConfig.numbers.slice();\n\n // Pull the last number off of the array so that we can inject it outside of the ng-repeat\n this.lastNumber = this.numbers.splice(this.numbers.length - 1, 1)[0];\n\n // Set the max length\n this.bcMaxLength = this.bcMaxLength || this.bcKeypadConfig.maxLength;\n\n this._setCustomTemplates();\n }\n\n /**\n * Add the selected number to the number string\n *\n * @param {String} number\n */\n\n }, {\n key: 'setNumber',\n value: function setNumber(number) {\n // If a max length is defined, verify we have not yet reached it\n if (!this.bcMaxLength || this.bcNumberModel.length < this.bcMaxLength) {\n this.bcNumberModel += number;\n }\n }\n\n /**\n * Delete the last number from the number model\n */\n\n }, {\n key: 'backspace',\n value: function backspace() {\n // If at least one number exists\n if (this.bcNumberModel.length > 0) {\n this.bcNumberModel = this.bcNumberModel.substring(0, this.bcNumberModel.length - 1);\n } else {\n // If backspace was hit when the model is already empty\n this.bcEmptyBackspaceMethod();\n }\n }\n\n /**\n * Actions for the LEFT button\n *\n * @param {Object} $event\n * @param {String} type\n */\n\n }, {\n key: 'leftButtonTrigger',\n value: function leftButtonTrigger($event, type) {\n if (type && type === 'backspace') {\n this.backspace();\n }\n\n // Call the bound method\n this.bcLeftButtonMethod({ '$event': $event, 'numbers': this.bcNumberModel });\n }\n\n /**\n * Actions for the RIGHT button\n *\n * @param {Object} $event\n * @param {String} type\n */\n\n }, {\n key: 'rightButtonTrigger',\n value: function rightButtonTrigger($event, type) {\n if (type && type === 'backspace') {\n this.backspace();\n }\n\n // Call the bound method\n this.bcRightButtonMethod({ '$event': $event, 'numbers': this.bcNumberModel });\n }\n\n /**\n * Determine the correct template for the left button\n *\n * @param {String} side\n * @return {String} template\n */\n\n }, {\n key: 'keyTemplate',\n value: function keyTemplate(type, side) {\n // If the button type matches one of the plug'n'play types\n if (this.bcKeypadConfig.types.indexOf(type) >= 0) {\n return this.templates[type + side];\n } else {\n return;\n }\n }\n\n /**\n * Overwrite templates if any custom templates were set in the provider\n */\n\n }, {\n key: '_setCustomTemplates',\n value: function _setCustomTemplates() {\n\n if (this.bcKeypadConfig.customSubmitTemplate) {\n var path = this.bcKeypadConfig.submitTemplate;\n this.$templateCache.put(path, this.bcKeypadConfig.customSubmitTemplate);\n }\n\n if (this.bcKeypadConfig.customBackspaceTemplate) {\n var _path = this.bcKeypadConfig.backspaceTemplate;\n this.$templateCache.put(_path, this.bcKeypadConfig.customBackspaceTemplate);\n }\n }\n }]);\n\n return KeypadController;\n}();\n\n\n/** WEBPACK FOOTER **\n ** ./src/keypad.controller.js\n **/","import backspaceLeftTemplate from './templates/backspace-left.html';\nimport backspaceRightTemplate from './templates/backspace-right.html';\nimport submitLeftTemplate from './templates/submit-left.html';\nimport submitRightTemplate from './templates/submit-right.html';\n\nexport class KeypadController {\n\n constructor(\n $rootScope, $templateCache,\n bcKeypadConfig\n ) {\n 'ngInject';\n\n this.$rootScope = $rootScope;\n this.$templateCache = $templateCache;\n this.bcKeypadConfig = bcKeypadConfig;\n\n\n this._activate();\n\n }\n\n\n\n\n _activate() {\n // If anything other than a string was bound, overwrite with an empty string\n if (!angular.isString(this.bcNumberModel)) {\n this.bcNumberModel = '';\n }\n\n this.templates = {\n backspaceRight: backspaceRightTemplate,\n backspaceLeft: backspaceLeftTemplate,\n submitRight: submitRightTemplate,\n submitLeft: submitLeftTemplate,\n };\n\n // The numbers that make up the keypad\n this.numbers = this.bcKeypadConfig.numbers.slice();\n\n // Pull the last number off of the array so that we can inject it outside of the ng-repeat\n this.lastNumber = this.numbers.splice(this.numbers.length - 1, 1)[0];\n\n // Set the max length\n this.bcMaxLength = this.bcMaxLength || this.bcKeypadConfig.maxLength;\n\n this._setCustomTemplates();\n }\n\n\n /**\n * Add the selected number to the number string\n *\n * @param {String} number\n */\n setNumber(number) {\n // If a max length is defined, verify we have not yet reached it\n if (!this.bcMaxLength || this.bcNumberModel.length < this.bcMaxLength) {\n this.bcNumberModel += number;\n }\n }\n\n\n /**\n * Delete the last number from the number model\n */\n backspace() {\n // If at least one number exists\n if (this.bcNumberModel.length > 0) {\n this.bcNumberModel = this.bcNumberModel.substring(0, this.bcNumberModel.length - 1);\n } else {\n // If backspace was hit when the model is already empty\n this.bcEmptyBackspaceMethod();\n }\n }\n\n\n /**\n * Actions for the LEFT button\n *\n * @param {Object} $event\n * @param {String} type\n */\n leftButtonTrigger($event, type) {\n if (type && type === 'backspace') {\n this.backspace();\n }\n\n // Call the bound method\n this.bcLeftButtonMethod({ '$event': $event, 'numbers': this.bcNumberModel });\n }\n\n\n /**\n * Actions for the RIGHT button\n *\n * @param {Object} $event\n * @param {String} type\n */\n rightButtonTrigger($event, type) {\n if (type && type === 'backspace') {\n this.backspace();\n }\n\n // Call the bound method\n this.bcRightButtonMethod({ '$event': $event, 'numbers': this.bcNumberModel });\n }\n\n\n /**\n * Determine the correct template for the left button\n *\n * @param {String} side\n * @return {String} template\n */\n keyTemplate(type, side) {\n // If the button type matches one of the plug'n'play types\n if (this.bcKeypadConfig.types.indexOf(type) >= 0) {\n return this.templates[type + side];\n } else {\n return;\n }\n }\n\n\n /**\n * Overwrite templates if any custom templates were set in the provider\n */\n _setCustomTemplates() {\n\n if (this.bcKeypadConfig.customSubmitTemplate) {\n const path = this.bcKeypadConfig.submitTemplate;\n this.$templateCache.put(path, this.bcKeypadConfig.customSubmitTemplate);\n }\n\n if (this.bcKeypadConfig.customBackspaceTemplate) {\n const path = this.bcKeypadConfig.backspaceTemplate;\n this.$templateCache.put(path, this.bcKeypadConfig.customBackspaceTemplate);\n }\n\n }\n\n\n}\n\n\n\n\n/** WEBPACK FOOTER **\n ** ./~/eslint-loader!./src/keypad.controller.js\n **/","var path = '/Users/bc/Code/open-source/angular-keypad/src/templates/backspace-left.html';\nvar html = \" \";\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/templates/backspace-left.html\n ** module id = 6\n ** module chunks = 0 1\n **/","var path = '/Users/bc/Code/open-source/angular-keypad/src/templates/backspace-right.html';\nvar html = \" \";\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/templates/backspace-right.html\n ** module id = 7\n ** module chunks = 0 1\n **/","var path = '/Users/bc/Code/open-source/angular-keypad/src/templates/submit-left.html';\nvar html = \" \";\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/templates/submit-left.html\n ** module id = 8\n ** module chunks = 0 1\n **/","var path = '/Users/bc/Code/open-source/angular-keypad/src/templates/submit-right.html';\nvar html = \" \";\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/templates/submit-right.html\n ** module id = 9\n ** module chunks = 0 1\n **/","var path = '/Users/bc/Code/open-source/angular-keypad/src/templates/keypad.html';\nvar html = \" {{ ::number }}
{{ ::vm.lastNumber }}
\";\nwindow.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);\nmodule.exports = path;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/templates/keypad.html\n ** module id = 10\n ** module chunks = 0 1\n **/"],"sourceRoot":""}
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 | var WebpackConf = require('./webpack.config.js');
3 | WebpackConf.entry = {};
4 | WebpackConf.devtool = 'inline-source-map';
5 |
6 | module.exports = function(config) {
7 | config.set({
8 |
9 | // base path that will be used to resolve all patterns (eg. files, exclude)
10 | basePath: './',
11 |
12 |
13 | // frameworks to use
14 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
15 | frameworks: ['jasmine'],
16 |
17 |
18 | // list of files / patterns to load in the browser
19 | files: [
20 | 'node_modules/angular/angular.js',
21 | 'node_modules/angular-mocks/angular-mocks.js',
22 | 'src/index.js',
23 | 'src/*.spec.js'
24 | ],
25 |
26 |
27 | // list of files to exclude
28 | exclude: [
29 | 'app/node_modules/**/!(angular|moment|angular-mocks).js'
30 | ],
31 |
32 |
33 | // preprocess matching files before serving them to the browser
34 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
35 | preprocessors: {
36 | 'src/!(*.spec).js': ['webpack', 'coverage'],
37 | 'src/*.spec.js': [ 'webpack', 'sourcemap' ]
38 | },
39 |
40 |
41 | webpack: WebpackConf,
42 |
43 |
44 | // Don't spam the browser console
45 | webpackServer: {
46 | noInfo: true
47 | },
48 |
49 |
50 | ngHtml2JsPreprocessor: {
51 | moduleName: 'templates'
52 | },
53 |
54 |
55 | // test results reporter to use
56 | // possible values: 'dots', 'progress'
57 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
58 | reporters: ['spec', 'coverage', 'coveralls'],
59 |
60 |
61 | // web server port
62 | port: 9876,
63 |
64 |
65 | // enable / disable colors in the output (reporters and logs)
66 | colors: true,
67 |
68 |
69 | // level of logging
70 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
71 | logLevel: config.LOG_INFO,
72 |
73 |
74 | // enable / disable watching file and executing tests whenever any file changes
75 | autoWatch: true,
76 |
77 |
78 | // start these browsers
79 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
80 | browsers: ['PhantomJS'],
81 |
82 |
83 | // Continuous Integration mode
84 | // if true, Karma captures browsers, runs the tests and exits
85 | singleRun: false,
86 |
87 | // Concurrency level
88 | // how many browser should be started simultaneous
89 | concurrency: Infinity,
90 |
91 |
92 | // Configure the reporter
93 | coverageReporter: {
94 | type : 'lcov',
95 | dir : 'coverage/',
96 | includeAllSources: true
97 | }
98 | })
99 | }
100 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-keypad",
3 | "version": "2.0.4",
4 | "description": "An Angular directive that creates a numeric keypad.",
5 | "keywords": [
6 | "angular",
7 | "keypad",
8 | "numeric",
9 | "keyboard",
10 | "numberpad",
11 | "numbers"
12 | ],
13 | "author": "Benjamin Charity ",
14 | "license": "MIT",
15 | "bugs": {
16 | "url": "https://github.com/benjamincharity/angular-keypad/issues"
17 | },
18 | "homepage": "https://github.com/benjamincharity/angular-keypad",
19 | "main": "dist/angular-keypad.js",
20 | "scripts": {
21 | "build": "npm run build:js && npm run build:css",
22 | "build:js": "WEBPACK_ENV=build webpack && osx-notifier --type \"pass\" --title \"Build successful\" --message \"gg\" --group \"npmBuild\"",
23 | "build:css": "npm run scss:compressed && npm run scss:expanded && npm run autoprefixer",
24 | "autoprefixer": "postcss -u autoprefixer -r dist/*.css",
25 | "scss:compressed": "node-sass --output-style compressed -o dist/ src && mv dist/angular-keypad.css dist/angular-keypad.min.css",
26 | "scss:expanded": "node-sass --output-style expanded -o dist/ src",
27 | "watch:css": "onchange 'src/*.scss' -- npm run build:css",
28 | "watch:js": "onchange 'src/*.js' 'src/templates/*.html' -- npm run build:js",
29 | "watch": "parallelshell 'npm run watch:css' 'npm run watch:js'",
30 | "test": "karma start --singleRun=true",
31 | "watch:tests": "karma start"
32 | },
33 | "repository": {
34 | "type": "git",
35 | "url": "https://github.com/benjamincharity/angular-keypad.git"
36 | },
37 | "dependencies": {
38 | "angular": "^1.4.0"
39 | },
40 | "devDependencies": {
41 | "angular-mocks": "^1.5.8",
42 | "autoprefixer": "^6.3.3",
43 | "babel": "6.3.13",
44 | "babel-core": "6.1.18",
45 | "babel-eslint": "5.0.0",
46 | "babel-loader": "6.1.0",
47 | "babel-plugin-add-module-exports": "0.1.2",
48 | "babel-preset-es2015": "^6.3.13",
49 | "eslint": "1.7.2",
50 | "eslint-config-moment": "^1.6.7",
51 | "eslint-loader": "1.1.0",
52 | "eslint-plugin-angular": "^1.4.1",
53 | "html-loader": "^0.4.2",
54 | "jasmine": "^2.4.1",
55 | "karma": "^1.1.2",
56 | "karma-chrome-launcher": "^1.0.1",
57 | "karma-coverage": "^1.1.1",
58 | "karma-coveralls": "^1.1.2",
59 | "karma-jasmine": "^1.0.2",
60 | "karma-phantomjs-launcher": "^1.0.1",
61 | "karma-sourcemap-loader": "^0.3.7",
62 | "karma-spec-reporter": "0.0.26",
63 | "karma-webpack": "^1.7.0",
64 | "loader-utils": "^0.2.12",
65 | "minifier": "^0.7.1",
66 | "ng-annotate-loader": "^0.1.0",
67 | "ng-annotate-webpack-plugin": "^0.1.2",
68 | "ngtemplate-loader": "^1.3.1",
69 | "node-sass": "^3.4.2",
70 | "onchange": "^2.2.0",
71 | "osx-notifier": "^0.2.2",
72 | "parallelshell": "^2.0.0",
73 | "phantomjs": "^2.1.7",
74 | "postcss-cli": "^2.5.1",
75 | "sass-loader": "^3.1.2",
76 | "source-map": "^0.5.3",
77 | "webpack": "1.12.9",
78 | "webpack-dev-server": "^1.14.1",
79 | "yargs": "3.32.0"
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/angular-keypad.scss:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | //
4 | // $KEYPAD
5 | //
6 | //
7 | // @author Benjamin Charity
8 | //
9 | // @doc
10 | // Styles for the keypad
11 | // @end
12 |
13 |
14 |
15 |
16 | // primary keypad container
17 | .bc-keypad {
18 | // Define colors
19 | $color_black: #000;
20 | $color_white: #fff;
21 | $color_light_gray: #ccc;
22 |
23 | // Define a nice scale effect animation
24 | @keyframes ripple {
25 | 100% {
26 | opacity: 0;
27 | transform: scale(2.5);
28 | }
29 | }
30 |
31 | display: flex;
32 | flex-flow: row wrap;
33 | overflow: hidden;
34 | padding-bottom: .375em;
35 | text-align: center;
36 |
37 | //
target the span injected by angular-ripple
38 | .angular-ripple {
39 | background-color: rgba($color_black, .1);
40 | border-radius: 50%;
41 | display: block;
42 | position: absolute;
43 | transform: scale(0);
44 |
45 | &.animate {
46 | animation: ripple .3s linear;
47 | }
48 | }
49 |
50 | &__key {
51 | position: relative;
52 | text-align: center;
53 | width: calc(100% / 3);
54 |
55 | &::before {
56 | display: block;
57 | content: '';
58 | padding-top: 50%;
59 | width: 100%;
60 | }
61 |
62 | // number button
63 | &-button {
64 | background: none;
65 | background-color: transparent;
66 | border: 0;
67 | color: inherit;
68 | cursor: pointer;
69 | font-size: 1.4rem;
70 | line-height: 1.5em;
71 | outline: 0;
72 | padding: 2%;
73 | position: absolute;
74 | bottom: 0;
75 | left: 0;
76 | right: 0;
77 | top: 0;
78 | text-align: center;
79 | width: 100%;
80 |
81 | // you should define your own 'active' styles per project
82 | &:focus {
83 | outline: 0;
84 | }
85 |
86 | // create pseudo element for underline
87 | &::after {
88 | background-color: $color_light_gray;
89 | content: '';
90 | display: block;
91 | height: 1px;
92 | position: absolute;
93 | left: 10%;
94 | right: 10%;
95 | // angular-ripple adds overflow: hidden so this cannot be below 0
96 | bottom: 0;
97 | }
98 |
99 | // icon
100 | svg {
101 | height: 44px;
102 | position: absolute;
103 | left: 50%;
104 | top: 50%;
105 | transform: translate(-50%, -50%);
106 | width: 50px;
107 | }
108 |
109 | &--icon {
110 | background-size: 50%;
111 | background-position: 45% 50%;
112 | background-repeat: no-repeat;
113 | border: 0;
114 | position: relative;
115 | }
116 |
117 | // target 'backspace' button
118 | &--backspace {
119 | fill: inherit;
120 | }
121 |
122 | // target 'submit' button
123 | &--submit {
124 | fill: inherit;
125 | }
126 | }
127 | }
128 |
129 |
130 | //
131 | // Angular-Ripple styles
132 | //
133 | // target the parent element (the button/link)
134 | [angular-ripple] {
135 | overflow: hidden;
136 | position: relative;
137 |
138 | &.bc-keypad__key-button {
139 | position: absolute;
140 | }
141 | }
142 |
143 | }
144 |
145 |
146 |
--------------------------------------------------------------------------------
/src/backspace.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 | delete
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import { KeypadConfig } from './keypad.provider';
2 | import { KeypadDirective } from './keypad.directive';
3 |
4 | angular.module('bc.AngularKeypad', [])
5 | .provider('bcKeypadConfig', KeypadConfig)
6 | .directive('bcKeypad', KeypadDirective)
7 | ;
8 |
9 |
--------------------------------------------------------------------------------
/src/keypad.controller.js:
--------------------------------------------------------------------------------
1 | import backspaceLeftTemplate from './templates/backspace-left.html';
2 | import backspaceRightTemplate from './templates/backspace-right.html';
3 | import submitLeftTemplate from './templates/submit-left.html';
4 | import submitRightTemplate from './templates/submit-right.html';
5 |
6 | export class KeypadController {
7 |
8 | constructor(
9 | $rootScope, $templateCache,
10 | bcKeypadConfig
11 | ) {
12 | 'ngInject';
13 |
14 | this.$rootScope = $rootScope;
15 | this.$templateCache = $templateCache;
16 | this.bcKeypadConfig = bcKeypadConfig;
17 |
18 |
19 | this._activate();
20 |
21 | }
22 |
23 |
24 |
25 |
26 | _activate() {
27 | // If anything other than a string was bound, overwrite with an empty string
28 | if (!angular.isString(this.bcNumberModel)) {
29 | this.bcNumberModel = '';
30 | }
31 |
32 | this.templates = {
33 | backspaceRight: backspaceRightTemplate,
34 | backspaceLeft: backspaceLeftTemplate,
35 | submitRight: submitRightTemplate,
36 | submitLeft: submitLeftTemplate,
37 | };
38 |
39 | // The numbers that make up the keypad
40 | this.numbers = this.bcKeypadConfig.numbers.slice();
41 |
42 | // Pull the last number off of the array so that we can inject it outside of the ng-repeat
43 | this.lastNumber = this.numbers.splice(this.numbers.length - 1, 1)[0];
44 |
45 | // Set the max length
46 | this.bcMaxLength = this.bcMaxLength || this.bcKeypadConfig.maxLength;
47 |
48 | this._setCustomTemplates();
49 | }
50 |
51 |
52 | /**
53 | * Add the selected number to the number string
54 | *
55 | * @param {String} number
56 | */
57 | setNumber(number) {
58 | // If a max length is defined, verify we have not yet reached it
59 | if (!this.bcMaxLength || this.bcNumberModel.length < this.bcMaxLength) {
60 | this.bcNumberModel += number;
61 | }
62 | }
63 |
64 |
65 | /**
66 | * Delete the last number from the number model
67 | */
68 | backspace() {
69 | // If at least one number exists
70 | if (this.bcNumberModel.length > 0) {
71 | this.bcNumberModel = this.bcNumberModel.substring(0, this.bcNumberModel.length - 1);
72 | } else {
73 | // If backspace was hit when the model is already empty
74 | this.bcEmptyBackspaceMethod();
75 | }
76 | }
77 |
78 |
79 | /**
80 | * Actions for the LEFT button
81 | *
82 | * @param {Object} $event
83 | * @param {String} type
84 | */
85 | leftButtonTrigger($event, type) {
86 | if (type && type === 'backspace') {
87 | this.backspace();
88 | }
89 |
90 | // Call the bound method
91 | this.bcLeftButtonMethod({ '$event': $event, 'numbers': this.bcNumberModel });
92 | }
93 |
94 |
95 | /**
96 | * Actions for the RIGHT button
97 | *
98 | * @param {Object} $event
99 | * @param {String} type
100 | */
101 | rightButtonTrigger($event, type) {
102 | if (type && type === 'backspace') {
103 | this.backspace();
104 | }
105 |
106 | // Call the bound method
107 | this.bcRightButtonMethod({ '$event': $event, 'numbers': this.bcNumberModel });
108 | }
109 |
110 |
111 | /**
112 | * Determine the correct template for the left button
113 | *
114 | * @param {String} side
115 | * @return {String} template
116 | */
117 | keyTemplate(type, side) {
118 | // If the button type matches one of the plug'n'play types
119 | if (this.bcKeypadConfig.types.indexOf(type) >= 0) {
120 | return this.templates[type + side];
121 | } else {
122 | return;
123 | }
124 | }
125 |
126 |
127 | /**
128 | * Overwrite templates if any custom templates were set in the provider
129 | */
130 | _setCustomTemplates() {
131 |
132 | if (this.bcKeypadConfig.customSubmitTemplate) {
133 | const path = this.bcKeypadConfig.submitTemplate;
134 | this.$templateCache.put(path, this.bcKeypadConfig.customSubmitTemplate);
135 | }
136 |
137 | if (this.bcKeypadConfig.customBackspaceTemplate) {
138 | const path = this.bcKeypadConfig.backspaceTemplate;
139 | this.$templateCache.put(path, this.bcKeypadConfig.customBackspaceTemplate);
140 | }
141 |
142 | }
143 |
144 |
145 | }
146 |
147 |
--------------------------------------------------------------------------------
/src/keypad.controller.spec.js:
--------------------------------------------------------------------------------
1 | describe('KeypadController', () => {
2 | let $compile;
3 | let $rootScope;
4 |
5 | // Include the module
6 | beforeEach(angular.mock.module('bc.AngularKeypad'));
7 |
8 | // Inject
9 | beforeEach(inject((_$compile_, _$rootScope_) => {
10 | $compile = _$compile_;
11 | $rootScope = _$rootScope_;
12 | }));
13 |
14 |
15 | describe('bcNumberModel is a string', () => {
16 | let $scope;
17 | let element;
18 | let vm;
19 |
20 | beforeEach(() => {
21 | $scope = $rootScope.$new();
22 | $scope.neededLength = 4;
23 | element = angular.element(`
24 |
28 | `);
29 | element = $compile(element)($scope);
30 | $scope.$apply();
31 | vm = element.isolateScope().vm;
32 | });
33 |
34 | it('should be a string even when nothing is passed in', () => {
35 | expect(typeof vm.bcNumberModel).toEqual('string');
36 | });
37 |
38 | });
39 |
40 |
41 | describe('setNumber()', () => {
42 |
43 | describe('test withOUT max length', () => {
44 | let $scope;
45 | let element;
46 | let vm;
47 |
48 | beforeEach(() => {
49 | $scope = $rootScope.$new();
50 | $scope.numbers = '';
51 | element = angular.element(`
52 |
53 | `);
54 | element = $compile(element)($scope);
55 | $scope.$apply();
56 | vm = element.isolateScope().vm;
57 | });
58 |
59 | afterEach(() => {
60 | $scope.numbers = '';
61 | });
62 |
63 | it('should add to the number model when small', () => {
64 | const ORIGINAL_LENGTH = vm.bcNumberModel.length;
65 | const NUMBER = 3;
66 | vm.setNumber(NUMBER);
67 |
68 | expect(vm.bcNumberModel.length).toEqual(ORIGINAL_LENGTH + 1);
69 | });
70 |
71 | it('should add to the number model when large', () => {
72 | const LONG_NUMBER = '123456789012345678901234567890';
73 |
74 | // Set the model to a long number
75 | vm.bcNumberModel = LONG_NUMBER;
76 | const ORIGINAL_LENGTH = vm.bcNumberModel.length;
77 | const NUMBER = 3;
78 | vm.setNumber(NUMBER);
79 |
80 | expect(vm.bcNumberModel.length).toEqual(ORIGINAL_LENGTH + 1);
81 | });
82 | });
83 |
84 | describe('test WITH max length', () => {
85 | let $scope;
86 | let element;
87 | let vm;
88 |
89 | beforeEach(() => {
90 | $scope = $rootScope.$new();
91 | $scope.numbers = '';
92 | $scope.neededLength = 4;
93 | element = angular.element(`
94 |
98 | `);
99 | element = $compile(element)($scope);
100 | $scope.$apply();
101 | vm = element.isolateScope().vm;
102 | });
103 |
104 | afterEach(() => {
105 | $scope.numbers = '';
106 | });
107 |
108 | it('should set the number when not at max length', () => {
109 | // Set to partial length
110 | vm.bcNumberModel = '12';
111 | const ORIGINAL_LENGTH = vm.bcNumberModel.length;
112 | const NUMBER = 3;
113 | vm.setNumber(NUMBER);
114 |
115 | expect(vm.bcNumberModel.length).toEqual(ORIGINAL_LENGTH + 1);
116 | });
117 |
118 | it('should NOT set the number if at max length', () => {
119 | // Set to max length
120 | vm.bcNumberModel = '1234';
121 | const ORIGINAL_LENGTH = vm.bcNumberModel.length;
122 | const NUMBER = 3;
123 | vm.setNumber(NUMBER);
124 |
125 | expect(vm.bcNumberModel.length).toEqual(ORIGINAL_LENGTH);
126 | });
127 |
128 | });
129 |
130 | });
131 |
132 |
133 | describe('backspace()', () => {
134 | let $scope;
135 | let element;
136 | let vm;
137 |
138 | beforeEach(() => {
139 | spyOn($rootScope, '$emit');
140 | $scope = $rootScope.$new();
141 | $scope.goBack = function() {};
142 | $scope.numbers = '';
143 | element = angular.element(`
144 |
149 | `);
150 | element = $compile(element)($scope);
151 | $scope.$apply();
152 | vm = element.isolateScope().vm;
153 |
154 | spyOn($scope, 'goBack');
155 | });
156 |
157 | afterEach(() => {
158 | $scope.numbers = '';
159 | });
160 |
161 | it('should remove the last number from the model', () => {
162 | vm.bcNumberModel = '12';
163 | const ORIGINAL_LENGTH = vm.bcNumberModel.length;
164 | vm.backspace();
165 |
166 | expect(vm.bcNumberModel.length).toEqual(ORIGINAL_LENGTH - 1);
167 | });
168 |
169 | it('should call ctrl method when called on empty model', () => {
170 | vm.backspace();
171 | expect($scope.goBack).toHaveBeenCalled();
172 | });
173 |
174 | });
175 |
176 |
177 | describe('button interaction', () => {
178 | let $scope;
179 | let element;
180 | let vm;
181 |
182 | beforeEach(() => {
183 | $scope = $rootScope.$new();
184 | $scope.buttonLeft = function($event, numbers) {};
185 | $scope.buttonRight = function($event, numbers) {};
186 | $scope.numbers = '12';
187 | element = angular.element(`
188 |
195 | `);
196 | element = $compile(element)($scope);
197 | $scope.$apply();
198 | vm = element.isolateScope().vm;
199 |
200 | spyOn($scope, 'buttonLeft');
201 | spyOn($scope, 'buttonRight');
202 | });
203 |
204 | afterEach(() => {
205 | $scope.numbers = '12';
206 | });
207 |
208 | it('should add to the number model when number key is clicked', () => {
209 | const ORIGINAL_LENGTH = vm.bcNumberModel.length;
210 | const buttonArray = element[0].querySelectorAll('.bc-keypad__key > button');
211 | const numberButton = buttonArray[2];
212 | angular.element(numberButton).triggerHandler('click');
213 |
214 | expect(vm.bcNumberModel.length).toEqual(ORIGINAL_LENGTH + 1);
215 | });
216 |
217 | it('should remove a number when BACKSPACE key is clicked', () => {
218 | const numberButton =
219 | element[0]
220 | .querySelectorAll('.bc-keypad__key--left .bc-keypad__key-button--backspace')[0];
221 | angular.element(numberButton).triggerHandler('click');
222 |
223 | expect($scope.numbers).toEqual('1');
224 | });
225 |
226 | it('should trigger the custom LEFT button method when key is clicked', () => {
227 | const numberButton = element[0].querySelectorAll('.bc-keypad__key--left button')[0];
228 | angular.element(numberButton).triggerHandler('click');
229 |
230 | expect($scope.buttonLeft).toHaveBeenCalled();
231 | });
232 |
233 | it('should trigger the custom RIGHT button method when key is clicked', () => {
234 | const numberButton = element[0].querySelectorAll('.bc-keypad__key--right button')[0];
235 | angular.element(numberButton).triggerHandler('click');
236 |
237 | expect($scope.buttonRight).toHaveBeenCalled();
238 | });
239 |
240 | });
241 |
242 |
243 | describe('custom button methods', () => {
244 | let $scope;
245 | let element;
246 | let vm;
247 |
248 | beforeEach(() => {
249 | $scope = $rootScope.$new();
250 | $scope.buttonLeft = function($event, numbers) {};
251 | $scope.buttonRight = function($event, numbers) {};
252 | $scope.numbers = '';
253 | element = angular.element(`
254 |
259 | `);
260 | element = $compile(element)($scope);
261 | $scope.$apply();
262 | vm = element.isolateScope().vm;
263 |
264 | spyOn($scope, 'buttonLeft');
265 | spyOn($scope, 'buttonRight');
266 | });
267 |
268 | it('should trigger the ctrl LEFT method when called', () => {
269 | vm.bcLeftButtonMethod();
270 | expect($scope.buttonLeft).toHaveBeenCalled();
271 | });
272 |
273 | it('should trigger the ctrl RIGHT method when called', () => {
274 | vm.bcRightButtonMethod();
275 | expect($scope.buttonRight).toHaveBeenCalled();
276 | });
277 |
278 |
279 | });
280 |
281 | describe('Config Invariance', () => {
282 | let $scope;
283 | let element;
284 | let vm;
285 | const defaultNumbers =
286 | [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; // eslint-disable-line no-magic-numbers
287 |
288 | beforeEach(() => {
289 | $scope = $rootScope.$new();
290 | $scope.buttonLeft = function($event, numbers) {};
291 | $scope.buttonRight = function($event, numbers) {};
292 | $scope.numbers = '';
293 | element = angular.element(`
294 |
299 | `);
300 | element = $compile(element)($scope);
301 | $scope.$apply();
302 | vm = element.isolateScope().vm;
303 |
304 | spyOn($scope, 'buttonLeft');
305 | spyOn($scope, 'buttonRight');
306 | });
307 |
308 | it('config should still contain the same numbers after keypad constructed', () => {
309 | const buttons = vm.bcKeypadConfig.numbers;
310 |
311 | expect(buttons).toEqual(defaultNumbers);
312 | });
313 |
314 | it('config should still remain the same after keypad constructions', () => {
315 | for (let i = 0; i < 3; i = i + 1) { // eslint-disable-line no-magic-numbers
316 | $scope = $rootScope.$new();
317 | $scope.numbers = '';
318 | element = angular.element(`
319 |
322 | `);
323 | element = $compile(element)($scope);
324 | $scope.$apply();
325 | vm = element.isolateScope().vm;
326 |
327 | const buttons = vm.bcKeypadConfig.numbers;
328 |
329 | expect(buttons).toEqual(defaultNumbers);
330 | }
331 | });
332 |
333 | it('the keypad should have 12 buttons given a left and right method', () => {
334 | const buttonArray = element[0].querySelectorAll('.bc-keypad__key');
335 |
336 | expect(buttonArray.length).toEqual(defaultNumbers.length + 2);
337 | });
338 |
339 | });
340 |
341 |
342 | });
343 |
344 |
--------------------------------------------------------------------------------
/src/keypad.directive.js:
--------------------------------------------------------------------------------
1 | import { KeypadController } from './keypad.controller';
2 | import template from './templates/keypad.html';
3 |
4 | /**
5 | * Creates a keypad
6 | *
7 | * @param {String} numberModel : '77043'
8 | * @param {Integer} maxLength : 10
9 | * @return {Element}
10 | */
11 | export function KeypadDirective() {
12 | 'ngInject';
13 |
14 | const directive = {
15 | restrict: 'E',
16 | replace: true,
17 | scope: {},
18 | bindToController: {
19 | bcNumberModel: '=',
20 | bcMaxLength: '@',
21 | bcLeftButton: '@',
22 | bcRightButton: '@',
23 | bcLeftButtonMethod: '&',
24 | bcRightButtonMethod: '&',
25 | bcEmptyBackspaceMethod: '&',
26 | },
27 | templateUrl: template,
28 | controller: KeypadController,
29 | controllerAs: 'vm',
30 | };
31 |
32 | return directive;
33 |
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/src/keypad.provider.js:
--------------------------------------------------------------------------------
1 | import backspaceTemplate from './backspace.svg';
2 | import submitTemplate from './submit.svg';
3 |
4 | export class KeypadConfig {
5 |
6 | // Define defaults
7 | constructor() {
8 |
9 | this.keypadDefaults = {
10 |
11 | // The array of numbers that makes up the keypad
12 | numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], // eslint-disable-line no-magic-numbers
13 |
14 | // By default there is no max length
15 | // Integer
16 | maxLength: null,
17 |
18 | // Plug'N'Play button types
19 | types: [
20 | 'backspace',
21 | 'submit',
22 | ],
23 |
24 | backspaceTemplate: backspaceTemplate,
25 | submitTemplate: submitTemplate,
26 |
27 | };
28 |
29 | }
30 |
31 |
32 |
33 |
34 |
35 | $get() {
36 | return this.keypadDefaults;
37 | }
38 |
39 |
40 | /**
41 | * Set a custom backspace button template
42 | * NOTE: $templateCache is not available yet so we save the template and the controller will
43 | * handle overwriting the default template
44 | *
45 | * @param {String} template
46 | */
47 | setBackspaceTemplate(template) {
48 | this.keypadDefaults.customBackspaceTemplate = template;
49 | }
50 |
51 |
52 | /**
53 | * Set a custom submit button template
54 | * NOTE: $templateCache is not available yet so we save the template and the controller will
55 | * handle overwriting the default template
56 | *
57 | * @param {String} template
58 | */
59 | setSubmitTemplate(template) {
60 | this.keypadDefaults.customSubmitTemplate = template;
61 | }
62 |
63 |
64 | /**
65 | * Overwrite the max length
66 | *
67 | * @param {Integer} length
68 | */
69 | setMaxLength(length) {
70 | this.keypadDefaults.maxLength = parseInt(length, 10);
71 | }
72 |
73 |
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/src/submit.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 | Submit
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/templates/backspace-left.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/templates/backspace-right.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/templates/keypad.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
13 | {{ ::number }}
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
29 | {{ ::vm.lastNumber }}
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/templates/submit-left.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/templates/submit-right.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
3 | var env = process.env.WEBPACK_ENV;
4 | var path = require('path');
5 |
6 | var libraryName = 'angular-keypad';
7 |
8 |
9 | var config = {
10 | entry: {
11 | 'angular-keypad': './src/index.js',
12 | 'angular-keypad.min': './src/index.js',
13 | },
14 | devtool: 'source-map',
15 | output: {
16 | path: __dirname + '/dist',
17 | filename: "[name].js",
18 | library: libraryName,
19 | libraryTarget: 'umd',
20 | umdNamedDefine: true
21 | },
22 | module: {
23 | preLoaders: [
24 | {
25 | test: /\.js$/,
26 | loader: 'eslint-loader',
27 | exclude: /node_modules/
28 | }
29 | ],
30 | loaders: [
31 | {
32 | test: /\.js$/,
33 | loaders: [
34 | 'ng-annotate',
35 | 'babel?presets[]=es2015'
36 | ],
37 | exclude: /bower_components/
38 | },
39 | {
40 | test: /\.(html|svg)$/,
41 | loader: 'ngtemplate!html'
42 | }
43 | ]
44 | },
45 | resolve: {
46 | root: path.resolve('./src'),
47 | extensions: ['', '.js']
48 | },
49 | plugins: [
50 | new webpack.optimize.UglifyJsPlugin({
51 | include: /\.min\.js$/,
52 | minimize: true
53 | })
54 | ]
55 | };
56 |
57 | module.exports = config;
58 |
59 |
--------------------------------------------------------------------------------