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