Skip to content
This repository has been archived by the owner on May 15, 2023. It is now read-only.

Commit

Permalink
add card icons for valid card types
Browse files Browse the repository at this point in the history
  • Loading branch information
notwaldorf committed May 26, 2015
1 parent a4b360f commit 01b5414
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 70 deletions.
32 changes: 0 additions & 32 deletions cc-validator.html

This file was deleted.

14 changes: 7 additions & 7 deletions cc-validator.js
Expand Up @@ -29,22 +29,22 @@ IN THE SOFTWARE.
card_types = [
{
name: 'amex',
icon: 'assets/amex.png',
icon: 'images/amex.png',
pattern: /^3[47]/,
valid_length: [15]
}, {
name: 'diners_club',
icon: 'assets/diners_club.png',
icon: 'images/diners_club.png',
pattern: /^30[0-5]/,
valid_length: [14]
}, {
name: 'diners_club',
icon: 'assets/diners_club.png',
icon: 'images/diners_club.png',
pattern: /^36/,
valid_length: [14]
}, {
name: 'jcb',
icon: 'assets/jcb.png',
icon: 'images/jcb.png',
pattern: /^35(2[89]|[3-8][0-9])/,
valid_length: [16]
}, {
Expand All @@ -57,12 +57,12 @@ IN THE SOFTWARE.
valid_length: [16]
}, {
name: 'visa',
icon: 'assets/visa.png',
icon: 'images/visa.png',
pattern: /^4/,
valid_length: [16]
}, {
name: 'mastercard',
icon: 'assets/mastercard.png',
icon: 'images/mastercard.png',
pattern: /^5[1-5]/,
valid_length: [16]
}, {
Expand All @@ -71,7 +71,7 @@ IN THE SOFTWARE.
valid_length: [12, 13, 14, 15, 16, 17, 18, 19]
}, {
name: 'discover',
icon: 'assets/discover.png',
icon: 'images/discover.png',
pattern: /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/,
valid_length: [16]
}
Expand Down
2 changes: 1 addition & 1 deletion demo/index.html
Expand Up @@ -26,7 +26,7 @@
</head>
<style>
gold-cc-input {
width: 200px;
width: 300px;
}
</style>
<body>
Expand Down
95 changes: 73 additions & 22 deletions gold-cc-input.html
Expand Up @@ -8,12 +8,15 @@
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
<link rel="import" href="../paper-input/paper-input-behavior.html">
<link rel="import" href="../paper-input/paper-input-container.html">
<link rel="import" href="../paper-input/paper-input-error.html">
<link rel="import" href="../iron-input/iron-input.html">
<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
<link rel="import" href="cc-validator.html">
<link rel="import" href="../iron-icon/iron-icon.html">

<script src="cc-validator.js"></script>

<!--
`gold-cc-input` is a Material Design field for entering a credit card number.
Expand All @@ -27,39 +30,45 @@
-->

<dom-module id="gold-cc-input">
<style>
<style is="custom-style">
:host {
display: block;
white-space: nowrap;
}

/* Use a container so that when hiding the icon, the layout doesn't jump around. */
.icon-container {
margin-left: 10px;
height: 27px;
}

iron-icon {
--iron-icon-width: 40px;
--iron-icon-height: 24px;
}
</style>

<template>

<paper-input-container id="container"
required$="[[required]]"
auto-validate="[[autoValidate]]"
attr-for-value="bind-value">
<paper-input-container id="container">

<template is="dom-if" if="[[label]]">
<label>[[label]]</label>
</template>

<cc-validator></cc-validator>

<input is="iron-input" id="input"
validator="cc-validator"
bind-value="{{value}}"
type="tel"
maxlength="30"
allowed-pattern="[0-9]"
prevent-invalid-input
name$="[[name]]">

<iron-icon id="icon" hidden></iron-icon>
<div class="horizontal layout">
<input is="iron-input" id="input"
bind-value="{{value}}"
type="tel"
maxlength="30"
required$="[[required]]"
allowed-pattern="[0-9]"
prevent-invalid-input
name$="[[name]]">
<div class="icon-container"><iron-icon id="icon"></iron-icon></div>
</div>

<template is="dom-if" if="[[errorMessage]]">
<paper-input-error id="error">[[errorMessage]]</paper-input-error>
<paper-input-error>[[errorMessage]]</paper-input-error>
</template>

</paper-input-container>
Expand All @@ -86,7 +95,15 @@
label: {
type: String,
value: "Card number"
}
},

