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