Error executing template "Designs/Rapido/ContentPage/Paragraph/ClubgearOverview.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_6d457ade26564b8cb6d1dba44df99f88.Execute() in D:\dynamicweb.net\Solutions\Mennt\chrisco-sport.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\ContentPage\Paragraph\ClubgearOverview.cshtml:line 12
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using System.Web; 3 @using Dynamicweb.Security.UserManagement; 4 @using Dynamicweb.Security.UserManagement.Common.CustomFields; 5 @using Dynamicweb.Core; 6 7 8 9 @{ 10 User currentUser = User.GetCurrentExtranetUser(); 11 string listFeedUrl = string.Format("/Default.aspx?ID={0}", GetPageIdByNavigationTag("clubgear")); 12 var userName = currentUser.Name; 13 var userImage = currentUser.Image; 14 var userColors = currentUser.CustomFieldValues.Find(x => x.CustomField.SystemName == "AccessUser_Colors"); 15 var userColorsValue = userColors.Value.ToString().Split(','); 16 string[] products = HttpContext.Current.Request.QueryString.Get("products").Split(','); 17 int productCounter = 1; 18 } 19 20 21 @*Klubb logo + farger start*@ 22 <div style="display:flex; flex-direction:column; align-items: center;"> 23 <div class="clubLogo" style="margin: 5rem auto 1rem;"> 24 <img style="width: 100%;" src="@userImage"></img> 25 </div> 26 <div style="text-align: center; width: 100%; padding: 3rem; border-bottom: solid 2px black"> 27 <h1 style="font-weight: bolder; font-size: 4rem; text-transform: uppercase; margin-bottom: 0.5rem;">@userName</h1> 28 <div style="display:block; margin-top: 2rem;"> 29 @foreach (var color in userColorsValue) 30 { 31 var colorFormatted = color.Replace(" ", ""); 32 <span class="dot" style="background-color: #@colorFormatted;"></span> 33 } 34 </div> 35 </div> 36 </div> 37 @*Klubb logo + farger end*@ 38 39 @*Page info + button start*@ 40 <div class="headingContainer"> 41 <div style="justify-self: start;"> 42 <a href="/Default.aspx?ID=6860" type="button" id="prevBtn" class="btn"><i class="fas fa-arrow-left fa-1_5x" style="margin-right: 2rem;"></i>Gå tilbake</a> 43 </div> 44 <div style="grid-column: 2/3; text-align: center;"> 45 <h2 style="font-size: 3rem;">Valgte klubbtøy</h2> 46 <p style="margin-top: 1.5rem; margin-bottom: 0rem;">Gå over og velg størrelse på dine </br> valgte klubbtøy</p> 47 </div> 48 @if (Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Mobile) 49 { 50 <div class="addToCart"> 51 <form id="basketForm" action='/handlekurv' method="post"></form> 52 <button type="button" onclick="addToBasket()" id="nextBtn" class="btn disabled">Legg i handlekurv<i class="fas fa-arrow-right fa-1_5x" style="margin-left: 2rem;"></i></button> 53 </div> 54 }else{ 55 <div style="justify-self: end;"> 56 <form id="basketForm" action='/handlekurv' method="post"></form> 57 <button type="button" onclick="addToBasket()" id="nextBtn" class="btn disabled">Legg i handlekurv<i class="fas fa-arrow-right fa-1_5x" style="margin-left: 2rem;"></i></button> 58 </div> 59 } 60 </div> 61 @*Page info + button end*@ 62 63 @*Klubbtøy container start*@ 64 <div class="grid__col-md-12" style="margin: 2rem auto; "> 65 <div class="ClubGearOverview"> 66 @foreach (var item in products) 67 { 68 var product = Dynamicweb.Ecommerce.Products.Product.GetProductById(item); 69 var image = "/Files/Images/Produktbilder/" + product.Id + ".jpg"; 70 var bom = product.Items; 71 var fabric = product.ProductFieldValues.GetProductFieldValue("FabricInformation"); 72 var fabricString = fabric.Value.ToString(); 73 74 List<string> variantOptionList = new List<string>(); 75 foreach (var variantCombination in product.VariantCombinationsWithStockCheck) 76 { 77 variantOptionList.Add(variantCombination.VariantId); 78 } 79 string variantOptionListFlat = String.Join(",", variantOptionList); 80 81 <div class="card ClubItemsOverview" data-item="@item"> 82 <div class="productImg"> 83 <img src="@image" style="max-height: 250px; padding: 2rem; margin: 0 auto; "></img> 84 </div> 85 <div class="ClubGearInfo ClubInfoOverview"> 86 <h2 style="margin: 1rem 0rem; font-weight: bold; font-size: 2.5rem;">@product.Name</h2> 87 88 <div> 89 <p style="font-weight: 500; margin: 0.6rem 0rem;">Varenummer: @product.Id</p> 90 <p style="font-weight: light; margin: 0.6rem 0rem;" class="">@fabricString</p> 91 92 @* PAKKEN INNEHOLDER *@ 93 <p style="font-weight: light;" class="u-no-margin">@Translate("Inkludert:")</p> 94 @if (bom != null) 95 { 96 foreach (Dynamicweb.Ecommerce.Products.ProductItem parts in bom) 97 { 98 if (parts.Products != null) 99 { 100 foreach (var part in parts.Products) 101 { 102 <p style="font-weight: light;" class="u-no-margin">@part.Name</p> 103 } 104 } 105 106 } 107 } 108 @* SLUTT PAKKEN INNEHOLDER *@ 109 </div> 110 111 112 <div class="chosenProduct" data-product="@item" data-variant-options="@variantOptionListFlat"> 113 @foreach (var variantGroup in product.VariantGroups) 114 { 115 string variantGroupName = variantGroup.GetLabel("LANG17"); 116 if (variantGroupName == "SIZE"){ 117 <div class="variantgroup" id="clubSizes" data-id="@variantGroup.Id"> 118 @foreach (var option in variantGroup.GetVariantOptions(product.Id)) 119 { 120 if (variantOptionListFlat.Contains(option.Id)) 121 { 122 string optionName = option.GetName("LANG17"); 123 string optionId = option.Id; 124 <div onclick="selectVariantOption(this)" class="btn variantOption" data-product="@item" data-variant-group="@variantGroup.Id" data-variant-value="@optionId">@optionName</div> 125 } 126 } 127 </div> 128 } 129 } 130 131 <div class="red chosenProductError hidden">Vennligst velg variant.</div> 132 </div> 133 134 @*<form id="clubSizes" class="u-margin"> 135 <div class="btn">XS</div> 136 <div class="btn">S</div> 137 <div class="btn">M</div> 138 <div class="btn">L</div> 139 <div class="btn">XL</div> 140 </form>*@ 141 </div> 142 <div class="productButtons"> 143 @if (Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Mobile) 144 { 145 146 <div id="addGearMobile"> 147 <a class="btn" onclick="copyProduct(this)"><i class="fas fa-plus fa-1_5x" id="addGearI" style="margin-right: 0.5rem;"></i>Kopier vare</a> 148 </div> 149 150 } 151 else 152 { 153 154 <div id="addGearBtn"> 155 <a type="button" class="btn" onclick="copyProduct(this)"><i class="fas fa-plus fa-1_5x" id="addGearI"></i></a> 156 </div> 157 158 } 159 <div id="deleteProduct"> 160 <a class="btn" onclick="removeProduct(this)"><i class="far fa-trash-alt fa-1_5x" style="margin-right: 0.5rem;"></i>Fjern vare</a> 161 </div> 162 </div> 163 </div> 164 } 165 </div> 166 167 </div> 168 @*Klubbtøy container end*@ 169 170 <script> 171 172 173 174 175 function removeProduct(e) { 176 const card = e.closest('.card'); 177 178 if (card) { 179 const item = card.dataset.item; 180 181 let products = JSON.parse(sessionStorage.getItem('products')) ?? []; 182 products.splice(products.indexOf(item), 1); 183 sessionStorage.setItem("products", JSON.stringify(products)); 184 185 card.remove(); 186 187 const params = new URLSearchParams(location.search); 188 params.set('products', products.join(',')); 189 window.history.replaceState({}, '', `${location.pathname}?${params}`); 190 } 191 } 192 193 function copyProduct(e) { 194 const card = e.closest('.card'); 195 196 if (card) { 197 const item = card.dataset.item; 198 199 let products = JSON.parse(sessionStorage.getItem('products')) ?? []; 200 products.push(item); 201 sessionStorage.setItem("products", JSON.stringify(products)); 202 203 let clone = card.cloneNode(true); 204 card.parentElement.appendChild(clone); 205 206 const params = new URLSearchParams(location.search); 207 params.set('products', products.join(',')); 208 window.history.replaceState({}, '', `${location.pathname}?${params}`); 209 } 210 } 211 212 function addToBasket() { 213 const chosenProducts = document.getElementsByClassName('chosenProduct'); 214 let errors = 0; 215 let validItems = []; 216 217 for (let i = 0; i < chosenProducts.length; i++) { 218 const selectedVariantOptions = chosenProducts[i].getElementsByClassName('selectedVariantOption'); 219 const variantgroups = chosenProducts[i].getElementsByClassName('variantgroup'); 220 const chosenProductError = chosenProducts[i].getElementsByClassName('chosenProductError'); 221 222 if (selectedVariantOptions.length < variantgroups.length) { 223 if (chosenProductError && chosenProductError.length > 0) { 224 chosenProductError[0].classList.remove('hidden'); 225 errors++; 226 } 227 } else { 228 chosenProductError[0].classList.add('hidden'); 229 230 let selectedVariantValues = []; 231 for (let ii = 0; ii < selectedVariantOptions.length; ii++) { 232 selectedVariantValues.push(selectedVariantOptions[ii].dataset.variantValue); 233 } 234 235 validItems.push({ 236 productId: chosenProducts[i].dataset.product, 237 variantId: selectedVariantValues.join('.') 238 }); 239 } 240 } 241 console.log(errors) 242 243 if (errors === 0) { 244 const form = document.getElementById('basketForm'); 245 246 if (form) { 247 const cartcmd = document.createElement('input'); 248 cartcmd.setAttribute('type', 'hidden'); 249 cartcmd.setAttribute('name', 'cartcmd'); 250 cartcmd.setAttribute('value', 'addMulti'); 251 form.appendChild(cartcmd); 252 253 const redirect = document.createElement('input'); 254 redirect.setAttribute('type', 'hidden'); 255 redirect.setAttribute('name', 'redirect'); 256 redirect.setAttribute('value', 'false'); 257 form.appendChild(redirect); 258 259 for (let i = 0; i < validItems.length; i++) { 260 const productLoopCounter = document.createElement('input'); 261 productLoopCounter.setAttribute('type', 'hidden'); 262 productLoopCounter.setAttribute('name', `ProductLoopCounter${i+1}`); 263 productLoopCounter.setAttribute('value', `${i+1}`); 264 form.appendChild(productLoopCounter); 265 266 const productId = document.createElement('input'); 267 productId.setAttribute('type', 'hidden'); 268 productId.setAttribute('name', `ProductId${i+1}`); 269 productId.setAttribute('value', `${validItems[i].productId}`); 270 form.appendChild(productId); 271 272 const variantId = document.createElement('input'); 273 variantId.setAttribute('type', 'hidden'); 274 variantId.setAttribute('name', `VariantId${i+1}`); 275 variantId.setAttribute('value', `${validItems[i].variantId}`); 276 form.appendChild(variantId); 277 278 const quantity = document.createElement('input'); 279 quantity.setAttribute('type', 'hidden'); 280 quantity.setAttribute('name', `Quantity${i+1}`); 281 quantity.setAttribute('value', `${1}`); 282 form.appendChild(quantity); 283 } 284 form.submit() 285 } 286 } 287 } 288 289 function selectVariantOption(e) { 290 const card = e.closest('.card'); 291 const el = card.querySelector(`[data-product="${e.dataset.product}"]`); 292 const selected = e.classList.contains('selectedVariantOption'); 293 const variantOptions = card.getElementsByClassName('variantOption'); 294 const ableBuy = document.getElementById("nextBtn"); 295 296 297 298 if (selected) { 299 e.classList.remove('selectedVariantOption'); 300 301 for (let i = 0; i < variantOptions.length; i++) { 302 const variantOption = variantOptions[i]; 303 if ((variantOption.dataset.variantGroup !== e.dataset.variantGroup) && (variantOption.dataset.product === e.dataset.product)) { 304 variantOptions[i].classList.remove('disabled'); 305 } 306 } 307 } else { 308 e.classList.add('selectedVariantOption'); 309 310 311 if (el) { 312 const variantOptionsFlat = el.dataset.variantOptions; 313 const variantOptionsArray = variantOptionsFlat.split(','); 314 315 for (let i = 0; i < variantOptions.length; i++) { 316 const variantOption = variantOptions[i]; 317 318 if ((variantOption.dataset.variantGroup !== e.dataset.variantGroup) && (variantOption.dataset.product === e.dataset.product)) { 319 const variantValue = variantOptions[i].dataset.variantValue; 320 const validVariantOptions = variantOptionsArray.filter(x => x.includes(e.dataset.variantValue)); 321 const matchingVariantOption = validVariantOptions.find(x => x.includes(variantValue)); 322 323 if (matchingVariantOption) { 324 variantOptions[i].classList.remove('disabled'); 325 326 327 } else { 328 variantOptions[i].classList.add('disabled'); 329 330 } 331 } 332 333 if ((variantOption.dataset.variantGroup === e.dataset.variantGroup) && (variantOption.dataset.product === e.dataset.product)) { 334 variantOption.classList.remove('selectedVariantOption'); 335 } 336 } 337 } 338 e.classList.add('selectedVariantOption'); 339 340 } 341 342 const chosenProducts = document.getElementsByClassName('chosenProduct'); 343 let errors = 0; 344 345 for (let i = 0; i < chosenProducts.length; i++) { 346 const selectedVariantOptions = chosenProducts[i].getElementsByClassName('selectedVariantOption'); 347 348 if (selectedVariantOptions.length === 0) { 349 errors++; 350 } 351 } 352 353 if (errors === 0){ 354 ableBuy.classList.remove('disabled'); 355 } else { 356 ableBuy.classList.add('disabled'); 357 } 358 } 359 </script> 360 361 <style> 362 .red { 363 color:red; 364 } 365 366 .hidden { 367 display:none; 368 } 369 370 .clubLogo { 371 clip-path: circle(40% at 50% 50%); 372 width: 100px; 373 display: flex; 374 align-items: center; 375 justify-content: center; 376 } 377 378 .dot { 379 height: 35px; 380 width: 35px; 381 border: 2px solid black; 382 border-radius: 50%; 383 display: inline-block; 384 } 385 386 .headingContainer { 387 margin-top: 5rem; 388 display: grid; 389 grid-template-columns: 1fr 1fr 1fr; 390 justify-content: center; 391 align-items: center; 392 width: 85%; 393 margin: 0 auto; 394 margin-top: 7rem; 395 } 396 397 .selectedGear { 398 border: 5px solid #009FE3; 399 } 400 401 .visibleBtn { 402 display: flex; 403 } 404 405 .hiddenBtn { 406 display: none; 407 } 408 409 #nextBtn { 410 display: flex; 411 justify-content: center; 412 align-items: center; 413 text-transform: uppercase; 414 font-weight: bold; 415 width: 100% !important; 416 padding: 1.5rem !important; 417 background: #009FE3; 418 color: black; 419 } 420 421 #nextBtn:hover { 422 background: #2f3335; 423 color: white; 424 } 425 426 #prevBtn { 427 display: flex; 428 justify-content: center; 429 align-items: center; 430 text-transform: uppercase; 431 font-weight: bold; 432 width: 245px ; 433 padding: 1.5rem !important; 434 background: none; 435 border: none; 436 } 437 438 #prevBtn:hover { 439 background: #2f3335; 440 color: white; 441 } 442 443 .ClubGearContainer { 444 postion: relative; 445 display: grid; 446 grid-template-columns: repeat(3,1fr); 447 grid-template-rows: repeat(2,1fr); 448 grid-gap: 2rem; 449 padding: 0rem 3rem; 450 margin: 2rem 6rem 6rem; 451 } 452 453 .selectedGear { 454 border: 5px solid #009FE3; 455 } 456 457 .selectedVariantOption { 458 border: 2px solid #009FE3 !important; 459 background: #009FE3 !important; 460 } 461 462 .selectedVariantOption:hover { 463 color: white !important; 464 } 465 466 .hide { 467 display: none; 468 } 469 470 .ShowItems:hover .hide { 471 display: block; 472 animation: 0.5s 1 alternate slideup; 473 } 474 475 .ClubGearInfo { 476 position: absolute; 477 background: lightgray; 478 border: 1px solid lightgray; 479 border-radius: 10px; 480 padding: 2rem 0rem; 481 482 width: 90%; 483 } 484 485 /*Overview items*/ 486 .ClubGearOverview { 487 display: grid; 488 grid-template-columns: repeat(2, 1fr); 489 grid-gap: 2rem; 490 margin: 2rem 0rem 6rem; 491 } 492 493 .ClubItemsOverview { 494 display: grid; 495 grid-template-columns: 235px auto; 496 grid-gap: 1.5rem; 497 background: #F9F9F9; 498 margin: 0 auto; 499 width: 100%; 500 align-items: center; 501 justify-items: center; 502 grid-template-rows: 300px; 503 border: 5px solid transparent; 504 } 505 506 .productImg { 507 display:flex; 508 align-items: center; 509 height: 300px; 510 width: 250px; 511 padding: 3rem; 512 background: #fff; 513 border-radius: 10px; 514 } 515 516 .ClubInfoOverview { 517 grid-column: 2/3; 518 background: none; 519 border: none; 520 width: 250px; 521 height: 340px; 522 } 523 524 #clubSizes { 525 margin-top: 2rem; 526 display: grid; 527 grid-template-columns: repeat(3, 1fr); 528 grid-template-rows: repeat(3, 1fr); 529 grid-gap: 1rem; 530 width: 270px; 531 532 } 533 534 #clubSizes div { 535 max-width: 100px; 536 background: #404040; 537 color: #fff; 538 border: 1px solid #404040; 539 border-radius: 5px; 540 font-size: 20px; 541 font-weight: 600; 542 padding: 1rem; 543 margin-bottom: 0rem; 544 line-height: normal; 545 546 } 547 548 #clubSizes div:hover { 549 background: #fff; 550 color: #404040; 551 } 552 553 /*#clubInitials { 554 align-self: flex-end; 555 } 556 557 #clubInitials input { 558 width: 100%; 559 border-radius: 4px; 560 margin-bottom: 0rem; 561 } 562 563 #clubInitials input:nth-child(2) { 564 background: #404040; 565 color: #fff; 566 border: 1px solid #404040; 567 border-radius: 5px; 568 } 569 570 #clubInitials input:nth-child(2):hover { 571 background: #fff; 572 color: #404040; 573 cursor: pointer; 574 }*/ 575 576 #deleteProduct { 577 position: absolute; 578 top: 4px; 579 right: -10px; 580 } 581 582 #deleteProduct a { 583 font-size: 1.3rem; 584 border: none; 585 text-transform: uppercase; 586 } 587 588 #deleteProduct a:hover { 589 color: inherit; 590 text-decoration: underline 2px; 591 text-underline-offset: 5px; 592 } 593 594 #addGearBtn{ 595 position: absolute; 596 top: 7px; 597 left: -10px; 598 display: flex; 599 } 600 601 #addGearBtn p{ 602 margin-bottom: 0rem; 603 font-family: Oswald; 604 font-size: 25px; 605 text-transform: uppercase; 606 } 607 608 #addGearBtn i{ 609 background: #009FE3; 610 display: flex; 611 /* padding: 1.2rem; */ 612 border-radius: 50px; 613 width: 50px; 614 height: 50px; 615 color: white; 616 justify-content: center; 617 align-items: center; 618 } 619 620 #addGearBtn i:hover{ 621 background: #2f3335; 622 } 623 624 #addGearBtn i:hover:after{ 625 content: "Kopier vare"; 626 color: black; 627 font-family: Oswald; 628 font-size: 25px; 629 text-transform: uppercase; 630 position: absolute; 631 top: 18px; 632 right: -130px; 633 } 634 635 #addGearBtn .btn{ 636 border: none; 637 display: flex; 638 align-items: center; 639 } 640 641 #addGearBtn .btn:active{ 642 background-color: transparent; 643 } 644 645 646 </style> 647