Error executing template "Designs/Dwsimple/eCom/Product/Product.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at Hounisen.Website.Helpers.GroupHelper.GetParentsRecursively(Group group, List`1 groupNames)
at CompiledRazorTemplates.Dynamic.RazorEngine_d485c02062d84913b0a8a74a0df16939.Execute() in D:\web\hounisen\Hounisen.Website\Files\Templates\Designs\Dwsimple\eCom\Product\Product.cshtml:line 790
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 @using System.Web;
2 @using System.Net;
3 @using System.Globalization;
4 @using System.Text.RegularExpressions;
5 @using Dynamicweb;
6 @using Dynamicweb.Rendering;
7 @using Dynamicweb.Security.UserManagement;
8 @using System.IO;
9 @using Dynamicweb.Content
10 @using Dynamicweb.Core;
11 @using Dynamicweb.Ecommerce.Products
12 @using Hounisen.Website.Helpers
13 @using HtmlAgilityPack
14 @using VestjyskMarketing.Models;
15
16
17 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
18
19 @using System.Globalization
20 @using Dynamicweb.Content
21 @using Dynamicweb.Ecommerce
22 @using Dynamicweb.Ecommerce.Products
23 @using Dynamicweb.Security.UserManagement
24 @using Hounisen.Website.Helpers
25 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
26
27 @using System.Text.RegularExpressions
28 @using System.Web
29
30
31 @functions{
32 public class WrapMethods
33 {
34 //Gets the contrasting color
35 public static string getContrastYIQ(string hexcolor)
36 {
37 if (hexcolor != "")
38 {
39 hexcolor = Regex.Replace(hexcolor, "[^0-9a-zA-Z]+", "");
40
41 int r = Convert.ToByte(hexcolor.Substring(0, 2), 16);
42 int g = Convert.ToByte(hexcolor.Substring(2, 2), 16);
43 int b = Convert.ToByte(hexcolor.Substring(4, 2), 16);
44 int yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
45
46 if (yiq >= 128)
47 {
48 return "black";
49 }
50 else
51 {
52 return "white";
53 }
54 }
55 else
56 {
57 return "black";
58 }
59 }
60
61
62 //Truncate text
63 public static string Truncate (string value, int count, bool strip=true)
64 {
65 if (strip == true){
66 value = StripHtmlTagByCharArray(value);
67 }
68
69 if (value.Length > count)
70 {
71 value = value.Substring(0, count - 1) + "...";
72 }
73
74 return value;
75 }
76
77
78 //Strip text from HTML
79 public static string StripHtmlTagByCharArray(string htmlString)
80 {
81 char[] array = new char[htmlString.Length];
82 int arrayIndex = 0;
83 bool inside = false;
84
85 for (int i = 0; i < htmlString.Length; i++)
86 {
87 char let = htmlString[i];
88 if (let == '<')
89 {
90 inside = true;
91 continue;
92 }
93 if (let == '>')
94 {
95 inside = false;
96 continue;
97 }
98 if (!inside)
99 {
100 array[arrayIndex] = let;
101 arrayIndex++;
102 }
103 }
104 return new string(array, 0, arrayIndex);
105 }
106
107 //Make the correct count of columns
108 public static string ColumnMaker(int Col, string ScreenSize)
109 {
110 string Columns = "";
111
112 switch (Col)
113 {
114 case 1:
115 Columns = "col-"+ScreenSize+"-12";
116 break;
117
118 case 2:
119 Columns = "col-"+ScreenSize+"-6";
120 break;
121
122 case 3:
123 Columns = "col-"+ScreenSize+"-4";
124 break;
125
126 case 4:
127 Columns = "col-"+ScreenSize+"-3";
128 break;
129
130 default:
131 Columns = "col-"+ScreenSize+"-3";
132 break;
133 }
134
135 return Columns;
136 }
137
138
139 private string Custom(string firstoption, string secondoption)
140 {
141 if (firstoption == "custom")
142 {
143 return secondoption;
144 }
145 else
146 {
147 return firstoption;
148 }
149 }
150 }
151 }
152
153
154
155
156
157
158 @helper GetProductList(dynamic Loop, int ColMD = 3, int ColSM = 3, int ColXS = 1)
159 {
160 int Count = 0;
161
162 int index = 1;
163
164 var embeddedScript = GetString("Ecom:Group:Field.ProductEmbeddedScript");
165 var embedIndex = GetInteger("Ecom:Group:Field.EmbedScriptStartingIndex");
166
167 IFormatProvider jsNumberFormat = new NumberFormatInfo() { NumberDecimalSeparator = ".", NumberGroupSeparator = "" };
168
169
170 var groupService = new GroupService();
171 var productService = new ProductService();
172 var pageService = new PageService();
173
174 // SKI AND Region H
175 bool hasSkiDeal = false;
176 bool hasRegionHDeal = false;
177 bool activateLimitedProducts = false;
178 string limitedProductNumbers = "";
179 var currentUser = User.GetCurrentExtranetUser();
180 if (currentUser != null)
181 {
182 var skiGroup = currentUser.Groups.FirstOrDefault(e => e.Name == "SKI");
183 if (skiGroup != null && !string.IsNullOrEmpty(skiGroup.Name))
184 {
185 hasSkiDeal = true;
186 }
187
188 hasRegionHDeal = Dynamicweb.Core.Converter.ToBoolean(currentUser.CustomFieldValues.Find(f => f.CustomField.SystemName == "AccessUser_RegionH").Value);
189 activateLimitedProducts = Dynamicweb.Core.Converter.ToBoolean(currentUser.CustomFieldValues.Find(f => f.CustomField.SystemName == "AccessUser_ActivateLimitedProducts").Value);
190 limitedProductNumbers = Dynamicweb.Core.Converter.ToString(currentUser.CustomFieldValues.Find(f => f.CustomField.SystemName == "AccessUser_LimitedProductNumbers").Value);
191 }
192
193 List<string> limitedProductNumbersList = new List<string>();
194 if (!String.IsNullOrWhiteSpace(limitedProductNumbers) && activateLimitedProducts)
195 {
196 limitedProductNumbersList = limitedProductNumbers.Split(',').ToList();
197 }
198
199
200 foreach (LoopItem product in Loop)
201 {
202 string GroupLink = "/Default.aspx?ID=" + product.GetString("Ecom:Product.PrimaryOrCurrentPageID") + "&groupid=" + product.GetString("Ecom:Product.PrimaryOrFirstGroupID") + "&productid=" + product.GetString("Ecom:Product.ID");
203 // string GroupLink = product.GetString("Ecom:Product.LinkGroup.Clean");
204 int stock = product.GetInteger("Ecom:Product.Stock");
205 string Name = product.GetString("Ecom:Product.Name");
206 string Description = product.GetString("Ecom:Product.ShortDescription");
207 string prodID = product.GetString("Ecom:Product.ID");
208 string prodVariantID = product.GetString("Ecom:Product.VariantID");
209 string prodLanguageID = product.GetString("Ecom:Product.LanguageID");
210 string Image = "/Admin/Public/GetImage.ashx?Image=/Files/Images/Ecom/Products/" + prodID + ".jpg&format=webp&quality=85";
211
212 //prices and units
213 string defaultUnitId = product.GetString("Ecom:Product.DefaultUnitID");
214 var prices = product.GetLoop("Product.Prices");
215 List<string> pricesHtmlList = Hounisen.Website.Helpers.Helpers.PricesListMakeListString(prices);
216 List<Hounisen.Website.Models.Unit> unitsDropdown = Hounisen.Website.Helpers.Helpers.PopulateUnitsDropdown(prices);
217 var unitDefault = unitsDropdown.Where(x => x.Id.Equals(defaultUnitId)).FirstOrDefault();
218 int minOrder = unitDefault != null ? unitDefault.MinOrder : 1;
219
220 if (!string.IsNullOrWhiteSpace(product.GetString("Ecom:Product.SelectedVariantComboID")))
221 {
222 prodID = product.GetString("Ecom:Product.ID") + "&" + product.GetString("Ecom:Product.SelectedVariantComboID");
223 }
224
225
226 GroupHelper gh = new GroupHelper();
227 var masterPage = pageService.GetPage(product.GetInteger("Ecom:Product.PrimaryOrCurrentPageID"));
228 masterPage.GetDisplayName();
229
230 var group = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(product.GetString("Ecom:Product.PrimaryOrFirstGroupID"));
231 var groups = "";
232 if (group != null)
233 {
234 var groupNames = gh.GetParentsRecursively(group, new List<string>());
235 groupNames = gh.Format(groupNames, masterPage.GetDisplayName(), group);
236 groups = gh.ListToString(groupNames);
237 }
238
239 // should the button for adding to cart be disabled and show different text
240 bool showLimitedProduct = false;
241 if (activateLimitedProducts)
242 {
243 showLimitedProduct = true;
244 if (limitedProductNumbersList.Count > 0 && limitedProductNumbersList.Contains(product.GetString("Ecom:Product.Number")))
245 {
246 showLimitedProduct = false;
247 }
248 }
249
250 <div class="product-list__item">
251 <div class="col-xs-12">
252 <div class="product-list__item-inner">
253 <div class="col-xs-12 col-sm-4 col-flex">
254
255 <div class="product-list-item__primary-image">
256 @if (currentUser != null)
257 {
258 <a href="@GroupLink" title="@Name">
259 <img class="product-list-item__image lazy" alt="@Name" data-src="@Image&width=300" class="img-responsive img-center">
260 </a>
261 <a class="fancybox" data-fancybox href="@Image&width=1000" title="@Name">
262 <svg class="product-list-item__image-icon">
263 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/dist/icons/icons.svg#fullscreen"></use>
264 </svg>
265 </a>
266 }
267 else
268 {
269 <a href="@GroupLink" title="@Name">
270 <img class="product-list-item__image lazy" alt="@Name" data-src="@Image&width=300" class="img-responsive img-center">
271 </a>
272 <a class="fancybox" data-fancybox href="@Image&width=1000" title="@Name">
273 <svg class="product-list-item__image-icon">
274 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/dist/icons/icons.svg#fullscreen"></use>
275 </svg>
276 </a>
277 }
278
279
280 </div>
281 @{
282 var productObj = productService.GetProductById(prodID, prodVariantID, prodLanguageID);
283 var overlayNameAndColors = new ProductImageOverlayHelper().GetTextAndColor(productObj);
284
285 <div class="product__primary-image__overlay-container">
286 @foreach (var overlayNameAndColo in overlayNameAndColors)
287 {
288 <div style="background-color: @overlayNameAndColo.Value" class="product__primary-image__overlay-container__item">
289 @overlayNameAndColo.Key
290 </div>
291 }
292 </div>}
293 </div>
294 <div class="col-xs-12 col-sm-8">
295 <div class="product-list-item__info js-product-info">
296 <div class="row">
297 @*Title & Number*@
298 <div class="col-xs-12">
299 <h4 data-name="@Name" data-product_id="@prodID" data-categories="@groups" class="product-list-item__title">
300 <a class="product-list-item__title-link" href="@GroupLink">@Name</a>
301 </h4>
302 </div>
303 </div>
304 <div class="row">
305 <div class="col-xs-12 col-sm-5">
306
307 <div class="product-list-item__attributes">
308 <p>
309 <strong>Varenummer:</strong> @product.GetString("Ecom:Product.Number")
310 </p>
311 <p>
312 <strong>@product.GetString("Ecom:Product:Field.Attribut1A"):</strong><br />@product.GetString("Ecom:Product:Field.Attribut1B")
313 </p>
314 <p>
315 <strong>@product.GetString("Ecom:Product:Field.Attribut2A"):</strong> @product.GetString("Ecom:Product:Field.Attribut2B")
316 </p>
317 </div>
318
319 <div class="hidden-xs">
320 <div class="">
321 @* IKONER *@
322 <div class="product-list-item__icons">
323 @{
324 foreach (var c in product.GetString("Ecom:Product:Field.Certificates").Split(','))
325 {
326 if (!string.IsNullOrEmpty(c))
327 {
328 string src = "/Admin/Public/GetImage.ashx?Image=/Files/Images/Ecom/Certificates/" + @c + ".jpg&format=webp&quality=85&width=100";
329 <img class="product-list-item__icon lazy" alt="@Translate("Cert_" + c, c)" title="@Translate("Cert_" + c, c)" data-src=@src src=@src>
330 }
331 }
332 }
333 </div>
334 </div>
335 </div>
336 </div>
337
338 <div class="col-xs-12 col-sm-7">
339 @if (Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")))
340 {
341 <ul class="product-list-item__prices">
342 @foreach (var priceHtml in pricesHtmlList)
343 {
344 <li>
345 @priceHtml
346 </li>
347 }
348 </ul>
349 }
350 </div>
351 </div>
352
353 <div class="row">
354 <div class="col-xs-12 col-sm-4 col-lg-5">
355 @* LAGERBEHOLDNING *@
356 <div class="product-list-item__stock">
357 @{
358 if (stock > 0)
359 {
360 <p class="product-list-item__stock-text">
361 <span class="product-list-item__stock-circle product-list-item__stock-circle--green"></span> På lager
362 </p>
363 }
364 else
365 {
366 <p class="product-list-item__stock-text">
367 <span class="product-list-item__stock-circle product-list-item__stock-circle--yellow"></span> Kontakt os for leveringstid: 86210800 eller salg@hounisen.com
368 </p>
369 }
370 }
371 </div>
372
373 <div class="product-list-item__see-product">
374 <a class="product-list-item__link" href="@GroupLink" class="">@Translate("See product", "Se produkt")</a>
375 </div>
376 </div>
377 <div class="col-xs-12 col-sm-8 col-lg-7">
378 @if (Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")))
379 {
380 <div class="row">
381 @if (showLimitedProduct)
382 {
383 <div class="col-xs-12">
384 <button class="btn btn--ghost product__button disabled">
385 @Translate("Kan bestilles på fritekstordre", "Kan bestilles på fritekstordre")
386 </button>
387 </div>
388 }
389 else
390 {
391 <div class="col-xs-7">
392 <div class="product__addtocart-input js-addtocart-input">
393 <input type="button" value="-" class="product-list-item__quantity-button product-list-item__quantity-button--minus qtyminus" field="quantity" />
394 <input type="number" class="product__quantity-input product-list-item__quantity-input quantity" data-name="quantity" name="quantity" value="@minOrder" field="quantity" />
395 <input type="button" value="+" class="product-list-item__quantity-button product-list-item__quantity-button--plus qtyplus" field="quantity" />
396 </div>
397 <div class="product__unit-selector" style="display: inline-block;">
398 @{
399 int counter = 0;
400 }
401 @foreach (var unitDropdown in unitsDropdown)
402 {
403 var currentUnitPrice = prices[counter].Values["Ecom:Product.Prices.Amount"];
404 <input type="radio" data-id="@index" data-price="@currentUnitPrice" class="unit-type" id="@(unitDropdown.Id + prodID)" name="UnitID@(product.GetString("Ecom:Product.Number"))" value="@unitDropdown.Id" required data-lot-size="@unitDropdown.LotSize" data-min-order="@unitDropdown.MinOrder" @(unitsDropdown.Count == 1 ? "checked='checked'" : "")>
405 <label for="@(unitDropdown.Id + prodID)">@unitDropdown.Name</label>
406 counter++;
407 }
408 </div>
409 <p class="product__unit-selector-error-message">
410 @Translate("unit-error-message", "* Du mangler at vælge type")
411 </p>
412 </div>
413 <div class="col-xs-5">
414 <div class="product__addtocart-button">
415 <button data-id="@index" type="submit" name="submit" onclick="AddToCart(event, '@prodID', $(this).parent().parent().prev().find('input.quantity').val(), $(this).parent().parent().prev().find('input[name=\'UnitID@(product.GetString("Ecom:Product.Number"))\']:checked').val());" class="btn btn-primary product__button">
416 @Translate("Add to cart", "Add to cart")
417 <svg class="product__button-icon hidden-xs">
418 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/dist/icons/icons.svg#basket"></use>
419 </svg>
420 </button>
421
422 <div class="product-list-item__favorite-list popup-wrap favorite">
423
424 @if (hasRegionHDeal == false)
425 {
426 <button class="popup-show" data-popup="favorite-list" type="button" title="@Translate("Add to favorites", "Add to favorites")">
427 <i class="fa fa-star-o"></i> <span>Tilføj til liste</span>
428 </button>
429 <div id="favorite-list" class="popup-form">
430 <div class="close">
431 <i class="fa fa-times"></i>
432 </div>
433 <h3>@Translate("Choose list", "Choose list")</h3>
434 <ul>
435 @{
436 var lists = Dynamicweb.Ecommerce.CustomerCenter.CustomerProductList.GetListsByUserCustomerNumber(currentUser.CustomerNumber);
437 }
438
439 @foreach (var list in lists)
440 {
441 if (list.Products.Where(p => p.ProductId.ToString() == prodID).Count() > 0)
442 {
443 <li>
444 <a href="@(System.Web.HttpContext.Current.Request.Url)&CCRemoveFromMyLists=@prodID&CCAddToListVariantID=&CCAddToListLanguageID=LANG1&CCAddToListID=@list.ListId&CCListType=">
445 <i class="fa fa-star"></i> @list.Name
446 </a>
447 </li>
448 }
449 else
450 {
451 <li>
452 <a href="@(System.Web.HttpContext.Current.Request.Url)&CCAddToMyLists=@prodID&CCAddToListVariantID=&CCAddToListLanguageID=LANG1&CCAddToListID=@list.ListId&CCListType=">
453 <i class="fa fa-star-o"></i> @list.Name
454 </a>
455 </li>
456 }
457 }
458 <li>
459 <a href="/mine-favoritter/opret-favoritliste?ProdID=@prodID">
460 <i class="fa fa-plus"></i>@Translate("Add new list", "Add new list")
461 </a>
462 </li>
463 </ul>
464 </div>
465 }
466
467 </div>
468 </div>
469 </div>
470 }
471
472 </div>
473 }
474 else
475 {
476 <div class="not-loggedin">
477 <p class="not-loggedin-text"><a data-toggle="modal" data-target="#login" href="">@Translate("Login", "Login")</a> eller <a href="/kontakt/opret-brugerprofil">Bliv kunde</a> for at se priser og købe på Hounisen.com</p>
478 <a data-toggle="modal" data-target="#login" href="" class="btn btn-primary not-loggedin-button">
479 <span>Log ind</span>
480 </a>
481 </div>
482 }
483 </div>
484 </div>
485 </div>
486
487
488 </div>
489 </div>
490 </div>
491 </div>
492
493 if (index == embedIndex)
494 {
495 <div class="product-list__item">
496 <div class="col-xs-12">
497 @embeddedScript
498 </div>
499 </div>
500 }
501
502
503 Count++;
504 index++;
505
506 if (Count == ColMD)
507 {
508 <div class="row"></div>
509 Count = 0;
510 }
511 }
512 }
513
514 <script>
515
516 document.addEventListener("DOMContentLoaded", function () {
517
518 var addToCartButtons = document.querySelectorAll('.product__button');
519 var unitTypes = document.getElementsByClassName("unit-type");
520 var product_names = document.getElementsByClassName("product-list-item__title");
521
522 addToCartButtons.forEach(function (item) {
523
524 item.addEventListener('click', function () {
525
526 var product_name = product_names[this.dataset.id - 1].dataset.name;
527 var product_id = product_names[this.dataset.id - 1].dataset.product_id;
528 var initialCategories = product_names[this.dataset.id - 1].dataset.categories;
529 var categories = initialCategories.split("_");
530 var quantity = document.getElementsByClassName("quantity")[this.dataset.id - 1].value;
531 var unitPrice;
532 var variantIsNull = true;
533 var unitTypeName = null;
534
535 //Get unittype price
536 for (const unitType of unitTypes) {
537
538 if (unitType.dataset.id == this.dataset.id) {
539
540 if (unitType.checked == true) {
541
542 var tempPrice = unitType.dataset.price.replace(".", "");
543 tempPrice = tempPrice.replace(",", ".");
544 unitPrice = parseFloat(tempPrice);
545 variantIsNull = false;
546 unitTypeName = unitType.value;
547
548 unitTypeName = unitTypeName.toString().split("_")[1];
549
550 }
551 }
552 }
553
554 if (!variantIsNull) {
555 dataLayer.push({ ecommerce: null });
556 dataLayer.push({
557 'event': 'add_to_cart',
558 "ecommerce": {
559 "currency": "DKK",
560 "value": unitPrice * parseInt(quantity).toFixed(2),
561 "items": [
562 {
563 "item_name": product_name + " - " + unitTypeName,
564 'item_id': product_id,
565 'price': unitPrice,
566 "item_brand": "",
567 "item_category": (categories[0] != null ? categories[0] : ""),
568 "item_category2": (categories[1] != null ? categories[1] : ""),
569 "item_category3": (categories[2] != null ? categories[2] : ""),
570 "item_category4": (categories[3] != null ? categories[3] : ""),
571 "item_category5": (categories[4] != null ? categories[4] : ""),
572 "quantity": parseInt(quantity),
573 }
574 ]
575 },
576
577 });
578 }
579 });
580 })
581 });
582
583 </script>
584 @using Dynamicweb.Security.UserManagement
585 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
586
587 @helper GetProductListRelated(dynamic Loop, int ColMD = 3, int ColSM = 3, int ColXS = 1)
588 {
589 var currentUser = User.GetCurrentExtranetUser();
590
591 <ul class="shop-list__list">
592
593 @foreach (LoopItem product in Loop)
594 {
595
596 string GroupLink = "/Default.aspx?ID=" + product.GetString("Ecom:Product.PrimaryOrCurrentPageID") + "&groupid=" + product.GetString("Ecom:Product.PrimaryOrFirstGroupID") + "&productid=" + product.GetString("Ecom:Product.ID");
597 string Name = product.GetString("Ecom:Product.Name");
598 string Description = product.GetString("Ecom:Product.ShortDescription");
599 string prodID = product.GetString("Ecom:Product.ID");
600 string Image = "/Admin/Public/GetImage.ashx?Image=/Files/Images/Ecom/Products/" + prodID + ".jpg&format=webp&quality=85";
601
602 <li class="shop-list__item col-xs-12">
603 <a class="shop-list__link" href="@GroupLink" title="@Name">
604 <figure class="shop-list__figure">
605 <img class="shop-list__image lazy" style="width: 213px;" alt="@Name" data-src="@Image&width=213">
606 </figure>
607 <h4 class="shop-list__title">@Name</h4>
608 <div class="shop-list__text">
609 @if (String.IsNullOrEmpty(product.GetString("Ecom:Product.LongDescription")))
610 {
611 var gr = Dynamicweb.Ecommerce.Products.Group.GetGroupById(product.GetString("Ecom:Product.PrimaryOrFirstGroupID"));
612
613 @gr.Description.Replace("<a ", "<span ").Replace("</a>", "</span>").Replace("<h2>", "<p>").Replace("</h2>", "</p>")
614 }
615 else
616 {
617 @product.GetString("Ecom:Product.LongDescription").Replace("<a ", "<span ").Replace("</a>", "</span>").Replace("<h2>", "<p>").Replace("</h2>", "</p>")
618 }
619
620 </div>
621 <div class="shop-list__price">
622 @if (currentUser != null)
623 {
624 string baseUnitPrice = String.Empty;
625 var price = product.GetLoop("Product.Prices").OrderBy(x => x.GetDouble("Ecom:Product.Prices.BaseUnitPrice")).FirstOrDefault();
626 if (price != null)
627 {
628 baseUnitPrice = price.GetString("Ecom:Product.Prices.BaseUnitPrice");
629 }
630 <span class="shop-list__price-from">Priser fra</span>
631 <span class="shop-list__price-value">@baseUnitPrice</span>
632 <span class="shop-list__price-unit">kr./stk.</span>
633 }
634 </div>
635 </a>
636 </li>
637
638 }
639 </ul>
640 }
641
642
643 @using Dynamicweb.Security.UserManagement
644 @using System.Text.RegularExpressions;
645 @using Hounisen.Website.Helpers
646 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
647
648 @helper GetProductListFullRelated(dynamic Loop, int ColMD = 4, int ColSM = 4, int ColXS = 1)
649 {
650 int Count = 0;
651
652 string ColumnsMD = WrapMethods.ColumnMaker(ColMD, "md");
653 string ColumnsSM = WrapMethods.ColumnMaker(ColSM, "sm");
654 string ColumnsXS = WrapMethods.ColumnMaker(ColXS, "xs");
655 var currentUser = User.GetCurrentExtranetUser();
656
657 foreach (LoopItem product in Loop)
658 {
659 string GroupLink = "/Default.aspx?ID=" + product.GetString("Ecom:Product.PrimaryOrCurrentPageID") + "&groupid=" + product.GetString("Ecom:Product.PrimaryOrFirstGroupID") + "&productid=" + product.GetString("Ecom:Product.ID");
660 string Name = product.GetString("Ecom:Product.Name");
661 string Description = GetFormattedDescription(product.GetString("Ecom:Product.LongDescription"));
662 string prodID = product.GetString("Ecom:Product.ID");
663 string Image = "/Admin/Public/GetImage.ashx?Image=/Files/Images/Ecom/Products/" + prodID + ".jpg&format=webp&quality=85";
664 var productObject = Dynamicweb.Ecommerce.Products.Product.GetProductById(product.GetString("Ecom:Product.ID"), product.GetString("Ecom:Product.VariantID"), product.GetString("Ecom:Product.LanguageID"));
665 var textAndColors = new ProductImageOverlayHelper().GetTextAndColor(productObject);
666 <li class="shop-list__item col-xs-12">
667 <a class="shop-list__link" href="@GroupLink" title="@Name">
668 <figure class="shop-list__figure" style="position: relative">
669 <img class="shop-list__image lazy" style="width: 213px;" alt="@Name" data-src="@Image&width=213">
670 <div class="product__primary-image__overlay-container">
671 @foreach (var overlayNameAndColor in textAndColors)
672 {
673 <div style="background-color: @overlayNameAndColor.Value" class="product__primary-image__overlay-container__item">
674 @overlayNameAndColor.Key
675 </div>
676 }
677 </div>
678 </figure>
679 <h4 class="shop-list__title">@Name</h4>
680 <div class="shop-list__text">@Description</div>
681 <div class="shop-list__price">
682 @if (currentUser != null)
683 {
684 string baseUnitPrice = String.Empty;
685 var price = product.GetLoop("Product.Prices").OrderBy(x => x.GetDouble("Ecom:Product.Prices.BaseUnitPrice")).FirstOrDefault();
686 if (price != null)
687 {
688 baseUnitPrice = price.GetString("Ecom:Product.Prices.BaseUnitPrice");
689 }
690
691 <span class="shop-list__price-from">Priser fra</span>
692 <span class="shop-list__price-value">@baseUnitPrice</span>
693 <span class="shop-list__price-unit">kr./stk</span>
694 }
695 </div>
696 </a>
697 </li>
698 }
699 }
700
701 @functions {
702 private static string GetFormattedDescription(string description = "")
703 {
704 string formattedDescription = Regex.Replace(description, @"<.*?>|[\r\n\t]| ", " ");
705 return formattedDescription.Length > 103 ? formattedDescription.Substring(0, 103).TrimEnd() + "..." : formattedDescription;
706 }
707 }
708
709 <script src="/Files/Templates/Designs/DwSimple/js/ProductVariantsAjax.js"></script>
710 <link rel="stylesheet" href="/Files/Templates/Designs/DwSimple/css/product.css"/>
711
712 @{
713 IFormatProvider jsNumberFormat = new NumberFormatInfo() { NumberDecimalSeparator = ".", NumberGroupSeparator = "" };
714 string initialPrice = string.Empty;
715 string metaDescription = string.Empty;
716 if (String.IsNullOrEmpty(GetString("Ecom:Product.LongDescription")))
717 {
718 metaDescription = StripHTML(GetString("Ecom:Group.Description"));
719 }
720 else
721 {
722 metaDescription = StripHTML(GetString("Ecom:Product.LongDescription"));
723 }
724
725 bool isMobile = Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Mobile;
726
727 //prices and units
728 string defaultUnitId = GetString("Ecom:Product.DefaultUnitID");
729 var prices = GetLoop("Product.Prices");
730 List<string> pricesHtmlList = Hounisen.Website.Helpers.Helpers.PricesListMakeListString(prices, false);
731 List<Hounisen.Website.Models.Unit> unitsDropdown = Hounisen.Website.Helpers.Helpers.PopulateUnitsDropdown(prices);
732 var unitDefault = unitsDropdown.Where(x => x.Id.Equals(defaultUnitId)).FirstOrDefault();
733 int minOrder = unitDefault != null ? unitDefault.MinOrder : 1;
734
735
736 //other vars
737 var pid = GetString("Ecom:Product.ID");
738 int stock = GetInteger("Ecom:Product.Stock");
739 string image = "/Admin/Public/GetImage.ashx?Image=/Files/Images/Ecom/Products/" + pid + ".jpg";
740 string productname = GetString("Ecom:Product.Name");
741 string productlink = "/Default.aspx?ID=" + GetString("Ecom:Product.PrimaryOrCurrentPageID") + "&groupid=" + GetString("Ecom:Product.PrimaryOrFirstGroupID") + "&productid=" + GetString("Ecom:Product.ID");
742
743
744 // SKI AND Region H
745 bool hasSkiDeal = false;
746 bool hasRegionHDeal = false;
747 bool activateLimitedProducts = false;
748 string limitedProductNumbers = "";
749 var currentUser = User.GetCurrentExtranetUser();
750 if (currentUser != null)
751 {
752 var skiGroup = currentUser.Groups.FirstOrDefault(e => e.Name == "SKI");
753 if (skiGroup != null && !string.IsNullOrEmpty(skiGroup.Name))
754 {
755 hasSkiDeal = true;
756 }
757
758 hasRegionHDeal = Dynamicweb.Core.Converter.ToBoolean(currentUser.CustomFieldValues.Find(f => f.CustomField.SystemName == "AccessUser_RegionH").Value);
759 activateLimitedProducts = Dynamicweb.Core.Converter.ToBoolean(currentUser.CustomFieldValues.Find(f => f.CustomField.SystemName == "AccessUser_ActivateLimitedProducts").Value);
760 limitedProductNumbers = Dynamicweb.Core.Converter.ToString(currentUser.CustomFieldValues.Find(f => f.CustomField.SystemName == "AccessUser_LimitedProductNumbers").Value);
761 }
762
763 List<string> limitedProductNumbersList = new List<string>();
764 if (!String.IsNullOrWhiteSpace(limitedProductNumbers) && activateLimitedProducts)
765 {
766 limitedProductNumbersList = limitedProductNumbers.Split(',').ToList();
767 }
768
769 // should the button for adding to cart be disabled and show different text
770 bool showLimitedProduct = false;
771 if (activateLimitedProducts)
772 {
773 showLimitedProduct = true;
774 if (limitedProductNumbersList.Count > 0 && limitedProductNumbersList.Contains(GetString("Ecom:Product.Number")))
775 {
776 showLimitedProduct = false;
777 }
778 }
779
780 //serialized data
781 var pagedata = new System.Collections.Generic.Dictionary<String, Object>();
782 Pageview.Area.Item.SerializeTo(pagedata);
783
784
785 var pageService = new PageService();
786 GroupHelper gh = new GroupHelper();
787 var group = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(GetString("Ecom:Product.PrimaryOrFirstGroupID"));
788 var masterPage = pageService.GetPage(GetInteger("Ecom:Product.PrimaryOrCurrentPageID"));
789 masterPage.GetDisplayName();
790 var groupNames = gh.GetParentsRecursively(group, new List<string>());
791 groupNames = gh.Format(groupNames, masterPage.GetDisplayName(), group);
792
793 var groups = gh.ListToString(groupNames);
794 }
795
796 <div class="col-md-12 col-sm-12 col-xs-12" style="margin-bottom: 25px">
797
798 <div class="row product" itemscope itemtype="http://schema.org/Product">
799 <section class="page-header" style="margin-top: 15px">
800 <div class="product__help-name-container">
801 <div class="col-xs-12 col-sm-7 p-0">
802 <meta itemprop="description" content="@metaDescription"/>
803 <h1 data-categories="@groups" data-group="@GetString("Ecom:Group.Name")" class="page-header__title" itemprop="name">@GetString("Ecom:Product.Name")</h1>
804 <div class="page-header__short-description">
805 <p class="product__number">@Translate("Productnumber", "Productnumber"): <span property="identifier" itemprop="mpn">@GetString("Ecom:Product.Number")</span></p>
806 @if (hasSkiDeal)
807 {
808 <p class="product__number">@Translate("Skinumber", "SKI nr"): <span property="identifier">@GetString("Ecom:Product:Field.SkiId")</span></p>
809 }
810 @if (hasRegionHDeal && GetBoolean("Ecom:Product:Field.RegionH"))
811 {
812 <p class="product__number">@Translate("RegionHText")</p>
813 }
814
815 </div>
816 </div>
817
818
819 <div class="d-none d-lg-block product__help-name-container__help p-0">
820 <div class="need-help product-view">
821 <img class="need-help__image lazy" width="81" height="81" data-src='@(Pageview.Area.Item["Support_Image"].ToString())?format=webp&width=81&quality=75'/>
822 <div class="need-help__text product-view">
823 @Pageview.Area.Item["Support_Content"].ToString()
824 </div>
825 </div>
826 </div>
827
828
829 </div>
830 </section>
831 <div class="row">
832
833 @* The image area *@
834 <div class="col-md-6 col-sm-4 col-xs-12 product__column">
835 <div class="product__gallery">
836
837 @* Discount sticker *@
838
839 @if (GetString("Ecom:Product.Discount.Price.PriceWithVATFormatted") != GetString("Ecom:Product.Price.PriceWithVATFormatted"))
840 {
841 if (pagedata["EcommerceStickerType"].ToString() == "ribbon")
842 {
843 <span class="ribbon base">@Translate("On sale!", "On sale!")</span>
844 }
845
846 if (pagedata["EcommerceStickerType"].ToString() == "ball")
847 {
848 <span class="ball">@Translate("On sale!", "On sale!")</span>
849 }
850 }
851
852
853 @* Product images *@
854 @{
855 string currenthost = HttpContext.Current.Request.Url.AbsoluteUri;
856 Uri uri = new Uri(currenthost);
857 currenthost = string.Format("{0}://{1}", uri.Scheme, uri.Authority);
858 string ImagePathloop = "";
859 string ImagePathClean = "";
860 string options = "format=webp&quality=85&width=1000";
861 List<string> imagepath = new List<string>();
862
863
864 //i starts at 1 - avoids showing the first image twice
865 for (int i = 1; i <= 5; i++)
866 {
867 ImagePathloop = "/Admin/Public/GetImage.ashx?Image=/Files/Images/Ecom/Products/" + pid + "-0" + i.ToString() + ".jpg";
868 //currenthost +
869 ImagePathClean = "/Files/Images/Ecom/Products/" + pid + "-0" + i.ToString() + ".jpg";
870
871 try
872 {
873 if (File.Exists(HttpContext.Current.Server.MapPath(ImagePathClean)))
874 {
875 imagepath.Add(ImagePathloop + "&" + options);
876 }
877
878 HttpWebRequest request = (HttpWebRequest)System.Net.WebRequest.Create(ImagePathloop);
879 using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
880 {
881 if (response.StatusCode == HttpStatusCode.NotFound)
882 {
883 break;
884 }
885 else
886 {
887 imagepath.Add("/Files/Images/Ecom/Products/" + pid + "-0" + i.ToString() + ".jpg" + "" + options);
888 }
889 }
890 }
891 catch (Exception ex)
892 {
893 }
894 }
895 }
896
897 @{
898 var resizedImageLarge = VestjyskMarketing.Helpers.ImageHelper.ResizeImage(new ResizeImageSettings()
899 {
900 Image = $"/Files/Images/Ecom/Products/{pid}.jpg",
901 Width = 1000,
902 Quality = 99
903 });
904
905 var resizedImage = VestjyskMarketing.Helpers.ImageHelper.ResizeImage(new ResizeImageSettings()
906 {
907 Image = $"/Files/Images/Ecom/Products/{pid}.jpg",
908 Width = 458,
909 Quality = 85
910 });
911 }
912
913 <div class="product__primary-image">
914 <a href="@resizedImageLarge" data-fancybox="product-gallery" class="fancybox">
915 <img src="@resizedImage" data-src="@resizedImage" width="458" alt="@productname" class="product__image img-responsive lazy" itemprop="image">
916 @{
917 var productObj = new ProductService().GetProductById(GetString("Ecom:Product.ID"), GetString("Ecom:Product.VariantID"), GetString("Ecom:Product.LanguageID"));
918 var overlayNameAndColors = new ProductImageOverlayHelper().GetTextAndColor(productObj);
919 }
920
921 <div class="product__primary-image__overlay-container">
922 @foreach (var overlayNameAndColor in overlayNameAndColors)
923 {
924 <div style="background-color: @overlayNameAndColor.Value" class="product__primary-image__overlay-container__item">
925 @overlayNameAndColor.Key
926 </div>
927 }
928 </div>
929 <svg class="product__image-icon">
930 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/dist/icons/icons.svg#fullscreen"></use>
931 </svg>
932 </a>
933 </div>
934 <div class="row">
935 <div class="product__thumbnail-list">
936 @foreach (var imageThumb in imagepath)
937 {
938 <div class="col-sm-3 col-xs-4">
939 <div class="product__thumbnail-images">
940 <a href="@imageThumb&width=1000" data-fancybox="product-gallery" rel="product" class="fancybox">
941 <img data-src="@imageThumb&width=458" width="458" alt="@productname" class="img-responsive lazy">
942 </a>
943 </div>
944 </div>
945 }
946 @{
947 var youtubeId = GetString("Ecom:Product:Field.YoutubeId");
948 // For Fancybox, we typically include “?autoplay=1” in the iframe URL.
949 var youtubeEmbedUrl = $"https://www.youtube.com/embed/{youtubeId}?autoplay=1&enablejsapi=1";
950
951 if (!string.IsNullOrEmpty(youtubeId))
952 {
953 <div class="col-sm-3 col-xs-4">
954 <div class="product__thumbnail-images">
955 <a style="height: 63px" href="@youtubeEmbedUrl"
956 data-fancybox="product-gallery"
957 data-type="iframe"
958 rel="product"
959 class="fancybox">
960 <svg class="product__play-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
961 <path d="M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM188.3 147.1c7.6-4.2 16.8-4.1 24.3 .5l144 88c7.1 4.4 11.5 12.1 11.5 20.5s-4.4 16.1-11.5 20.5l-144 88c-7.4 4.5-16.7 4.7-24.3 .5s-12.3-12.2-12.3-20.9l0-176c0-8.7 4.7-16.7 12.3-20.9z"/>
962 </svg>
963 </a>
964 </div>
965 </div>
966 }
967
968 string mp4Path = GetString("Ecom:Product:Field.ProductVideo.FullPath");
969
970 if (!string.IsNullOrEmpty(mp4Path))
971 {
972 <div class="col-sm-3 col-xs-4">
973 <div class="product__thumbnail-images">
974 <!--
975 Link to a hidden <div> containing our <video>.
976 We use data-fancybox="product-gallery" to group it with our images.
977 data-src="#mp4VideoContent" + data-type="inline" to open inline HTML content.
978 -->
979 <a style="height: 63px" data-fancybox="product-gallery"
980 data-src="#mp4VideoContent"
981 data-type="inline"
982 href="javascript:;">
983 <svg class="product__play-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
984 <path d="M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM188.3 147.1c7.6-4.2 16.8-4.1 24.3 .5l144 88c7.1 4.4 11.5 12.1 11.5 20.5s-4.4 16.1-11.5 20.5l-144 88c-7.4 4.5-16.7 4.7-24.3 .5s-12.3-12.2-12.3-20.9l0-176c0-8.7 4.7-16.7 12.3-20.9z"/>
985 </svg>
986 </a>
987 </div>
988 </div>
989
990 <!-- Hidden HTML content that Fancybox will open -->
991 <div style="display:none;" id="mp4VideoContent">
992 <video controls style="width:100%; height:auto;">
993 <source src="@mp4Path" type="video/mp4"/>
994 <!-- You can add WebM or OGG sources if you like for broader browser support -->
995 Your browser does not support the video tag.
996 </video>
997 </div>
998 }
999 }
1000 </div>
1001 </div>
1002 </div>
1003 <section class="d-block d-lg-none page-header p-0 m-0" style="border: none">
1004 <div class="product__help-name-container">
1005 <div class=" product__help-name-container__help second">
1006 <div class="need-help product-view">
1007 <img class="need-help__image lazy" width="81" height="81" data-src='@(Pageview.Area.Item["Support_Image"].ToString())?format=webp&width=81&quality=75'/>
1008 <div class="need-help__text product-view second">
1009 @Pageview.Area.Item["Support_Content"].ToString()
1010 </div>
1011 </div>
1012 </div>
1013 </div>
1014 </section>
1015 </div>
1016
1017
1018 @* The main product information area *@
1019
1020 <div class="col-md-6 col-sm-8 col-xs-12 product__column">
1021 <div class="product-info js-product-info" id="productinfo">
1022 <div class="product__control">
1023 <div class="row">
1024 <div class="col-xs-12 col-sm-6">
1025 @* LAGERBEHOLDNING *@
1026 <div class="product__stock">
1027 @{
1028 if (stock > 0)
1029 {
1030 <p class="product__stock-text">
1031 <span class="product__stock-circle product__stock-circle--green"></span> På lager
1032 </p>
1033 }
1034 else
1035 {
1036 <p class="product__stock-text">
1037 <span class="product__stock-circle product__stock-circle--yellow"></span> Kontakt os for leveringstid: 86210800 eller salg@hounisen.com
1038 </p>
1039 }
1040 }
1041 </div>
1042 </div>
1043 <div class="col-xs-12 col-sm-6">
1044 @* FAVORITTER *@
1045 @if (Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")))
1046 {
1047 if (hasRegionHDeal == false)
1048 {
1049 <div class="product__favorite-list popup-wrap favorite">
1050 <button class="popup-show" data-popup="favorite-list" type="button" title="@Translate("Add to favorites", "Add to favorites")">
1051 <i class="fa fa-star-o"></i> <span>@Translate("Add to favorites", "Add to favorites")</span>
1052 </button>
1053 <div id="favorite-list" class="popup-form">
1054 <div class="close">
1055 <i class="fa fa-times"></i>
1056 </div>
1057 <h3>@Translate("Choose list", "Choose list")</h3>
1058 <ul>
1059 @{
1060 var lists = Dynamicweb.Ecommerce.CustomerCenter.CustomerProductList.GetListsByUserCustomerNumber(currentUser.CustomerNumber);
1061 }
1062
1063 @foreach (var list in lists)
1064 {
1065 if (list.Products.Where(p => p.ProductId.ToString() == GetString("Ecom:Product.ID")).Count() > 0)
1066 {
1067 <li>
1068 <a href="@(System.Web.HttpContext.Current.Request.Url)&CCRemoveFromMyLists=@GetString("Ecom:Product.ID")&CCAddToListVariantID=&CCAddToListLanguageID=LANG1&CCAddToListID=@list.ListId&CCListType=">
1069 <i class="fa fa-star"></i> @list.Name
1070 </a>
1071 </li>
1072 }
1073 else
1074 {
1075 <li>
1076 <a href="@(System.Web.HttpContext.Current.Request.Url)&CCAddToMyLists=@GetString("Ecom:Product.ID")&CCAddToListVariantID=&CCAddToListLanguageID=LANG1&CCAddToListID=@list.ListId&CCListType=">
1077 <i class="fa fa-star-o"></i> @list.Name
1078 </a>
1079 </li>
1080 }
1081 }
1082 <li>
1083 <a href="/mine-favoritter/opret-favoritliste?ProdID=@GetString("Ecom:Product.ID")">
1084 <i class="fa fa-plus"></i>@Translate("Add new list", "Add new list")
1085 </a>
1086 </li>
1087 </ul>
1088 </div>
1089 </div>
1090 }
1091 }
1092 else
1093 {
1094 <div class="not-loggedin">
1095 <p class="not-loggedin-text"><a data-toggle="modal" data-target="#login" href="">@Translate("Login", "Login")</a> eller <a href="/kontakt/opret-brugerprofil">Bliv kunde</a> for at se priser og købe på Hounisen.com</p>
1096 <a data-toggle="modal" data-target="#login" href="" class="btn btn-primary not-loggedin-button">
1097 <span>Log ind</span>
1098 </a>
1099 </div>
1100 }
1101 </div>
1102 </div>
1103
1104
1105 @* Prices and actions *@
1106 @if (Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")))
1107 {
1108 var product = GetString("Ecom:Product.ID");
1109 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product.SelectedVariantComboID")))
1110 {
1111 product = GetString("Ecom:Product.ID") + "&" + GetString("Ecom:Product.SelectedVariantComboID");
1112 }
1113
1114 <div class="row">
1115 <div class="col-xs-12">
1116 <ul class="product__prices">
1117 @foreach (var priceHtml in pricesHtmlList)
1118 {
1119 <li>
1120 @priceHtml
1121 </li>
1122 }
1123 </ul>
1124 </div>
1125 </div>
1126
1127 <div class="row">
1128 @if (showLimitedProduct)
1129 {
1130 <div class="col-xs-12">
1131 <button class="btn btn--ghost product__button disabled">
1132 @Translate("Kan bestilles på fritekstordre", "Kan bestilles på fritekstordre")
1133 </button>
1134 </div>
1135 }
1136 else
1137 {
1138 <div class="col-xs-7">
1139 <div class="product__addtocart-input js-addtocart-input">
1140 <input type="button" value="-" class="product__quantity-button product__quantity-button--minus qtyminus" field="quantity"/>
1141 <input type="number" class="product__quantity-input quantity" data-name="quantity" name="quantity" value="@minOrder" field="quantity"/>
1142 <input type="button" value="+" class="product__quantity-button product__quantity-button--plus qtyplus" field="quantity"/>
1143 </div>
1144 <div class="product__unit-selector" style="display: inline-block;">
1145
1146 @{
1147 var index = 0;
1148 }
1149
1150 @foreach (var unitDropdown in unitsDropdown)
1151 {
1152 index++;
1153 var currentUnitPrice = prices[index - 1].Values["Ecom:Product.Prices.Amount"];
1154 <input data-price="@currentUnitPrice" class="unit-type" type="radio" id="@unitDropdown.Id" name="UnitID" value="@unitDropdown.Id" required data-lot-size="@unitDropdown.LotSize" data-min-order="@unitDropdown.MinOrder" @(unitsDropdown.Count == 1 ? "checked='checked'" : "")>
1155 <label for="@unitDropdown.Id">@unitDropdown.Name</label>
1156 }
1157 </div>
1158 <p class="product__unit-selector-error-message">
1159 * Du mangler at vælge type
1160 </p>
1161 </div>
1162 <div class="col-xs-5">
1163 <div class="product__addtocart-button">
1164 <button type="submit" name="submit" onclick="AddToCart(event, '@product', $(this).parent().parent().prev().find('input.quantity').val(), $(this).parent().parent().prev().find('input[name=\'UnitID\']:checked').val());" class="btn btn-primary product__button">
1165 @Translate("Add to cart", "Add to cart")
1166 <svg class="product__button-icon hidden-xs">
1167 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/dist/icons/icons.svg#basket"></use>
1168 </svg>
1169 </button>
1170 </div>
1171 </div>
1172 }
1173 </div>
1174 }
1175 </div>
1176
1177 @* Product details *@
1178 <div>
1179 @* IKONER *@
1180 <div class="product__icons">
1181 @{
1182 foreach (var c in GetString("Ecom:Product:Field.Certificates").Split(','))
1183 {
1184 if (!string.IsNullOrEmpty(c))
1185 {
1186 <img class="product__icon lazy" data-src="/Files/Images/Ecom/certificates/@(c).jpg" title="@Translate("Cert_" + c, c)"/>
1187 }
1188 }
1189 }
1190
1191
1192 </div>
1193
1194
1195 </div>
1196 </div>
1197 </div>
1198 </div>
1199 </div>
1200 </div>
1201
1202
1203 @helper RenderDocuments()
1204 {
1205
1206 bool hasAtLeastOneLink =
1207 !string.IsNullOrEmpty(GetString("Ecom:Product:Field.Link1Label")) ||
1208 !string.IsNullOrEmpty(GetString("Ecom:Product:Field.Link2Label")) ||
1209 !string.IsNullOrEmpty(GetString("Ecom:Product:Field.Link3Label")) ||
1210 !string.IsNullOrEmpty(GetString("Ecom:Product:Field.Link4Label")) ||
1211 !string.IsNullOrEmpty(GetString("Ecom:Product:Field.Link5Label"));
1212 bool atleastOneProductDetail = hasAtLeastOneLink ||
1213 !string.IsNullOrEmpty(GetString("Ecom:Product:Field.Guidance.Value.Clean")) ||
1214 !string.IsNullOrEmpty(GetString("Ecom:Product:Field.FAQ.Value.Clean"));
1215
1216
1217
1218 @* DOWNLOAD *@
1219 if (hasAtLeastOneLink)
1220 {
1221 <div class="row">
1222 <div class="col-xs-12">
1223 <div onclick="updateDetailAccessibility(this)" class="product__section-container">
1224 <h3 class="product__header">@Translate("Dokumenter")</h3>
1225 <div class="product__section-container__icon-wrapper" data-height="0px" data-content-id="documents">
1226 <svg style="display: block" class="product__section-container__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
1227 <path d="M240 64c0-8.8-7.2-16-16-16s-16 7.2-16 16l0 176L32 240c-8.8 0-16 7.2-16 16s7.2 16 16 16l176 0 0 176c0 8.8 7.2 16 16 16s16-7.2 16-16l0-176 176 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-176 0 0-176z"/>
1228 </svg>
1229 <svg style="display: none" class="product__section-container__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
1230 <path d="M424 256c0 4.4-3.6 8-8 8L32 264c-4.4 0-8-3.6-8-8s3.6-8 8-8l384 0c4.4 0 8 3.6 8 8z"/>
1231 </svg>
1232 </div>
1233
1234 </div>
1235 </div>
1236 <div class="col-xs-12">
1237 <div style="display: block;">
1238 <div class="product__details">
1239 <div data-content-id="documents" class="product__details__content" style="max-height: 0px;">
1240
1241
1242 @if (GetString("Ecom:Product:Field.Link1Label") != "")
1243 {
1244 <div>
1245 <a class="product__download-pdf" target="_blank" href="@GetString("Ecom:Product:Field.Link1File.Clean")" class="">@GetString("Ecom:Product:Field.Link1Label")</a>
1246 </div>
1247 }
1248 @if (GetString("Ecom:Product:Field.Link2Label") != "")
1249 {
1250 <div>
1251 <a class="product__download-pdf" target="_blank" href="@GetString("Ecom:Product:Field.Link2File.Clean")" class="">@GetString("Ecom:Product:Field.Link2Label")</a>
1252 </div>
1253 }
1254 @if (GetString("Ecom:Product:Field.Link3Label") != "")
1255 {
1256 <div>
1257 <a class="product__download-pdf" target="_blank" href="@GetString("Ecom:Product:Field.Link3File.Clean")" class="">@GetString("Ecom:Product:Field.Link3Label")</a>
1258 </div>
1259 }
1260 @if (GetString("Ecom:Product:Field.Link4Label") != "")
1261 {
1262 <div>
1263 <a class="product__download-pdf" target="_blank" href="@GetString("Ecom:Product:Field.Link4File.Clean")" class="">@GetString("Ecom:Product:Field.Link4Label")</a>
1264 </div>
1265 }
1266 @if (GetString("Ecom:Product:Field.Link5Label") != "")
1267 {
1268 <div>
1269 <a class="product__download-pdf" target="_blank" href="@GetString("Ecom:Product:Field.Link5File.Clean")" class="">@GetString("Ecom:Product:Field.Link5Label")</a>
1270 </div>
1271 }
1272 </div>
1273 </div>
1274 </div>
1275 </div>
1276 </div>
1277 <hr class="product__hr"/>
1278 }
1279 }
1280
1281 @helper RenderGuidance()
1282 {
1283 if (!String.IsNullOrEmpty(GetString("Ecom:Product:Field.Guidance.Value.Clean")))
1284 {
1285 <div class="row">
1286
1287 <div class="col-xs-12">
1288
1289
1290 <div onclick="updateDetailAccessibility(this)" class="product__section-container">
1291 <h3 class="product__header">Vejledning</h3>
1292
1293 <div class="product__section-container__icon-wrapper" data-height="0px" data-content-id="Guidance">
1294 <svg style="display: block" class="product__section-container__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
1295 <path d="M240 64c0-8.8-7.2-16-16-16s-16 7.2-16 16l0 176L32 240c-8.8 0-16 7.2-16 16s7.2 16 16 16l176 0 0 176c0 8.8 7.2 16 16 16s16-7.2 16-16l0-176 176 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-176 0 0-176z"/>
1296 </svg>
1297 <svg style="display: none" class="product__section-container__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
1298 <path d="M424 256c0 4.4-3.6 8-8 8L32 264c-4.4 0-8-3.6-8-8s3.6-8 8-8l384 0c4.4 0 8 3.6 8 8z"/>
1299 </svg>
1300 </div>
1301
1302 </div>
1303 </div>
1304 <div class="col-xs-12 py-4">
1305 <div style="display: block;">
1306 <div class="product__details">
1307 @{
1308 var text = GetString("Ecom:Product:Field.Guidance.Value.Clean");
1309 }
1310
1311 <div data-content-id="Guidance" class="product__details__content" style="max-height: 0px;">
1312 @text
1313 </div>
1314
1315 </div>
1316 </div>
1317 </div>
1318 </div>
1319
1320 <hr class="product__hr"/>
1321 }
1322 }
1323
1324 @helper RenderFAQ()
1325 {
1326 if (!String.IsNullOrEmpty(GetString("Ecom:Product:Field.FAQ.Value.Clean")))
1327 {
1328 <div class="row">
1329
1330 <div class="col-xs-12">
1331
1332
1333 <div onclick="updateDetailAccessibility(this)" class="product__section-container">
1334 <h3 class="product__header">@Translate("FAQ")</h3>
1335
1336 <div class="product__section-container__icon-wrapper" data-height="0px" data-content-id="FAQ">
1337 <svg style="display: block" class="product__section-container__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
1338 <path d="M240 64c0-8.8-7.2-16-16-16s-16 7.2-16 16l0 176L32 240c-8.8 0-16 7.2-16 16s7.2 16 16 16l176 0 0 176c0 8.8 7.2 16 16 16s16-7.2 16-16l0-176 176 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-176 0 0-176z"/>
1339 </svg>
1340 <svg style="display: none" class="product__section-container__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
1341 <path d="M424 256c0 4.4-3.6 8-8 8L32 264c-4.4 0-8-3.6-8-8s3.6-8 8-8l384 0c4.4 0 8 3.6 8 8z"/>
1342 </svg>
1343 </div>
1344
1345 </div>
1346 </div>
1347 <div class="col-xs-12 py-4">
1348 <div style="display: block;">
1349 <div class="product__details">
1350 @{
1351 var text = GetString("Ecom:Product:Field.FAQ.Value.Clean");
1352 }
1353
1354 <div data-content-id="FAQ" class="product__details__content" style="max-height: 0px;">
1355 @text
1356 </div>
1357
1358 </div>
1359 </div>
1360 </div>
1361 </div>
1362
1363 <hr class="product__hr"/>
1364 }
1365 }
1366
1367 @helper RenderSpecifikationer()
1368 {
1369 <div class="row">
1370 <div class="col-xs-12">
1371 <hr class="product__hr"/>
1372 <div class="product__section-container product__section-container--no-hover">
1373 <h3 class="product__header">Specifikationer</h3>
1374 </div>
1375 </div>
1376 <div class="col-xs-12 py-4">
1377 <div style="display: block;">
1378 <div class="product__details">
1379
1380
1381 <div data-content-id="specifikationer" class="product__details__content" style="max-height: 9999px;">
1382
1383 @* ATTRIBUTTER *@
1384 <div class="product__information">
1385
1386 <dl class="product__information-table">
1387 @{
1388 int attributeLineCount = 0;
1389 for (int i = 1; i < 8; i++)
1390 {
1391 attributeLineCount++;
1392 string attributeName = "Ecom:Product:Field.Attribut" + attributeLineCount + "A";
1393 string attributeValue = "Ecom:Product:Field.Attribut" + attributeLineCount + "B";
1394 string attributeBrand = string.Empty;
1395
1396 if (GetString(attributeName) != "")
1397 {
1398 if (attributeLineCount == 7)
1399 {
1400 attributeBrand = "itemprop=\"brand\"";
1401 }
1402
1403 <dt>@GetString(attributeName) :</dt>
1404 <dd @attributeBrand>@GetString(attributeValue)</dd>
1405 }
1406 }
1407
1408 string manufacturerName = GetString("Ecom:Manufacturer.Name");
1409 string manufacturerUrl = GetString("Ecom:Manufacturer.Web");
1410
1411 if (!manufacturerName.IsNullOrEmpty() && !manufacturerUrl.IsNullOrEmpty())
1412 {
1413 <dt>Brand :</dt>
1414 <dd>
1415 <a target="_blank" class="product__information-table__manufacturer" href="@manufacturerUrl">@manufacturerName</a>
1416 </dd>
1417 }
1418 }
1419
1420 </dl>
1421 </div>
1422
1423
1424 </div>
1425
1426 </div>
1427 </div>
1428 </div>
1429 </div>
1430 }
1431
1432 @helper RenderDescription()
1433 {
1434 if (!String.IsNullOrEmpty(GetString("Ecom:Product.LongDescription")))
1435 {
1436 var description = GetString("Ecom:Product.LongDescription");
1437
1438 // Remove HTML tags
1439 string cleanedText = Regex.Replace(description, "<.*?>", " ");
1440 string[] words = cleanedText.Split(new[] { ' ', '\n', '\r', '\t' }, StringSplitOptions.RemoveEmptyEntries);
1441 bool readMoreButton = words.Length > 80;
1442
1443 <div class="row">
1444
1445 <div class="col-xs-12">
1446 <hr class="product__hr"/>
1447 <div onclick="updateDetailAccessibility(this)" class="product__section-container">
1448 <h3 style="@(!readMoreButton ? "cursor: auto" : "") " id="productLongDescriptionID" class="product__header">@Translate("Description", "Description")</h3>
1449
1450 <div class="product__section-container__icon-wrapper" data-height="95px" data-content-id="description">
1451
1452 @if (readMoreButton)
1453 {
1454 <svg style="display: block" class="product__section-container__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
1455 <path d="M240 64c0-8.8-7.2-16-16-16s-16 7.2-16 16l0 176L32 240c-8.8 0-16 7.2-16 16s7.2 16 16 16l176 0 0 176c0 8.8 7.2 16 16 16s16-7.2 16-16l0-176 176 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-176 0 0-176z"/>
1456 </svg>
1457 <svg style="display: none" class="product__section-container__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
1458 <path d="M424 256c0 4.4-3.6 8-8 8L32 264c-4.4 0-8-3.6-8-8s3.6-8 8-8l384 0c4.4 0 8 3.6 8 8z"/>
1459 </svg>
1460 }
1461 </div>
1462 </div>
1463 </div>
1464 <div class="col-xs-12 py-4">
1465 <div style="display: block;">
1466 <div class="product__details">
1467
1468 @if (readMoreButton)
1469 {
1470 <div data-content-id="description" class="product__details__content" style="min-height: 95px;max-height: 95px;">
1471 @description
1472 </div>
1473 }
1474 else
1475 {
1476 @description
1477 }
1478 </div>
1479 </div>
1480 </div>
1481 </div>
1482 }
1483 }
1484
1485
1486
1487
1488 <div class="row product__column__wrapper">
1489 <div class="col-md-6 col-sm-12 col-xs-12 product__column">
1490 @if (isMobile)
1491 {
1492 @RenderSpecifikationer()
1493 @RenderDescription()
1494 <hr class="product__hr"/>
1495 }
1496 else
1497 {
1498 @RenderDescription()
1499 <hr class="product__hr"/>
1500 @RenderGuidance()
1501 @RenderFAQ()
1502 }
1503
1504 </div>
1505 <div class="col-md-6 col-sm-12 col-xs-12 product__column">
1506 @if (isMobile)
1507 {
1508 @RenderDocuments()
1509 @RenderGuidance()
1510 @RenderFAQ()
1511 }
1512 else
1513 {
1514 @RenderSpecifikationer()
1515 <hr class="product__hr"/>
1516 @RenderDocuments()
1517 }
1518 </div>
1519 </div>
1520
1521
1522 @* Related products *@
1523
1524 @if (GetString("Ecom:Product.RelatedCount") != "0")
1525 {
1526 <div class="row">
1527 <div class="col-xs-12 p-15 p-md-0 @(isMobile ? "related-products-slider" : "")">
1528 <h2 class="product__header product__header--mobile-center">Relaterede varer</h2>
1529 <ul class="shop-list__list p-0-fc @(isMobile ? "owl-carousel" : "") ">
1530 @foreach (LoopItem relatedgroup in GetLoop("ProductRelatedGroups"))
1531 {
1532 var relatedproductloop = relatedgroup.GetLoop("RelatedProducts").OrderByDescending(g => g.GetString("Ecom:Product.LoopCounter")).Take(4).ToList();
1533 @GetProductListFullRelated(relatedproductloop, 3, 3, 1)
1534 }
1535 </ul>
1536 </div>
1537 </div>
1538 }
1539
1540
1541 <!-- Udforsk mere -->
1542
1543 @functions
1544 {
1545 List<int> GetIds(string idsRaw)
1546 {
1547 List<int> ids = new List<int>();
1548 if (idsRaw.IsNotNullOrEmpty())
1549 {
1550 foreach (var articleId in idsRaw.Split(','))
1551 {
1552 if (int.TryParse(articleId, out int id))
1553 {
1554 ids.Add(id);
1555 }
1556 }
1557 }
1558
1559 return ids;
1560 }
1561 }
1562
1563 @{
1564 var articlesPageId = GetPageIdByNavigationTag("ProductviewUniverseArticles");
1565 bool hasActiveArticles = false;
1566
1567 var productId = Dynamicweb.Context.Current.Request.QueryString["productid"];
1568 var defaultGroup = new ProductService().GetProductById(productId, "", true).DefaultGroup;
1569
1570 if (defaultGroup != null)
1571 {
1572 string articlesIdsRaw = defaultGroup.ProductGroupFieldValues.GetProductGroupFieldValue("Articles").Value.ToString();
1573 string articleSubGroupIdsRaw = defaultGroup.ProductGroupFieldValues.GetProductGroupFieldValue("ArticleSubCategories").Value.ToString();
1574
1575 List<int> articlesIds = new List<int>();
1576 if (!string.IsNullOrEmpty(articlesIdsRaw))
1577 {
1578 articlesIds = GetIds(articlesIdsRaw);
1579
1580 if (articlesIds.Count > 0)
1581 {
1582 hasActiveArticles = articlesIds.Any(x => new PageService().GetPage(x).Active);
1583 }
1584 }
1585
1586 if (!string.IsNullOrEmpty(articleSubGroupIdsRaw))
1587 {
1588 var subCategoryIds = GetIds(articleSubGroupIdsRaw);
1589
1590 List<string> subCategoryNames = new List<string>();
1591
1592 foreach (int subCategoryId in subCategoryIds)
1593 {
1594 var subCategory = new PageService().GetPage(subCategoryId);
1595 if (subCategory != null)
1596 {
1597 subCategoryNames.Add(subCategory.GetDisplayName());
1598 }
1599 }
1600
1601 foreach (string subCategoryName in subCategoryNames)
1602 {
1603 try
1604 {
1605 var subCategoryArticles = new PageService().GetPagesForItems(new List<string> { "UniverseArticlePage" }).Where(x => x.Item["SubCategories"].ToString().Contains(subCategoryName));
1606 if (subCategoryArticles.Any(x => x.Active))
1607 {
1608 hasActiveArticles = true;
1609 }
1610 }
1611 catch
1612 {
1613 }
1614 }
1615 }
1616 }
1617
1618 if (hasActiveArticles)
1619 {
1620 string articlesHeader = "";
1621 articlesHeader = defaultGroup.ProductGroupFieldValues.GetProductGroupFieldValue("ArticlesHeader").Value.ToString();
1622
1623 if (string.IsNullOrEmpty(articlesHeader))
1624 {
1625 articlesHeader = Translate("ProductViewArticleHeader");
1626 }
1627
1628 var paragraph = new ParagraphService().GetParagraphsByPageId(articlesPageId).FirstOrDefault();
1629
1630 if (paragraph != null)
1631 {
1632 <div class="row" style="margin-top: 15px">
1633 <div class="col-xs-12 p-15 p-md-0">
1634 <h2 class="product__header product__header--mobile-center articles">@articlesHeader</h2>
1635 </div>
1636
1637 </div>
1638
1639 <div class="row-25">
1640 @RenderParagraphContent(paragraph.ID)
1641 </div>
1642 }
1643 }
1644 }
1645
1646
1647 <div class="row p-15 p-md-0" style="margin-top: 15px">
1648 <!-- display block in clerk.js if at least one product -->
1649 <h2 class="product__header product__header--mobile-center" id="product-header-clerk" style="display: block;">Ofte købt sammen med</h2>
1650 <span class="clerk"
1651 data-template="@@product-page-others-also-bought"
1652 data-products='["@GetString("Ecom:Product.ID")"]'>
1653 </span>
1654 </div>
1655
1656
1657 <div class="row">
1658 <div class="col-md-12 col-sm-12 col-xs-12"> </div>
1659 </div>
1660
1661 @{
1662 var priceInitial = prices.Where(x => x.GetString("Ecom:Product.Prices.UnitID").Equals(unitDefault.Id)).OrderBy(x => x.GetDouble("Ecom:Product.Prices.Quantity")).FirstOrDefault();
1663
1664 CultureInfo us = new CultureInfo("en-US");
1665 string datalayerPriceInitial = string.Empty;
1666 if (priceInitial != null && Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")))
1667 {
1668 datalayerPriceInitial = priceInitial.GetDouble("Ecom:Product.Prices.Amount").ToString("n", us).Replace(",", "");
1669 }
1670
1671 var pricesJs = new List<Dynamicweb.Ecommerce.LiveIntegration.Products.ProductPrice>();
1672 foreach (var priceJs in prices)
1673 {
1674 var productPrice = new Dynamicweb.Ecommerce.LiveIntegration.Products.ProductPrice();
1675 productPrice.BaseUnitPrice = priceJs.GetDouble("Ecom:Product.Prices.BaseUnitPrice");
1676 productPrice.PriceQuantityPerUnit = priceJs.GetDouble("Ecom:Product.Prices.PriceQuantityPerUnit");
1677 productPrice.Quantity = priceJs.GetDouble("Ecom:Product.Prices.Quantity");
1678 productPrice.UnitId = priceJs.GetString("Ecom:Product.Prices.UnitID");
1679 pricesJs.Add(productPrice);
1680 }
1681 }
1682
1683 @if (!String.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.ScriptsBottom")))
1684 {
1685 @SnippetStart("JavaScriptBottom")
1686 @GetString("Ecom:Product:Field.ScriptsBottom")
1687 @SnippetEnd("JavaScriptBottom")
1688 }
1689
1690 <script>
1691 var pricesJs = JSON.parse('@Newtonsoft.Json.JsonConvert.SerializeObject(pricesJs)');
1692
1693 // Create our number formatter.
1694 var formatterUs = new Intl.NumberFormat('en-US', {
1695 minimumFractionDigits: 2,
1696 });
1697
1698
1699
1700
1701 $('.product__addtocart-button').on('click', function () {
1702
1703 var quantityAdded = parseInt($(this).parent().prev().find('input.quantity').val());
1704 var unitAdded = $(this).parent().prev().find('select.unit').val();
1705 var priceFound = null;
1706 for (const key in pricesJs) {
1707 if (pricesJs[key].UnitId == unitAdded && quantityAdded >= parseInt(pricesJs[key].Quantity)){
1708 priceFound = pricesJs[key];
1709 }
1710 }
1711
1712 var priceAdded = 0;
1713 if (priceFound != null) {
1714 priceAdded = (priceFound.BaseUnitPrice * priceFound.PriceQuantityPerUnit) * quantityAdded; }
1715
1716 var quantity = document.getElementsByClassName("product__quantity-input")[0].value;
1717 var unitTypes = document.getElementsByClassName("unit-type");
1718 var isVariantNull = true;
1719
1720 var index = 0;
1721 var unitPrice;
1722 var currentUnitName;
1723 for (const button of unitTypes){
1724
1725 if (button.checked != false)
1726 {
1727 isVariantNull = false;
1728 var tempPrice = button.dataset.price.replace(".","");
1729 tempPrice = tempPrice.replace(",",".");
1730 unitPrice = parseFloat(tempPrice);
1731 currentUnitName = button.value.split("_")[1];
1732 index++;
1733 }
1734 }
1735
1736 if (!isVariantNull)
1737 {
1738 dataLayer.push({ecommerce:null});
1739 dataLayer.push({
1740 'event': 'add_to_cart',
1741 "ecommerce":{
1742 "currency" : "@GetString("Ecom:Product.CurrencyCode")",
1743 "value" : unitPrice * (parseInt(quantity)).toFixed(2),
1744 "items":[
1745 {
1746 "item_name": "@GetString("Ecom:Product.Name")" + " - " + currentUnitName,
1747 'item_id': '@GetString("Ecom:Product.ID")',
1748 'price': unitPrice,
1749 "item_brand" : "",
1750 "item_category": (categories[0] != null ? categories[0] : ""),
1751 "item_category2": (categories[1] != null ? categories[1] : ""),
1752 "item_category3": (categories[2] != null ? categories[2] : ""),
1753 "item_category4": (categories[3] != null ? categories[3] : ""),
1754 "item_category5": (categories[4] != null ? categories[4] : ""),
1755 "quantity": parseInt(quantity),
1756 }
1757 ]
1758 },
1759
1760 });
1761 }
1762
1763 });
1764
1765 //Sets the unittype if only one unittype for the product exists
1766 var types = document.getElementsByClassName("unit-type");
1767 var currentUnitName;
1768
1769 if (types.length === 1){
1770 currentUnitName = " - " + (types[0].value.split("_")[1]);
1771
1772 }
1773 else{
1774 currentUnitName = "";
1775 }
1776
1777
1778 var initialCategories = document.getElementsByClassName("page-header__title")[0].dataset.categories;
1779 var categories = initialCategories.split("_");
1780
1781
1782 if (types.length === 1){
1783
1784 var currentUnitPrice = 0;
1785 var tempPrice = types[0].dataset.price.replace(".","");
1786 tempPrice = tempPrice.replace(",",".");
1787 currentUnitPrice = parseFloat(tempPrice);
1788
1789 // View_item initial, if only one unit type exists
1790 dataLayer.push({ecommerce:null});
1791 dataLayer.push({
1792 'event': 'view_item',
1793 "ecommerce":{
1794 "currency" : "@GetString("Ecom:Product.CurrencyCode")",
1795 "value" : currentUnitPrice,
1796 "items":[
1797 {
1798 "item_name": "@GetString("Ecom:Product.Name")" + currentUnitName,
1799 'item_id': '@GetString("Ecom:Product.ID")',
1800 'price': currentUnitPrice,
1801 "item_brand" : "",
1802 "item_category": (categories[0] != null ? categories[0] : ""),
1803 "item_category2": (categories[1] != null ? categories[1] : ""),
1804 "item_category3": (categories[2] != null ? categories[2] : ""),
1805 "item_category4": (categories[3] != null ? categories[3] : ""),
1806 "item_category5": (categories[4] != null ? categories[4] : ""),
1807 "quantity": 1,
1808
1809 }
1810 ]
1811 },
1812
1813 });
1814 }
1815
1816
1817 var unitTypes = document.getElementsByClassName("unit-type");
1818
1819 var price;
1820 var oldPrice;
1821
1822 for (const btn of unitTypes)
1823 {
1824 btn.addEventListener("click", function () {
1825
1826
1827 tempPrice = this.dataset.price.replace(".","");
1828 tempPrice = tempPrice.replace(",",".");
1829 price = parseFloat(tempPrice);
1830
1831 currentUnitName = btn.value.split("_")[1];
1832
1833 //checks to see if the new variant is the same as the old one
1834 if (price != oldPrice){
1835
1836 dataLayer.push({ecommerce:null});
1837 dataLayer.push({
1838 'event': 'view_item',
1839 "ecommerce":{
1840 "currency" : "@GetString("Ecom:Product.CurrencyCode")",
1841 "value" : price,
1842 "items":[
1843 {
1844 "item_name": "@GetString("Ecom:Product.Name")" + " - " + currentUnitName,
1845 'item_id': '@GetString("Ecom:Product.ID")',
1846 'price': price,
1847 "item_brand" : "",
1848 "item_category": (categories[0] != null ? categories[0] : ""),
1849 "item_category2": (categories[1] != null ? categories[1] : ""),
1850 "item_category3": (categories[2] != null ? categories[2] : ""),
1851 "item_category4": (categories[3] != null ? categories[3] : ""),
1852 "item_category5": (categories[4] != null ? categories[4] : ""),
1853 "quantity": 1,
1854
1855 }
1856 ]
1857 },
1858
1859 });
1860
1861 }
1862 oldPrice = price;
1863 })
1864 }
1865
1866 </script>
1867
1868 @SnippetStart("JavaScriptBottom")
1869 <script type="text/javascript" src="~/Files/Templates/Designs/Dwsimple/js/video-api.js"></script>
1870
1871 @if (currentUser != null)
1872 {
1873 <script type="text/javascript" src="~/Files/Templates/Designs/Dwsimple/js/clerk.js"></script>
1874 }
1875
1876 <script>
1877 function on() {
1878 document.getElementById("overlay").style.display = "block";
1879 callPlayer('product-video', 'playVideo');
1880 }
1881 function off() {
1882 document.getElementById("overlay").style.display = "none";
1883 callPlayer('product-video', 'pauseVideo');
1884 }
1885 function updateDetailAccessibility(button) {
1886
1887 //set wrapper equal to first child of button with class product__section-container__icon-wrapper
1888 wrapper = button.parentElement.parentElement.querySelector('.product__section-container__icon-wrapper');
1889
1890
1891 var content = document.querySelector('.product__details__content[data-content-id="' + wrapper.getAttribute('data-content-id') + '"]');
1892 var defaultHeight = wrapper.getAttribute("data-height");
1893
1894 if (content.style.maxHeight == defaultHeight) {
1895 content.style.maxHeight = content.scrollHeight + "px";
1896 } else {
1897 content.style.maxHeight = defaultHeight;
1898 }
1899
1900 var icons = wrapper.querySelectorAll('.product__section-container__icon');
1901 icons.forEach(function(icon) {
1902 icon.style.display = icon.style.display === 'none' ? 'block' : 'none';
1903 });
1904
1905 }
1906
1907 </script>
1908
1909 @SnippetEnd("JavaScriptBottom")
1910
1911 @functions {
1912
1913 public static string StripHTML(string input)
1914 {
1915 var doc = new HtmlDocument();
1916 doc.LoadHtml(input);
1917 return doc.DocumentNode.InnerText;
1918 }
1919
1920 }
1921
1922
1923 <style>
1924
1925 .product__details {
1926 position: relative;
1927 margin-top: 10px;
1928 margin-bottom: 10px;
1929 p {
1930 margin: 0;
1931 width: fit-content;
1932 }
1933 a:hover{
1934 cursor: pointer;
1935 }
1936
1937 .product__details__content {
1938
1939
1940 overflow: hidden;
1941 transition: max-height 0.3s ease;
1942 }
1943
1944 }
1945
1946
1947 </style>