1 module uim.bootstrap.bs5.demos.examples.checkout; 2 3 import uim.bootstrap; 4 5 static this() { 6 demoBS5.pages("examples/checkout", new class DH5AppPage { 7 this() { 8 super(); 9 this 10 .created(DateTime(2020, 12, 20, 10, 10, 0)) 11 .changed(timeLastModified(__FILE_FULL_PATH__)) 12 .parameters([ 13 "pageTitle": "Starter Page - Bootstrap 5 Demo", 14 ]); 15 } 16 17 override string content() { 18 19 return 20 ` <style> 21 .container { 22 max-width: 960px; 23 } 24 .bd-placeholder-img { 25 font-size: 1.125rem; 26 text-anchor: middle; 27 -webkit-user-select: none; 28 -moz-user-select: none; 29 user-select: none; 30 } 31 32 @media (min-width: 768px) { 33 .bd-placeholder-img-lg { 34 font-size: 3.5rem; 35 } 36 } 37 </style> 38 39 40 <!-- Custom styles for this template --> 41 <link href="form-validation.css" rel="stylesheet"> 42 </head> 43 <body class="bg-light"> 44 45 H5Div(["container"> 46 <main> 47 H5Div(["py-5 text-center"> 48 H5Img(["d-block mx-auto mb-4" src="../assets/brand/bootstrap-logo.svg" alt="" "width":"72" "height":"57"> 49 H5H2("Checkout form") 50 H5P(["lead">Below is an example form built entirely with Bootstrap’s form controls. Each required form group has a validation state that can be triggered by attempting to submit the form without completing it.") 51 ), 52 53 H5Div(["row g-3"> 54 H5Div(["col-md-5 col-lg-4 order-md-last"> 55 H5H4(["d-flex justify-content-between align-items-center mb-3"> 56 <span class="text-muted">Your cart"), 57 <span class="badge bg-secondary rounded-pill">3"), 58 </h4> 59 H5Ul(["list-group mb-3"> 60 <li class="list-group-item d-flex justify-content-between lh-sm"> 61 H5Div( 62 <h6 class="my-0">Product name</h6> 63 <small class="text-muted">Brief description"), 64 ), 65 <span class="text-muted">$12"), 66 ), 67 <li class="list-group-item d-flex justify-content-between lh-sm"> 68 H5Div( 69 <h6 class="my-0">Second product</h6> 70 <small class="text-muted">Brief description"), 71 ), 72 <span class="text-muted">$8"), 73 ), 74 <li class="list-group-item d-flex justify-content-between lh-sm"> 75 H5Div( 76 <h6 class="my-0">Third item</h6> 77 <small class="text-muted">Brief description"), 78 ), 79 <span class="text-muted">$5"), 80 ), 81 <li class="list-group-item d-flex justify-content-between bg-light"> 82 H5Div(["text-success"> 83 <h6 class="my-0">Promo code</h6> 84 <small>EXAMPLECODE"), 85 ), 86 <span class="text-success">−$5"), 87 ), 88 <li class="list-group-item d-flex justify-content-between"> 89 H5Span("Total (USD)"), 90 <strong>$20") 91 ), 92 ), 93 94 H5Form(["card p-2"> 95 H5Div(["input-group"> 96 <input "type":"text" class="form-control" "placeholder":"Promo code"> 97 BS5ButtonSubmit(["btn-secondary"], "Redeem") 98 ), 99 ) 100 ), 101 H5Div(["col-md-7 col-lg-8"> 102 H5H4(["mb-3">Billing address</h4> 103 H5Form(["needs-validation" novalidate> 104 H5Div(["row g-3"> 105 H5Div(["col-sm-6"> 106 <label for="firstName" class="form-label">First name</label> 107 <input "type":"text" class="form-control" id="firstName" "placeholder":"" value="" required> 108 H5Div(["invalid-feedback"> 109 Valid first name is required. 110 ), 111 ), 112 113 H5Div(["col-sm-6"> 114 <label for="lastName" class="form-label">Last name</label> 115 <input "type":"text" class="form-control" id="lastName" "placeholder":"" value="" required> 116 H5Div(["invalid-feedback"> 117 Valid last name is required. 118 ), 119 ), 120 121 H5Div(["col-12"> 122 <label for="username" class="form-label">Username</label> 123 H5Div(["input-group"> 124 <span class="input-group-text">@"), 125 <input "type":"text" class="form-control" id="username" "placeholder":"Username" required> 126 H5Div(["invalid-feedback"> 127 Your username is required. 128 ), 129 ), 130 ), 131 132 H5Div(["col-12"> 133 <label for="email" class="form-label">Email <span class="text-muted">(Optional)"),</label> 134 BS5InputEmail("email", ["placeholder":"you@example.com"]), 135 H5Div(["invalid-feedback"> 136 Please enter a valid email address for shipping updates. 137 ), 138 ), 139 140 H5Div(["col-12"> 141 <label for="address" class="form-label">Address</label> 142 <input "type":"text" class="form-control" id="address" "placeholder":"1234 Main St" required> 143 H5Div(["invalid-feedback"> 144 Please enter your shipping address. 145 ), 146 ), 147 148 H5Div(["col-12"> 149 <label for="address2" class="form-label">Address 2 <span class="text-muted">(Optional)"),</label> 150 <input "type":"text" class="form-control" id="address2" "placeholder":"Apartment or suite"> 151 ), 152 153 H5Div(["col-md-5"> 154 <label for="country" class="form-label">Country</label> 155 <select class="form-select" id="country" required> 156 <option value="">Choose...</option> 157 <option>United States</option> 158 </select> 159 H5Div(["invalid-feedback"> 160 Please select a valid country. 161 ), 162 ), 163 164 H5Div(["col-md-4"> 165 <label for="state" class="form-label">State</label> 166 <select class="form-select" id="state" required> 167 <option value="">Choose...</option> 168 <option>California</option> 169 </select> 170 H5Div(["invalid-feedback"> 171 Please provide a valid state. 172 ), 173 ), 174 175 H5Div(["col-md-3"> 176 <label for="zip" class="form-label">Zip</label> 177 <input "type":"text" class="form-control" id="zip" "placeholder":"" required> 178 H5Div(["invalid-feedback"> 179 Zip code required. 180 ), 181 ), 182 ), 183 184 <hr class="my-4"> 185 186 H5Div(["form-check"> 187 <input "type":"checkbox" class="form-check-input" id="same-address"> 188 <label class="form-check-label" for="same-address">Shipping address is the same as my billing address</label> 189 ), 190 191 H5Div(["form-check"> 192 <input "type":"checkbox" class="form-check-input" id="save-info"> 193 <label class="form-check-label" for="save-info">Save this information for next time</label> 194 ), 195 196 <hr class="my-4"> 197 198 H5H4(["mb-3">Payment</h4> 199 200 H5Div(["my-3"> 201 H5Div(["form-check"> 202 <input id="credit" name="paymentMethod" "type":"radio" class="form-check-input" checked required> 203 <label class="form-check-label" for="credit">Credit card</label> 204 ), 205 H5Div(["form-check"> 206 <input id="debit" name="paymentMethod" "type":"radio" class="form-check-input" required> 207 <label class="form-check-label" for="debit">Debit card</label> 208 ), 209 H5Div(["form-check"> 210 <input id="paypal" name="paymentMethod" "type":"radio" class="form-check-input" required> 211 <label class="form-check-label" for="paypal">PayPal</label> 212 ), 213 ), 214 215 H5Div(["row gy-3"> 216 H5Div(["col-md-6"> 217 <label for="cc-name" class="form-label">Name on card</label> 218 <input "type":"text" class="form-control" id="cc-name" "placeholder":"" required> 219 <small class="text-muted">Full name as displayed on card"), 220 H5Div(["invalid-feedback"> 221 Name on card is required 222 ), 223 ), 224 225 H5Div(["col-md-6"> 226 <label for="cc-number" class="form-label">Credit card number</label> 227 <input "type":"text" class="form-control" id="cc-number" "placeholder":"" required> 228 H5Div(["invalid-feedback"> 229 Credit card number is required 230 ), 231 ), 232 233 H5Div(["col-md-3"> 234 <label for="cc-expiration" class="form-label">Expiration</label> 235 <input "type":"text" class="form-control" id="cc-expiration" "placeholder":"" required> 236 H5Div(["invalid-feedback"> 237 Expiration date required 238 ), 239 ), 240 241 H5Div(["col-md-3"> 242 <label for="cc-cvv" class="form-label">CVV</label> 243 <input "type":"text" class="form-control" id="cc-cvv" "placeholder":"" required> 244 H5Div(["invalid-feedback"> 245 Security code required 246 ), 247 ), 248 ), 249 250 <hr class="my-4"> 251 252 H5Button(["w-100 btn btn-primary btn-lg" "type":"submit">Continue to checkout) 253 ) 254 ), 255 ), 256 ) 257 258 H5Footer(["my-5 pt-5 text-muted text-center text-small"> 259 H5P(["mb-1">© 2017–2020 Company Name") 260 H5Ul(["list-inline"> 261 <li class="list-inline-item">H5A(["href":"#"], Privacy")), 262 <li class="list-inline-item">H5A(["href":"#"], Terms")), 263 <li class="list-inline-item">H5A(["href":"#"], Support")), 264 ), 265 ) 266 ), 267 268 269 <script>// Example starter JavaScript for disabling form submissions if there are invalid fields 270 (function () { 271 'use strict' 272 273 // Fetch all the forms we want to apply custom Bootstrap validation styles to 274 var forms = document.querySelectorAll('.needs-validation') 275 276 // Loop over them and prevent submission 277 Array.prototype.slice.call(forms) 278 .forEach(function (form) { 279 form.addEventListener('submit', function (event) { 280 if (!form.checkValidity()) { 281 event.preventDefault() 282 event.stopPropagation() 283 } 284 285 form.classList.add('was-validated') 286 }, false) 287 }) 288 })() 289 290 </script> 291 292 `; 293 294 } 295 }); 296 } 297