Delivery 1-2 business days|
Free shipping in Denmark on purchases of more than EUR 40
|
Free shipping in Sweden on purchases of more than EUR 67
Error executing template "Designs/Rapido/eCom/Product/Product.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<RenderStickers>b__14_0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 522
   at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<RenderImage>b__15_0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 595
   at RazorEngine.Templating.TemplateWriter.ToString()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 204
   at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 146
   at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 226
   at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 135
   at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 226
   at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 146
   at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<RenderProductTop>b__56_0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 2875
   at RazorEngine.Templating.TemplateWriter.ToString()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 204
   at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 118
   at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.Execute() in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 2865
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using System.Web @using Dynamicweb.Extensibility @using Dynamicweb.Content @using System @using System.IO @using Dynamicweb.Core @using System.Web @using System.Globalization @using System.Web.UI.HtmlControls @using Dynamicweb.Rapido.Blocks @using Dynamicweb.Ecommerce @functions { List<LoopItem> downloadDocuments = new List<LoopItem>(); //downloadDocuments variable, will be defined in Fields.cshtml and used in ProductAssets.cshtml BlocksPage productsPage = BlocksPage.GetBlockPage("Product"); public static string ToPascalCase(string str) { return CultureInfo.InvariantCulture.TextInfo .ToTitleCase(str.ToLowerInvariant()) .Replace("-", "") .Replace("_", "") .Replace(" ", ""); } } @{ bool isB2BCustomer = Pageview.User != null && Pageview.User.GroupsIds.Contains(91); if (isB2BCustomer && GetBoolean("Ecom:Product:Field.Hide_In_B2B")) { var productsList = Dynamicweb.Services.Pages.GetPageByNavigationTag(Pageview.AreaID, "ProductsPage"); if (productsList != null) { Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + productsList.ID); } else { Dynamicweb.Context.Current.Response.Redirect("/"); } Dynamicweb.Context.Current.Response.End(); } string productBlocksPosition = Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition").SelectedValue : "thumbs-image-info"; bool productInfoOnTheRight = productBlocksPosition.LastIndexOf("info") == productBlocksPosition.Length - 4; Block productTop = new Block() { Id = "Top", SortId = 10, SkipRenderBlocksList = true, Template = RenderProductTop() }; productsPage.Add(productTop); Block productMainInfo = new Block() { Id = "MainInformation", SortId = productInfoOnTheRight ? 20 : 10, Design = new Design { Size = "auto", RenderType = RenderType.Column } }; productsPage.Add("Top", productMainInfo); //Optional mini tabs block Block miniTabsBlock = new Block() { Id = "MiniTabs", SortId = 40, Template = RenderProductMiniTabs(), SkipRenderBlocksList = true }; productsPage.Add("MainInformation", miniTabsBlock); //----- Block productTabsBlock = new Block() { Id = "Tabs", SortId = 30, Template = RenderProductTabs(), SkipRenderBlocksList = true }; productsPage.Add(productTabsBlock); Block productDetailsBlock = new Block() { Id = "Section", SortId = 30 }; productsPage.Add(productDetailsBlock); Block productSnippetsBlock = new Block() { Id = "Snippets", SortId = 40 }; productsPage.Add(productSnippetsBlock); } @* Include the required Grid builder (Contains the methods @RenderBlockList and @RenderBlock) *@ @using System.Text.RegularExpressions 2 @using System.Collections.Generic 3 @using System.Reflection 4 @using System.Web.UI.HtmlControls 5 @using Dynamicweb.Rapido.Blocks.Components 6 @using Dynamicweb.Rapido.Blocks.Components.Articles 7 @using Dynamicweb.Rapido.Blocks.Components.Documentation 8 @using Dynamicweb.Rapido.Blocks 9 10 11 @*--- START: Base block renderers ---*@ 12 13 @helper RenderBlockList(List<Block> blocks) 14 { 15 blocks = blocks.OrderBy(item => item.SortId).ToList(); 16 17 foreach (Block item in blocks) 18 { 19 <!-- START: @item.Id --> 20 21 if (item.Design == null) 22 { 23 @RenderBlock(item) 24 } 25 else if (item.Design.RenderType == RenderType.None) { 26 string cssClass = item.Design.CssClass != null ? item.Design.CssClass : ""; 27 28 <div class="@cssClass dw-mod"> 29 @RenderBlock(item) 30 </div> 31 } 32 else if (item.Design.RenderType != RenderType.Hide) 33 { 34 string cssClass = item.Design.CssClass != null ? item.Design.CssClass : ""; 35 36 if (!item.SkipRenderBlocksList) { 37 if (item.Design.RenderType == RenderType.Row) 38 { 39 <div class="grid grid--align-content-start @cssClass dw-mod" id="Block__@item.Id"> 40 @RenderBlock(item) 41 </div> 42 } 43 44 if (item.Design.RenderType == RenderType.Column) 45 { 46 string hidePadding = item.Design.HidePadding ? "u-no-padding" : ""; 47 string size = item.Design.Size ?? "12"; 48 size = Regex.IsMatch(size, @"\d") ? "md-" + item.Design.Size : item.Design.Size; 49 50 <div class="grid__col-lg-@item.Design.Size grid__col-md-@item.Design.Size grid__col-sm-12 grid__col-xs-12 @hidePadding @cssClass dw-mod" id="Block__@item.Id"> 51 @RenderBlock(item) 52 </div> 53 } 54 55 if (item.Design.RenderType == RenderType.Table) 56 { 57 <table class="table @cssClass dw-mod" id="Block__@item.Id"> 58 @RenderBlock(item) 59 </table> 60 } 61 62 if (item.Design.RenderType == RenderType.TableRow) 63 { 64 <tr class="@cssClass dw-mod" id="Block__@item.Id"> 65 @RenderBlock(item) 66 </tr> 67 } 68 69 if (item.Design.RenderType == RenderType.TableColumn) 70 { 71 <td class="@cssClass dw-mod" id="Block__@item.Id"> 72 @RenderBlock(item) 73 </td> 74 } 75 76 if (item.Design.RenderType == RenderType.CardHeader) 77 { 78 <div class="card-header @cssClass dw-mod"> 79 @RenderBlock(item) 80 </div> 81 } 82 83 if (item.Design.RenderType == RenderType.CardBody) 84 { 85 <div class="card @cssClass dw-mod"> 86 @RenderBlock(item) 87 </div> 88 } 89 90 if (item.Design.RenderType == RenderType.CardFooter) 91 { 92 <div class="card-footer @cssClass dw-mod"> 93 @RenderBlock(item) 94 </div> 95 } 96 } 97 else 98 { 99 @RenderBlock(item) 100 } 101 } 102 103 <!-- END: @item.Id --> 104 } 105 } 106 107 @helper RenderBlock(Block item) 108 { 109 if (item.Template != null) 110 { 111 @BlocksPage.RenderTemplate(item.Template) 112 } 113 114 if (item.Component != null) 115 { 116 string methodName = item.Component.HelperName; 117 dynamic[] methodParameters = new dynamic[1]; 118 methodParameters[0] = item.Component; 119 Type methodType = this.GetType(); 120 MethodInfo generalMethod = methodType.GetMethod(methodName); 121 122 if (generalMethod != null) { 123 @generalMethod.Invoke(this, methodParameters).ToString(); 124 } else { 125 throw new Exception(item.Component.GetType().Name + " method '" + methodName +"' could not be invoked"); 126 } 127 } 128 129 if (item.BlocksList.Count > 0 && !item.SkipRenderBlocksList) 130 { 131 @RenderBlockList(item.BlocksList) 132 } 133 } 134 135 @*--- END: Base block renderers ---*@ 136 @* Include the Blocks for the page *@ @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 137 @using Dynamicweb.Core 138 @using System 139 @using System.Web 140 @using System.Collections.Generic 141 @using Dynamicweb.Rapido.Blocks 142 143 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 144 @using System.Linq; 145 146 @functions{ 147 public class Sticker { 148 public string className { get; set; } 149 public string text { get; set; } 150 public string groupColor { get; set; } 151 public string image { get; set; } 152 public string imageSrc { get; set; } 153 } 154 155 public class StickersContainer { 156 public string position { get; set; } 157 public List<Sticker> Stickers { get; set; } 158 } 159 160 public void AddSticker(List<StickersContainer> list, Sticker sticker, string stickerPosition) { 161 StickersContainer stickersContainerTemp; 162 if (string.IsNullOrEmpty(stickerPosition)) { 163 stickerPosition = "top-left"; 164 } 165 stickersContainerTemp = list.FirstOrDefault(stickersContainer => stickersContainer.position == stickerPosition); 166 if (stickersContainerTemp == null) { 167 stickersContainerTemp = new StickersContainer() { 168 position = stickerPosition, 169 Stickers = new List<Sticker>() 170 }; 171 list.Add(stickersContainerTemp); 172 } 173 stickersContainerTemp.Stickers.Add(sticker); 174 } 175 176 public List<StickersContainer> GetStickersContainersList(List<LoopItem> discountsLoop, double discountPrice, double price, DateTime createdDate, string customStickerValue, string groupName, string newGroupColor) { 177 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 178 bool isSaleStickersEnabled = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetBoolean("Enable"); 179 bool isNewsStickersEnabled = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetBoolean("Enable"); 180 bool isCustomStickersEnabled = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetBoolean("Enable"); 181 bool b2cUser = false; 182 if (Pageview.User == null || Pageview.User != null && Pageview.User.HasGroup(7913)) { 183 b2cUser = true; 184 } 185 186 List<StickersContainer> resultList = new List<StickersContainer>(); 187 188 if (!pointShopOnly && isSaleStickersEnabled && b2cUser) { 189 string contentType = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetString("ContentType"); 190 contentType = !string.IsNullOrEmpty(contentType) ? contentType : "Name"; 191 var currency = Dynamicweb.Ecommerce.Services.Currencies.GetDefaultCurrency(); 192 Sticker saleSticker = new Sticker(); 193 saleSticker.className = "stickers-container__tag--sale"; 194 195 switch (contentType) { 196 case "Name": 197 foreach (LoopItem discount in discountsLoop) { 198 saleSticker.text = discount.GetString("Ecom:Product.Discount.Name"); 199 saleSticker.image = discount.GetString("Ecom:Product.Discount.CampaignImage"); 200 if (!string.IsNullOrEmpty(saleSticker.image)) { 201 int startPath = saleSticker.image.IndexOf("src=\"")+5; 202 saleSticker.imageSrc = saleSticker.image.Substring(startPath, saleSticker.image.IndexOf("\" ") - startPath); 203 } 204 saleSticker.groupColor = discount.GetString("Ecom:Product.Discount.CampaignColor"); 205 } 206 break; 207 case "Amount": 208 if (discountsLoop.Count > 0) { 209 saleSticker.text = Dynamicweb.Ecommerce.Services.Currencies.Format(currency, discountPrice - price); 210 } 211 break; 212 case "Percents": 213 double percents = 0; 214 foreach (LoopItem discount in discountsLoop) { 215 percents += discount.GetDouble("Ecom:Product.Discount.PercentWithoutVAT"); 216 } 217 if (percents > 0) { 218 saleSticker.text = Math.Round(percents, 0) + "%"; 219 } 220 break; 221 case "Amount+and+percents": 222 double amount = 0; 223 double percent = 0; 224 foreach (LoopItem discount in discountsLoop) { 225 if (discount.GetString("Ecom:Product.Discount.Type") == "PERCENT") { 226 percent += discount.GetDouble("Ecom:Product.Discount.PercentWithoutVAT"); 227 } else if (discount.GetString("Ecom:Product.Discount.Type") == "AMOUNT") { 228 amount += discount.GetDouble("Ecom:Product.Discount.AmountWithVAT"); 229 } 230 } 231 232 if (percent > 0) { 233 saleSticker.text = percent + "%"; 234 } else if (amount > 0) { 235 saleSticker.text = "-" + Dynamicweb.Ecommerce.Services.Currencies.Format(currency, amount); 236 } 237 break; 238 default: 239 if (discountsLoop.Count > 0) { 240 saleSticker.text = Translate("Sale!"); 241 } 242 break; 243 } 244 245 string saleStickerPosition = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetList("Position") != null ? 246 Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetList("Position").SelectedValue : "topLeft"; 247 if (!string.IsNullOrEmpty(saleSticker.text)) { 248 AddSticker(resultList, saleSticker, saleStickerPosition); 249 } 250 } 251 252 if (!pointShopOnly && isNewsStickersEnabled && createdDate.AddDays(Converter.ToDouble(Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetString("Expiration"))) > DateTime.Now) { 253 Sticker newSticker = new Sticker(); 254 newSticker.className = "stickers-container__tag--new"; 255 newSticker.text = Translate("New!"); 256 string newStickerPosition = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetList("Position") != null ? 257 Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetList("Position").SelectedValue : "topLeft"; 258 AddSticker(resultList, newSticker, newStickerPosition); 259 } 260 261 if (!pointShopOnly && isCustomStickersEnabled && !string.IsNullOrEmpty(customStickerValue)) { 262 Sticker customSticker = new Sticker(); 263 customSticker.className = "stickers-container__tag--custom"; 264 customSticker.text = customStickerValue; 265 string customStickerPosition = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetList("Position") != null ? 266 Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetList("Position").SelectedValue : "topLeft"; 267 AddSticker(resultList, customSticker, customStickerPosition); 268 } 269 if (!string.IsNullOrWhiteSpace(groupName)) { 270 Sticker groupSticker = new Sticker(); 271 groupSticker.className = "stickers-container__tag--group"; 272 groupSticker.text = groupName; 273 if (!string.IsNullOrWhiteSpace(newGroupColor)) { 274 groupSticker.className += " " + newGroupColor; 275 } 276 277 //følger bare custom sticker pos. kan evt. udvides efter behov. 278 string groupStickerPosition = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetList("Position") != null ? 279 Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetList("Position").SelectedValue : "topLeft"; 280 AddSticker(resultList, groupSticker, groupStickerPosition); 281 282 } 283 284 return resultList; 285 } 286 } 287 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 288 289 290 @* 291 This is a temporary fallback for the DefaultImage. The image pattern MUST be set up like this: 292 293 ImageSmall = /{ProductNumber}.jpg 294 ImageMedium = /{ProductNumber}{VariantOptionLevel1}.jpg 295 ImageLarge = /{ProductNumber}{VariantComboName}.jpg 296 297 In addition to the ImageDefault setting 298 *@ 299 300 @functions { 301 public string GetProductImage(LoopItem productObject = null) 302 { 303 string theImage = ""; 304 305 if (productObject == null) { 306 theImage = GetString("Ecom:Product.ImageDefault.Default.Clean"); 307 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageLarge.Clean") : theImage; 308 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageMedium.Clean") : theImage; 309 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageSmall.Clean") : theImage; 310 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageLarge.Default.Clean") : theImage; 311 } else { 312 theImage = productObject.GetString("Ecom:Product.ImageDefault.Default.Clean"); 313 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageLarge.Clean") : theImage; 314 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageMedium.Clean") : theImage; 315 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageSmall.Clean") : theImage; 316 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageLarge.Default.Clean") : theImage; 317 } 318 319 return theImage; 320 } 321 } 322 323 @functions { 324 BlocksPage mainImagePage = BlocksPage.GetBlockPage("Product"); 325 bool showThumbs; 326 bool thumbsOnTheSide; 327 } 328 329 @{ 330 string imageBlockWidth = Pageview.AreaSettings.GetItem("ProductPage").GetList("TopLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("TopLayout").SelectedValue : "6"; 331 string blocksPosition = Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition").SelectedValue : "thumbs-image-info"; 332 bool infoOnTheRight = blocksPosition.LastIndexOf("info") == blocksPosition.Length - 4; 333 showThumbs = blocksPosition.IndexOf("thumbs") != -1; 334 thumbsOnTheSide = showThumbs && blocksPosition.IndexOf("thumbsBottom") == -1; 335 bool thumbsOnTheLeft = blocksPosition.IndexOf("image") > blocksPosition.IndexOf("thumbs"); 336 //imageBlockWidth = imageBlockPosition == "left-left" || imageBlockPosition == "left-right" ? Converter.ToString(12 - Converter.ToInt32(imageBlockWidth)) : imageBlockWidth; 337 338 Block mainImageBlock = new Block() 339 { 340 Id = "MainImage", 341 SortId = infoOnTheRight ? 10 : 20, 342 Design = new Design 343 { 344 Size = imageBlockWidth, 345 RenderType = RenderType.Column 346 }, 347 BlocksList = new List<Block> 348 { 349 new Block { 350 Id = "MainImageRow", 351 SortId = 10, 352 Design = new Design 353 { 354 RenderType = RenderType.Row 355 }, 356 BlocksList = new List<Block> 357 { 358 new Block 359 { 360 Id = "Carousel", 361 SortId = 10, 362 Template = RenderThumbnails(), 363 Design = new Design 364 { 365 Size = thumbsOnTheSide ? "2" : "12", 366 RenderType = RenderType.Column, 367 CssClass = thumbsOnTheSide ? "u-hidden-xxs" : "" 368 } 369 } 370 } 371 } 372 } 373 }; 374 mainImagePage.Add("Top", mainImageBlock); 375 376 mainImagePage.Add("MainImageRow", 377 new Block() 378 { 379 Id = "ProductImageModal", 380 SortId = 0, 381 Template = RenderModal() 382 }); 383 384 if (showThumbs) 385 { 386 mainImagePage.Add("MainImageRow", 387 new Block 388 { 389 Id = "Image", 390 SortId = thumbsOnTheLeft ? 20 : 0, 391 Template = RenderImage(), 392 Design = new Design 393 { 394 Size = thumbsOnTheSide ? "auto" : "12", 395 RenderType = RenderType.Column 396 } 397 }); 398 } 399 } 400 401 @helper RenderModal() 402 { 403 <!-- Trigger for the gallery modal --> 404 <input type="checkbox" id="GalleryModalTrigger" class="modal-trigger" /> 405 406 if (!string.IsNullOrEmpty(GetString("Ecom:Product.ImageLarge.Default.Clean"))) 407 { 408 <!-- Gallery modal --> 409 <div class="modal-container"> 410 <label for="GalleryModalTrigger" id="GalleryModalOverlay" class="modal-overlay"></label> 411 <div class="modal" id="GalleryModal"> 412 <div class="modal__body modal__body--full"> 413 @RenderCarousel("modalCarousel", 1, "horizontal", 3, true) 414 <label class="modal__close-btn dw-mod" for="GalleryModalTrigger"></label> 415 </div> 416 </div> 417 </div> 418 } 419 } 420 421 @helper RenderStickers() 422 { 423 var primaryProductGroup = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(GetString("Ecom:Product.PrimaryOrFirstGroupID")); 424 string groupColor = "" + primaryProductGroup.ProductGroupFieldValues.Where(x => x.ProductGroupField.SystemName == "StandardStickerColor").FirstOrDefault().Value; 425 bool isVariant = !string.IsNullOrWhiteSpace(GetString("Ecom:Product.VariantID")); 426 427 if (isVariant) 428 { 429 foreach (var i in Dynamicweb.Ecommerce.Products.Group.GetGroupsByProduct(Dynamicweb.Ecommerce.Products.Product.GetProductById(GetString("Ecom:Product.ID")))) 430 { 431 groupColor += i.ProductGroupFieldValues.Where(x => x.ProductGroupField.SystemName == "StandardStickerColor").FirstOrDefault().Value; 432 } 433 } 434 List<StickersContainer> StickersContainers = GetStickersContainersList( 435 GetLoop("ProductDiscounts"), 436 GetDouble("Ecom:Product.Discount.Price.Price"), 437 GetDouble("Ecom:Product.Price.Price"), 438 GetDate("Ecom:Product.Created"), 439 GetString("Ecom:Product:Field.CustomSticker.Value"), 440 GetString("Ecom:Group.Name"), 441 groupColor 442 443 ); 444 445 @*foreach (StickersContainer stickersContainer in StickersContainers) 446 { 447 <div class="stickers-container stickers-container--@(stickersContainer.position) dw-mod"> 448 @foreach (Sticker sticker in stickersContainer.Stickers) 449 { 450 <div class="stickers-container__tag @sticker.className dw-mod">@sticker.text</div> 451 } 452 </div> 453 }*@ 454 455 foreach (StickersContainer stickersContainer in StickersContainers) 456 { 457 string isImageClass = ""; 458 459 //if (!String.IsNullOrWhiteSpace(stickersContainer.Stickers(image))) 460 //{ 461 // isImageClass = "withImage"; 462 //} 463 464 bool anyWithImage = stickersContainer.Stickers.Any(x => String.IsNullOrWhiteSpace(x.image)); 465 if (anyWithImage) 466 { 467 isImageClass = "withImage"; 468 } 469 470 <div class="stickers-container stickers-container--@(stickersContainer.position) dw-mod @(isImageClass)"> 471 @foreach (Sticker sticker in stickersContainer.Stickers.Where(x => String.IsNullOrWhiteSpace(x.image))) 472 { 473 <div class="stickers-container__tag @sticker.className dw-mod"> 474 @sticker.text 475 </div> 476 } 477 478 @foreach (Sticker sticker in stickersContainer.Stickers.Where(x => !String.IsNullOrWhiteSpace(x.image))) 479 { 480 <div class="stickers-container__tag @sticker.className dw-mod sticker-with-image"> 481 @sticker.image 482 </div> 483 } 484 485 </div> 486 } 487 } 488 489 @helper RenderImage() 490 { 491 string imagePrefix = "/Admin/Public/GetImage.ashx?width=800&amp;height=800&amp;crop=5&Format=jpg&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image="; 492 string productId = GetString("Ecom:Product.ID"); 493 string image = GetProductImage(); 494 495 <label for="GalleryModalTrigger" class="product__image-container u-position-relative"> 496 <img class="product__image-container__image dw-mod b-lazy" src="/Files/Images/placeholder.gif" data-src="@imagePrefix@image" alt="@GetString("Ecom:Product.Name")" id="Image_@productId" data-for="FullImage" data-number="0" onclick="modalCarousel.GoToSlide('modalCarousel', this.getAttribute('data-number'))" /> 497 @RenderStickers() 498 </label> 499 } 500 501 @helper RenderThumbnails() 502 { 503 <div class="@(showThumbs ? "product__thumbs" : "") dw-mod"> 504 @RenderCarousel( 505 "productCarousel", 506 !showThumbs ? 1 : 5, 507 thumbsOnTheSide ? "vertical" : "horizontal", 508 !showThumbs ? 3 : 2 509 ) 510 @if (!showThumbs) 511 { 512 @RenderStickers() 513 } 514 </div> 515 } 516 517 @helper RenderCarousel(string id, int slidesInView, string direction, int preloaderSize, bool isModal = false) 518 { 519 <div class="carousel dw-mod" id="@id"> 520 <div class="thumb-list carousel__container @(slidesInView != 1 ? "carousel__container--hidden" : "") js-carousel-slides dw-mod"> 521 @*Main image thumb*@ 522 @RenderProductImage(GetProductImage(), slidesInView == 1, isModal ? "modal--full__img" : "", true, isModal) 523 524 @foreach (LoopItem alternativeImage in GetLoop("Ecom:Product.AlternativeImages")) 525 { 526 if (!string.IsNullOrEmpty(alternativeImage.GetString("Ecom:Product.AlternativeImages.Image"))) 527 { 528 @RenderProductImage(alternativeImage.GetString("Ecom:Product.AlternativeImages.Image"), slidesInView == 1, isModal ? "modal--full__img" : "", false, isModal) 529 } 530 } 531 532 @foreach (LoopItem detail in GetLoop("Details")) 533 { 534 if (!string.IsNullOrEmpty(detail.GetString("Ecom:Product:Detail.Image.Clean"))) 535 { 536 string ext = Path.GetExtension(detail.GetString("Ecom:Product:Detail.Image.Clean")).ToLower(); 537 if (ext == ".jpg" || ext == ".jpeg" || ext == ".gif" || ext == ".png") 538 { 539 @RenderProductImage(detail.GetString("Ecom:Product:Detail.Image.Clean"), slidesInView == 1, isModal ? "modal--full__img" : "", false, isModal) 540 } 541 } 542 } 543 </div> 544 545 <script> 546 document.addEventListener("DOMContentLoaded", function () { 547 @id = new CarouselModule('#@id', { 548 slidesInView: @slidesInView, 549 direction: "@direction", 550 preloaderSize: @preloaderSize, 551 showCounter: @isModal.ToString().ToLower() 552 }); 553 }); 554 </script> 555 </div> 556 } 557 558 @helper RenderProductImage(string image, bool isBig, string cssClass = "", bool isActive = false, bool isModal = false) 559 { 560 //Add product image to the og meta data 561 Pageview.Meta.AddTag("og:image", string.Format("{0}://{1}{2}", Dynamicweb.Context.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Host, GetProductImage())); 562 563 string productId = GetString("Ecom:Product.ID"); 564 string thumbPrefix = "/Admin/Public/GetImage.ashx?width=200&amp;height=200&amp;crop=5&Format=jpg&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image="; 565 string imagePrefix = "/Admin/Public/GetImage.ashx?width=800&amp;height=800&amp;crop=5&Format=jpg&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image="; 566 567 <div class="carousel__slide dw-mod"> 568 @if (isModal) 569 { 570 <img src="@imagePrefix@image" class="@cssClass" alt="@GetString("Ecom:Product.Name")"> 571 } 572 else if (isBig) 573 { 574 <label for="GalleryModalTrigger"> 575 <img src="@imagePrefix@image" alt="@GetString("Ecom:Product.Name")" class="js-gallery @cssClass" data-for="FullImage" data-image="@image" onclick="modalCarousel.GoToSlide('modalCarousel', this.closest('.carousel__slide').index());"> 576 </label> 577 } 578 else 579 { 580 <div class="thumb-list__item dw-mod js-thumb js-gallery @(isActive ? "js-thumb--active thumb-list__item--active" : "")" data-for="Image_@productId" data-image="@imagePrefix@image" onmouseover="Gallery.openImage(this)"> 581 <label for="GalleryModalTrigger"> 582 <img src="@thumbPrefix@image" alt="@GetString("Ecom:Product.Name")" class="js-gallery @cssClass" data-for="FullImage" data-image="@imagePrefix@image" onclick="modalCarousel.GoToSlide('modalCarousel', this.closest('.carousel__slide').index());"> 583 </label> 584 </div> 585 } 586 </div> 587 } @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 588 @using Dynamicweb.Core 589 @using System 590 @using System.Web 591 @using System.Collections.Generic 592 @using Dynamicweb.Rapido.Blocks 593 @functions { 594 bool useFacebookPixel; 595 bool useGoogleTagManager; 596 BlocksPage mainInfoPage = BlocksPage.GetBlockPage("Product"); 597 } 598 599 @{ 600 //ck ændrede fra 1 til 10 for at omgå problem med at få vist pris. Kan muligvis have forårsaget andet visnings gejl. 601 bool mainInfoRenderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 10 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList"); 602 603 useFacebookPixel = !string.IsNullOrWhiteSpace(Pageview.AreaSettings.GetItem("Settings").GetString("FacebookPixelID")); 604 useGoogleTagManager = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("GoogleTagManagerID")); 605 bool hidePrice = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HidePrice"); 606 bool hideAddToCartButton = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("hideAddToCartButton"); 607 608 Block mainInfoHeader = new Block() 609 { 610 Id = "MainInfoHeader", 611 SortId = 21, 612 Template = RenderMainInfoHeader() 613 }; 614 mainInfoPage.Add("MainInformation", mainInfoHeader); 615 616 Block mainInfoDescription = new Block() 617 { 618 Id = "ShortDescription", 619 SortId = 30, 620 Template = RenderShortDescription() 621 }; 622 mainInfoPage.Add("MainInformation", mainInfoDescription); 623 624 if (!mainInfoRenderVariantsAsProducts) { 625 Block mainInfoVariants = new Block() 626 { 627 Id = "Variants", 628 SortId = 50, 629 Template = RenderMainInfoVariants() 630 }; 631 mainInfoPage.Add("MainInformation", mainInfoVariants); 632 } 633 634 Block mainInfoBOM = new Block() 635 { 636 Id = "BOM", 637 SortId = 60, 638 Template = RenderMainInfoBOM() 639 }; 640 mainInfoPage.Add("MainInformation", mainInfoBOM); 641 642 if (!mainInfoRenderVariantsAsProducts) { 643 if (!hidePrice && !hideAddToCartButton) { 644 Block mainInfoBuy = new Block() 645 { 646 Id = "Buy", 647 SortId = 31, 648 Template = RenderMainInfoBuy() 649 }; 650 mainInfoPage.Add("MainInformation", mainInfoBuy); 651 } 652 653 Block stockAndShipping = new Block() 654 { 655 Id = "StockAndShipping", 656 SortId = 90, 657 Template = RenderStockAndShipping() 658 }; 659 mainInfoPage.Add("MainInformation", stockAndShipping); 660 } 661 } 662 663 @helper RenderMainInfoHeader() 664 { 665 bool renderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList"); 666 string pageId = GetGlobalValue("Global:Page.ID").ToString(); 667 string currentPrice = GetString("Ecom:Product.Discount.Price.PriceFormatted") == GetString("Ecom:Product.Price.PriceFormatted") ? GetString("Ecom:Product.Price.PriceFormatted") : GetString("Ecom:Product.Discount.Price.PriceFormatted"); 668 // bool hideFavorites = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideFavoriteButton"); 669 bool hideProductNumber = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideProductNumber"); 670 671 bool useFontAwesomePro = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetBoolean("UseFontAwesomePro"); 672 // var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star"; 673 //string favoriteIcon = "fas fa-" + selectedFavoriteIcon; 674 // string favoriteOutlineIcon = "far fa-" + selectedFavoriteIcon; 675 676 //fix for displaying variant name - don't remove next line! 677 GetLoop("VariantCombinations"); 678 679 string helsamLink = "http://www.helsam.dk/_cart.asp?action=add&ProductEAN=" + GetString("Ecom:Product.ID.UrlEncoded") + "&quantity=1"; 680 string helsebixLink = "http://www.helsebixen.dk/shop/easyshopping/index/updatecart/?e_sku=" + GetString("Ecom:Product.ID.UrlEncoded") + "&e_qty=1"; 681 682 bool b2cUser = false; 683 bool b2bUser = false; 684 if (Pageview.User != null) { 685 b2cUser = Pageview.User.GroupsIds.Contains(7913); 686 b2bUser = Pageview.User.GroupsIds.Contains(91); 687 688 } else { 689 b2cUser = true; 690 } 691 692 <div> 693 @if (!b2cUser) { 694 var findDealer = Dynamicweb.Services.Pages.GetPageByNavigationTag(Pageview.AreaID, "finddealer"); 695 696 if (Pageview.User == null || !b2bUser) { 697 string discernibleHelsam = Translate("Køb") + " " + GetString("Ecom:Product.Name") + Translate("hos Helsam"); 698 string discernibleHelsebixen = Translate("Køb") + " " + GetString("Ecom:Product.Name") + Translate("hos Helsebixen"); 699 <div class="product_direct_sale"> 700 @*<div class="find-shop-img"> 701 <a href="@helsamLink" target="_blank" title="helsam - @Translate("Buy here")" class="" aria-label="@discernibleHelsam"> 702 <img src="/Files/Images/Graphics/helsam.png" class="" alt="helsam" /> 703 </a> 704 <a href="@helsebixLink" target="_blank" title="helsebixen.dk - @Translate("Buy here")" class="" aria-label="@discernibleHelsebixen"> 705 <img src="/Files/Images/Graphics/helsebixen.png" class="" alt="helse bixen" /> 706 </a> 707 </div>*@ 708 @if (findDealer != null) { 709 string link = "/Default.aspx?ID=" + findDealer.ID; 710 711 <div class="find-shop-link"> 712 <a href="@link" title="@Translate("Find shop")" class="btn btn--secondary dw-mod"> 713 <i class="fal fa-map-signs"></i> 714 @Translate("Find shop") 715 </a> 716 717 </div> 718 } 719 720 </div> 721 } 722 } 723 724 <div class="u-pull--left product__title dw-mod"> 725 726 <h1 class="u-no-margin">@GetString("Ecom:Product.Name") </h1> 727 728 <div class="item-number dw-mod"> 729 <div class="item-number dw-mod"> 730 731 @if (!hideProductNumber) { 732 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product.Number"))) { 733 <span class="item-number dw-mod">@Translate("Product number"): @GetString("Ecom:Product.Number")</span> 734 } 735 736 if (Pageview.User != null && Pageview.User.GroupsIds.Contains(91)) { 737 738 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.EAN"))) { 739 <span class="item-number item-ean-number dw-mod">| @Translate("EAN"): @GetString("Ecom:Product:Field.EAN")</span> 740 } 741 } 742 } 743 </div> 744 745 </div> 746 </div> 747 748 @{ 749 bool hideFavorites = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideFavoriteButton"); 750 // bool renderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList"); 751 752 var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star"; 753 string favoriteIcon = "fas fa-" + selectedFavoriteIcon; 754 string favoriteOutlineIcon = "far fa-" + selectedFavoriteIcon; 755 } 756 <div class="u-pull--right"> 757 @*@if (!hideFavorites && Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")) && !renderVariantsAsProducts) {*@ 758 @if (!hideFavorites && Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName"))) { 759 760 string favoriteId = "Favorite" + GetString("Ecom:Product.ID"); 761 <div id="@favoriteId" class="favorites favorites--md u-pull--right js-favorite-btn dw-mod"> 762 <div> 763 @{ 764 string favorite = GetBoolean("Ecom:Product.IsProductInFavoriteList") ? favoriteIcon : favoriteOutlineIcon; 765 string AddToWishlist = "fbq('track', 'AddToWishlist', {" + 766 "content_name: '" + GetString("Ecom:Product.Name") + "'," + 767 "content_ids: ['" + GetString("Ecom:Product.Number") + "']," + 768 "value: " + GetDouble("Ecom:Product.Price.Price") + "," + 769 "currency: '" + GetString("Ecom:Product.Price.Currency.Code") + "'" + 770 "});"; 771 } 772 <label for="FavoriteTrigger"><i class="@favorite fa-1_5x"></i></label> 773 </div> 774 <input type="checkbox" id="FavoriteTrigger" class="dropdown-trigger" /> 775 776 <div class="dropdown"> 777 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod"> 778 <ul class="list list--clean dw-mod"> 779 @if (GetLoop("CustomerCenter.ListTypes").Count > 0) { 780 foreach (LoopItem listType in GetLoop("CustomerCenter.ListTypes")) { 781 foreach (LoopItem list in listType.GetLoop("CustomerCenter.ProductLists")) { 782 string favLinkType = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? list.GetString("Ecom:Product.RemoveFromThisList") : list.GetString("Ecom:Product.AddToThisListAction"); 783 string isInListIcon = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? favoriteIcon : favoriteOutlineIcon; 784 string listElementName = list.GetString("Ecom:CustomerCenter.List.Name") == "My favorites" ? Translate("My favorites") : list.GetString("Ecom:CustomerCenter.List.Name"); 785 <li> 786 <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(list.GetString("Ecom:Product.List.IsProductInThisList") != "True" && useFacebookPixel ? AddToWishlist : "")"><i class="@isInListIcon"></i> @listElementName</a> 787 </li> 788 } 789 } 790 } else { 791 string favLinkType = GetString("Ecom:Product.AddToFavorites") + "&CCListType=0&CCCreateNewList=" + Translate("My favorites"); 792 string isInListIcon = favoriteOutlineIcon; 793 <li> 794 <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(useFacebookPixel ? AddToWishlist : "")"><i class="@isInListIcon"></i> @Translate("My favorites")</a> 795 </li> 796 } 797 </ul> 798 </div> 799 <label class="dropdown-trigger-off" for="FavoriteTrigger"></label> 800 </div> 801 </div> 802 } 803 </div> 804 </div> 805 } 806 807 @helper RenderStockAndShipping() 808 { 809 bool hideStockState = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideStockState"); 810 bool hideDelivery = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideShipping"); 811 bool onlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null; 812 813 if (!onlyPreview && (!string.IsNullOrEmpty(GetString("Ecom:Product:Stock.Text")) || !string.IsNullOrEmpty(GetString("Ecom:Product:Stock.DeliveryText")))) { 814 string stockIcon = GetInteger("Ecom:Product.Stock") > 0 ? "stock-icon--in" : "stock-icon--not"; 815 816 <div class="product__stock-delivery dw-mod"> 817 @if (!hideStockState) { 818 @GetString("Ecom:Product:Stock.Text") <div class="stock-icon @stockIcon"></div> 819 } 820 821 @if (!String.IsNullOrEmpty(GetString("Ecom:Product:Stock.DeliveryText")) && !hideDelivery) { 822 <span>@Translate("Shipping")</span> <span>@GetString("Ecom:Product:Stock.DeliveryText")</span> <span>@GetString("Ecom:Product:Stock.DeliveryUnit")</span> 823 } 824 </div> 825 } 826 } 827 828 @helper RenderShortDescription() 829 { 830 var livsstilOptions = GetLoop("Livsstil.Options").Where(x => x.GetBoolean("Livsstil.Option.IsSelected")); 831 832 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product.ShortDescription"))) { 833 Pageview.Meta.AddTag("og:description", GetString("Ecom:Product.ShortDescription").Replace("<p>", "").Replace("</p>", "").Trim()); 834 <div class="introduction-text"> 835 @GetString("Ecom:Product.ShortDescription") 836 </div> 837 } 838 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Salgsfeatures"))) { 839 <p>@GetString("Ecom:Product:Field.Salgsfeatures")</p> 840 } 841 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Anvendelse"))) { 842 843 <p class="mb-1"><strong>@Translate(GetString("Ecom:Product:Field.Anvendelse.Name")):. </strong> @GetString("Ecom:Product:Field.Anvendelse")</p> 844 } 845 846 if (livsstilOptions.Any()) { 847 <ul class="lifestyle-icons"> 848 @foreach (var i in livsstilOptions) { 849 string iconSrc = "/Files/Images/Graphics/Icons/Lifestyle/" + i.GetString("Livsstil.Option.Value") + ".png"; 850 string iconName = Translate(i.GetString("Livsstil.Option.Name")); 851 <li> 852 <img src="@iconSrc" title="@iconName" alt="@iconName" class="" /> 853 </li> 854 } 855 </ul> 856 } 857 858 } 859 860 @helper RenderMainInfoVariants() 861 { 862 string pageId = GetGlobalValue("Global:Page.ID").ToString(); 863 string productId = GetString("Ecom:Product.ID"); 864 string variantSelection = !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("variantId")) ? HttpContext.Current.Request.QueryString.Get("variantId").Replace(".", ",") : ""; 865 string hideHelpText = ""; 866 867 foreach (LoopItem variantgroup in GetLoop("VariantGroups")) { 868 foreach (LoopItem variantoption in variantgroup.GetLoop("VariantAvailableOptions")) { 869 if (variantoption.GetBoolean("Ecom:VariantOption.Selected")) { 870 hideHelpText = "u-hidden"; 871 } 872 } 873 } 874 875 if (GetLoop("VariantGroups").Count > 0) { 876 var variantCombinationsObject = new List<Array>(); 877 foreach (LoopItem variantcomb in GetLoop("VariantStockCombinations")) { 878 string[] combinations = variantcomb.GetString("Ecom:VariantStockCombination.VariantID").Split('.'); 879 variantCombinationsObject.Add(combinations); 880 } 881 882 string combinationsJson = Newtonsoft.Json.JsonConvert.SerializeObject(variantCombinationsObject).Replace("\"", "\'"); 883 884 var variantGroupsObject = new List<List<String>>(); 885 foreach (LoopItem variantGroup in GetLoop("VariantGroups")) { 886 var variantsObject = new List<String>(); 887 foreach (LoopItem variantOption in variantGroup.GetLoop("VariantAvailableOptions")) { 888 variantsObject.Add(variantOption.GetString("Ecom:VariantOption.ID")); 889 } 890 variantGroupsObject.Add(variantsObject); 891 } 892 string variantsJson = Newtonsoft.Json.JsonConvert.SerializeObject(variantGroupsObject).Replace("\"", "\'"); 893 string productGroupId = HttpContext.Current.Request["GroupId"]; 894 <div> 895 <div class="js-variants" data-total-variant-groups="@GetLoop("VariantGroups").Count" data-combinations="@combinationsJson" data-variants="@variantsJson" data-variant-selections="@variantSelection" data-selection-complete="UpdatePage" data-page-id="@pageId" data-product-id="@productId" data-group-id="@productGroupId"> 896 @foreach (LoopItem variantGroup in GetLoop("VariantGroups")) { 897 string groupId = variantGroup.GetString("Ecom:VariantGroup.ID"); 898 899 <div> 900 <div class="product__variant-group-name u-bold dw-mod">@variantGroup.GetString("Ecom:VariantGroup.Name")</div> 901 <div class="u-margin-top"> 902 @foreach (LoopItem variantOption in variantGroup.GetLoop("VariantAvailableOptions")) { 903 string selected = variantOption.GetBoolean("Ecom:VariantOption.Selected") ? "checked" : ""; 904 string color = !String.IsNullOrEmpty(variantOption.GetString("Ecom:VariantOption.Colorcode")) ? variantOption.GetString("Ecom:VariantOption.Colorcode") : null; 905 color = color == null && !String.IsNullOrEmpty(variantOption.GetString("Ecom:VariantOption.Color")) ? variantOption.GetString("Ecom:VariantOption.Color") : color; 906 907 if (!string.IsNullOrEmpty(variantOption.GetString("Ecom:VariantOption.ImgSmall.Clean"))) { 908 string variantImage = "/Admin/Public/GetImage.ashx?width=100&amp;height=50&amp;crop=5&amp;Compression=75&amp;image=/Images/" + variantOption.GetString("Ecom: VariantOption.ImgSmall.Clean"); 909 <img data-variant-id="@variantOption.GetString("Ecom:VariantOption.ID")" data-variant-group="@groupId" src="@variantImage" onclick="MatchVariants.SelectThis(event)" alt="@variantOption.GetString("Ecom:VariantOption.Name")" title="@variantOption.GetString("Ecom:VariantOption.Name")" class="btn btn--tag @selected js-variant-option" data-check="@selected" /> 910 } else if (!String.IsNullOrEmpty(color)) { 911 <button type="button" data-variant-id="@variantOption.GetString("Ecom:VariantOption.ID")" data-variant-group="@groupId" onclick="MatchVariants.SelectThis(event)" class="btn btn--colorbox u-margin-right @selected js-variant-option" data-check="@selected" style="background-color: @color"></button> 912 } else { 913 <button type="button" data-variant-id="@variantOption.GetString("Ecom:VariantOption.ID")" data-variant-group="@groupId" onclick="MatchVariants.SelectThis(event)" class="btn btn--tag @selected js-variant-option" data-check="@selected">@variantOption.GetString("Ecom:VariantOption.Name")</button> 914 } 915 } 916 </div> 917 </div> 918 } 919 </div> 920 <small class="js-help-text help-text @hideHelpText">@Translate("Please select variant!")</small> 921 </div> 922 } 923 } 924 925 @helper RenderMainInfoBOM() 926 { 927 if (GetLoop("BOMProducts").Count > 0) { 928 <h2 class="section-title">@Translate("Including products")</h2> 929 foreach (LoopItem BOMProductItem in GetLoop("BOMProducts")) { 930 string link = "/" + BOMProductItem.GetString("Ecom:Product.LinkGroup.Clean") + (!String.IsNullOrEmpty(BOMProductItem.GetString("Ecom:Product.VariantID")) ? "&VariantID=" + BOMProductItem.GetString("Ecom:Product.VariantID") : ""); 931 <div class="grid__col--border grid"> 932 <div class="grid__cell grid__cell--align-middle-left"> 933 <a href="@link" class="u-pull--left u-margin-right"> 934 <img class="b-lazy" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=50&image=@GetProductImage(BOMProductItem)&Compression=99" alt="@BOMProductItem.GetString("Ecom:Product.Name")" /> 935 </a> 936 <a href="@link">@BOMProductItem.GetString("Ecom:Product.Name")</a> 937 </div> 938 </div> 939 } 940 } 941 } 942 943 @helper RenderMainInfoBuy() 944 { 945 string pageId = GetGlobalValue("Global:Page.ID").ToString(); 946 string variantId = HttpContext.Current.Request.QueryString.Get("variantId"); 947 string productId = GetString("Ecom:Product.ID"); 948 string feedId = pageId + "&ProductID=" + productId + "&VariantID=" + variantId + "&Feed=True&redirect=false"; 949 950 //string productIndicativePrice = GetString("Ecom:Product:Field.Vejledendepris"); 951 952 953 <div class="product__price-actions js-handlebars-root dw-mod" id="PriceAndActions" data-template="PricesAndActionsTemplate" data-json-feed="/Default.aspx?ID=@feedId" data-preloader="minimal"></div> 954 <input type="hidden" value="@GetString("Ecom:Product.VariantID.Extented")" name="Variant" id="Variant_@GetString("Ecom:Product.ID")" /> 955 @RenderMainInfoBuyScripts() 956 } 957 958 @helper RenderMainInfoBuyScripts() 959 { 960 961 962 /* Custom user level start*/ 963 int userRank = 99; 964 bool b2cUser = false; 965 bool b2bUser = false; 966 if (Pageview.User != null) { 967 b2cUser = Pageview.User.GroupsIds.Contains(7913); 968 b2bUser = Pageview.User.GroupsIds.Contains(91); 969 for (int i = 1; i <= 3; i++) { 970 if (Pageview.User.HasGroup(Pageview.AreaSettings.GetItem("Custom").GetItem("CustomSettings").GetInt32("EcomCustomerRank" + i))) { 971 userRank = i; 972 break; 973 } 974 } 975 } 976 /* Custom user level end*/ 977 bool hidePrice = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HidePrice"); 978 //Hiding cart options for lower user ranks 979 bool hideAddToCartButton = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("hideAddTshowVATPriceoCartButton") || userRank > 2; 980 bool onlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null || userRank > 2; 981 string b2cSoldoutDisable = ""; 982 983 if (!b2bUser) { 984 hideAddToCartButton = false; 985 986 if (GetBoolean("Ecom:Product:Field.B2cCurrentlySoldout")) { 987 b2cSoldoutDisable = "disabled"; 988 } 989 } 990 991 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 992 string variantId = HttpContext.Current.Request.QueryString.Get("variantId") ?? ""; 993 string feedId = GetGlobalValue("Global:Page.ID").ToString() + "&ProductID=" + GetString("Ecom:Product.ID") + "&VariantID=" + variantId + "&Feed=True&redirect=false"; 994 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; 995 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("ShowBothPricesWithWithoutVAT"); 996 bool isPricesWithVATEnabled = Converter.ToBoolean(Pageview.Area.EcomPricesWithVat); 997 998 @* Handlebars templates *@ 999 <script id="PricesAndActionsTemplate" type="text/x-template"> 1000 {{#.}} 1001 @if (!onlyPreview || !b2bUser) { 1002 if (!hidePrice) { 1003 1004 <div class="product__price-actions__price dw-mod u-margin-top--lg"> 1005 @if (pointShopOnly) { 1006 <text> 1007 {{#if havePointPrice}} 1008 <div class="price price--product-page dw-mod">{{points}} @Translate("points")</div> 1009 {{else}} 1010 @Translate("Not available") 1011 {{/if}} 1012 </text> 1013 } else { 1014 1015 if (b2bUser) { 1016 <div class="u-flex grid--wrap"> 1017 <div class="grid__col-md-6"></div> 1018 <div class="price price--product-page dw-mod">@Translate("Normal pris pr. stk.")</div> 1019 <div class="price price--product-page dw-mod" style="margin-left: auto">{{vejledendePris}}</div> 1020 </div> 1021 <div class="u-flex grid--wrap"> 1022 <div class="grid__col-md-6"></div> 1023 <div class="price price--product-page dw-mod" style="font-size: 16px">@Translate("Din pris pr. stk.")</div> 1024 <div class="price price--product-page dw-mod" style="margin-left: auto; font-size: 16px">{{livePriceFormatted}}</div> 1025 </div> 1026 } else { 1027 <div class="before-price {{onSale}} dw-mod">{{discount}}</div> 1028 <div class="u-flex grid--wrap"> 1029 <div class="grid__col-md-6"></div> 1030 @*<div class="price price--product-page dw-mod">Pris pr. stk.</div>*@ 1031 @*<div class="price price--product-page dw-mod" style="margin-left: auto">{{priceWithVAT}} @GetString("Ecom:Product.Currency.Code")</div>*@ 1032 <div class="price price--product-page dw-mod" style="margin-left: auto">{{priceWithVAT}}</div> 1033 </div> 1034 } 1035 1036 if (showVATPrice && false) { 1037 1038 <small class="vat-price vat-price--product-page u-margin-top dw-mod"> 1039 @if (isPricesWithVATEnabled) { 1040 @Translate("excl. VAT") <text>({{priceWithoutVAT}})</text> 1041 } else { 1042 @Translate("incl. VAT") <text>({{priceWithVAT}})</text> 1043 } 1044 </small> 1045 } 1046 } 1047 </div> 1048 1049 <h5 class="color-primary fw-500 text-right u-margin-bottom u-margin-top">@Translate("Delivery costs may be added")</h5> 1050 1051 } 1052 if (!hideAddToCartButton) { 1053 <div class="buttons-collection buttons-collection--right product__price-actions__actions dw-mod u-margin-top--lg"> 1054 1055 <input type="checkbox" id="UnitOptions_{{id}}" class="dropdown-trigger" /> 1056 <div class="dropdown u-w150px u-w80px--xs use-btn-primary-height dw-mod {{hasUnits}}"> 1057 <label class="dropdown__header dropdown__btn dw-mod" for="UnitOptions_{{id}}">{{unitName}}</label> 1058 <div id="unitOptions" class="dropdown__content dw-mod"> 1059 {{#unitOptions}} 1060 {{>UnitOption}} 1061 {{/unitOptions}} 1062 </div> 1063 <label class="dropdown-trigger-off" for="UnitOptions_{{id}}"></label> 1064 </div> 1065 1066 @*<span class="package-size"> 1067 @Translate("Kollistørrelse"): @GetString("Ecom:Product:Field.Kollistoerrelse") 1068 </span>*@ 1069 1070 <input type="hidden" value="{{unitId}}" name="Unit" id="Unit_{{id}}" /> 1071 @if (pointShopOnly) { 1072 <button type="button" id="CartButton_{{id}}" class="btn btn--primary btn--condensed u-no-margin dw-mod js-cart-btn {{disabledBuyButton}} {{#unless canBePurchasedWithPoints}}js-stay-disabled{{/unless}}" name="CartCmd" value="addWithPoints" 1073 onclick="Cart.AddToCart(event, { 1074 id: '{{productId}}', 1075 variantId: '{{variantid}}', 1076 unitId: '{{unitId}}', 1077 quantity: 1, 1078 buyForPoints: true, 1079 productInfo: {{productInfo}} 1080 }); {{facebookPixelAction}}"> 1081 <i class="@cartIcon"></i><span class="u-hidden-xs u-hidden-xxs"> @Translate("Buy with points")</span> 1082 </button> 1083 <text> 1084 {{#unless canBePurchasedWithPoints}} 1085 {{#if havePointPrice}} 1086 <small class="help-text u-no-margin u-margin-top">@Translate("Not enough points to buy this")</small> 1087 {{/if}} 1088 {{/unless}} 1089 </text> 1090 } else { 1091 1092 <div class="u-flex grid--wrap u-margin-bottom" style="margin-right: 0"> 1093 <div class="grid__col-md-6"></div> 1094 @if (b2bUser) { 1095 <div class="price price--product-page grid--align-self-center dw-mod" style="font-size: 16px"> 1096 {{#if packageSize}} 1097 @Translate("Kollistørrelse"): {{packageSize}} 1098 {{/if}} 1099 </div> 1100 } 1101 1102 <div style="margin-left: auto"> 1103 1104 1105 @if (!string.IsNullOrWhiteSpace(b2cSoldoutDisable)) { 1106 <button style="opacity:1 !important" disabled type="button" id="" class="btn btn--primary btn--condensed u-no-margin dw-mod js-cart-btn" name="submit"> 1107 <span>@Translate("Currently soldout")</span> 1108 @*<span class="u-hidden-xs u-hidden-xxs"> @Translate("Currently soldout")</span>*@ 1109 </button> 1110 } else { 1111 <input type="number" class="product__quantity-selector u-w70px use-btn-primary-height dw-mod" id="Quantity_{{id}}" name="Quantity" value="{{quantity}}" min="1" onchange="HandlebarsBolt.UpdateContent('PriceAndActions', '/Default.aspx?ID=@feedId&quantity=' + (+(this.value) <= 0 ? 1 : +(this.value)))" style="margin-bottom: 0"> 1112 <button type="button" id="CartButton_{{id}}" class="btn btn--secondary btn--condensed u-no-margin dw-mod js-cart-btn" name="submit" 1113 onclick="Cart.AddToCart(event, { 1114 id: '{{productId}}', 1115 variantId: '{{variantid}}', 1116 unitId: '{{unitId}}', 1117 quantity: document.getElementById('Quantity_{{id}}').value, 1118 productInfo: {{productInfo}} 1119 }); {{facebookPixelAction}}"> 1120 <i class="d-sm-block @cartIcon"></i> 1121 <span class="u-hidden-xs u-hidden-xxs"> @Translate("Add to cart")</span> 1122 </button> 1123 } 1124 </div> 1125 </div> 1126 if (b2bUser) { 1127 <div class="u-flex grid--wrap u-margin-bottom" style="margin-right: 0"> 1128 <div class="grid__col-md-6"></div> 1129 <div class="price price--product-page dw-mod" style="font-size: 16px">@Translate("Total")</div> 1130 <div class="price price--product-page dw-mod" style="margin-left: auto; font-size: 16px">{{livePriceTotalFormatted}}</div> 1131 </div> 1132 } 1133 1134 1135 @*bool hideFavorites = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideFavoriteButton"); 1136 bool renderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList"); 1137 1138 var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star"; 1139 string favoriteIcon = "fas fa-" + selectedFavoriteIcon; 1140 string favoriteOutlineIcon = "far fa-" + selectedFavoriteIcon; 1141 1142 <div class=""> 1143 @if (!hideFavorites && Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")) && !renderVariantsAsProducts) { 1144 string favoriteId = "Favorite" + GetString("Ecom:Product.ID"); 1145 <div id="@favoriteId" class="favorites favorites--md u-pull--right js-favorite-btn dw-mod"> 1146 <div> 1147 @{ 1148 string favorite = GetBoolean("Ecom:Product.IsProductInFavoriteList") ? favoriteIcon : favoriteOutlineIcon; 1149 string AddToWishlist = "fbq('track', 'AddToWishlist', {" + 1150 "content_name: '" + GetString("Ecom:Product.Name") + "'," + 1151 "content_ids: ['" + GetString("Ecom:Product.Number") + "']," + 1152 "value: " + GetDouble("Ecom:Product.Price.Price") + "," + 1153 "currency: '" + GetString("Ecom:Product.Price.Currency.Code") + "'" + 1154 "});"; 1155 } 1156 <label for="FavoriteTrigger"><i class="@favorite"></i> @Translate("Add to favorites")</label> 1157 </div> 1158 <input type="checkbox" id="FavoriteTrigger" class="dropdown-trigger" /> 1159 1160 <div class="dropdown"> 1161 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod"> 1162 <ul class="list list--clean dw-mod"> 1163 @if (GetLoop("CustomerCenter.ListTypes").Count > 0) { 1164 foreach (LoopItem listType in GetLoop("CustomerCenter.ListTypes")) { 1165 foreach (LoopItem list in listType.GetLoop("CustomerCenter.ProductLists")) { 1166 string favLinkType = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? list.GetString("Ecom:Product.RemoveFromThisList") : list.GetString("Ecom:Product.AddToThisListAction"); 1167 string isInListIcon = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? favoriteIcon : favoriteOutlineIcon; 1168 <li> 1169 <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(list.GetString("Ecom:Product.List.IsProductInThisList") != "True" && useFacebookPixel ? AddToWishlist : "")"><i class="@isInListIcon"></i> @list.GetValue("Ecom:CustomerCenter.List.Name")</a> 1170 </li> 1171 } 1172 } 1173 } else { 1174 string favLinkType = GetString("Ecom:Product.AddToFavorites") + "&CCListType=0&CCCreateNewList=" + Translate("My favorites"); 1175 string isInListIcon = favoriteOutlineIcon; 1176 <li> 1177 <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(useFacebookPixel ? AddToWishlist : "")"><i class="@isInListIcon"></i> @Translate("My favorites")</a> 1178 </li> 1179 } 1180 </ul> 1181 </div> 1182 <label class="dropdown-trigger-off" for="FavoriteTrigger"></label> 1183 </div> 1184 </div> 1185 } 1186 </div>*@ 1187 } 1188 </div> 1189 if (Pageview.User != null && !pointShopOnly && Dynamicweb.Security.Licensing.LicenseManager.LicenseHasFeature("LoyaltyPoints")) { 1190 <text> 1191 {{#if canBePurchasedWithPoints}} 1192 <form method="post" role="form" class="u-no-margin u-margin-top"> 1193 <input type="hidden" name="ProductID" value="{{id}}" /> 1194 <button type="submit" class="btn btn--loyalty-points u-no-margin dw-mod pull-right u-no-margin js-cart-btn {{disabledBuyButton}}" name="CartCmd" value="addWithPoints">@Translate("Buy for") {{points}} @Translate("points")</button> 1195 </form> 1196 {{/if}} 1197 </text> 1198 } 1199 } else { 1200 <button type="button" id="CartButton_{{id}}" class="u-hidden"></button> 1201 } 1202 } else { 1203 <div class="product__price-actions__price dw-mod u-margin-bottom--lg"> 1204 @if (pointShopOnly) { 1205 // something. 1206 } else { 1207 @*<div class="before-price {{onSale}} dw-mod">{{discount}}</div>*@ 1208 1209 <div class="price price--product-page dw-mod"> 1210 {{#ifCond vejledendePrisDouble '>' 0}} 1211 @Translate("Vejl. pris"): @Translate("DKK") {{vejledendePris}} 1212 {{/ifCond}} 1213 </div> 1214 @*if(showVATPrice) { 1215 <small class="vat-price vat-price--product-page u-margin-top dw-mod"> 1216 @if(isPricesWithVATEnabled) { 1217 @Translate("excl. VAT") <text>({{priceWithoutVAT}})</text> 1218 } else { 1219 @Translate("incl. VAT") <text>({{priceWithVAT}})</text> 1220 } 1221 </small> 1222 }*@ 1223 } 1224 </div> 1225 } 1226 {{/.}} 1227 </script> 1228 1229 <script id="Units" type="text/x-template"> 1230 <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent('PriceAndActions', '/Default.aspx?ID=@feedId&UnitID={{value}}')">{{{name}}}</div> 1231 </script> 1232 1233 <script id="UnitOption" type="text/x-template"> 1234 <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent('PriceAndActions', '{{link}}&feed=true&UnitID={{value}}&rid={{id}}')">{{{name}}}</div> 1235 </script> 1236 1237 1238 <script> 1239 document.addEventListener("DOMContentLoaded", function () { 1240 if (document.getElementById("PriceAndActions")) { 1241 document.getElementById("PriceAndActions").addEventListener("contentLoaded", function (event) { 1242 if (document.querySelector(".js-variants") != null) { 1243 MatchVariants.Update(document.querySelector(".js-variants"), "DoNothing"); 1244 } 1245 }); 1246 } 1247 }); 1248 </script> 1249 } 1250 1251 @if (useGoogleTagManager) { 1252 var groupObject = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(GetString("Ecom:Product.PrimaryOrFirstGroupID")); 1253 //var gtmPrice = (GetDouble("Ecom:Product.Discount.Price.Price") != GetDouble("Ecom:Product.Price.Price") ? GetDouble("Ecom:Product.Discount.Price.Price") : GetDouble("Ecom:Product.Price.Price")); 1254 var gtmPrice = GetDouble("Ecom:Product:Field.Vejledendepris.Value.Raw"); 1255 <script> 1256 // Measure a view of product details. This example assumes the detail view occurs on pageload, 1257 // and also tracks a standard pageview of the details page. 1258 1259 dataLayer.push({ 1260 "ecommerce": { 1261 "detail": { 1262 "actionField": {}, // 'detail' actions have an optional list property. 1263 "products": [{ 1264 "name": "@GetString("Ecom:Product.Name")", // Name or ID is required. 1265 "id": "@GetString("Ecom:Product.ID")", 1266 "price": "@gtmPrice", 1267 "brand": "@GetString("Ecom:Product:Field.brand.Value")", 1268 "category": "@(groupObject != null ? groupObject.Name : "")", 1269 "variant": "@(!string.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) ? GetString("Ecom:Product.VariantID") : GetString("Ecom:Product.VariantID.Extented"))" 1270 }] 1271 } 1272 } 1273 }); 1274 </script> 1275 } @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 1276 @using Dynamicweb.Core 1277 @using System 1278 @using System.Web 1279 @using System.Collections.Generic 1280 @using Dynamicweb.Rapido.Blocks 1281 @functions { 1282 BlocksPage productAssetsPage = BlocksPage.GetBlockPage("Product"); 1283 } 1284 1285 @{ 1286 string productAssetsLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("ProductAssetsLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductAssetsLayout").SelectedValue : "Section"; 1287 productAssetsLayout = productAssetsLayout == "Ribbon" ? "Section" : productAssetsLayout; 1288 1289 if (productAssetsLayout != "hide") 1290 { 1291 Block productAssetsBlock = new Block() 1292 { 1293 Name = productAssetsLayout != "MainInformation" ? Translate("Product assets") : "", 1294 Id = "ProductAssets", 1295 SortId = 10, 1296 @*downloadDocuments variable, declared in Product.cshtml and defined in Fields.cshtml*@ 1297 Template = RenderProductAssets(productAssetsLayout, downloadDocuments), 1298 Design = new Design 1299 { 1300 Size = "12", 1301 RenderType = RenderType.Column, 1302 HidePadding = true 1303 } 1304 }; 1305 productAssetsPage.Add(productAssetsLayout, productAssetsBlock); 1306 } 1307 } 1308 1309 @helper RenderProductAssets(string layout, List<LoopItem> documents) 1310 { 1311 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductAssetsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 1312 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductAssetsLayout").SelectedValue == "Ribbon" ? "u-padding--lg" : ""; 1313 string exportPageId = GetPageIdByNavigationTag("ProductExportFeed").ToString(); 1314 1315 //images 1316 1317 HashSet<string> images = new HashSet<string>(); 1318 1319 images.Add(GetProductImage()); 1320 1321 foreach (LoopItem alternativeImage in GetLoop("Ecom:Product.AlternativeImages")) 1322 { 1323 string alt_image = alternativeImage.GetString("Ecom:Product.AlternativeImages.Image"); 1324 1325 if (!string.IsNullOrEmpty(alt_image)) 1326 { 1327 images.Add(alt_image); 1328 } 1329 } 1330 1331 foreach (LoopItem detail in GetLoop("Details")) 1332 { 1333 string detail_image = detail.GetString("Ecom:Product:Detail.Image.Clean"); 1334 1335 if (!string.IsNullOrEmpty(detail_image)) 1336 { 1337 images.Add(detail_image); 1338 } 1339 } 1340 1341 <div class="product__section @ribbonClasses dw-mod"> 1342 <div class="product__description center-container @ribbonSubClasses dw-mod"> 1343 @if (layout == "Section") 1344 { 1345 <h2>@Translate("Product assets")</h2> 1346 } 1347 1348 <form action="/Default.aspx?ID=@exportPageId&ProductID=@System.Web.HttpContext.Current.Request.QueryString.Get("ProductID")&VariantID=@System.Web.HttpContext.Current.Request.QueryString.Get("VariantID")" method="post" class="u-flex grid--direction-column u-no-margin"> 1349 <div class="grid"> 1350 @if (images.Count > 0) 1351 { 1352 <div class="grid__col-md-4"> 1353 <div class="u-margin-bottom"> 1354 <input type="checkbox" class="u-no-margin form__control" id="allImages" onchange="selectAll(this)" /> 1355 <label for="allImages" class="u-bold u-inline-block">@Translate("Images") (@(images.Count))</label> 1356 </div> 1357 1358 <ul class="panel-list"> 1359 @foreach (string image in images) 1360 { 1361 @RenderPanelListItem(image) 1362 } 1363 </ul> 1364 </div> 1365 } 1366 1367 @if (documents.Count > 0) 1368 { 1369 <div class="grid__col-md-4"> 1370 <div class="u-margin-bottom"> 1371 <input type="checkbox" class="u-no-margin form__control" id="allDocuments" onchange="selectAll(this)" /> 1372 <label for="allDocuments" class="u-bold u-inline-block">@Translate("Documents") (@documents.Count)</label> 1373 </div> 1374 1375 <ul class="panel-list"> 1376 @foreach (LoopItem document in documents) 1377 { 1378 string fieldValue; 1379 if (!string.IsNullOrEmpty(document.GetString("Document.FullPath"))) 1380 { 1381 fieldValue = document.GetString("Product.CustomField.Value.Clean"); 1382 @RenderDocument(fieldValue) 1383 } 1384 if (document.GetString("Ecom:Product.CategoryField.TypeID") == "9") 1385 { 1386 fieldValue = document.GetString("Ecom:Product.CategoryField.Value"); 1387 @RenderDocument(fieldValue) 1388 } 1389 } 1390 </ul> 1391 </div> 1392 } 1393 <div class="grid__col-md-4"> 1394 <input id="ID" name="ID" type="hidden" value="532" /> 1395 <input id="download" name="download" type="hidden" value="true" /> 1396 <input name="siteUrl" type="hidden" value="@string.Format("{0}://{1}", GetGlobalValue("Global:Request.Scheme"), GetGlobalValue("Global:Request.Host"))" /> 1397 1398 <div class="u-bold u-margin-bottom">@Translate("Export")</div> 1399 1400 <label for="exportLanguage">@Translate("Language")</label> 1401 <select id="exportLanguage" name="RequestLanguageId" class="u-full-width"> 1402 @foreach (var lang in Services.Languages.GetLanguages().OrderBy(l => l.Name)) 1403 { 1404 var selected = lang.IsDefault ? "selected" : ""; 1405 <option value="@lang.LanguageId" @selected>@lang.Name</option> 1406 } 1407 </select> 1408 1409 <label for="purpose">@Translate("Image purpose")</label> 1410 <select id="purpose" name="purpose" class="u-full-width"> 1411 <option value="Office">@Translate("Office")</option> 1412 <option value="Original">@Translate("Original")</option> 1413 <option value="Print">@Translate("Print")</option> 1414 <option value="Web">@Translate("Web")</option> 1415 </select> 1416 1417 <label for="exportFormat">@Translate("Export format")</label> 1418 <select id="exportFormat" name="format" class="u-full-width"> 1419 <option value="csv">Csv</option> 1420 <option value="json">Json</option> 1421 <option value="xml">Xml</option> 1422 </select> 1423 1424 <input type="submit" value="@Translate("Download")" class="btn btn--full btn--primary u-no-margin dw-mod" title="@Translate("Download")" /> 1425 </div> 1426 </div> 1427 </form> 1428 </div> 1429 </div> 1430 <script> 1431 function selectAll(checkbox) { 1432 Array.prototype.slice.call(checkbox.parentElement.nextElementSibling.getElementsByTagName('input')).forEach(function (input) { 1433 input.checked = checkbox.checked; 1434 }); 1435 } 1436 </script> 1437 } 1438 1439 @helper RenderPanelListItem(string imageName) 1440 { 1441 <li class="panel-list__item"> 1442 <div class="panel-list__item-check"> 1443 <input type="checkbox" name="Image_@imageName" class="u-no-margin form__control" id="Image_@imageName" /> 1444 <label for="Image_@imageName"></label> 1445 </div> 1446 <div class="panel-list__item-image"> 1447 <label for="Image_@imageName"> 1448 <img class="b-lazy flex-img" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=55&amp;height=55&amp;crop=5&amp;FillCanvas=True&amp;Compression=75&amp;image=@imageName" alt="@Path.GetFileName(imageName)"> 1449 </label> 1450 </div> 1451 <div class="panel-list__item-name"> 1452 <label for="Image_@imageName" class="u-truncate-text u-w170px"> 1453 @Path.GetFileName(imageName) 1454 </label> 1455 </div> 1456 </li> 1457 } 1458 1459 @helper RenderDocument(string fieldValue) 1460 { 1461 <li class="panel-list__item"> 1462 <div class="panel-list__item-check"> 1463 <input type="checkbox" name="Document_@fieldValue" class="u-no-margin form__control" id="Document_@fieldValue" /> 1464 <label for="Document_@fieldValue"></label> 1465 </div> 1466 <div class="panel-list__item-name"> 1467 <label for="Document_@fieldValue" class="u-truncate-text u-max-w220px"> 1468 @Path.GetFileName(fieldValue) 1469 </label> 1470 </div> 1471 </li> 1472 } @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 1473 @using Dynamicweb.Core 1474 @using System 1475 @using System.Web 1476 @using System.Collections.Generic 1477 @using Dynamicweb.Rapido.Blocks 1478 1479 @functions { 1480 BlocksPage productGeneratePDFPage = BlocksPage.GetBlockPage("Product"); 1481 } 1482 1483 @{ 1484 string generatePDFLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("GeneratePDFLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("GeneratePDFLayout").SelectedValue : "Section"; 1485 generatePDFLayout = generatePDFLayout == "Ribbon" ? "Section" : generatePDFLayout; 1486 1487 if (GetPageIdByNavigationTag("PdfFolder") > 0 && generatePDFLayout != "hide") 1488 { 1489 Block generatePDFBlock = new Block() 1490 { 1491 Name = generatePDFLayout != "MainInformation" ? Translate("Generate PDF") : "", 1492 Id = "GeneratePDF", 1493 SortId = 10, 1494 Template = RenderGeneratePDFSection(generatePDFLayout), 1495 Design = new Design 1496 { 1497 Size = "12", 1498 RenderType = RenderType.Column, 1499 HidePadding = true 1500 } 1501 }; 1502 1503 productGeneratePDFPage.Add(generatePDFLayout, generatePDFBlock); 1504 } 1505 } 1506 1507 @helper RenderGeneratePDFSection(string layout) 1508 { 1509 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("GeneratePDFLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 1510 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses; 1511 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("GeneratePDFLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 1512 string exportPageId = GetPageIdByNavigationTag("ProductExportFeed").ToString(); 1513 int pdfFolderId = GetPageIdByNavigationTag("PdfFolder"); 1514 1515 <div class="product__section @ribbonClasses grid dw-mod"> 1516 <div class="dw-mod grid__col-md-4 @ribbonSubClasses"> 1517 @if (layout == "Section") { 1518 <h2>@Translate("Generate PDF")</h2> 1519 } 1520 1521 <form action="/Default.aspx?ID=@exportPageId&ProductID=@System.Web.HttpContext.Current.Request.QueryString.Get("ProductID")&VariantID=@System.Web.HttpContext.Current.Request.QueryString.Get("VariantID")&GeneratePdf=true" method="post" class="u-no-margin"> 1522 <input name="siteUrl" type="hidden" value="@string.Format("{0}://{1}", GetGlobalValue("Global:Request.Scheme"), GetGlobalValue("Global:Request.Host"))" /> 1523 1524 <label for="PdfLanguageId">@Translate("Language")</label> 1525 <select id="PdfLanguageId" name="PdfLanguageId" class="u-full-width"> 1526 @foreach (var lang in Services.Languages.GetLanguages().OrderBy(l => l.Name)) 1527 { 1528 var selected = lang.IsDefault ? "selected" : ""; 1529 <option value="@lang.LanguageId" @selected>@lang.Name</option> 1530 } 1531 </select> 1532 <label for="PdfPageId">@Translate("Generate PDF")</label> 1533 <select id="PdfPageId" name="PdfPageId" class="u-full-width"> 1534 <option value="" selected>@Translate("Select type")</option> 1535 @foreach (Dynamicweb.Content.Page page in ServiceLocator.Current.GetPageService().GetPagesByParentID(pdfFolderId)) 1536 { 1537 <option value="@page.ID">@page.MenuText</option> 1538 } 1539 </select> 1540 1541 <input type="submit" value="@Translate("Generate PDF")" class="btn btn--full btn--primary u-no-margin dw-mod" title="@Translate("Generate PDF")" /> 1542 </form> 1543 </div> 1544 </div> 1545 } @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 1546 @using Dynamicweb.Core 1547 @using System 1548 @using System.Web 1549 @using System.Collections.Generic 1550 @using Dynamicweb.Rapido.Blocks 1551 1552 @functions { 1553 BlocksPage productDescriptionPage = BlocksPage.GetBlockPage("Product"); 1554 } 1555 1556 @{ 1557 string fullDesctiptionLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("FullDescriptionLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue : "Section"; 1558 fullDesctiptionLayout = fullDesctiptionLayout == "Ribbon" ? "Section" : fullDesctiptionLayout; 1559 1560 if (!string.IsNullOrEmpty(GetString("Ecom:Product.LongDescription")) && fullDesctiptionLayout != "hide") { 1561 Block detailsDescription = new Block() { 1562 Name = fullDesctiptionLayout != "MainInformation" ? Translate("Detailed description") : "", 1563 Id = "FullDescription", 1564 SortId = 10, 1565 Template = RenderProductDescription(fullDesctiptionLayout), 1566 Design = new Design { 1567 Size = "12", 1568 RenderType = RenderType.Column, 1569 HidePadding = true 1570 } 1571 }; 1572 productDescriptionPage.Add(fullDesctiptionLayout, detailsDescription); 1573 } 1574 1575 } 1576 1577 @helper RenderProductDescription(string layout) { 1578 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 1579 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses; 1580 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 1581 1582 bool b2cUser = false; 1583 if (Pageview.User != null) { 1584 b2cUser = Pageview.User.GroupsIds.Contains(7913); 1585 1586 } else { 1587 b2cUser = true; 1588 } 1589 1590 <div class="product__section @ribbonClasses dw-mod"> 1591 <div class="product__description center-container @ribbonSubClasses dw-mod"> 1592 @if (layout == "Section") { 1593 <h2>@Translate("Description")</h2> 1594 } 1595 @GetString("Ecom:Product.LongDescription") 1596 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Kollistoerrelse")) && !b2cUser) { 1597 <p class="color-gray">@Translate(GetString("Ecom:Product:Field.Kollistoerrelse.Name")): @GetString("Ecom:Product:Field.Kollistoerrelse")</p> 1598 } 1599 1600 </div> 1601 </div> 1602 } @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 1603 @using Dynamicweb.Core 1604 @using System 1605 @using System.Web 1606 @using System.Globalization; 1607 @using System.Collections.Generic 1608 @using Dynamicweb.Rapido.Blocks 1609 1610 @functions { 1611 BlocksPage productFieldsPage = BlocksPage.GetBlockPage("Product"); 1612 1613 static string ConvertBytes(long bytes) 1614 { 1615 double size = bytes / 1024; //KB 1616 if (size > 1024) 1617 { 1618 size = (bytes / 1024f) / 1024f; //MB 1619 return string.Format("{0:n1} MB", size); 1620 } 1621 else 1622 { 1623 return string.Format("{0:n0} KB", size); 1624 } 1625 } 1626 1627 static bool isImage(string path) 1628 { 1629 return new List<string> { ".jpg", ".jpeg", ".gif", ".png", ".svg" }.Contains(Path.GetExtension(path).ToLower()); 1630 } 1631 1632 string getIconForFile(string fileName) 1633 { 1634 string ext = Path.GetExtension(fileName); 1635 string icon = ""; 1636 switch (ext.ToLower()) 1637 { 1638 case ".xls": 1639 case ".xlsx": 1640 icon = "fa-file-excel"; 1641 break; 1642 case ".ppt": 1643 case ".pptx": 1644 icon = "fa-file-powerpoint"; 1645 break; 1646 case ".doc": 1647 case ".docx": 1648 icon = "fa-file-word"; 1649 break; 1650 case ".jpg": 1651 case ".jpeg": 1652 case ".png": 1653 case ".gif": 1654 case ".pdf": 1655 return "<img class='product__document-img' alt='" + fileName + "' src='/Admin/Public/GetImage.ashx?crop=5&height=70&width=120&Compression=75&DoNotUpscale=true&image=" + fileName + "' />"; 1656 default: 1657 icon = "fa-file"; 1658 break; 1659 } 1660 return "<i class='product__document-icon far " + icon + "'></i> "; 1661 } 1662 } 1663 1664 @*downloadDocuments variable, declared in Product.cshtml - this variable also will be used in ProductAssets.cshtml*@ 1665 1666 @{ 1667 foreach (LoopItem customField in GetLoop("CustomFieldValues")) 1668 { 1669 if (!string.IsNullOrEmpty(customField.GetString("Product.CustomField.Name")) && !string.IsNullOrEmpty(customField.GetString("Product.CustomField.Value.Clean")) && customField.GetString("Product.CustomField.Name") != "Custom sticker") 1670 { 1671 if (!string.IsNullOrEmpty(customField.GetString("Document.FullPath"))) 1672 { 1673 downloadDocuments.Add(customField); 1674 } 1675 } 1676 } 1677 1678 foreach (LoopItem customField in GetLoop("ProductCategories")) 1679 { 1680 foreach (LoopItem field in customField.GetLoop("ProductCategoryFields")) 1681 { 1682 if (!string.IsNullOrEmpty(field.GetString("Ecom:Product.CategoryField.Label")) && !string.IsNullOrEmpty(field.GetString("Ecom:Product.CategoryField.Value"))) 1683 { 1684 if (field.GetString("Ecom:Product.CategoryField.TypeID") == "9") 1685 { 1686 downloadDocuments.Add(field); 1687 } 1688 } 1689 } 1690 } 1691 1692 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true; 1693 string detailFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout").SelectedValue : "Section"; 1694 detailFieldsLayout = detailFieldsLayout == "Ribbon" || string.IsNullOrEmpty(detailFieldsLayout) ? "Section" : detailFieldsLayout; 1695 string categoryFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout").SelectedValue : "Section"; 1696 categoryFieldsLayout = categoryFieldsLayout == "Ribbon" || string.IsNullOrEmpty(categoryFieldsLayout) ? "Section" : categoryFieldsLayout; 1697 string downloadsFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout").SelectedValue : "Section"; 1698 downloadsFieldsLayout = downloadsFieldsLayout == "Ribbon" || string.IsNullOrEmpty(downloadsFieldsLayout) ? "Section" : downloadsFieldsLayout; 1699 1700 string detailFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsView").SelectedValue : "grid"; 1701 string categoryFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsView").SelectedValue : "grid"; 1702 string downloadsFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsFieldsView").SelectedValue : "grid"; 1703 1704 //Fjern && false for at få vist detajle fanen 1705 if (GetLoop("CustomFieldValues").Count > 0 && detailFieldsLayout != "hide" && false) 1706 { 1707 Block detailsCustom = new Block() 1708 { 1709 Name = detailFieldsLayout != "MainInformation" ? Translate("Details") : "", 1710 Id = "CustomFields", 1711 SortId = 30, 1712 Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Information"), RenderCustomFields(GetLoop("CustomFieldValues"), detailFieldsView)), 1713 Design = new Design 1714 { 1715 Size = "12", 1716 RenderType = RenderType.Column, 1717 HidePadding = true 1718 } 1719 }; 1720 1721 productFieldsPage.Add(detailFieldsLayout, detailsCustom); 1722 } 1723 1724 if (categoryFieldsLayout != "hide") 1725 { 1726 foreach (LoopItem categoryGroup in GetLoop("ProductCategories")) 1727 { 1728 bool hasFields = categoryGroup.GetLoop("ProductCategoryFields").FirstOrDefault(cf => !string.IsNullOrEmpty(cf.GetString("Ecom:Product.CategoryField.Value"))) != null; 1729 1730 if (collectAllDownloads) { 1731 int downloadableCount = 0; 1732 foreach (LoopItem field in categoryGroup.GetLoop("ProductCategoryFields")) 1733 { 1734 if (field.GetString("Ecom:Product.CategoryField.TypeID") == "9") 1735 { 1736 downloadableCount++; 1737 } 1738 } 1739 1740 if (downloadableCount == categoryGroup.GetLoop("ProductCategoryFields").Count) { 1741 hasFields = false; 1742 } 1743 } 1744 1745 if (hasFields) 1746 { 1747 Block detailsCategoryFields = new Block() 1748 { 1749 Name = categoryFieldsLayout != "MainInformation" ? categoryGroup.GetString("Ecom:Product.Category.Name") : "", 1750 Id = ToPascalCase(categoryGroup.GetString("Ecom:Product.Category.Name")), 1751 SortId = 40, 1752 Template = RenderProductSection(categoryFieldsLayout, categoryFieldsView, categoryGroup.GetString("Ecom:Product.Category.Name"), RenderProductCategoryFields(categoryGroup.GetLoop("ProductCategoryFields"), categoryFieldsView)), 1753 Design = new Design 1754 { 1755 Size = "12", 1756 RenderType = RenderType.Column, 1757 HidePadding = true 1758 } 1759 }; 1760 1761 productFieldsPage.Add(categoryFieldsLayout, detailsCategoryFields); 1762 } 1763 } 1764 } 1765 1766 if (downloadDocuments.Count > 0 && downloadsFieldsLayout != "hide" && collectAllDownloads == true) 1767 { 1768 Block detailsDownloads = new Block() 1769 { 1770 Name = downloadsFieldsLayout != "MainInformation" ? Translate("Downloads") : "", 1771 Id = "StandardDownloads", 1772 SortId = 50, 1773 Template = RenderProductSection(downloadsFieldsLayout, downloadsFieldsView, Translate("Downloads"), RenderProductDownloadsFields(downloadDocuments, downloadsFieldsView)), 1774 Design = new Design 1775 { 1776 Size = "12", 1777 RenderType = RenderType.Column, 1778 HidePadding = true 1779 } 1780 }; 1781 1782 productFieldsPage.Add(downloadsFieldsLayout, detailsDownloads); 1783 } 1784 } 1785 1786 @helper RenderCustomFields(List<LoopItem> fieldsLoop, string viewType) 1787 { 1788 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true; 1789 1790 foreach (LoopItem customField in fieldsLoop) 1791 { 1792 string customSystemField = customField.GetString("Product.CustomField.System"); 1793 if( customSystemField == "Indholddagsdosis" || 1794 customSystemField == "Kollistoerrelse" || 1795 customSystemField == "Anprisninger" || 1796 customSystemField == "Pligttekst" || 1797 customSystemField == "Anvendelse" || 1798 customSystemField == "Salgsfeatures" || 1799 customSystemField == "Livsstil" || 1800 customSystemField == "Ingredienser" || 1801 customSystemField == "Naeringsindhold" || 1802 customSystemField == "Indeholder" || 1803 customSystemField == "EAN" || 1804 customSystemField == "Vejledendepris") { 1805 continue; 1806 } 1807 string fieldValue = customField.GetString("Product.CustomField.Value.Clean"); 1808 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; 1809 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; 1810 1811 if (customField.GetLoop("Product.CustomField.Options").Count > 0) 1812 { 1813 fieldValue = customField.GetString("Product.CustomField.Label"); 1814 } 1815 1816 if (!string.IsNullOrEmpty(customField.GetString("Product.CustomField.Name")) && !string.IsNullOrEmpty(fieldValue) && customField.GetString("Product.CustomField.Name") != "Custom sticker") 1817 { 1818 if (string.IsNullOrEmpty(customField.GetString("Document.FullPath")) && collectAllDownloads == false) 1819 { 1820 @RenderFieldItem(customField.GetString("Product.CustomField.Name"), fieldValue, viewType); 1821 } 1822 else if (collectAllDownloads == false) 1823 { 1824 @RenderFieldItem(customField.GetString("Product.CustomField.Name"), fieldValue, viewType, "download"); 1825 } 1826 } 1827 } 1828 } 1829 1830 @helper RenderProductSection(string layout, string viewType, string name, RazorEngine.Templating.TemplateWriter writer) { 1831 string ribbonClasses = layout == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 1832 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses; 1833 string ribbonSubClasses = layout == "Ribbon" ? "center-container--ribbon" : ""; 1834 1835 <div class="product__section @ribbonClasses dw-mod"> 1836 <div class="center-container @ribbonSubClasses dw-mod"> 1837 @if (layout == "Section") 1838 { 1839 <h2>@name</h2> 1840 } 1841 1842 @if (viewType != "table") 1843 { 1844 <div class="grid grid--bleed u-margin-bottom--lg"> 1845 @writer 1846 </div> 1847 } 1848 else 1849 { 1850 string tableWidth = layout != "MainInformation" ? "grid__col-md-6" : "grid__col-md-12"; 1851 1852 <div class="grid grid--external-bleed-x u-margin-bottom--lg"> 1853 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12"> 1854 <table class="table--no-top-border"> 1855 @writer 1856 </table> 1857 </div> 1858 </div> 1859 } 1860 </div> 1861 </div> 1862 } 1863 1864 @helper RenderProductCategoryFields(List<LoopItem> fieldsLoop, string viewType) { 1865 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true; 1866 1867 foreach (LoopItem categoryField in fieldsLoop) 1868 { 1869 string fieldValue = categoryField.GetString("Ecom:Product.CategoryField.Value"); 1870 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; 1871 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; 1872 1873 if (!string.IsNullOrEmpty(categoryField.GetString("Ecom:Product.CategoryField.Label")) && !string.IsNullOrEmpty(fieldValue)) 1874 { 1875 if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") != "9" || collectAllDownloads == false) 1876 { 1877 if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "15") 1878 { 1879 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), categoryField.GetString("Ecom:Product.CategoryField.OptionLabel"), viewType); 1880 } 1881 else if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "8") 1882 { 1883 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType, "link"); 1884 } 1885 else if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "9") 1886 { 1887 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType, "download"); 1888 } 1889 else 1890 { 1891 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType); 1892 } 1893 } 1894 } 1895 } 1896 } 1897 1898 @helper RenderProductDownloadsFields(List<LoopItem> fieldsLoop, string viewType) { 1899 foreach (LoopItem document in fieldsLoop) 1900 { 1901 string fieldValue; 1902 if (!string.IsNullOrEmpty(document.GetString("Document.FullPath"))) 1903 { 1904 fieldValue = document.GetString("Product.CustomField.Value.Clean"); 1905 @RenderFieldItem(fieldValue, document.GetString("Document.FullPath"), viewType, "download") 1906 } 1907 1908 if (document.GetString("Ecom:Product.CategoryField.TypeID") == "9") 1909 { 1910 fieldValue = document.GetString("Ecom:Product.CategoryField.Value"); 1911 @RenderFieldItem(fieldValue, fieldValue, viewType, "download") 1912 } 1913 } 1914 } 1915 1916 @helper RenderFieldItem(string name, string value, string viewType, string fieldType = "clean") 1917 { 1918 if (viewType != "table") 1919 { 1920 string fieldColumns = viewType == "list" ? "12" : "4"; 1921 <div class="grid__col-md-@fieldColumns grid__col-sm-12 u-margin-bottom"> 1922 <div class="u-bold"> 1923 @name 1924 </div> 1925 <div> 1926 @RenderFieldItemContent(name, value, fieldType) 1927 </div> 1928 </div> 1929 } 1930 else 1931 { 1932 <tr> 1933 <th>@name</th> 1934 <td> 1935 @RenderFieldItemContent(name, value, fieldType) 1936 </td> 1937 </tr> 1938 } 1939 } 1940 1941 @helper RenderFieldItemContent(string name, string value, string fieldType = "clean") 1942 { 1943 if (fieldType == "link") 1944 { 1945 <a target="_blank" rel="noopener" href="@value"> 1946 @if (isImage(value)) 1947 { 1948 @getIconForFile(value) 1949 } 1950 else 1951 { 1952 @value 1953 } 1954 </a> 1955 } 1956 else if (fieldType == "download") 1957 { 1958 FileInfo info = new FileInfo(Dynamicweb.Core.SystemInformation.MapPath(value)); 1959 1960 if (info.Exists) 1961 { 1962 <div class="grid grid--no-wrap"> 1963 <a href="@value" download title="@Translate("Download")" class="product__document u-min-w120px u-ta-center dw-mod">@getIconForFile(value)</a> 1964 <div class="product__document-info dw-mod"> 1965 <a href="@value" download title="@Translate("Download")" class="product__document dw-mod">@Path.GetFileName(value)</a> 1966 <small class="u-block u-margin-top">@ConvertBytes(info.Length)</small> 1967 </div> 1968 </div> 1969 } 1970 } 1971 else 1972 { 1973 @value 1974 } 1975 } 1976 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 1977 @using Dynamicweb.Core 1978 @using System 1979 @using System.Web 1980 @using System.Collections.Generic 1981 @using Dynamicweb.Rapido.Blocks 1982 1983 @functions{ 1984 BlocksPage productVideoPage = BlocksPage.GetBlockPage("Product"); 1985 } 1986 1987 @{ 1988 string videosLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue : "Section"; 1989 videosLayout = videosLayout == "Ribbon" || string.IsNullOrEmpty(videosLayout) ? "Section" : videosLayout; 1990 1991 int videosCount = 0; 1992 1993 foreach (LoopItem detailField in GetLoop("Details")) 1994 { 1995 if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("youtube.com/embed") != -1) 1996 { 1997 videosCount++; 1998 } 1999 if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("vimeo.com") != -1) 2000 { 2001 videosCount++; 2002 } 2003 } 2004 2005 if (videosCount > 0 && videosLayout != "hide") 2006 { 2007 Block detailsVideos = new Block() 2008 { 2009 Name = videosLayout != "MainInformation" ? Translate("Videos") : "", 2010 Id = "Videos", 2011 SortId = 60, 2012 Template = ProductVideos(videosCount, videosLayout), 2013 Design = new Design 2014 { 2015 Size = "12", 2016 RenderType = RenderType.Column 2017 } 2018 }; 2019 productVideoPage.Add(videosLayout, detailsVideos); 2020 } 2021 } 2022 2023 @helper ProductVideos(int videosCount, string layout) { 2024 string videoColumn = "12"; 2025 videoColumn = videosCount == 2 ? "6" : videoColumn; 2026 videoColumn = videosCount > 2 ? "4" : videoColumn; 2027 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 2028 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses; 2029 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 2030 2031 <div class="product__section @ribbonClasses dw-mod"> 2032 <div class="center-container @ribbonSubClasses dw-mod"> 2033 @if (layout == "Section") { 2034 <h2>@Translate("Videos")</h2> 2035 } 2036 2037 <div class="grid grid--external-bleed-x u-margin-bottom--lg"> 2038 @foreach (LoopItem detailField in GetLoop("Details")) 2039 { 2040 if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("youtube.com/embed") != -1 || detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("vimeo.com") != -1) 2041 { 2042 <div class="grid__col-md-@videoColumn grid__col-lg-@videoColumn"> 2043 <div class="video-wrapper"> 2044 @detailField.GetString("Ecom:Product:Detail.Text") 2045 </div> 2046 </div> 2047 } 2048 } 2049 </div> 2050 </div> 2051 </div> 2052 } @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2053 @using Dynamicweb.Core 2054 @using System 2055 @using System.Web 2056 @using System.Collections.Generic 2057 @using Dynamicweb.Rapido.Blocks 2058 2059 @functions{ 2060 BlocksPage productRelatedPage = BlocksPage.GetBlockPage("Product"); 2061 } 2062 2063 @{ 2064 string relatedProductsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue : "Section"; 2065 relatedProductsLayout = relatedProductsLayout == "Ribbon" || string.IsNullOrEmpty(relatedProductsLayout) ? "Section" : relatedProductsLayout; 2066 bool relatedOnlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null; 2067 bool relatedShowStock = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowStockAndShipping"); 2068 bool showAddToDownloadButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToDownloadButton"); 2069 bool relatedShowPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice"); 2070 bool relatedShowFavoriteButton = !Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("HideFavoriteButton") && Pageview.User != null; 2071 bool relatedPointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 2072 bool relatedShowCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToCartButton"); 2073 bool relatedShowViewButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowViewButton"); 2074 string relatedCartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; 2075 string relatedMoreText = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText")) ? Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText") : "View"; 2076 bool relatedShowNumber = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowProductNumber"); 2077 2078 // int relatedProductsPageSize = 4; 2079 int relatedProductsPageSize = 16; 2080 int relatedProductsColumnWidth = 3; 2081 2082 if (Pageview.Device.ToString() == "Mobile") { 2083 relatedProductsPageSize = 1; 2084 relatedProductsColumnWidth = 12; 2085 } 2086 2087 if (Pageview.Device.ToString() == "Tablet") { 2088 relatedProductsPageSize = 3; 2089 relatedProductsColumnWidth = 4; 2090 } 2091 2092 if (relatedProductsLayout != "hide") { 2093 if (GetLoop("eCom:Related.CustomersWhoSawThisAlsoSaw").Any()) { 2094 2095 string[] customersWhoSawThisAlsoSawProductIds = GetLoop("eCom:Related.CustomersWhoSawThisAlsoSaw").Select(x => x.GetString("Ecom:Product.ID")).ToArray(); 2096 string relatedGroupId = "OtherSeenProducts"; 2097 string baseFeedPageUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + 4 + "&ProdID=" + GetString("Ecom:Product.ID") + "&feed=true"; 2098 string relatedFeed = baseFeedPageUrl + "&" + relatedGroupId + "=" + string.Join(",", customersWhoSawThisAlsoSawProductIds); 2099 string relatedGroupName = "otherSeenProducts"; 2100 Block detailsRelated = new Block() 2101 { 2102 Name = relatedGroupName, 2103 Id = relatedGroupId, 2104 SortId = 70, 2105 Template = RenderRelatedProducts(relatedGroupName, relatedGroupId, relatedFeed, relatedProductsLayout, Translate("CustomersWhoSawThisAlsoSaw")), 2106 Design = new Design 2107 { 2108 Size = "12", 2109 RenderType = RenderType.Column, 2110 HidePadding = true 2111 } 2112 }; 2113 2114 productRelatedPage.Add(relatedProductsLayout, detailsRelated); 2115 } 2116 foreach (LoopItem relatedGroup in GetLoop("ProductRelatedGroups")) { 2117 string relatedGroupId = ToPascalCase(relatedGroup.GetString("Ecom:Product:RelatedGroup.Name")); 2118 string baseFeedPageUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + relatedProductsPageSize + "&ProdID=" + GetString("Ecom:Product.ID") + "&feed=true"; 2119 string relatedFeed = baseFeedPageUrl + "&" + relatedGroupId + "=" + GetString("Ecom:Product.ID") + "&GroupName=" + relatedGroupId; 2120 string relatedGroupName = relatedProductsLayout != "maininformation" ? relatedGroup.GetString("Ecom:Product:RelatedGroup.Name") : ""; 2121 Block detailsRelated = new Block() 2122 { 2123 Name = relatedGroupName, 2124 Id = relatedGroupId, 2125 SortId = 80, 2126 Template = RenderRelatedProducts(relatedGroupName, relatedGroupId, relatedFeed, relatedProductsLayout, Translate("Relaterede varer")), 2127 Design = new Design 2128 { 2129 Size = "12", 2130 RenderType = RenderType.Column, 2131 HidePadding = true 2132 } 2133 }; 2134 2135 productRelatedPage.Add(relatedProductsLayout, detailsRelated); 2136 } 2137 2138 //CustomersWhoSawThisAlsoSaw 2139 2140 2141 } 2142 } 2143 2144 @helper RenderRelatedProducts(string name, string groupId, string relatedFeedUrl, string layout, string header = "") 2145 { 2146 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 2147 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses; 2148 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 2149 2150 <div class="product__section @ribbonClasses dw-mod"> 2151 <div class="center-container @ribbonSubClasses dw-mod"> 2152 <h2>@header</h2> 2153 @if (layout == "Section") { 2154 @*<h2>@name</h2>*@ 2155 2156 } 2157 <div class="js-handlebars-root" id="ProductList_@groupId" data-template="ProductContainer" data-pre-render-template="ProductPreRenderContainer" data-json-feed="@relatedFeedUrl" data-preloader="minimal"></div> 2158 </div> 2159 </div> 2160 } 2161 2162 @* Script templates for related products *@ 2163 <script id="ProductPreRenderContainer" type="text/x-template"> 2164 <div class="u-h600px u-full-width"> 2165 <div class="grid"> 2166 <div class="grid__col-12"> 2167 <div class="pre-render-element pre-render-element--md"></div> 2168 </div> 2169 </div> 2170 </div> 2171 </script> 2172 2173 <script id="ProductContainer" type="text/x-template"> 2174 {{#.}} 2175 @*<h2>@Translate("Relaterede varer")</h2>*@ 2176 <div class="u-min-h400px u-full-width"> 2177 <div class="grid"> 2178 @*<div class="grid__col-45px grid__col--bleed-x"><div class="grid__cell grid__cell--align-middle-left"><button class="btn btn--condensed btn--clean {{prevdisabled}} dw-mod" onclick="HandlebarsBolt.UpdateContent('ProductList_{{groupName}}', '{{prevPage}}')" {{prevdisabled}}><i class="fas fa-chevron-left fa-2x"></i></button></div></div>*@ 2179 <div class="grid__col-auto grid__col--bleed-x"> 2180 <div id="ProductsContainer" data-template="ProductGridItemContainer" class="grid product-list dw-mod" data-save-cookie="true"> 2181 {{#ProductsContainer}} 2182 <div id="Product{{productId}}" class="grid__col-@relatedProductsColumnWidth product-list__grid-item dw-mod"> 2183 {{#Product}} 2184 @if (useGoogleTagManager) { 2185 <text>{{{googleEnchantImpression 'Related products' currency googleImpression}}}</text> 2186 } 2187 <div class="grid__cell product-list__grid-item__image dw-mod {{noImage}}"> 2188 <a href="{{link}}" onclick="Scroll.SavePosition(event)" class="u-block u-position-relative"> 2189 <img class="grid__cell-img grid__cell-img--centered b-lazy" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=300&amp;height=300&amp;crop=5&amp;Format=jpg&amp;Compression=75&amp;image={{image}}" alt="{{{name}}}" /> 2190 2191 </a> 2192 @if (relatedShowFavoriteButton) { 2193 <div class="favorites favorites--for-grid-view u-pull--right {{hasVariants}} dw-mod" {{hasVariants}}> 2194 {{#Favorite}} 2195 {{>FavoriteTemplate}} 2196 {{/Favorite}} 2197 </div> 2198 } 2199 </div> 2200 2201 <div class="grid__cell product-list__grid-item__price-info {{shortGridInfo}} dw-mod"> 2202 2203 {{#StickersContainers}} 2204 {{>StickersContainer}} 2205 {{/StickersContainers}} 2206 2207 <a href="{{link}}" onclick="Scroll.SavePosition(event)" title="{{{name}}}"> 2208 <h6 class="u-condensed-text"> 2209 {{{name}}} 2210 </h6> 2211 </a> 2212 2213 @if (relatedShowNumber) { 2214 <div class="item-number dw-mod">@Translate("Product number"): {{number}}</div> 2215 } 2216 2217 @if (relatedShowPrice && !relatedOnlyPreview) { 2218 if (relatedPointShopOnly) { 2219 <text> 2220 {{#if havePointPrice}} 2221 <div>{{points}} @Translate("points")</div> 2222 {{else}} 2223 @Translate("Not available") 2224 {{/if}} 2225 </text> 2226 } else { 2227 <div class="price price--product-list dw-mod">{{livePriceFormatted}}</div> 2228 <div class="before-price {{onSale}} dw-mod">{{discount}}</div> 2229 } 2230 } 2231 </div> 2232 2233 <div class="product-list__grid-item__footer dw-mod"> 2234 @if (relatedShowCartButton && !relatedOnlyPreview) { 2235 <div class="u-ta-center u-inline-block"> 2236 <div class="buttons-collection {{hideBuyOptions}}"> 2237 @if (relatedPointShopOnly) { 2238 <button type="button" id="CartButton_{{id}}" class="btn btn--primary btn--condensed u-no-margin dw-mod js-cart-btn {{disabledBuyButton}} {{#unless canBePurchasedWithPoints}}js-stay-disabled{{/unless}}" name="CartCmd" value="addWithPoints" 2239 onclick="Cart.AddToCart(event, { 2240 id: {{productId}}', 2241 variantId: '{{variantid}}', 2242 unitId: '{{unitId}}', 2243 quantity: 1, 2244 buyForPoints: true, 2245 productInfo: {{productInfo}} 2246 }); {{facebookPixelAction}}" {{disabledBuyButton}}> 2247 <i class="@relatedCartIcon"></i><span class="u-hidden-xs u-hidden-xxs"> @Translate("Buy with points")</span> 2248 </button> 2249 } else { 2250 <button type="button" id="CartButton_{{id}}" class="js-cart-btn btn btn--primary btn--condensed u-no-margin u-pull--right dw-mod {{disabledBuyButton}}" name="submit" 2251 onclick="Cart.AddToCart(event, { 2252 id: '{{productId}}', 2253 variantId: '{{variantid}}', 2254 unitId: '{{unitId}}', 2255 quantity: document.getElementById('Quantity_{{id}}').value, 2256 productInfo: {{productInfo}} 2257 }); {{facebookPixelAction}}" {{disabledBuyButton}}> 2258 <i class="@relatedCartIcon"></i><span class="u-hidden-xs u-hidden-xxs"> @Translate("Add to cart")</span> 2259 </button> 2260 <input type="number" class="u-w80px u-pull--right" id="Quantity_{{id}}" name="Quantity{{id}}" value="1" min="1"> 2261 } 2262 </div> 2263 </div> 2264 2265 if (relatedShowViewButton) { 2266 <div class="u-ta-center {{hideViewMore}}"> 2267 <a href="{{link}}" id="CartButton_{{id}}" class="btn btn--secondary u-no-margin dw-mod" onclick="Scroll.SavePosition(event); {{googleImpressionClick}}" title="@Translate(relatedMoreText)">@Translate(relatedMoreText)</a> 2268 </div> 2269 } 2270 2271 } else if (relatedShowViewButton) { 2272 <div class="u-ta-center"> 2273 <a href="{{link}}" id="CartButton_{{id}}" class="btn btn--secondary u-no-margin dw-mod" onclick="Scroll.SavePosition(event); {{googleImpressionClick}}" title="@Translate(relatedMoreText)">@Translate(relatedMoreText)</a> 2274 </div> 2275 } 2276 2277 @if (!relatedOnlyPreview && relatedShowStock) { 2278 <div class="u-margin-top"> 2279 <div><span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span> {{stockText}}</div> 2280 <div> 2281 {{#if deliveryText}} 2282 {{deliveryText}} 2283 {{else}} 2284 - 2285 {{/if}} 2286 </div> 2287 </div> 2288 } 2289 2290 @if (showAddToDownloadButton && Pageview.User != null) { 2291 <button type="button" class="btn btn--primary u-no-margin u-margin-top btn--condensed dw-mod js-add-to-downloads" title="@Translate("Add")" data-product-id="{{productId}}"> 2292 <i class="fas fa-plus js-button-icon"></i> 2293 <span class="js-button-text">@Translate("Add")</span> 2294 </button> 2295 } 2296 </div> 2297 {{/Product}} 2298 </div> 2299 {{/ProductsContainer}} 2300 </div> 2301 </div> 2302 @*<div class="grid__col-45px grid__col--bleed-x"><div class="grid__cell grid__cell--align-middle-right"><button class="btn btn--condensed btn--clean {{nextdisabled}} dw-mod" onclick="HandlebarsBolt.UpdateContent('ProductList_{{groupName}}', '{{nextPage}}')" {{nextdisabled}}><i class="fas fa-chevron-right fa-2x"></i></button></div></div>*@ 2303 </div> 2304 </div> 2305 {{/.}} 2306 </script> 2307 2308 @* Favorites templates *@ 2309 2310 <script id="FavoriteTemplate" type="text/x-template"> 2311 <div class="favorites-list u-ta-left"> 2312 <label for="FavoriteTrigger_{{id}}" class="u-no-margin"><i class="{{favoriteIcon}} fa-1_5x"></i></label> 2313 <input type="checkbox" id="FavoriteTrigger_{{id}}" class="dropdown-trigger" /> 2314 <div class="dropdown dropdown--absolute-position"> 2315 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod"> 2316 <ul class="list list--clean dw-mod"> 2317 {{#FavoriteLists}} 2318 {{>FavoriteListItem}} 2319 {{/FavoriteLists}} 2320 </ul> 2321 </div> 2322 <label class="dropdown-trigger-off" for="FavoriteTrigger_{{id}}"></label> 2323 </div> 2324 </div> 2325 </script> 2326 2327 <script id="StickersContainer" type="text/x-template"> 2328 <div class="stickers-container stickers-container--{{position}} dw-mod"> 2329 {{#Stickers}} 2330 {{>Sticker}} 2331 {{/Stickers}} 2332 </div> 2333 </script> 2334 2335 @*<script id="Sticker" type="text/x-template"> 2336 <div class="stickers-container__tag {{className}} dw-mod">{{text}}</div> 2337 </script>*@ 2338 2339 <script id="Sticker" type="text/x-template"> 2340 {{#if groupColor}} 2341 <div class="stickers-container__tag {{className}} dw-mod" style="background-color:{{groupColor}};">{{text}}</div> 2342 {{else}} 2343 <div class="stickers-container__tag {{className}} dw-mod">{{text}}</div> 2344 {{/if}} 2345 </script> 2346 2347 <script id="FavoriteListItem" type="text/x-template"> 2348 <li> 2349 <a href="{{link}}" class="list__link u-no-underline dw-mod" onclick="{{facebookPixelAction}}"><i class="{{favoriteIcon}}"></i> {{{name}}}</a> 2350 </li> 2351 </script> @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2352 @using Dynamicweb.Core 2353 @using System 2354 @using System.Web 2355 @using System.Collections.Generic 2356 @using Dynamicweb.Rapido.Blocks 2357 2358 @functions { 2359 BlocksPage productVariantsPage = BlocksPage.GetBlockPage("Product"); 2360 } 2361 2362 @{ 2363 bool renderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList"); 2364 bool variantsOnlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null; 2365 bool showProductNumberForVariants = !Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideProductNumbers"); 2366 bool showImageForEachVariant = !Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideImageForEachVariant"); 2367 bool variantsPointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 2368 string variantsListPageSize = HttpContext.Current.Request.QueryString.Get("PageSize") ?? "30"; 2369 string variantsFeedUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + variantsListPageSize + "&MainProductID=" + GetString("Ecom:Product.ID") + "&OnlyShowVariants=true&feed=true"; 2370 string variantsCartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; 2371 string variantsListLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue : "Section"; 2372 variantsListLayout = variantsListLayout == "Ribbon" ? "Section" : variantsListLayout; 2373 2374 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("ShowBothPricesWithWithoutVAT"); 2375 bool isPricesWithVATEnabled = Converter.ToBoolean(Pageview.Area.EcomPricesWithVat); 2376 2377 if (renderVariantsAsProducts && variantsListLayout != "hide") 2378 { 2379 Block detailsVariantsList = new Block() 2380 { 2381 Name = variantsListLayout != "MainInformation" ? Translate("Variants list") : "", 2382 Id = "VariantsList", 2383 SortId = 20, 2384 Template = RenderVariantsProductList(variantsListLayout), 2385 Design = new Design 2386 { 2387 Size = "12", 2388 RenderType = RenderType.Column, 2389 HidePadding = true 2390 } 2391 }; 2392 productVariantsPage.Add(variantsListLayout, detailsVariantsList); 2393 } 2394 } 2395 2396 @helper RenderVariantsProductList(string layout) 2397 { 2398 string variantsListPageSize = HttpContext.Current.Request.QueryString.Get("PageSize") ?? "30"; 2399 string variantsFeedUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + variantsListPageSize + "&MainProductID=" + GetString("Ecom:Product.ID") + "&OnlyShowVariants=true&feed=true"; 2400 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 2401 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses; 2402 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 2403 2404 <div class="product__section @ribbonClasses dw-mod"> 2405 <div class="center-container @ribbonSubClasses dw-mod"> 2406 @if (layout == "Section") { 2407 <h2>@Translate("Variants")</h2> 2408 } 2409 2410 <div class="js-handlebars-root" id="VariantsListRoot" data-template="VariantProductsContainer" data-json-feed="@variantsFeedUrl" data-preloader="minimal"></div> 2411 </div> 2412 </div> 2413 } 2414 2415 2416 @* Script templates for variant products *@ 2417 2418 <script id="VariantProductsContainer" type="text/x-template"> 2419 {{#.}} 2420 <div class=""> 2421 <table id="VariantsProductsContainer" class="table u-position-relative dw-mod"> 2422 <thead> 2423 <tr> 2424 @if (showImageForEachVariant) 2425 { 2426 <td width="75">&nbsp;</td> 2427 } 2428 <td>@Translate("Product")</td> 2429 {{#AvailableCustomFields}} 2430 {{>TableFieldNameTemplate}} 2431 {{/AvailableCustomFields}} 2432 @if (Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantGroupsInTable")) { 2433 foreach (LoopItem variantgroup in GetLoop("VariantGroups")) 2434 { 2435 <td>@variantgroup.GetString("Ecom:VariantGroup.Name")</td> 2436 } 2437 } 2438 <td width="360">&nbsp;</td> 2439 </tr> 2440 </thead> 2441 2442 <tbody id="VariantProductListContainer" data-template="VariantProductItemContainer" data-save-cookie="true"> 2443 {{#ProductsContainer}} 2444 {{>VariantProductItemContainer}} 2445 {{/ProductsContainer}} 2446 </tbody> 2447 </table> 2448 </div> 2449 2450 <div class="grid"> 2451 <div class="grid__col-12 grid__col--bleed-y"> 2452 <button type="button" id="LoadMoreButton" class="btn btn--primary {{nextdisabled}} dw-mod" data-current="{{currentPage}}" data-page-size="{{pageSize}}" data-total="{{totalPages}}" data-container="VariantProductListContainer" data-feed-url="@variantsFeedUrl{{loadMoreFeedParams}}" onclick="LoadMore.Next(this)" {{nextdisabled}}>@Translate("Load") @Translate("more")</button> 2453 </div> 2454 </div> 2455 {{/.}} 2456 </script> 2457 2458 <script id="VariantProductItemContainer" type="text/x-template"> 2459 {{#.}} 2460 <tr id="VariantProduct{{id}}" data-template="VariantProductItem" data-preloader="overlay" style="z-index: {{zIndex}}"> 2461 {{#Product}} 2462 {{>VariantProductItem}} 2463 {{/Product}} 2464 </tr> 2465 {{/.}} 2466 </script> 2467 2468 <script id="VariantProductItem" type="text/x-template"> 2469 {{#.}} 2470 @if (showImageForEachVariant) 2471 { 2472 <td width="75"> 2473 <div class="lightbox u-hidden-xxs"> 2474 <a href="{{link}}" onclick="Scroll.SavePosition(event)"> 2475 <img class="lightbox__image {{noImage}}" src="/Admin/Public/GetImage.ashx?width=220&amp;height=220&amp;crop=5&amp;Compression=75&amp;image={{image}}" alt="{{{name}}}" /> 2476 <div class="u-margin-right {{noImage}}"> 2477 <img src="/Admin/Public/GetImage.ashx?width=75&amp;height=55&amp;crop=5&FillCanvas=true&amp;Compression=75&amp;image={{image}}" alt="{{{name}}}" /> 2478 </div> 2479 </a> 2480 </div> 2481 </td> 2482 } 2483 2484 <td class="u-va-middle"> 2485 <a href="{{link}}" onclick="Scroll.SavePosition(event)" title="{{{name}}}"><h6 class="u-no-margin">{{{name}}}</h6></a> 2486 <div class="item-number item-number--compressed dw-mod"> 2487 @if (showProductNumberForVariants) 2488 { 2489 <div class="u-margin-bottom">@Translate("Product number"): {{number}}</div> 2490 } 2491 @*@if (!variantsOnlyPreview) 2492 { 2493 <div> 2494 <span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span> {{stockText}} {{deliveryText}} 2495 </div> 2496 }*@ 2497 else 2498 { 2499 <div class="grid__cell-footer stickers-container stickers-container--block dw-mod"> 2500 {{#Stickers}} 2501 {{>MiniSticker}} 2502 {{/Stickers}} 2503 </div> 2504 } 2505 </div> 2506 </td> 2507 {{#CustomFields}} 2508 {{>TableFieldValueTemplate}} 2509 {{/CustomFields}} 2510 @if (Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantGroupsInTable")) 2511 { 2512 <text> 2513 {{#VariantSelectionNames}} 2514 {{>TableFieldNameTemplate}} 2515 {{/VariantSelectionNames}} 2516 </text> 2517 } 2518 <td width="365" class="u-va-middle"> 2519 @if (variantsOnlyPreview) 2520 { 2521 <div class="u-hidden-sm"> 2522 <div class="u-full-width u-ta-right u-padding-right"> 2523 <div class="before-price {{onSale}} before-price--micro dw-mod">{{discount}}</div> 2524 <div class="price price--product-list price--micro dw-mod">{{livePriceFormatted}}</div> 2525 </div> 2526 </div> 2527 } 2528 else 2529 { 2530 <div class="grid grid--align-center grid--justify-end"> 2531 2532 <div class="u-margin-right"> 2533 <input type="checkbox" id="UnitOptions_{{id}}" class="dropdown-trigger" /> 2534 <div class="dropdown u-w120px {{hasUnits}} dw-mod"> 2535 <label class="dropdown__header dropdown__btn dw-mod" for="UnitOptions_{{id}}">{{unitName}}</label> 2536 <div id="unitOptions" class="dropdown__content dw-mod"> 2537 {{#unitOptions}} 2538 {{>UnitOption}} 2539 {{/unitOptions}} 2540 </div> 2541 <label class="dropdown-trigger-off" for="UnitOptions_{{id}}"></label> 2542 </div> 2543 <input type="hidden" value="{{unitId}}" name="Unit{{id}}" id="Unit_{{id}}" /> 2544 <input type="hidden" value="{{variantid}}" name="VariantID{{id}}" id="Variant_{{id}}" /> 2545 </div> 2546 <div class="u-margin-right u-hidden-xs u-hidden-xxs"> 2547 @if (variantsPointShopOnly) { 2548 <text> 2549 {{#if canBePurchasedWithPoints}} 2550 <div class="price price--product-list price--micro dw-mod">{{points}} @Translate("points")</div> 2551 {{else}} 2552 {{#if havePointPrice}} 2553 <small class="help-text u-no-margin u-margin-top">@Translate("Not enough points to buy this")</small> 2554 {{else}} 2555 <small class="help-text u-no-margin u-margin-top">@Translate("Not available")</small> 2556 {{/if}} 2557 {{/if}} 2558 </text> 2559 } else { 2560 <div class="before-price before-price--micro {{onSale}} dw-mod">{{discount}}</div> 2561 <div class="price price--condensed price--product-list dw-mod"> 2562 {{price}} 2563 @if (showVATPrice) { 2564 <small class="vat-price vat-price--product-page u-margin-top dw-mod"> 2565 @if (isPricesWithVATEnabled) { 2566 @Translate("excl. VAT") <text>({{priceWithoutVAT}})</text> 2567 } else { 2568 @Translate("incl. VAT") <text>({{priceWithVAT}})</text> 2569 } 2570 </small> 2571 } 2572 </div> 2573 } 2574 </div> 2575 @if (variantsPointShopOnly) { 2576 <div> 2577 <button {{#unless canBePurchasedWithPoints}} disabled{{/unless}} type="button" 2578 id="CartButton_{{id}}" 2579 class="btn btn--primary btn--condensed u-no-margin dw-mod js-cart-btn {{#unless canBePurchasedWithPoints}}disabled js-stay-disabled{{/unless}}" 2580 name="CartCmd" 2581 value="addWithPoints" 2582 onclick="Cart.AddToCart(event, { 2583 id: '{{productId}}', 2584 variantId: '{{variantid}}', 2585 unitId: '{{unitId}}', 2586 quantity: 1, 2587 buyForPoints: true, 2588 productInfo: {{productInfo}} 2589 })"> 2590 <i class="@variantsCartIcon"></i> 2591 </button> 2592 </div> 2593 } else { 2594 <div> 2595 <input type="number" class="u-w80px u-no-margin u-margin-right" id="Quantity_{{id}}" name="Quantity{{id}}" value="1" min="1"> 2596 </div> 2597 <div> 2598 <button type="button" id="CartButton_{{id}}" class="btn btn--primary btn--condensed u-no-margin dw-mod" name="submit" 2599 onclick="Cart.AddToCart(event, { 2600 id: '{{productId}}', 2601 variantId: '{{variantid}}', 2602 unitId: '{{unitId}}', 2603 quantity: document.getElementById('Quantity_{{id}}').value, 2604 productInfo: {{productInfo}} 2605 });"> 2606 <i class="@variantsCartIcon"></i> 2607 </button> 2608 </div> 2609 } 2610 <div class="favorites u-margin-left {{hasVariants}} dw-mod" {{hasVariants}}> 2611 {{#Favorite}} 2612 {{>FavoriteTemplate}} 2613 {{/Favorite}} 2614 </div> 2615 </div> 2616 } 2617 </td> 2618 {{/.}} 2619 </script> 2620 2621 <script id="TableFieldNameTemplate" type="text/x-template"> 2622 <td class="u-va-middle">{{{name}}}</td> 2623 </script> 2624 2625 <script id="TableFieldValueTemplate" type="text/x-template"> 2626 <td class="u-va-middle">{{value}}</td> 2627 </script> 2628 2629 <script id="MiniSticker" type="text/x-template"> 2630 <div class="stickers-container__tag stickers-container__tag--micro {{className}} dw-mod">{{text}}</div> 2631 </script> @if(File.Exists(HttpContext.Current.Server.MapPath("/Files/Templates/Designs/Rapido/eCom/Product/Blocks/Custom__Blocks.cshtml"))) { <text>@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2632 @using Dynamicweb.Core 2633 @using System 2634 @using System.Web 2635 @using System.Collections.Generic 2636 @using Dynamicweb.Rapido.Blocks 2637 2638 @{ 2639 BlocksPage customProductBlocks = BlocksPage.GetBlockPage("Product"); 2640 2641 //detailFieldsLayout skulle gerne være Tabs 2642 2643 2644 2645 if(detailFieldsLayout != "hide" && (GetLoop("Indeholder.Options").Where(x => x.GetBoolean("Indeholder.Option.IsSelected")).Any() || !string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Naeringsindhold")) || !string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Ingredienser")))) { 2646 Block contentsBlock = new Block { 2647 Id = "Contents", 2648 Name = Translate("Indhold"), 2649 SortId = 102, 2650 Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Indhold"), RenderContents()), 2651 Design = new Design { 2652 Size = "12", 2653 RenderType = RenderType.Column, 2654 HidePadding = true 2655 } 2656 }; 2657 customProductBlocks.Add(detailFieldsLayout, contentsBlock); 2658 } 2659 2660 2661 if(detailFieldsLayout != "hide" && !string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Pligttekst"))) { 2662 Block dutyTextBlock = new Block { 2663 Id = "DutyText", 2664 Name = Translate("Pligttekst"), 2665 SortId = 105, 2666 Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Pligttekst"), RenderDutyText()), 2667 Design = new Design { 2668 Size = "12", 2669 RenderType = RenderType.Column, 2670 HidePadding = true 2671 } 2672 }; 2673 customProductBlocks.Add(detailFieldsLayout, dutyTextBlock); 2674 } 2675 if(detailFieldsLayout != "hide" && !string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Anprisninger"))) { 2676 Block excellenceBlock = new Block { 2677 Id = "Excellence", 2678 Name = Translate("Anprisninger"), 2679 SortId = 110, 2680 Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Anprisninger"), RenderExcellence()), 2681 Design = new Design { 2682 Size = "12", 2683 RenderType = RenderType.Column, 2684 HidePadding = true 2685 } 2686 }; 2687 customProductBlocks.Add(detailFieldsLayout, excellenceBlock); 2688 } 2689 2690 } 2691 2692 @helper RenderExcellence() { 2693 <div class="grid grid--external-bleed-x u-margin-bottom--lg"> 2694 <div class="grid__col-md-12 grid__col-sm-12 grid__col-xs-12"> 2695 <ul> 2696 @foreach(var i in GetLoop("Anprisninger.Options").Where(x => x.GetBoolean("Anprisninger.Option.IsSelected"))) { 2697 var excellencePage = Dynamicweb.Services.Pages.GetPageByNavigationTag(Pageview.AreaID, i.GetString("Anprisninger.Option.Value")); 2698 if(excellencePage != null) { 2699 <li> 2700 <a href="/Default.aspx?ID=@excellencePage.ID">@excellencePage.MenuText</a> 2701 </li> 2702 } 2703 } 2704 </ul> 2705 </div> 2706 </div> 2707 } 2708 2709 2710 @helper RenderContents() { 2711 2712 var indeholderLoop = GetLoop("Indeholder.Options").Where(x => x.GetBoolean("Indeholder.Option.IsSelected")); 2713 <div class="grid grid--external-bleed-x u-margin-bottom--lg"> 2714 <div class="grid__col-md-12 grid__col-sm-12 grid__col-xs-12"> 2715 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Ingredienser"))) { 2716 <div class="u-bold">@Translate("Ingredienser")</div> 2717 <p>@GetString("Ecom:Product:Field.Ingredienser")</p> 2718 } 2719 @if (indeholderLoop.Any()) { 2720 <div class="u-bold">@Translate("Dette produkt indeholder"):</div> 2721 <ul> 2722 @foreach (var i in indeholderLoop) { 2723 <li>@i.GetString("Indeholder.Option.Name")</li> 2724 } 2725 </ul> 2726 2727 } 2728 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Naeringsindhold"))) { 2729 <div class="u-bold">@Translate("Næringsindhold")</div> 2730 <p>@GetString("Ecom:Product:Field.Naeringsindhold")</p> 2731 } 2732 2733 2734 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Indholddagsdosis"))) { 2735 <div class="u-bold">@Translate("Indhold pr. dagsdosis")</div> 2736 <p>@GetString("Ecom:Product:Field.Indholddagsdosis")</p> 2737 } 2738 2739 </div> 2740 </div> 2741 } 2742 @helper RenderDutyText() { 2743 <div class="grid grid--external-bleed-x u-margin-bottom--lg"> 2744 <div class="grid__col-md-12 grid__col-sm-12 grid__col-xs-12"> 2745 <p> 2746 @GetString("Ecom:Product:Field.Pligttekst") 2747 </p> 2748 </div> 2749 </div> 2750 }</text> } <div class="product__info dw-mod u-margin-bottom--lg js-product"> <div class="grid grid--align-content-start"> @* The @RenderBlockList base helper is included in Components/GridBuilder.cshtml *@ @RenderBlockList(productsPage.BlocksRoot.BlocksList) </div> </div> @helper RenderProductTop() { List<Block> subBlocks = productsPage.GetBlockListById("Top").OrderBy(item => item.SortId).ToList(); <div class="product__top paragraph-container paragraph-container--full-width dw-mod"> <div class="center-container u-padding dw-mod"> <div class="grid"> @RenderBlockList(subBlocks) </div> </div> </div> } @helper RenderProductMiniTabs() { List<Block> subBlocks = productsPage.GetBlockListById("MiniTabs").OrderBy(item => item.SortId).ToList(); if(subBlocks.Count > 0) { <div class="grid__col-12 product__info tabs u-no-padding u-margin-bottom--lg dw-mod"> @{ bool firstTab = true; foreach(Block item in subBlocks) { string isChecked = firstTab ? "checked" : ""; firstTab = false; <input type="radio" class="tabs__trigger" name="productMiniTabs" id="@item.Id" onchange="bLazy.revalidate()" @isChecked /> } } <div class="tabs__list dw-mod"> @foreach(Block item in subBlocks) { <label for="@item.Id" class="tabs__label dw-mod">@item.Name</label> } </div> <div class="tabs__blocks dw-mod"> @foreach(Block item in subBlocks) { string hidePadding = item.Design.HidePadding ? "u-no-padding" : ""; if(item.Design.RenderType != RenderType.Hide) { <div class="tabs__block u-border dw-mod" id="Block__@item.Id"> <block class="product__block paragraph-container product__block--bordered dw-mod"> <div class="center-container u-padding--lg dw-mod"> @RenderBlock(item) </div> </block> </div> } } </div> </div> } } @helper RenderProductTabs() { List<Block> subBlocks = productsPage.GetBlockListById("Tabs").OrderBy(item => item.SortId).ToList(); <div class="grid__col-12 product__info product__info--tabs tabs dw-mod"> @{ bool firstTab = true; foreach(Block item in subBlocks) { string isChecked = firstTab ? "checked" : ""; firstTab = false; <input type="radio" class="tabs__trigger" name="productTabs" id="@item.Id" onchange="bLazy.revalidate()" @isChecked /> } } <div class="tabs__list dw-mod"> @foreach(Block item in subBlocks) { <label for="@item.Id" class="tabs__label dw-mod">@item.Name</label> } </div> <div class="tabs__blocks dw-mod"> @foreach(Block item in subBlocks) { string hidePadding = item.Design.HidePadding ? "u-no-padding" : ""; if(item.Design.RenderType != RenderType.Hide) { <div class="tabs__block dw-mod" id="Block__@item.Id"> <section class="product__section paragraph-container paragraph-container--full-width product__section--bordered dw-mod"> <div class="center-container u-padding--lg dw-mod"> @RenderBlock(item) </div> </section> </div> } } </div> </div> }