学习《html5 in action》

第二章:表单代码

  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>&nbsp;</div>
 35                     <input name="address2" placeholder="Address line 2">
 36                     <div>&nbsp;</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>&nbsp;</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>
index.html
(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('
');
          alert('Please fix the following errors:
'+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);
}) ();
app.js
  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; }
style.css
原文地址:https://www.cnblogs.com/zf723/p/4776157.html