学习《html5 in action》
第二章:表单代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="utf-8"> 5 <title>Order Form</title> 6 <link rel="stylesheet" href="style.css"> 7 <script src="modernizr.js"></script> 8 <script src="app.js"></script> 9 </head> 10 11 <body> 12 <form name="order" method="post" action="/submit"> 13 <h1>Order Form</h1> 14 <fieldset> 15 <legend>Contact Details</legend> 16 <ul> 17 <li> 18 <label class="required"> 19 <div>Full Name</div> 20 <input name="name" required autofocus> 21 </label> 22 </li> 23 <li> 24 <label class="required"> 25 <div>Email Adress</div> 26 <input type="email" name="email" required> 27 </label> 28 </li> 29 <li> 30 <label> 31 <div>Post Adress </div> 32 <input name="address1" placeholder="Address line 1"> 33 </label> 34 <div> </div> 35 <input name="address2" placeholder="Address line 2"> 36 <div> </div> 37 <input name="city" class="city" placeholder="Town/City"> 38 <input name="state" class="state" placeholder="State"> 39 <input name="zip" class="zip" placeholder="Zip Code"> 40 <div> </div> 41 <select name="country"> 42 <option value ="0">Country</option> 43 <option value="US">United States</option> 44 <option value="CA">Canada</option> 45 </select> 46 </li> 47 <li> 48 <label> 49 <div>Home Phone No.</div> 50 <input type="tel" name="homephone"> 51 </label> 52 </li> 53 <li> 54 <label> 55 <div>Cell Phone No.</div> 56 <input type="tel" name="cellphone"> 57 </label> 58 </li> 59 <li> 60 <label> 61 <div>Skype Name</div> 62 <input name="skype"> 63 </label> 64 </li> 65 <li> 66 <label> 67 <div>Twitter</div> 68 <span class"twitter_prefix">@</span> 69 <input name="twitter" class="twitter"> 70 </label> 71 </li> 72 </ul> 73 </fieldset> 74 75 <fieldset> 76 <legend>Login Details</legend> 77 <ul> 78 <li> 79 <label class="required"> 80 <div>password</div> 81 <input typ="password" name="password" required> 82 </label> 83 </li> 84 <li> 85 <label class="required"> 86 <div>Confirm Password</div> 87 <input type="password" name="confirm_password" required> 88 </label> 89 </li> 90 </ul> 91 </fieldset> 92 93 <fieldset> 94 <legend>Order Details</legend> 95 <table> 96 <thead> 97 <tr> 98 <th>Product Code</th><th>Description</th><th>Qty</th> 99 <th>Price</th><th>total</th> 100 </tr> 101 </thead> 102 <tbody> 103 <tr> 104 <td> 105 COMP001 106 <input type="hidden" name="product_code" value="COMP001"> 107 </td> 108 <td>The Ultimate Smartphone</td> 109 <td> 110 <input type="number" data-price="399.99" name="quantity" value="0" min="0" max="99" maxlength="2"> 111 </td> 112 <td>$399.99</td> 113 <td> 114 <output name="item_total" class="item_total">$0.00</output> 115 </td> 116 </tr> 117 <td> 118 COMP002 119 <input type="hidden" name="product_code" value="COMP001"> 120 </td> 121 <td>The Ultimate Tablet</td> 122 <td> 123 <input type="number" data-price="499.99" name="quantity" value="0" min="0" max="99" maxlength="2"> 124 </td> 125 <td>$499.99</td> 126 <td> 127 <output name="item_total" class="item_total">$0.00</output> 128 </td> 129 </tr> 130 <td> 131 COMP003 132 <input type="hidden" name="product_code" value="COMP001"> 133 </td> 134 <td>The Ultimate Netbook</td> 135 <td> 136 <input type="number" data-price="299.99" name="quantity" value="0" min="0" max="99" maxlength="2"> 137 </td> 138 <td>$299.99</td> 139 <td> 140 <output name="item_total" class="item_total">$0.00</output> 141 </td> 142 </tr> 143 <tfoot> 144 <tr> 145 <td colspan="4">Order total</td> 146 <td> 147 <output name="order_total" id="order_total">$0.00</output> 148 </td> 149 </tr> 150 </tfoot> 151 </table> 152 </fieldset> 153 154 <fieldset> 155 <legend>payment Details</legend> 156 <ul> 157 <li> 158 <label class="required"> 159 <div>Name on card</div> 160 <input name="card_name" required> 161 </label> 162 </li> 163 <li> 164 <label class="required"> 165 <div>Credit on card</div> 166 <input name="card_number" pattern="[0-9]{13,16}" maxlength="16" required title="13-16difits,no spaces"> 167 </label> 168 </li> 169 <li> 170 <label class="required"> 171 <div>Expiry Date</div> 172 <input type="date" name="card_expiry" maxlength="10" placeholder="YYYY-MM-DD" required value="2015-6-1"> 173 </label> 174 </li> 175 </ul> 176 </fieldset> 177 178 179 <div class="buttons"> 180 <input type="submit" value="submit order"> 181 <input type="submit" id="saveOrder" value="save order" formnovalidate formaction="/save"> 182 </div> 183 </form> 184 </body> 185 </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
(function() { var init = function() { var orderForm = document.forms.order, saveBtn = document.getElementById('saveOrder'), saveBtnClicked = false; var saveForm = function() { if(!('formAction' in document.createElement('input'))) { var formAction = saveBtn.getAttribute('formaction'); orderForm.setAttribute('action',formAction); } saveBtnClicked = true; }; saveBtn.addEventListener('click',saveForm, false); var qtyFields = orderForm.quantity, totalFields = document.getElementsByClassName('item_total'), orderTotalField = document.getElementById('order_total'); var formatMoney = function(value) { return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); } var calculateTotals = function() { var i = 0, ln = qtyFields.length, itemQty = 0, itemPrice = 0.00, itemTotal = 0.00, itemTotalMoney = '$0.00', orderTotal = 0.00, orderTotalMoney = '$0.00'; for(;i<ln;i++) { if(!!qtyFields[i].valueAsNumber) { itemQty =qtyFields[i].valueAsNumber || 0; } else { itemQty =parseFloat(qtyFields[i].value) || 0; } if(!!qtyFields[i].dataset) { itemPrice =parseFloat(qtyFields[i].dataset.price); } else { itemPrice =parseFloat(qtyFields[i].getAttribute('data-price')); } itemTotal =itemQty *itemPrice; itemTotalMoney = '$'+formatMoney(itemTotal.toFixed(2)); orderTotal +=itemTotal; orderTotalMoney = '$'+formatMoney(orderTotal.toFixed(2)); if(!!totalFields[i].value) { totalFields[i].value =itemTotalMoney; orderTotalField.value =orderTotalMoney; } else { totalFields[i].innerHTML =itemTotalMoney; orderTotalField.innerHTML =orderTotalMoney; } } }; calculateTotals(); var qtyListeners = function() { var i = 0, ln = qtyFields.length; for(;i<ln;i++) { qtyFields[i].addEventListener('input',calculateTotals, false); qtyFields[i].addEventListener('keyup',calculateTotals, false); } }; qtyListeners(); var doCustomValidity = function(field, msg) { if('setCustomValidity' in field) { field.setCustomValidity(msg); } else { field.validationMessage = msg; } }; var validateForm = function() { doCustomValidity(orderForm.name, ''); doCustomValidity(orderForm.password, ''); doCustomValidity(orderForm.confirm_password, ''); doCustomValidity(orderForm.card_name, ''); if(!Modernizr.inputtypes.month || !Modernizr.input.pattern) { fallbackValidation(); } if(orderForm.name.value.length < 4) { doCustomValidity( orderForm.name, 'Full Name must be at least 4 characters long' ); } if(orderForm.password.value.length < 8) { doCustomValidity( orderForm.password, 'Password must be at least 8 characters long' ); } if(orderForm.password.value != orderForm.confirm_password.value) { doCustomValidity( orderForm.confirm_password, 'Confirm Password must match Password' ); } if(orderForm.card_name.value.length < 4) { doCustomValidity( orderForm.card_name, 'Name on Card must be at least 4 characters long' ); } }; orderForm.addEventListener('input', validateForm, false); orderForm.addEventListener('keyup', validateForm, false); var styleInvalidForm = function() { orderForm.className = 'invalid'; } orderForm.addEventListener('invalid', styleInvalidForm, true); Modernizr.load({ test: Modernizr.inputtypes.month, nope: 'monthpicker.js' }); var getFieldLabel = function(field) { if('labels' in field && field.labels.length > 0) { return field.labels[0].innerText; } if(field.parentNode && field.parentNode.tagName.toLowerCase()=== 'label') { return field.parentNode.innerText; } return ''; } var submitForm = function(e) { if(!saveBtnClicked) { validateForm(); var i = 0, ln = orderForm.length, field, errors = [], errorFields = [], errorMsg = ''; for(; i<ln; i++) { field = orderForm[i]; if((!!field.validationMessage && field.validationMessage.length > 0) || (!!field.checkValidity && !field.checkValidity()) ) { errors.push( getFieldLabel(field)+': '+field.validationMessage ); errorFields.push(field); } } if(errors.length > 0) { e.preventDefault(); errorMsg = errors.join('\n'); alert('Please fix the following errors:\n'+errorMsg, 'Error'); orderForm.className = 'invalid'; errorFields[0].focus(); } } }; orderForm.addEventListener('submit', submitForm, false); var fallbackValidation = function() { var i = 0, ln = orderForm.length, field; for(;i<ln;i++) { field = orderForm[i]; doCustomValidity(field, ''); if(field.hasAttribute('pattern')) { var pattern = new RegExp(field.getAttribute('pattern').toString()); if(!pattern.test(field.value)) { var msg = 'Please match the requested format.'; if(field.hasAttribute('title') && field.getAttribute('title').length > 0) { msg += ' '+field.getAttribute('title'); } doCustomValidity(field, msg); } } if(field.hasAttribute('type') && field.getAttribute('type').toLowerCase()=== 'email') { var pattern = new RegExp(/\S+@\S+\.\S+/); if(!pattern.test(field.value)) { doCustomValidity(field, 'Please enter an email address.'); } } if(field.hasAttribute('required') && field.value.length < 1) { doCustomValidity(field, 'Please fill out this field.'); } } }; }; window.addEventListener('load',init, false); }) ();
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 html, body, form, fieldset, legend, h1, ul { 2 margin: 0; 3 padding: 0; 4 border: 0; 5 outline: 0; 6 font-weight: inherit; 7 font-style: inherit; 8 font-size: 100%; 9 font-family: inherit; 10 vertical-align: baseline; 11 font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 12 font-weight: 300; 13 } 14 15 form { 16 width: 800px; margin: 30px auto; 17 background-color: #DCD4CE; 18 border: 1px solid #423021; 19 box-shadow: 2px 2px 10px #666; 20 } 21 22 h1 { 23 background-color: #BEB0A3; 24 border-bottom: 1px solid #423021; 25 font-size: 2em; font-weight: 600; 26 padding: 5px 15px; 27 text-shadow: 1px 1px 0px #fff; 28 } 29 30 fieldset { 31 border: none; margin: 20px 20px; 32 border-bottom: 1px dashed #BEB0A3; padding-bottom: 20px; 33 } 34 35 legend { 36 display: block; font-weight: bold; font-size: 1.25em; 37 width: 100%; padding-bottom: 10px; 38 text-shadow: 1px 1px 0px #fff; 39 } 40 41 input:not([type=submit]), select { 42 border: 1px solid #999; 43 padding: 2px; 44 } 45 46 input:required, select:required { 47 background-color: lightyellow; 48 } 49 50 form.invalid input:invalid, form.invalid select:invalid, 51 form.invalid input.invalid, form.invalid select.invalid { 52 background-color: #FFD4D4; 53 border: 1px solid maroon; 54 } 55 56 ul { 57 list-style-type: none; 58 } 59 60 li { 61 display: block; width: 380px; float: left; 62 } 63 64 li div { 65 width: 130px; float: left; margin-top: 5px; 66 color: #444; font-size: 0.8em; font-weight: 300; 67 } 68 69 li label.required div { 70 font-weight: bold; 71 } 72 73 li label span { 74 font-size: 11px; font-weight: 300; color: #333; 75 } 76 77 li input, li select { 78 width: 225px; margin-bottom: 5px; 79 font-size: 0.9em; 80 } 81 82 span.twitter_prefix { color: #666; font-size: .95em; font-weight: bold; } 83 84 input.city { width: 80px; margin-right: 0; } 85 input.state { width: 35px; margin-right: 0; } 86 input.zip { width: 90px; } 87 input.twitter { width: 206px; } 88 89 table { 90 width: 100%; 91 border: 1px solid #705536; 92 border-collapse: collapse; 93 box-shadow: 1px 1px 10px #666; 94 } 95 96 th, td { 97 border: 1px solid #705536; 98 padding: 5px 10px; 99 } 100 101 th { 102 text-shadow: 1px 1px 0px #000; font-weight: bold; 103 } 104 105 106 thead th:nth-child(1), thead th:nth-child(2) { 107 text-align: left; 108 } 109 110 thead th:nth-child(4), thead th:nth-child(5) { 111 text-align: right; 112 } 113 114 tbody tr td { 115 background-color: #e5dad2; 116 } 117 118 tbody tr:nth-child(even) td { 119 background-color: #fff3e9; 120 } 121 122 tbody td:nth-child(1) { 123 width: 110px; 124 } 125 126 tbody td:nth-child(3) { 127 width: 60px; text-align: center; 128 } 129 130 td input { 131 width: 50px; height: 28px; font-size: 1.1em; text-align: right; 132 } 133 134 tbody td:nth-child(4) { 135 width: 60px; text-align: right; 136 } 137 138 tbody td:nth-child(5) { 139 width: 80px; text-align: right; 140 } 141 142 th { 143 background-color: #614023; 144 color: #fff; 145 } 146 147 tfoot td { 148 background-color: #BEB0A3; 149 text-align: right; font-weight: bold; 150 font-size: 1.15em; 151 text-shadow: 1px 1px 0px #fff; 152 } 153 154 input[type=month] { width: 100px; } 155 input.cvv { width: 60px; text-align: right; } 156 157 .buttons { 158 margin: 15px 20px 10px; text-align: right; 159 } 160 161 input[type=submit], input[type=button] { 162 border: 1px solid #423021; 163 background-color: #896640; 164 color: #fff; padding: 6px 10px; 165 border-radius: 6px; 166 text-shadow: 1px 1px 0px #000; 167 font-size: 0.9em; cursor: pointer; 168 font-weight: bold; 169 background-image: -webkit-linear-gradient(top, #896640 0%, #705536 100%); 170 background-image: -moz-linear-gradient(top, #896640 0%, #705536 100%); 171 background-image: -o-linear-gradient(top, #896640 0%, #705536 100%); 172 background-image: -ms-linear-gradient(top, #896640 0%, #705536 100%); 173 background-image: linear-gradient(to bottom, #896640 0%, #705536 100%); 174 } 175 176 input[type=submit]:active, input[type=button]:active { 177 background-color: #705536; 178 background-image: -webkit-linear-gradient(bottom, #896640 0%, #705536 100%); 179 background-image: -moz-linear-gradient(bottom, #896640 0%, #705536 100%); 180 background-image: -o-linear-gradient(bottom, #896640 0%, #705536 100%); 181 background-image: -ms-linear-gradient(bottom, #896640 0%, #705536 100%); 182 background-image: linear-gradient(to top, #896640 0%, #705536 100%); 183 } 184 185 .placeholder { 186 color: #999; 187 } 188 189 .month-picker-month { width: 115px; } 190 .month-picker-year { width: 55px; text-align: right; }