1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="utf-8" /> 5 <meta http-equiv="Content-Security-Policy" content="img-src * data:; connect-src 'self' https://www.google-analytics.com https://analytics.google.com https://www.google.com https://cdn.weglot.com https://cdn-api-weglot.com https://connect.facebook.net https://www.facebook.com https://vice-prod.sdiapi.com https://reports.sdiapi.com ; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.google.com *.gstatic.com *.googletagmanager.com *.googleadservices.com *.windows.net *.google-analytics.com *.doubleclick.net *.weglot.com *.cdn-api.weglot.com *.facebook.com *.facebook.net *.sdiapi.com ;" /> 6 <meta name="viewport" content="width=device-width, minimum-scale=1.0, user-scalable=yes"> 7 <title>Login â Local Foods Plymouth</title> 8 <meta name="description" /> 9 <meta name="keywords" /> 10 11
11<script> 12 vice={config: { 13 viceAccountId: 'c27bb423-83d9-4612-ad7e-3e95d5a9822c', 14 viceSiteId: '6f5d3c6e-95f0-41ab-8eb9-d7cd845f05ef', 15 } 16 } 17 </script>
17 18
18<script src='//vice-prod.sdiapi.com/vice_loader/c27bb423-83d9-4612-ad7e-3e95d5a9822c/6f5d3c6e-95f0-41ab-8eb9-d7cd845f05ef'> 19 </script>
19 20 21
21<script src="/Scripts/jquery-3.5.1.js"></script>
21 22 23
23<script src="/Scripts/jquery.validate.js"></script>
vendor: 2 bytes, line 23
23
24<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
vendor: 2 bytes, line 24
24
25<script src="/Scripts/jquery.tmpl.min.js"></script>
25 26 27 28
28<script src="/js/uikit.min.js?v5.06"></script>
28 29
29<script src="/js/uikit-icons.min.js?v5.06"></script>
29 30
30<script src="/top/back-to-top.js"></script>
30 31 32 <link href="/css/uikit.min.css?v5.06" rel="stylesheet" /> 33 <link href="/css/font-awesome.min.css" rel="stylesheet" /> 34 <link href="/top/back-to-top.css" rel="stylesheet" /> 35 36
36<script src="/Scripts/modernizr-2.6.2.js"></script>
vendor: 2 bytes, line 36
36
37<script src="/Scripts/modernizr-2.8.3.js"></script>
vendor: 85 bytes, lines 37-43
37 38 39 40 41 <script src="//www.google.com/recaptcha/api.js"></script> 42 43
43<script src="/Scripts/checkout.js?v5.06"></script>
43 44 45
45<script src="/Scripts/jquery.validate.js"></script>
vendor: 2 bytes, line 45
45
46<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
vendor: 2 bytes, line 46
46
47<script src="/Scripts/jquery.tmpl.min.js"></script>
47 48 49 50 51 52 53 <link rel="stylesheet" href="/Content/Site.css?v5.06" /> 54 <link rel="stylesheet" href="https://lfmimages.blob.core.windows.net/400952-lfp/assets/css/Theme.css?v5.06" /> 55 <link rel="stylesheet" href="https://lfmimages.blob.core.windows.net/400952-lfp/assets/css/Site-Specific.css?v5.06" /> 56 57 <!-- Anything site specific that needs to be included in the head should be placed here. --> <link rel="icon" href="https://lfmimages.blob.core.windows.net/400952-lfp/favicon.ico"> <meta property="og:title" content="Online Farmers Market in Plymouth, NH | Local Foods Plymouth" /> <meta property="og:description" content="Shop fresh, local food from small farms and makers across the region. Weekly online ordering with Thursday pickup in Plymouth, NH and delivery available." /> <meta property="og:image" content="https://lfmimages.blob.core.windows.net/400952-lfp/Logo.jpg" /> <meta property="og:url" content="https://shop.localfoodsplymouth.org/" /> <title>Online Farmers Market in Plymouth, NH | Local Foods Plymouth</title> <meta name="description" content="Shop fresh, local food from small farms and makers across the region. Weekly online ordering with Thursday pickup in Plymouth, NH and delivery available." /> 58</head> 59<body class="uk-height-1-1"> 60 <a href="#main-content" class="lfm-skip-link">Skip to main content</a> 61 62 <div id="global-overlay"> 63 <span id="global-spinner" uk-spinner="ratio: 3.0"></span> 64 </div> 65 66 <header id="header"> 67 <!-- Any site specific scripts that need to be included in the header should be placed here. -->� 68 <div id="main-nav"><div id="weglot"></div><div class="uk-container nav-center"><div id="logo"><img src="https://lfmimages.blob.core.windows.net/400952-lfp/Logo.jpg" id="logo-img" alt="Site Logo" /></div><div id="menu-box" class="uk-visible@s"> 69<nav class="uk-navbar-container" uk-navbar> 70<div class="uk-navbar-left"> 71<ul class="uk-navbar-nav uk-flex-between"> 72<li class="menu-item"><a href="//shop.localfoodsplymouth.org/Index">HOME</a></li> 73<li class="menu-item"><a href="//shop.localfoodsplymouth.org/Products">SHOP NOW</a></li> 74<li class="menu-item"><a href="//shop.localfoodsplymouth.org/Account/Register">SIGN UP!</a></li> 75<li class="menu-item"><a href="//shop.localfoodsplymouth.org/Contact">CONTACT US</a></li> 76<li class="menu-item"><a target="_blank" href="https://plymouthenergy.org/">PAREI</a></li> 77<li class="menu-item"><a target="_blank" href="https://secure.lglforms.com/form_engine/s/wNHi1pQIn44PLdSe57N0bQ">DONATE $20 TO CELEBRATE 20 YEARS</a></li> 78 </ul> 79</div> 80</nav> 81</div> 82<a id="toggle-menu" href="#offcanvas" class="uk-navbar-toggle uk-hidden@s" title="Mobile Main Menu" u
82k-toggle uk-navbar-toggle-icon></a><div id="offcanvas" uk-offcanvas><div id="offcanvas-menu" class="uk-offcanvas-bar uk-offcanvas-bar-light"><ul class="uk-nav-default" uk-nav><li class="mobile-menu-item"><a href="//shop.localfoodsplymouth.org/Index">HOME</a></li> 83<li class="mobile-menu-item"><a href="//shop.localfoodsplymouth.org/Products">SHOP NOW</a></li> 84<li class="mobile-menu-item"><a href="//shop.localfoodsplymouth.org/Account/Register">SIGN UP!</a></li> 85<li class="mobile-menu-item"><a href="//shop.localfoodsplymouth.org/Contact">CONTACT US</a></li> 86<li class="mobile-menu-item"><a target="_blank" href="https://plymouthenergy.org/">PAREI</a></li> 87<li class="mobile-menu-item"><a target="_blank" href="https://secure.lglforms.com/form_engine/s/wNHi1pQIn44PLdSe57N0bQ">DONATE $20 TO CELEBRATE 20 YEARS</a></li> 88</ul> 89</div> 90</div> 91</div></div> 92 93 94<div class="sticky-bar" uk-sticky> 95 <div class="lfm-nav-container"> 96 <div class="uk-flex uk-flex-between"> 97 <div id="period-message"> 98 <!--period message used to be here--> 99 </div> 100 101 <nav class="uk-navbar-container uk-navbar-transparent" uk-navbar="mode: click"> 102 <div class="uk-navbar-right"> 103 <ul class="uk-navbar-nav top-bar-navbar"> 104 <li> 105 <div class="uk-button-group"> 106 <div class="uk-inline"> 107 <button class="uk-button top-bar-button" type="button"> <span uk-icon="user" aria-hidden="true"></span></button> 108 <div uk-dropdown="mode: click; target: !.uk-button-group; pos:bottom-right;" class="top-bar-dropdown"> 109 <ul class="uk-nav uk-dropdown-nav"> 110<li id="logged-out-products-link"><a href="//shop.localfoodsplymouth.org/Products">Shop</a></li><li id="logged-out-login-link"><a href="//shop.localfoodsplymouth.org/Account/Login">Login</a></li> </ul> 111 </div> 112 </div> 113 </div> 114 </li> 115 <li> 116 <div class="uk-button-group"> 117 <div class="uk-inline"> 118 <button id="cart-trigger-btn" class="uk-button top-bar-button" onclick="openCart();" type="button" aria-label="View Shopping Cart" aria-expanded="false" aria-controls="shopping-cart"> 119 <span uk-icon="cart" aria-label="shopping cart"></span> 120 <span class="uk-badge" id="item-count" style=display:none;>0</span> 121 </button> 122 123 <!-- off-canvas shopping cart--> 124 <dialog id="shopping-cart" aria-labelledby="cart-panel-heading"> 125 <div class="uk-offcanvas-bar uk-offcanvas-bar-light"> 126 <h2 id="cart-panel-heading" class="visually-hidden">Shopping Cart</h2> 127 <button id="cart-continue-shopping" class="uk-button uk-button-small uk-button-primary uk-margin-small-bottom" style="width:100%;" type="button" onclick="closeCart();">Continue Shopping</button> 128 <div> 129 <div id="cart-alert-area-success" class="uk-alert-success uk-margin-small-bottom" uk-alert role="status" aria-live="polite" aria-atomic="true" style="display:none;"> 130 <a href="#" class="uk-alert-close" uk-close></a> 131 <p id="cart-alert-success-text"></p> 132 </div> 133 134 <div class="" > 135 <div class="uk-text-bold" id="cart-selected-sub-text">For Distribution on: Thu Oct, 1</div> 136 </div> 137 <div id="order-list-body" class="uk-margin-small-top" > 138 <div id="order-icon-table" class="uk-overflow-auto" style=display:none;> 139 140 <div id="cart-message" class="uk-margin-bottom uk-text-danger" style="display:none;"></div> 141 142 <div class="shopping-cart-text" id="cart-selected-sub-nameloc"> 143 144 </div> 145 <div class="uk-margin-small-top shopping-cart-text" id="cart-ordernum-text" style="border-bottom: thin solid #333; padding-bottom: 2px;"> 146 147 </div> 148 <table class="uk-table uk-table-small"> 149 <tbody id="order-items"> 150 </tbody> 151 </table> 152 </div> 153 </div> 154 155 <div id="cart-items-empty" class="uk-margin-small-top" > 156 <div class=""> 157 There are no items in your cart for this distribution day. 158 </div> 159 <div> 160 <a class="uk-button uk-button-small uk-button-secondary" href="/Products">Shop</a> 161 </div> 162 </div> 163 164 <div id="edit-order-row" class="edit-order-button uk-margin-small-top" style=display:none;> 165 <div class="order-total" id="order-total" aria-live="polite" aria-atomic="true">Total: $0.00</div> 166 167 <div class="uk-margin-small-top"> 168 <a id="edit-order-button" class="uk-button uk-button-small uk-button-secondary" href="/Order/Edit/0"></a> 169 </div> 170 </div> 171 172 <!-- subscriptions --> 173 <div id="subscription-list-body" class="uk-margin-medium-top"> 174 <div id="order-icon-subs" class="uk-overflow-auto" style=display:none;> 175 <hr /> 176 <div class="uk-gri
176d uk-grid-small"> 177 <div class="uk-width-1-1">Subscription Orders</div> 178 179 <div class="uk-width-1-1" id="cart-subs-items"> 180 181 </div> 182 </div> 183 </div> 184 </div> 185 186 <!-- pre-orders--> 187 <div id="pre-order-list-body" class="uk-margin-medium-top"> 188 <div id="order-icon-pre-orders" class="uk-overflow-auto" style=display:none;> 189 <hr /> 190 <div class="uk-grid uk-grid-small"> 191 <div class="uk-width-1-1">Pre-Orders</div> 192 193 <div class="uk-width-1-1" id="cart-pre-orders"> 194 195 </div> 196 </div> 197 </div> 198 </div> 199 200 </div> 201 </div> 202 </dialog> 203 </div> 204 </div> 205 </li> 206 </ul> 207 </div> 208 </nav> 209 </div> 210 </div> 211</div> 212 213 </header> 214 <a href="#0" class="cd-top" aria-label="Back to top" role="button">Top</a> 215 <div id="content" class="content-area"> 216 <span id="main-content" tabindex="-1"></span> 217 <div id="aria-status" role="status" aria-live="polite" aria-atomic="true" class="visually-hidden"></div> 218 219 220 221<form action="/Account/Login" class="" method="post" role="main"> <div class="uk-container" id="loginPage"> 222 223 <fieldset class="uk-fieldset"> 224 <h1 class="uk-h3 underline">Login</h1> 225 <div class="uk-grid" uk-grid> 226 <div class="uk-width-1-1"> 227 <div class="uk-text-danger"></div> 228 <input name="__RequestVerificationToken" type="hidden" value="7gfyzqcKzemejKQqnlWNojToHBUkBSai2TEgIzhv0
228M32KXMeqOJfGbLeuZ_Lg_XxtU-JQCmCAYsmlos1zzGY4UhSWcA1" /> 229 230 <div role="alert" aria-live="assertive"></div> 231 </div> 232 <div id="login-top-text" class="uk-width-1-1"> 233 234 </div> 235 <div class="uk-width-1-3@m uk-width-1-1@s uk-margin-top"> 236 <div class="uk-margin underline uk-h4"> 237 Already have an account? 238 </div> 239 <div id="login-email-label" class=""> 240 <label class="" for="login-email">Email</label> 241 </div> 242 <div class="uk-margin-small"> 243 <input aria-describedby="Email-error" aria-required="true" autocomplete="email" class="max-width-340 uk-input" id="login-email" maxlength="60" name="Email" onKeyPress="return eatCR(event);" placeholder="Enter email address" required="required" type="email" value="" /> 244 </div> 245 <div id="login-email-validation" class="uk-margin" role="alert" aria-live="assertive"> 246 247 </div> 248 <div id="login-password-label" class=""> 249 <label class="" for="login-password">Password</label> 250 </div> 251 <div class="uk-margin-small"> 252 <input aria-describedby="Password-error" aria-required="true" autocomplete="current-password" class="max-width-340 uk-input" id="login-password" maxlength="64" name="Password" onKeyPress="return eatCR(event);" placeholder="Enter password" required="required" type="password" value="" /> 253 </div> 254 <div id="login-password-validation" class="uk-margin" role="alert" aria-live="assertive"> 255 256 </div> 257 <div id="login-remember-me" class="uk-margin"> 258 <input id="RememberMe" name="RememberMe" type="checkbox" value="true" /><input name="RememberMe" type="hidden" value="false" /> 259 <label for="RememberMe">Remember me?</label> 260 </div> 261 <div id="login-submit-button" class="uk-margin"> 262 <button type="submit" id="btnSubmit" class="uk-button uk-button-primary">Login</button> 263 </div> 264 </div> 265 <div class="uk-width-1-6@m uk-width-1-1@s"> </div> 266 <div class="uk-width-1-3@m uk-width-1-1@s uk-margin-top"> 267 <div id="login-forgot-password-section" class="uk-margin" style="max-width:400px;"> 268 <a href="/Account/ForgotPassword" class="uk-button uk-button-primary">Forgot your password?</a> 269 </div> 270 <div id="login-register-section" class="uk-margin-top"> 271 <div class="uk-margin underline uk-h4"> 272 Need an account? 273 </div> 274 <div id="btnRegister" class="uk-margin" style="max-width:400px;"> 275 <a href="Register" class="uk-button uk-button-primary">Register</a> 276 </div> 277 </div> 278 <div id="login-help-section" class="uk-margin"> 279 <br /> 280 <a target="_blank" href="http://home.localfoodmarketplace.com/trouble-logging-in/">Having trouble logging in?</a> 281 </div> 282 </div> 283 <div class="uk-width-1-6"> </div> 284 </div> 285 </fieldset> 286 </div> 287
287<script type="text/javascript"> 288 $(document).ready(function () { 289 var $errorContainer = $('#login-error-container'); 290 var hasErrors = $errorContainer.hasClass('validation-summary-errors'); 291 292 if (hasErrors) { 293 $errorContainer.focus(); 294 $('#login-email, #login-password').attr('aria-invalid', 'true'); 295 } else { 296 $('#login-email').focus(); 297 } 298 299 $('#login-email, #login-password').on('input', function () { 300 $(this).removeAttr('aria-invalid'); 301 }); 302 }); 303 </script>
303 304</form> 305 </div> 306 307 <div class="uk-clearfix"></div><footer id="footer"><div class="nav-center footer-center-color uk-grid"><div class="uk-width-1-6@l uk-width-1-1@m uk-width-1-1@s"></div><div class="uk-width-2-3@l uk-width-1-1@m uk-width-1-1@s"><ul class="footer-list"><li><a class="" href="/Home/Page/privacy">Privacy Policy</a> </li><li><a class="" href="/Home/Page/terms_of_service">Terms of Service</a> </li><li><a class="" href="/Home/Page/refunds">Refund Policy</a> </li><li><a class="" target="_blank" href="https://lfp.lfmadmin.com/grow/Home/Index">Producer Login</a> </li><li><a class="" href="/Contact">Contact Us</a></li></ul><ul class="footer-list"><li>© Powered By -<a href="http://home.localfoodmarketplace.com">Local Food Marketplace Inc.</a></li></ul></div><div class="uk-width-1-6@l uk-width-1-1@m uk-width-1-1@s"></div></div></footer> 308 <!-- Any site specific scripts that need to be included in the footer should be placed here. --> 309 310
310<script type="text/x-jquery-tmpl" id="tmplOrderItem"> 311 <tr class="shopping-cart-row shopping-cart-text"> 312 <td> 313 <div class="shopping-cart-product-name">${itemName}</div> 314 <div class="shopping-cart-unit-name">${itemUnit} - ${itemUnitPrice}</div> 315 </td> 316 <td class="uk-flex uk-flex-center"> 317 {{if canDeleteItem}} 318 <button type="button" uk-icon="icon: minus; ratio: 1" class="uk-icon-link shopping-cart-adjustor" onclick="decreaseQty('${itemId}');" aria-label="Decrease quantity of ${itemName}"></button> 319 {{/if}} 320 <input type="text" class="uk-input uk-form-small uk-text-center" value="${itemQty}" readonly="readonly" id="cart-qty-${itemId}" style="width: 50px;" aria-label="Quantity of ${itemName}" /> 321 {{if canDeleteItem}} 322 <button type="button" uk-icon="icon: plus; ratio: 1" class="uk-icon-link shopping-cart-adjustor" onclick="increaseQty('${itemId}');" aria-label="Increase quantity of ${itemName}"></button> 323 {{/if}} 324 </td> 325 </tr> 326 </script>
326 327 328
328<script type="text/x-jquery-tmpl" id="tmplSubsItem"> 329 <div class="uk-margin-top"> 330 <div class="shopping-cart-text">{{html name}}</div> 331 332 {{each orders}} 333 <div class="uk-margin-small-top shopping-cart-text" style="border-bottom: thin solid #333; padding-bottom: 2px;"> 334 Order# ${orderId} 335 </div> 336 {{each items}} 337 <ul class=""> 338 <li class="shopping-cart-text">${name}</li> 339 </ul> 340 {{/each}} 341 <div class="uk-margin-small-top"> 342 <button class="uk-button uk-button-small uk-button-secondary" onclick="window.location='${orderLink}';">Subscription Checkout</button> 343 </div> 344 <hr /> 345 {{/each}} 346 347 </div> 348 </script>
348 349 350
350<script type="text/x-jquery-tmpl" id="tmplPreOrder"> 351 <div class="uk-margin-small-top"> 352 <div class="uk-text-bold">{{html distribDay}}</div> 353 <div class="shopping-cart-text">${pickupDay}</div> 354 <div class="shopping-cart-text">${locName}</div> 355 356 <div class="uk-margin-small-top shopping-cart-text" style="border-bottom: thin solid #333; padding-bottom: 2px;"> 357 Order# ${orderId} 358 </div> 359 <div class="shopping-cart-text uk-margin-small-top">${itemCount} item(s)</div> 360 <div class="shopping-cart-text">Total: ${orderTotal}</div> 361 362 <div class="uk-margin-small-top"> 363 <button class="uk-button uk-button-small uk-button-secondary" onclick="window.location='${orderLink}';">Review and Confirm Pre-Order</button> 364 </div> 365 <hr /> 366 367 </div> 368 </script>
368 369 370
370<script type="text/javascript"> 371 var baseUrl = "//shop.localfoodsplymouth.org/"; 372 373 // display the shopping cart 374 function displayCart(onReady) { 375 376 // clear cart message 377 $("#cart-message").html(""); 378 $("#cart-message").hide(); 379 380 $.ajax({ 381 type: "POST", 382 contentType: "application/json; charset=utf-8", 383 dataType: "json", 384 url: baseUrl + 'api/ProductApi/getOrderInfo', 385 success: function (data) { 386 387 $("#item-count").html(data.itemCount); 388 $("#order-total").html("Total: " + data.orderTotal); 389 390 // clear carts first 391 $("#order-items").empty(); 392 $("#cart-subs-items").empty(); 393 $("#cart-pre-orders").empty(); 394 395 //set for delete order item 396 orderId = data.orderId; 397 398 // hide/show stuff 399 if (data.orderItemCount > 0) { 400 // build items 401 $(data.orderItems).each(function (i, item) { 402 $("#order-items").append($("#tmplOrderItem").tmpl(item)); 403 }); 404 $("#order-icon-table").show(); 405 $("#edit-order-row").show(); 406 $("#order-list-body").show(); 407 $("#cart-items-empty").hide(); 408 $("#edit-order-button").attr("href", baseUrl + 'Order/Edit/' + data.orderId); 409 $("#edit-order-button").text(data.orderButtonText); 410 $("#cart-selected-sub-text").html(data.selectedSubText); 411 $("#cart-selected-sub-nameloc").html(data.selectedSubNameAndLoc); 412 $("#cart-ordernum-text").html(data.orderNumberText); 413 } 414 else { 415 $("#order-icon-table").hide(); 416 } 417 418 if (data.hasSubscriptions) { 419 // build subs list 420 $(data.subsDays).each(function (i, item) { 421 $("#cart-subs-items").append($("#tmplSubsItem").tmpl(item)); 422 }); 423 $("#order-icon-subs").show(); 424 } 425 else { 426 $("#order-icon-subs").hide(); 427 } 428 429 if (data.hasPreOrders) { 430 // build pre-order list 431 $(data.preOrders).each(function (i, item) { 432 $("#cart-pre-orders").append($("#tmplPreOrder").tmpl(item)); 433 }); 434 $("#order-icon-pre-orders").show(); 435 } 436 else { 437 $("#order-icon-pre-orders").hide(); 438 } 439 if (typeof onReady === 'function') { onReady(); } 440 }, 441 error: function (error) { 442 console.log(error.responseText); 443 } 444 }); 445 } 446 447 function openProducer(pGuid) { 448 url = baseUrl + "Producer/" + pGuid; 449 window.open(url, "+blank"); 450 } 451 452 function hideCartMessage() { 453 $("#cart-message").hide(); 454 } 455 456 function updateCartMessage(message) { 457 $("#cart-message").html(message); 458 $("#cart-message").show(); 459 } 460 461 function deleteOrderItem(itemId) { 462 var id = itemId; 463 $.ajax({
464 type: "GET", 465 contentType: "application/json; charset=utf-8", 466 dataType: "json", 467 url: baseUrl + 'api/ProductApi/deleteOrderItem/?id=' + id + "&orderId=" + orderId, 468 469 success: function (data) { 470 if (data.success) { 471 var href = window.location.href; 472 var contains = href.includes("Order"); 473 displayCart() 474 475 // handle analytics 476 if (data.gaItem != null) { 477 window.dataLayer = window.dataLayer || []; 478 function gtag() { dataLayer.push(arguments); } 479 gtag("event", "remove_from_cart", data.gaItem); 480 } 481 } 482 else { 483 displayCart() 484 hideLoading(); 485 $("#cart-message").html(data.message); 486 $("#cart-message").show(); 487 } 488 489 if (contains) { location.reload() } 490 }, 491 error: function (error) { 492 console.log(error.responseText); 493 } 494 }); 495 } 496 497 function increaseQty(itemId) { 498 hideCartMessage(); 499 500 var id = itemId; 501 502 var qty = $("#cart-qty-" + itemId).val(); 503 if (!qty || isNaN(qty)) { 504 updateCartMessage("The current quantity of the item is not a valid number"); 505 return; 506 } 507 508 // increase the qty 509 qty++; 510 511 $.ajax({
512 type: "GET", 513 contentType: "application/json; charset=utf-8", 514 dataType: "json", 515 url: baseUrl + 'api/ProductApi/changeOrderItem/?id=' + id + "&orderId=" + orderId + "&qty=1", 516 517 success: function (data) { 518 if (data.success) { 519 var href = window.location.href; 520 var contains = href.includes("Order"); 521 displayCart() 522 } 523 else { 524 displayCart() 525 updateCartMessage(data.message); 526 } 527 528 if (contains) { location.reload() } 529 }, 530 error: function (error) { 531 console.log(error.responseText); 532 } 533 }); 534 } 535 536 function decreaseQty(itemId) { 537 hideCartMessage(); 538 539 var id = itemId; 540 541 var qty = $("#cart-qty-" + itemId).val(); 542 if (!qty || isNaN(qty)) { 543 updateCartMessage("The current quantity of the item is not a valid number"); 544 return; 545 } 546 547 // decrease the qty 548 qty--; 549 550 if (qty <= 0) { 551 deleteOrderItem(itemId); 552 return; 553 } 554 555 $.ajax({
556 type: "GET", 557 contentType: "application/json; charset=utf-8", 558 dataType: "json", 559 url: baseUrl + 'api/ProductApi/changeOrderItem/?id=' + id + "&orderId=" + orderId + "&qty=-1", 560 561 success: function (data) { 562 if (data.success) { 563 var href = window.location.href; 564 var contains = href.includes("Order"); 565 displayCart() 566 } 567 else { 568 displayCart() 569 570 $("#cart-message").html(data.message); 571 $("#cart-message").show(); 572 } 573 574 if (contains) { location.reload() } 575 }, 576 error: function (error) { 577 console.log(error.responseText); 578 } 579 }); 580 } 581 582 // -- Scroll-lock helpers for native <dialog> elements (shared by all six site dialogs) -- 583 // Measures and compensates for scrollbar width to prevent layout shift on lock. 584 var _dialogOpenCount = 0; 585 586 // -- Focus-trap helpers (2.1.2) -- 587 // Attaches/detaches a keydown handler on the dialog that manually cycles 588 // Tab/Shift+Tab between the first and last focusable elements. 589 // This is a belt-and-suspenders fallback: showModal() should trap focus 590 // natively, but Chromium's built-in trap breaks when overflow is set on 591 // the <dialog> element itself (crbug.com/1450137). Even after fixing that 592 // CSS bug we keep this handler so the trap works in all supported browsers. 593 var FOCUSABLE_SELECTORS = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'; 594 595 function _trapFocus(e) { 596 if (e.key !== 'Tab') return; 597 var dlg = e.currentTarget; 598 // Filter to elements that are actually reachable by the browser's tab order: 599 // hidden UIKit switcher panels (display:none) satisfy the selector but are 600 // skipped by the browser, making our computed "last" wrong and causing escape. 601 var focusable = Array.prototype.slice.call(dlg.querySelectorAll(FOCUSABLE_SELECTORS)).filter(function (el) { 602 return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length); 603 }); 604 if (!focusable.length) { e.preventDefault(); return; } 605 var first = focusable[0]; 606 var last = focusable[focusable.length - 1]; 607 // document.activeElement can equal dlg itself when Chromium places the 608 // <dialog> element at the end of its own tab cycle (after all children).
609 // Without this check the condition below would be false and focus would 610 // escape to the browser chrome on the very next Tab press. 611 if (e.shiftKey) { 612 if (document.activeElement === first || document.activeElement === dlg) { e.preventDefault(); last.focus(); } 613 } else { 614 if (document.activeElement === last || document.activeElement === dlg) { e.preventDefault(); first.focus(); } 615 } 616 } 617 618 function openDialog(dlg) { 619 if (dlg.open) return; 620 if (_dialogOpenCount === 0) { 621 var sw = window.innerWidth - document.documentElement.clientWidth; 622 document.body.style.paddingRight = sw > 0 ? sw + 'px' : ''; 623 document.body.style.overflow = 'hidden'; 624 } 625 _dialogOpenCount++; 626 dlg.showModal(); 627 dlg.addEventListener('keydown', _trapFocus); 628 } 629 function closeDialog(dlg) { 630 if (!dlg.open) return; 631 dlg.removeEventListener('keydown', _trapFocus); 632 dlg.close(); 633 _dialogOpenCount = Math.max(0, _dialogOpenCount - 1); 634 if (_dialogOpenCount === 0) { 635 document.body.style.overflow = ''; 636 document.body.style.paddingRight = ''; 637 } 638 } 639 // -- End scroll-lock / focus-trap helpers -- 640 641 function openCart() { 642 var dlg = document.getElementById('shopping-cart'); 643 if (!dlg.open) { openDialog(dlg); } 644 var trigger = document.getElementById('cart-trigger-btn'); 645 if (trigger) trigger.setAttribute('aria-expanded', 'true'); 646 // Focus the first static element immediately so Escape works from the start 647 var continueShopping = document.getElementById('cart-continue-shopping'); 648 if (continueShopping) continueShopping.focus(); 649 // Refresh cart data; re-focus the first interactive element once content is rendered 650 displayCart(function () { 651 var first = dlg.querySelector('button:not([disabled]), a[href], input:not([disabled])'); 652 if (first) first.focus(); 653 }); 654 } 655 656 function closeCart() { 657 var dlg = document.getElementById('shopping-cart'); 658 closeDialog(dlg); 659 } 660 661 // -- Cart focus management (ACC-001 / ACC-027b) -------------------------- 662 // This script runs at end of <body>, so DOM is already ready â no 663 // DOMContentLoaded wrapper needed (and it would never fire anyway). 664 (function () { 665 var cartDlg = document.getElementById('shopping-cart'); 666 if (!cartDlg) return; 667 668 // Return focus to the trigger and reset aria-expanded on any close 669 cartDlg.addEventListener('close', function () { 670 var trigger = document.getElementById('cart-trigger-btn'); 671 if (trigger) { 672 trigger.setAttribute('aria-expanded', 'false'); 673 trigger.focus(); 674 } 675 }); 676 677 // Backdrop click: click on the <dialog> element itself (not its children) 678 cartDlg.addEventListener('click', function (e) { 679 if (e.target === this) closeDialog(this); 680 }); 681 }()); 682 // -- End cart focus management ----------------------------------------- 683 684 function announceStatus(message) { 685 var el = document.getElementById("aria-status"); 686 if (el) { 687 el.textContent = ""; 688 setTimeout(function () { el.textContent = message; }, 50); 689 } 690 } 691 692 // -- Modal focus management utility (T2-011) -- 693 // lfmOpenModal(modalId, triggerEl) - opens a UIKit modal and records the 694 // trigger so focus is returned to it automatically when the modal closes. 695 // lfmCloseModal(modalId) - programmatically closes a UIKit modal. 696 (function () { 697 var _triggers = {}; 698 699 window.lfmOpenModal = function (modalId, triggerEl) { 700 _triggers[modalId] = triggerEl || document.activeElement; 701 UIkit.modal(modalId).show(); 702 }; 703 704 window.lfmCloseModal = function (modalId) { 705 UIkit.modal(modalId).hide(); 706 }; 707 708 // Return focus to the recorded trigger element when any modal closes, 709 // and detach the focus trap from the inner dialog div. 710 UIkit.util.on(document, 'hidden', '.uk-modal', function (e) { 711 var id = '#' + e.target.id; 712 var dialog = e.target.querySelector('[role="dialog"], .uk-modal-dialog'); 713 if (dialog) { dialog.removeEventListener('keydown', _trapFocus); } 714 var trigger = _triggers[id]; 715 if (trigger && typeof trigger.focus === 'function') { 716 trigger.focus(); 717 } 718 delete _triggers[id]; 719 }); 720
721 // On open: stamp ARIA roles/labels, attach focus trap, move focus to first element. 722 UIkit.util.on(document, 'shown', '.uk-modal', function (e) { 723 var FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'; 724 var dialog = e.target.querySelector('[role="dialog"], .uk-modal-dialog'); 725 if (!dialog) return; 726 727 // -- 4.1.2 / 1.3.1: ensure role, aria-modal, aria-labelledby on every modal -- 728 if (!dialog.getAttribute('role')) { 729 dialog.setAttribute('role', 'dialog'); 730 } 731 if (!dialog.getAttribute('aria-modal')) { 732 dialog.setAttribute('aria-modal', 'true'); 733 } 734 if (!dialog.getAttribute('aria-labelledby')) { 735 // Look for a title element with an id inside .uk-modal-title 736 var titleEl = dialog.querySelector('.uk-modal-title [id], .uk-modal-title[id]'); 737 if (titleEl) { 738 var titleId = titleEl.id || titleEl.getAttribute('id'); 739 if (titleId) { 740 dialog.setAttribute('aria-labelledby', titleId); 741 } 742 } 743 } 744 // -- end ARIA stamp -- 745 746 dialog.addEventListener('keydown', _trapFocus); 747 var first = dialog.querySelector(FOCUSABLE); 748 if (first) { first.focus(); } 749 }); 750 }()); 751 // -- End modal focus management utility -- 752 </script>
752 753</body> 754</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.