/**
* The type of the credit card, if it is valid. Empty otherwise.
*/
cardType: {
type: String,
notify: true
},
},

observers: [
Expand All @@ -112,8 +129,42 @@
// space, we need to advance the selection to maintain the caret position.
if (!previousCharASpace && this.value.charAt(start - 1) == ' ')
this.$.input.selectionStart++;
}

if (this.autoValidate)
this.validate();
},

validate: function() {
// Empty, non-required input is valid.
if (!this.required && this.value == '') {
return true;
}

var result = CreditCardValidator.validate(this.value);
var valid = result.valid && result.length_valid;
this.cardType = valid ? result.card_type.name : '';

// Update the container and its addons (i.e. the custom error-message).
this.$.container.invalid = !valid;
this.$.container.updateAddons({
inputElement: this.$.input,
value: this.value,
invalid: !valid
});

// We don't have icons for all the card types.
if (valid && result.card_type.icon) {
this.$.icon.src ='../' + result.card_type.icon;
this.$.icon.alt = this.cardType;
this.$.icon.hidden = false;
} else {
this.$.icon.src = null;
this.$.icon.alt = '';
this.$.icon.hidden = true;
}

return valid;
}
})

})();
Expand Down
Binary file added images/amex.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/diners_club.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/discover.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/jcb.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/mastercard.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/visa.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 29 additions & 8 deletions test/basic.html
Expand Up @@ -36,6 +36,12 @@
</template>
</test-fixture>

<test-fixture id="ErrorWithoutAutoValidate">
<template>
<gold-cc-input required error-message="error"></gold-cc-input>
</template>
</test-fixture>

<test-fixture id="required">
<template>
<gold-cc-input auto-validate required error-message="error"></gold-cc-input>
Expand All @@ -59,6 +65,7 @@
var container = Polymer.dom(input.root).querySelector('paper-input-container');
assert.ok(container, 'paper-input-container exists');
assert.isTrue(container.invalid);
assert.equal(input.cardType, '');
});

test('valid input is ok', function() {
Expand All @@ -69,6 +76,7 @@
var container = Polymer.dom(input.root).querySelector('paper-input-container');
assert.ok(container, 'paper-input-container exists');
assert.isFalse(container.invalid);
assert.equal(input.cardType, 'visa');
});

test('empty required input shows error', function() {
Expand All @@ -80,17 +88,30 @@
assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
});

test('caret position is preserved', function() {
var input = fixture('required');
var ironInput = input.querySelector('input[is="iron-input"]');
input.value='1111 1111';
ironInput.selectionStart = (2,2);
input.value='1122 1111 11';
test('invalid input shows error message after manual validation', function() {
var input = fixture('ErrorWithoutAutoValidate');
forceXIfStamp(input);
var error = Polymer.dom(input.root).querySelector('paper-input-error');
assert.ok(error, 'paper-input-error exists');

assert.equal(ironInput.selectionStart, 2, 'selectionStart is preserved');
assert.equal(ironInput.selectionEnd, 2, 'selectionEnd is preserved');
// The error message is only displayed after manual validation.
assert.equal(getComputedStyle(error).display, 'none', 'error is not display:none');
input.validate();
assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
});

// TODO: re-enable when PolymerElements/iron-input/issues/24 is fixed.
// test('caret position is preserved', function() {
// var input = fixture('required');
// var ironInput = input.querySelector('input[is="iron-input"]');
// input.value='1111 1111';
// ironInput.selectionStart = (2,2);
// input.value='1122 1111 11';
//
// assert.equal(ironInput.selectionStart, 2, 'selectionStart is preserved');
// assert.equal(ironInput.selectionEnd, 2, 'selectionEnd is preserved');
// });

});

</script>
Expand Down

0 comments on commit 01b5414

Please sign in to comment.