The following code create a web page form. It asks a user to enter a character in an input box, then a sentence in an another box. Then the user should be able to click in a button to count the number of times the character appeared in the sentence entered in the second input box. The sentence should include only letters . The problem I am having is that I am having an error message saying that I entered non alphabets in the box, although i enter only characters!
Any idea why this is happening please !
Here is my HTML / javascript code:
//<![DATA[
'use strict';
function updateForm(id) {
var letter = "";
var sentence = "";
var occurencies = 0;
var form = document.getElementById(id);
letter = form.box1.value;
sentence = form.box2.value;
for (var i = 0; i < sentence.length; i++)
if (sentence.charAt(i) == letter)
occurencies++;
form.box3.value = occurencies;
}
function isAlphabet(elem, helperMsg) {
var alphaExp = /^[a-zA-Z]+$/;
if (elem.value.match(alphaExp)) {
return true;
} else {
alert(helperMsg);
elem.focus();
return false;
}
} //-->
body {
background-color: lightblue;
}
form {
width: 500px;
margin: 0 auto;
}
h4 {
font-family: sans-serif;
font-size: xx-large;
text-align: center;
}
h1,
h2,
h3 {
font-family: sans-serif;
font-style: italic;
font-size: large;
text-align: center;
}
input[type="text"] {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
box-sizing: border-box;
font-style: italic;
}
input[type="button"] {
background: #B9DFFF;
color: #fff;
border: 10px solid #eee;
border-radius: 30px;
box-shadow: 10px 10px 10px #eee;
position: absolute;
left: auto;
}
input[type="button"]:hover {
background: #016ABC;
color: #fff;
border: 5px solid #eee;
border-radius: 30px;
box-shadow: 10px 10px 10px #eee;
}
<form action="#" id="boxes">
Box 1:
<input type="text" name="box1" value="" placeholder="Enter a single
letter" maxlength="1" />
<li class="rq">Only alphabet letters are allowed.</li>
<br />Box 2:
<input type="text" name="box2" value="" placeholder="Enter a sentence" />
<br />Result:
<input type="text" id="letters" name="box3" readonly />
<br />
<input type="button" name="update" value="Update" onclick="isAlphabet(document.getElementById('letters'), 'Only Letters are allowed')" />
</form>
You are checking the wrong form field:
onclick="isAlphabet(document.getElementById('letters')...
As I understand you want to check box1 not 'box3/letters'...
Add id='box1' to that input element and then check like this:
onclick="isAlphabet(document.getElementById('box1')...
You code seems to be fine, just try and trim the element value before you match the same
if (elem.value.trim().match(alphaExp)) {
return true;
}
ensure that you are passing right value to this isAlphabet function
<input type="button" name="update" value="Update" onclick="isAlphabet(document.getElementById('box1'), 'Only Letters are allowed')" />
to count the number of occurences
letter = form.box1.value;
sentence = form.box2.value;
var occurences = sentence.split( letter ).length - 1;
Only the isAlphabet function is called in this code. And it checks an empty field. Your onclick attribute is addressed to that element.
onclick="isAlphabet(document.getElementById('letters'), 'Only Letters are allowed')"
It is holding an empty string when the isAlphabet function is called. An empty string is non-alphanumeric so it returns false.
As robert mentions, you need to include a reference to box1 or box2 in your call to isAlphabet as this is it's input. That is if you need to call it at all.
Also, I can't see a call to you main updateForm function anywhere. Unless this is not the full code, you need to include that. For example, you could do...
<input type="button" name="update" value="Update" onclick="isAlphabet(getElementById('box1, box2'))" />
with those parameters passed to the function.
Because they are passed to the function you don't need to declare them, they are right there for you to use.
You can also just include the validation within this function. To alert if it's non alphabetic.
function updateForm(letter, sentence) {
var occurences = 0;
var form = document.getElementById(id);
for (var i = 0; i < sentence.length; i++) {
if (sentence.charAt(i) == letter) {
occurences++;
}
}
if(letter.match(alphaExp) && sentence.match(alphaExp)) {
..do the thing..
} else {
alert('Only Letters are allowed');
}
}
Related
I have a revenue input field in a javascript/jquery form:
Need a dollar sign :before
add commas as the currency increases
I have a dollar sign showing via css, but issues centering it and ensuring the field entry point is next to it without overlapping. Unsure how to do the commas. Any suggestions or tips are welcome!
HTML:
<form id="rev-calculator">
<label for="price">Monthly Revenue</label>
<div class="fields">
<input type="number" name="price" id="price" min="0" max="10000000000" required data-type="number"> </input>
<br>
</form>
CSS:
<style>
.body {
text-align: left;
}
.fields {
margin: 0 10px 0 0;
}
.fields:before {
content: "$";
text-align: center;
position: relative;
left:30px;
}
#price {
border-radius: 5px;
margin: 15px;
padding: 10px;
color: black;
}
</style>
JS:
<script>
$('#rev-calculator').on('click', 'button', function(e) {
e.preventDefault();
var price = $("#price").val();
console.log(price);
})
</script>
codepen: https://codepen.io/kedarPE/pen/JjroYyb
input field
Well here's a way, though in truth not as simple as I hoped when I started down this path. You can use Intl.NumberFormat to get the comma in there (according to locale). To accomodate decimals, I sniff for them in the beginning and append them to the result.
To allow for the comma, I made this a text field with a pattern attribute. Also, I adjusted your CSS to make it a little nicer looking with the $
$('#price').keydown(function(e) {
setTimeout(() => {
let parts = $(this).val().split(".");
let v = parts[0].replace(/\D/g, ""),
dec = parts[1]
let calc_num = Number((dec !== undefined ? v + "." + dec : v));
// use this for numeric calculations
// console.log('number for calculations: ', calc_num);
let n = new Intl.NumberFormat('en-EN').format(v);
n = dec !== undefined ? n + "." + dec : n;
$(this).val(n);
})
})
.body {
text-align: left;
}
.fields {
margin: 0 10px 0 0;
}
.fields:before {
content: "$";
text-align: center;
position: relative;
left: 35px;
}
#price {
border-radius: 5px;
margin: 15px;
padding: 10px 10px 10px 20px;
color: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="rev-calculator">
<label for="price">Monthly Revenue</label>
<div class="fields">
<input type="text" pattern="[0-9.,]+" name="price" id="price" required data-type="number" />
<br>
</form>
I'm surprised the unique answer for this issue has a lot of votes because it has a tiny but major flaw: the event shouldn't be keydown, it should be keyup. If you use keydown, it won't read the keys you are pressing at the moment but the previous one. So, please update your answer.
I'm trying to make a simple rgb to hex converter and I keep getting stuck with Javascript, what am I doing wrong?
In html part I made a form which on submit calls convert() function.
function convert() {
r = parseInt(document.getElementById('r').value);
g = parseInt(document.getElementById('g').value);
b = parseInt(document.getElementById('b').value);
rgb(r, g, b);
function rgb(r, g, b){
res = ColorToHex(r) + ColorToHex(g) + ColorToHex(b);
function ColorToHex(color) {
if (color > 255) return "FF";
else if (color < 0) return "00";
else color.toString(16).padStart(2, "0").toUpperCase();
}
}
document.getElementById('result').innerHTML = res;
return false;
}
This returns hex from RGB
console.log(convert('255','18', '50'));
function convert(r, g, b) {
r = parseInt(r); g = parseInt(g); b = parseInt(b);
res = r.toString(16) + g.toString(16) + b.toString(16);
res = res.toUpperCase();
return res;
}
First, please declare your variables properly. I don't know what else you have going on in the rest of your code, it may or may not be a factor.
Second, I don't know what you are doing in your HTML. From the code shown, I am assuming your HTML has something like:
<input id="r" type="number"/>
<input id="g" type="number"/>
<input id="b" type="number"/>
And
<span id="result">This Space For Lease</span>
Though I gather you have some of that enclosed in a <form> with a submit button, which is not strictly necessary. For instance you could use something like onBlur to call convert() every time you make any input change for a more dynamic UX. And further, use ' onclick="select()" ` so that when you click in an input it auto-selects the existing contents.
Other optimizations noted in the comments in the below example.
<body>
<h3>Enter integer RGB values</h3>
<input id="r" type="number" onclick="select()" onblur="convert()" value="00" style="width: 5em; background:#fcc;" />
<input id="g" type="number" onclick="select()" onblur="convert()" value="00" style="width: 5em; background:#cfc;" />
<input id="b" type="number" onclick="select()" onblur="convert()" value="00" style="width: 5em; background:#ccf;" />
<br>
<h3>Result as a HEX string</h3>
<div style="margin:1em 0.5em; padding: 0.5em 0;">THE COLOR IS:
<span id="colorPatch" style="margin: 0.5em; padding: 1em; background-color: black; border-radius: 0.6em;"> </span><br>
<span id="result">#000000</span>
</div>
</body>
<script>
// create variables for all "getElement..." this was the DOM
// only needs to be parsed on page load, so future access to
// the elements is via the variable instead for better performance.
let inputR = document.getElementById('r'),
inputG = document.getElementById('g'),
inputB = document.getElementById('b'),
resultOut = document.getElementById('result'),
colorOut = document.getElementById('colorPatch');
function convert() {
// here making the assumption that the expected inputs are
// unsigned integers, we clamp the values to 0-255, then
// make each into a 2 char hex str with padding.
let hexR = Math.min(Math.max(inputR.value, 0), 255).toString(16).padStart(2, "0"),
hexG = Math.min(Math.max(inputG.value, 0), 255).toString(16).padStart(2, "0"),
hexB = Math.min(Math.max(inputB.value, 0), 255).toString(16).padStart(2, "0");
// concatenate to a hex color string
let resultColor = "#" + hexR + hexG + hexB;
// Send to output and set color of sample color patch.
// toUpperCase() is performed once on the final string,
// instead of the substrings
resultOut.innerHTML =
colorOut.style.backgroundColor = resultColor.toUpperCase();
}
</script>
And also added it as a snippet below. Please do read the code comments as they explain what and why things are as they are.
Now, as for the concatenation, it could be even tighter:
function convert() {
colorOut.style.backgroundColor =
resultOut.innerHTML = ("#"
+ Math.min(Math.max(inputR.value,0),255).toString(16).padStart(2,"0")
+ Math.min(Math.max(inputG.value,0),255).toString(16).padStart(2,"0")
+ Math.min(Math.max(inputB.value,0),255).toString(16).padStart(2,"0")).toUpperCase();
}
Everything all on one logical line (line breaks added only for readability), so no need to declare and assign any more variables. Though this kind of thing can impact code readability if taken too far.
When making big strings, I like to put the concatenation operator (+) at the head of each line, which is the opposite of how I'd breakup a long equation by putting the math operators at the end of each line. This makes it clear the + is for concatenation and not addition.
Let me know if any questions...
// create variables for all "getElement..." this was the DOM
// only needs to be parsed on page load, so future access to
// the elements is via the variable instead for better
let inputR = document.getElementById('r'),
inputG = document.getElementById('g'),
inputB = document.getElementById('b'),
resultOut = document.getElementById('result'),
colorOut = document.getElementById('colorPatch');
function convert() {
// here making the assumption that the expected inputs are
// unsigned integers, we clamp the values to 0-255, then
// make each into a 2 char hex str with padding.
let hexR = Math.min(Math.max(inputR.value, 0), 255).toString(16).padStart(2, "0"),
hexG = Math.min(Math.max(inputG.value, 0), 255).toString(16).padStart(2, "0"),
hexB = Math.min(Math.max(inputB.value, 0), 255).toString(16).padStart(2, "0");
// concatenate to a hex color string
let resultColor = "#" + hexR + hexG + hexB;
// Send to output and set color of sample color patch.
// toUpperCase() is performed once on the final string,
// instead of the substrings
resultOut.innerHTML =
colorOut.style.backgroundColor = resultColor.toUpperCase();
}
body {
margin: 0;
padding: 0.5em 1.5em ;
font-family: sans-serif;
background-color: #ffd;
}
h2, h3 { position: relative; font-style: oblique; }
h2 { margin: 0.5em 1em 0.5em;}
h3 { margin: 0.5em 2em 1.4em;}
#r,#g,#b {
width: 5em;
height: 1.75em;
font-size: 1.33em;
font-weight: 600;
text-align: center;
border-radius: 0.6em;
}
#r { background:#fcc; }
#g { background:#cfc; }
#b { background:#ccf; }
.resultDiv {
display: inline-block;
position: relative;
margin: 1.33em;
padding: 0.5em 0.5em 2em;
background-color: #4bb4;
border-radius: 2em;
text-shadow: 0.15em 0.15em 0.3em #6886;
box-shadow: inset 3px 3px 6px #0448,
inset 0 0 22px #4888;
}
.resultVal {
position: relative;
margin: 1em 2em;
padding: 0em;
}
#result {
font-size: 1.5em;
font-weight: 500;
letter-spacing: 0.07em;
color: #135a;
text-shadow: -0.05em -0.05em 0.08em #defd,
0.05em 0.05em 0.08em #1238;
}
#colorPatch {
min-width: 5em;
margin: 0.5em;
padding: 0.5em 1em 2em;
font-size: 1.25em;
background-color: black;
border: 0.33em solid #999;
border-radius: 0.75em;
box-shadow: 2px 2px 3px #2449;
}
<body>
<h2>Enter integer RGB values</h2>
<input id="r" type="number" onclick="select()" onblur="convert()" value="00"/>
<input id="g" type="number" onclick="select()" onblur="convert()" value="00"/>
<input id="b" type="number" onclick="select()" onblur="convert()" value="00"/>
<br>
<div class="resultDiv">
<h3>Result as a HEX string</h3>
<div class="resultVal">THE COLOR IS:
<span id="colorPatch" > </span><br>
<span id="result">#000000</span>
</div>
</div>
</body>
I'm creating a function using Javascript where the user puts in two integers, and the function will output the smaller of the two integers:
function minimum(num1, num2) {
var num1 = document.getElementById('input1').value;
var num2 = document.getElementById('input2').value;
if(num1 < num2){
document.getElementById('para').innerHTML = num1;
}
else if (num2 < num1){
document.getElementById('para').innerHTML = num2;
}
else {
document.getElementById('para').innerHTML = "There was something weird about your numbers. Please try again.";
}
}
body{
background-color: #A9927D ;
max-width: 900px;
min-width: 600px;
}
h1{
color: #F2F4F3;
text-align: center;
font-size: 45px;
}
h3 {
font-size: 20px;
color: #F2F4F3;
}
.container{
text-align: center;
}
.button-container {
padding: 50px;
}
.bttn{
height: 50px;
border-radius: 40px;
font-size: 20px;
font-family:'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
padding: 30px;
background-color: #5E503F;
box-shadow: 2px 2px 2px 2px #312A21;
color: #F2F4F3;
}
.bttn:hover {
background-color: #251F18;
}
.bttn:active {
box-shadow: 0 1px 0px #251F18;
}
.npt {
height: 40px;
width: 100px;
}
#para{
text-align: center;
margin: auto;
width: 40%;
height: 100px;
border: 1px solid #6E5E49;
background-color: #9C8568;
font-size: 20px;
color:#F2F4F3;
}
<div class="container">
<h1>Find the Minimum</h1>
<h3>by Solange Wright</h2>
<div class = "button-container">
<input class = "npt" type="number" id = "input1"><br><br>
<input class = "npt" type="number" id = "input2"><br><br><br><br>
<span class = bttn onclick = "minimum(num1, num2)">Find</span>
</div>
<p id="para"></p>
</div>
For some reason, I'm getting an error like this:
How do I define num1? Is it an issue with data types? Does the .value method in Javascript do type coercion, or is there another additional step to make sure the two values are integers?
You need to pass the id of the input.
Replace
<span class="bttn" onclick="minimum(num1, num2)">Find</span>
with
<span class"bttn" onclick="minimum('input1', 'input2')">Find</span>
It's generally not a good idea to use inline event handlers. You can use one handler for the document and use a generic handler (event delegation). Doing so gives you the possibility to use everything you need within the handler function.
Furthermore, the submitted values have to be checked (do both input have values?) and converted to Number (retrieved input values are always strings).
Finally you can use Math to determine the smallest number in an array of numbers.
This brings us to (removed stuff to present a minimum reproducable example):
document.addEventListener("click", getMinimalValue);
// ^ add a click listener method document wide
function getMinimalValue(evt) {
if (evt.target.id === "findSmallest") {
const numbers = [
document.querySelector("#input1").value || NaN,
document.querySelector("#input2").value || NaN
]
// ^ aggregate values into array (assign NaN if no value)
.map(Number)
// ^ convert values to Number (NaN will remain NaN)
.filter(n => !isNaN(n));
// ^ filter numbers only
document.querySelector("#para").textContent =
numbers.length < 2 ?
// ^ if not both entered values are numbers
// [numbers] array length is < 2
"You did not enter two numeric values" :
`Minimum of ${numbers.join(' and ')}: ${Math.min.apply(null, numbers)}`;
}
}
.npt {
width: 50px;
margin-bottom: 5px;
}
<input class="npt" type="number" id="input1">
<input class="npt" type="number" id="input2">
<span id="para"></span>
<br><button id="findSmallest">Find Minimum</button>
Remove the minimum parameters in the JS code (and also check if num1 and num2 are numbers)
function minimum() {
var num1 = document.getElementById('input1').value;
var num2 = document.getElementById('input2').value;
if (Number.isNaN(num1) || Number.isNaN(num2)){
document.getElementById('para').innerHTML = "please insert valid numbers";
return;
}
if(num1 < num2){
document.getElementById('para').innerHTML = num1;
}
else if (num2 < num1){
document.getElementById('para').innerHTML = num2;
}
else {
document.getElementById('para').innerHTML = "There was something weird about your numbers. Please try again.";
}
}
Refactor the button onclick not to pass paramters.
<div class="container">
<h1>Find the Minimum</h1>
<h3>by Solange Wright</h2>
<div class = "button-container">
<input class = "npt" type="number" id = "input1"><br><br>
<input class = "npt" type="number" id = "input2"><br><br><br><br>
<span class = "bttn" onclick = "minimum()">Find</span>
</div>
<p id="para"></p>
</div>
I'm using normal JS and JSP which contains normal HTML tags. I have an input field with the type as PASSWORD which contains the maxlength of 10 digits.
Now I want to display the last 4 digits of the field values and other digits should be masked.
I'm not using jQuery and I want to use in normal JS.
So can anyone please suggest me any approach on it to achieve.
Try following these steps.
Get the password value.
Get the 2 parts (last 4 characters and the remaining leading characters).
Replace the leading characters with • (ASCII-7 character).
Generate new password to show (masked + 4 visible characters).
Set the password value.
Check out this fiddle.
Here is the snippet.
var passField = document.getElementById('pass');
passField.type = "text";
var passValue = passField.value;
var passLength = passValue.length;
var masked = passValue.substring(0, passLength - 4);
masked = masked.replace(/./g, '•'); //The character is ASCII-7 (Press Alt+7 to type)
var text = passValue.substring(passLength - 4);
var newPass = masked + text;
passField.value = newPass;
<input type='password' id='pass' value="ThisIsPassword" />
CSS
#wrapper {
position: relative;
}
#wrapper > input {
font-family: monospace;
text-align: right;
}
#wrapper > [type=password]::-ms-reveal{
display: none;
}
#passwordMasked {
width: 10em;
border: solid 1px black;
border-right: none;
}
#wrapper > #passwordUnmasked {
border: solid 1px black;
border-left: none;
width: 3em;
text-align: left;
}
#password {
position: absolute;
left: 0;
opacity: 0;
width: 13em;
}
HTML
<div id="wrapper">
<input type="password" onkeyup="updateunmasked()" id="passwordMasked" /><input type="text" id="passwordUnmasked" readonly /><input type="password" onkeyup="updateunmasked()" id="password" />
</div>
Javascript
function updateunmasked() {
var p = document.getElementById("password").value;
document.getElementById("passwordUnmasked").value = (' ' + p.substring(Math.max(p.length - 4, 0))).substring(Math.min(p.length, 4));
document.getElementById("passwordMasked").value = p.substring(4);
}
JSBin - https://jsbin.com/wijifupuco/1/edit?html,css,js,output
I am using jquery.card.js from jessepollak. It is awesome.
If anyone has experience with it, could you please tell me if there is an option to choose what types of credit card you want to support?
e.g.
//This is how I would like it to be...
var card = new Card({
supportedCardTypes: 'Visa, Master'; //I don't want DC or AMEX etc...
});
Is there any options like that? How do I achieve it?
Thank you.
Answer ------------------------------------------------------------
Turns out, only changing cardTypes as TMan suggested didn't work. But it is not about the fish, it is about giving me the idea of fishing. Following TMan's idea hacking into the script, I found adding this line would work:
Card.prototype.handlers = {
setCardType: function($el, e) {
//my modification here to support only Visa and Master!!
var cardType = e.data === 'mastercard' || e.data === 'visa' ? e.data : 'unknown';
//end of my modification!!
if (!QJ.hasClass(this.$card, cardType)) {
QJ.removeClass(this.$card, 'jp-card-unknown');
QJ.removeClass(this.$card, this.cardTypes.join(' '));
QJ.addClass(this.$card, "jp-card-" + cardType);
QJ.toggleClass(this.$card, 'jp-card-identified', cardType !== 'unknown');
return this.cardType = cardType;
}
},
You can just hack the library source code, quick and dirty NOT the best idea, or do something to initialise the handlers your way in your own code.
Thanks again.
Great ideas all around. Here's a way to take your addition to the handler and override it without having to hack at the library. This will persist future changes much better.
var setCardTypeOrig = Card.prototype.handlers.setCardType;
Card.prototype.handlers.setCardType = function($el, e) {
var allowedCards = ['mastercard','visa'];
if (allowedCards.indexOf(e.data) < 0) e.data = 'unknown';
setCardTypeOrig.call(this, $el, e);
}
Demo in Stack Snippets
var setCardTypeOrig = Card.prototype.handlers.setCardType;
Card.prototype.handlers.setCardType = function($el, e) {
var allowedCards = ['mastercard','visa'];
if (allowedCards.indexOf(e.data) < 0) e.data = 'unknown';
setCardTypeOrig.call(this, $el, e);
}
var card = new Card({ form: '.form-container form', container: '.card-wrapper' })
.form-container {
margin-top: 20px;
}
.form-container input {
font-family: 'Helvetica Neue', Helvetica, Helvetica, Arial, sans-serif;
float: left;
}
.form-container input.col-6 {
width: 50%
}
.form-container input.col-3 {
width: 25%
}
.form-container input[type="text"] {
background-color: #fff;
border: 1px solid #cccccc;
font-size: 0.875rem;
margin: 0 0 1rem 0;
padding: 0.5rem;
height: 2.3125rem;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.form-container .button {
cursor: pointer;
position: relative;
text-decoration: none;
text-align: center;
font-size: 0.875rem;
margin: 0 0 1rem 0;
padding: 0.5rem;
height: 2.3125rem;
color: #fff;
background-color: #008CBA;
border-width: 0;
}
.form-container .button:hover,
.form-container .button:focus {
background-color: #007295;
}
<script src="https://rawgit.com/jessepollak/card/master/lib/js/card.js"></script>
<div class="demo-container">
<div class="card-wrapper"></div>
<div class="form-container">
<form action="">
<input placeholder="Card number" type="text" name="number" class="col-6"/>
<input placeholder="Full name" type="text" name="name" class="col-6"/>
<input placeholder="MM/YY" type="text" name="expiry" class="col-3"/>
<input placeholder="CVC" type="text" name="cvc" class="col-3"/>
<input type="submit" value="Submit" class="button col-6"/>
</form>
</div>
</div>
To test it, you can look at the card payment definitions:
mastercard (55*) - works ✓
visa (4*) - works ✓
amex (37*) - doesn't ✓
Based on the Coffeescript file, I think your best bet would be to fork the library and then remove the cards you don't want to support from the cardTypes array so that all other numbers would show up as undefined.
https://github.com/jessepollak/card/blob/master/src/coffee/card.coffee
Or the following line in card.js:
https://github.com/jessepollak/card/blob/master/lib/js/card.js#L1134
Card.prototype.cardTypes = ['jp-card-amex', 'jp-card-dankort', 'jp-card-dinersclub',
'jp-card-discover', 'jp-card-jcb', 'jp-card-laser', 'jp-card-maestro',
'jp-card-mastercard', 'jp-card-unionpay', 'jp-card-visa', 'jp-card-visaelectron'];
You'll also probably want to modify the cardTemplate variable to remove the DOM nodes that no longer apply:
https://github.com/jessepollak/card/blob/master/src/coffee/card.coffee#L36