An error occurred while attaching module (Dynamicweb.Frontend.Content)

System.NullReferenceException: Object reference not set to an instance of an object.
   at Dynamicweb.Ecommerce.ProductCatalog.ProductCatalogFrontend.RenderProduct(String productId, String variantId, String groupId, ProductCatalogSettings settings)
   at Dynamicweb.Ecommerce.ProductCatalog.ProductCatalogFrontend.GetContent()
   at Dynamicweb.Frontend.Content.GetModuleOutput(Paragraph paragraph, PageView pageview)

Error executing template "Designs/Swift/Paragraph/Swift_ProductStock.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_0083d002f1cd4ab2a756ab76c851fd89.Execute() in C:\inetpub\wwwroot\plus-prod\Files\Templates\Designs\Swift\Paragraph\Swift_ProductStock.cshtml:line 41
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 4 @{ 5 ProductViewModel product = new ProductViewModel(); 6 7 ProductViewModelSettings productSetting = new ProductViewModelSettings 8 { 9 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID, 10 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code, 11 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2, 12 ShopId = Pageview.Area.EcomShopId 13 }; 14 15 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 16 { 17 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 18 } else if (Pageview.Item["DummyProduct"] != null) { 19 20 string dummyProductId = ""; 21 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 22 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 23 if (productList.Products != null) 24 { 25 foreach (var p in productList.Products) { dummyProductId = p.Id; } 26 ProductViewModel dummyProduct = dummyProductId != "" ? ViewModelFactory.CreateView(productSetting, dummyProductId) : new ProductViewModel(); 27 product = dummyProduct; 28 } else { 29 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id); 30 } 31 } else if (Pageview.Item["DummyProduct"] == null) { 32 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id); 33 } 34 35 bool IsNeverOutOfStock = product.NeverOutOfstock; 36 bool isDiscontinued = product.Discontinued; 37 38 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 39 horizontalAlign = horizontalAlign == "center" ? "text-center" : horizontalAlign; 40 horizontalAlign = horizontalAlign == "end" ? "text-end" : horizontalAlign; 41 product.ProductFields.TryGetValue("ProductNextBackorderDate", out FieldValueViewModel backInStockDateValue); 42 DateTime backInstockDate = backInStockDateValue.Value != null? DateTime.Parse(backInStockDateValue.Value.ToString()) : DateTime.Today.AddDays(-1); 43 bool hasBackInstockDate = backInStockDateValue != null && backInstockDate >= DateTime.Today; 44 bool hasExpectedDelivery = product.ExpectedDelivery != null && product.ExpectedDelivery >= DateTime.Today; 45 string expectedDeliveryDate = hasBackInstockDate ? backInstockDate.ToShortDateString() : product.ExpectedDelivery?.ToShortDateString() ?? ""; 46 47 bool isErpConnectionDown = !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); 48 bool hideStock = Model.Item.GetBoolean("HideStockState") || (Pageview.AreaSettings.GetBoolean("ErpDownHideStock") && isErpConnectionDown); 49 50 string liveInfoClass = ""; 51 string productInfoFeed = ""; 52 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsLazyLoadingForProductInfoEnabled; 53 if (isLazyLoadingForProductInfoEnabled) 54 { 55 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 56 { 57 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 58 if (!string.IsNullOrEmpty(productInfoFeed)) 59 { 60 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 61 } 62 } 63 liveInfoClass = "js-live-info"; 64 } 65 } 66 67 @if (!hideStock) 68 { 69 if (!IsNeverOutOfStock && product.Id != null && !isDiscontinued) { 70 if (isLazyLoadingForProductInfoEnabled) 71 { 72 string hideStockState = string.IsNullOrEmpty(product.VariantId) && product.VariantInfo.VariantInfo != null ? "d-none" : ""; 73 <div class="js-stock-state @horizontalAlign item_@Model.Item.SystemName.ToLower() @liveInfoClass" data-product-id="@product.Id" @productInfoFeed> 74 <div class="mt-3 js-stock-state spinner-border @hideStockState"> 75 @if (!Model.Item.GetBoolean("HideInventory")) 76 { 77 <div class="small text-success d-none" data-show-if="LiveProductInfo.product.StockLevel > 0"> 78 <span class="js-text-stock"></span> 79 @Translate("In stock") 80 </div> 81 } 82 else 83 { 84 <div class="small text-success d-none" data-show-if="LiveProductInfo.product.StockLevel > 0">@Translate("In stock")</div> 85 } 86 <div class="small text-danger d-none" data-show-if="LiveProductInfo.product.StockLevel <= 0">@Translate("Out of Stock")</div> 87 88 <div class="d-none" data-show-if="LiveProductInfo.product.ExpectedDelivery != null && new Date(LiveProductInfo.product.ExpectedDelivery) > new Date()"> 89 <span>@Translate("Expected back in stock"): </span> 90 <span class="js-text-expected-delivery"></span> 91 </div> 92 </div> 93 </div> 94 } 95 else 96 { 97 <div class="js-stock-state @horizontalAlign item_@Model.Item.SystemName.ToLower()"> 98 99 100 101 @if(!string.IsNullOrWhiteSpace(product.StockStatus)) { 102 <p class="mb-1">@product.StockStatus</p> 103 if(!string.IsNullOrWhiteSpace(product.StockDeliveryText)) { 104 <p class="mb-1">@product.StockDeliveryText</p> 105 } 106 if (hasExpectedDelivery || hasBackInstockDate) 107 { 108 <div class="mb-1"> 109 <span>@Translate("Expected in stock"): </span> 110 <span>@expectedDeliveryDate</span> 111 </div> 112 } 113 } else { 114 if (product.StockLevel > 0) 115 { 116 if (!Model.Item.GetBoolean("HideInventory")) 117 { 118 @*<div class="text-success">@product.StockLevel @Translate("In stock")</div>*@ 119 <div class="text-success">@Translate("In stock")</div> 120 } 121 else 122 { 123 <div class="text-success">@Translate("In stock")</div> 124 } 125 if (hasExpectedDelivery || hasBackInstockDate) 126 { 127 <div class="mb-1"> 128 <span>@Translate("Expected in stock"): </span> 129 <span>@expectedDeliveryDate</span> 130 </div> 131 } 132 } 133 else 134 { 135 <div class="text-danger">@Translate("Out of Stock")</div> 136 137 if (hasExpectedDelivery || hasBackInstockDate) 138 { 139 <div> 140 <span>@Translate("Expected in stock"): </span> 141 <span>@expectedDeliveryDate</span> 142 </div> 143 } 144 } 145 } 146 147 148 @*@if (!string.IsNullOrWhiteSpace(product.StockStatus)) { 149 <div class="">@product.StockStatus</div> 150 <div class="">@product.StockDeliveryText</div> 151 { 152 <div> 153 <span>@Translate("Expected in stock"): </span> 154 <span>@expectedDeliveryDate</span> 155 </div> 156 } 157 } else { 158 if (product.StockLevel > 0) 159 { 160 if (!Model.Item.GetBoolean("HideInventory")) 161 { 162 <div class="text-success">@product.StockLevel @Translate("In stock")</div> 163 <div class="text-success">@Translate("In stock")</div> 164 165 } 166 else 167 { 168 <div class="text-success">@Translate("In stock")</div> 169 } 170 } 171 else 172 { 173 <div class="text-danger">@Translate("Out of Stock")</div> 174 175 if (hasExpectedDelivery || hasBackInstockDate) 176 { 177 <div> 178 <span>@Translate("Expected in stock"): </span> 179 <span>@expectedDeliveryDate</span> 180 </div> 181 } 182 } 183 }*@ 184 185 </div> 186 } 187 } else if (Pageview.IsVisualEditorMode) { 188 <div class="alert alert-info">@Translate("No products available")</div> 189 } 190 } 191
Error executing template "Designs/Swift/Paragraph/Swift_ProductCertificates_EA.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_a1db57f119074552b260f1cf8e10d500.Execute() in C:\inetpub\wwwroot\plus-prod\Files\Templates\Designs\Swift\Paragraph\Swift_ProductCertificates_EA.cshtml:line 43
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 4 @{ 5 ProductViewModel product = new ProductViewModel(); 6 7 ProductViewModelSettings productSetting = new ProductViewModelSettings 8 { 9 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID, 10 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code, 11 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2, 12 ShopId = Pageview.Area.EcomShopId 13 }; 14 15 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 16 { 17 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 18 } 19 else if (Pageview.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 20 { 21 string dummyProductId = ""; 22 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 23 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 24 if (productList.Products != null) 25 { 26 foreach (var p in productList.Products) { dummyProductId = p.Id; } 27 ProductViewModel dummyProduct = dummyProductId != "" ? ViewModelFactory.CreateView(productSetting, dummyProductId) : new ProductViewModel(); 28 product = dummyProduct; 29 } 30 else 31 { 32 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id); 33 } 34 } 35 else if (Pageview.Item["DummyProduct"] == null) 36 { 37 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id); 38 } 39 40 var bagdeItems = Model.Item?.GetItems("Certificate") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 41 42 FieldValueViewModel fscBadge; 43 product.ProductFields.TryGetValue("FSC", out fscBadge); 44 45 } 46 47 @if (product.Id != null) { 48 <div> 49 @if (bagdeItems.Count() > 0 && !string.IsNullOrEmpty(fscBadge.Value.ToString())) { 50 51 foreach (var badge in bagdeItems) 52 { 53 string imagePath = badge.GetString("Image"); 54 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + 50 + "&image=" + imagePath + "&format=webp"; 55 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + 100 + "&image=" + imagePath + "&format=webp"; 56 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + 200 + "&image=" + imagePath + "&format=webp"; 57 58 if (fscBadge.Value.ToString().Contains(badge.GetString("Title"))) { 59 60 if (!string.IsNullOrEmpty(badge.GetLink("Link").Url)) { 61 <a href="@badge.GetLink("Link")" target="_self" class=""> 62 <img class="" 63 srcset="@imagePathXs 500w, @imagePathS 100w" 64 sizes="(max-width: 480px) 50px, 100px" 65 src="@imagePathFallBack" 66 loading="lazy" 67 decoding="async" 68 alt="@badge.GetString("Title")" /> 69 </a> 70 } else { 71 72 <img class="" 73 srcset="@imagePathXs 500w, @imagePathS 100w" 74 sizes="(max-width: 480px) 50px, 100px" 75 src="@imagePathFallBack" 76 loading="lazy" 77 decoding="async" 78 alt="@badge.GetString("Title")" /> 79 } 80 } 81 } 82 } else { 83 if (Pageview.IsVisualEditorMode) { 84 <div class="alert alert-dark m-0" role="alert"> 85 <span>@Translate("Certificates: The certificates selectors will be shown here, if any")</span> 86 </div> 87 } 88 } 89 </div> 90 } 91
Error executing template "Designs/Swift/Paragraph/Swift_EA_DeliveryCost.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at Dynamicweb.Ecommerce.Products.ProductService.GetProductFieldValue(Product product, String productFieldSystemName)
   at Plus.CustomModules.Helpers.ShippingBasedOnProductSetting.GetShippingId(String eComCountryCode, Product productToShow)
   at CompiledRazorTemplates.Dynamic.RazorEngine_d0ac8bb8632b4788a25bcbe032c96511.Execute() in C:\inetpub\wwwroot\plus-prod\Files\Templates\Designs\Swift\Paragraph\Swift_EA_DeliveryCost.cshtml:line 71
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using System.Linq 3 @using Dynamicweb.Core 4 @using Dynamicweb.Ecommerce.ProductCatalog 5 @using Dynamicweb.Ecommerce.Products 6 @using Dynamicweb.Ecommerce; 7 @using Plus.CustomModules.Helpers 8 9 @{ 10 ProductViewModel product = new ProductViewModel(); 11 12 ProductViewModelSettings productSetting = new ProductViewModelSettings 13 { 14 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID, 15 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code, 16 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2, 17 ShopId = Pageview.Area.EcomShopId 18 }; 19 20 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 21 { 22 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 23 } else if (Pageview.Item["DummyProduct"] != null) { 24 25 string dummyProductId = ""; 26 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 27 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 28 if (productList.Products != null) 29 { 30 foreach (var p in productList.Products) { dummyProductId = p.Id; } 31 ProductViewModel dummyProduct = dummyProductId != "" ? ViewModelFactory.CreateView(productSetting, dummyProductId) : new ProductViewModel(); 32 product = dummyProduct; 33 } else { 34 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id); 35 } 36 } else if (Pageview.Item["DummyProduct"] == null) { 37 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id); 38 } 39 40 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 41 bool anonymousUser = Pageview.User == null; 42 bool isErpConnectionDown = !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); 43 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 44 45 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 46 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 47 48 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-2"); 49 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 50 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 51 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 52 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 53 54 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 55 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 56 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 57 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 58 59 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 60 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 61 string order = layout == "horizontal" ? string.Empty : "order-2"; 62 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? "theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 63 theme = GetViewParameter("theme") != null ? GetViewParameterString("theme") : theme; 64 } 65 66 @{ 67 string ecomCountryCode = !string.IsNullOrEmpty(Pageview.Area.EcomCountryCode) ? Pageview.Area.EcomCountryCode : ""; 68 var countryVat = Services.Countries.GetCountry(ecomCountryCode).Vat > 0 ? Services.Countries.GetCountry(ecomCountryCode).Vat : 0; 69 var productToShow = Services.Products.GetProductById(product.Id, product.VariantId, product.LanguageId); 70 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 71 string shipId = ecomCountryCode.IsNotNullOrEmpty() ? ShippingBasedOnProductSetting.GetShippingId(ecomCountryCode, productToShow) : ""; 72 73 if (!string.IsNullOrEmpty(ecomCountryCode) && !hidePrice && product.Id != null && shipId != null) 74 { 75 var shippingFeeAmount = ShippingBasedOnProductSetting.GetShippingAmount(shipId, countryVat, productToShow, currency); 76 77 if (shippingFeeAmount != null) 78 { 79 <div class="@textAlign item_@Model.Item.SystemName.ToLower()"> 80 <div class="@priceFontSize @flexDirection @flexGap @horizontalAlign @theme"> 81 <p>@Translate("Levering fra") @currency @shippingFeeAmount</p> 82 </div> 83 </div> 84 } 85 } 86 } 87
Error executing template "Designs/Swift/Paragraph/Swift_ProductAddToCart.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at Dynamicweb.Ecommerce.Products.ProductService.GetProductFieldValue(Product product, String productFieldSystemName)
   at Plus.CustomModules.Helpers.ShippingBasedOnProductSetting.GetShippingId(String eComCountryCode, Product productToShow)
   at CompiledRazorTemplates.Dynamic.RazorEngine_5b6ffb7e389c45a7b072e55cdd18f2b4.Execute() in C:\inetpub\wwwroot\plus-prod\Files\Templates\Designs\Swift\Paragraph\Swift_ProductAddToCart.cshtml:line 86
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using System.Linq 3 @using System.Runtime 4 @using Dynamicweb.Core 5 @using Dynamicweb.Ecommerce 6 @using Dynamicweb.Ecommerce.ProductCatalog 7 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 8 @using Plus.CustomModules.Helpers 9 10 @{ 11 ProductViewModel product = new ProductViewModel(); 12 13 ProductViewModelSettings productSetting = new ProductViewModelSettings 14 { 15 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID, 16 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code, 17 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2, 18 ShopId = Pageview.Area.EcomShopId 19 }; 20 21 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 22 { 23 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 24 } 25 else if (Pageview.Item["DummyProduct"] != null) 26 { 27 28 string dummyProductId = ""; 29 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 30 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 31 if (productList.Products != null) 32 { 33 foreach (var p in productList.Products) { dummyProductId = p.Id; } 34 ProductViewModel dummyProduct = dummyProductId != "" ? ViewModelFactory.CreateView(productSetting, dummyProductId) : new ProductViewModel(); 35 product = dummyProduct; 36 } 37 else 38 { 39 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id); 40 } 41 } 42 else if (Pageview.Item["DummyProduct"] == null) 43 { 44 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id); 45 } 46 47 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 48 horizontalAlign = horizontalAlign == "center" ? "justify-content-center" : horizontalAlign; 49 horizontalAlign = horizontalAlign == "end" ? "justify-content-end" : horizontalAlign; 50 horizontalAlign = horizontalAlign == "full" ? "" : horizontalAlign; 51 52 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 53 bool anonymousUser = Pageview.User == null; 54 bool isErpConnectionDown = !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); 55 bool hideAddToCart = anonymousUsersLimitations.Contains("cart") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHideAddToCart") && isErpConnectionDown; 56 hideAddToCart = Pageview.IsVisualEditorMode ? false : hideAddToCart; 57 bool favoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 58 bool showFavoritesSelectorMasterProduct = !string.IsNullOrEmpty(Model.Item.GetString("ShowFavoritesSelectorMasterProduct")) ? Model.Item.GetBoolean("ShowFavoritesSelectorMasterProduct") : false; 59 bool quantitySelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowQuantitySelector")) ? Model.Item.GetBoolean("ShowQuantitySelector") : false; 60 bool unitsSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowUnitsSelector")) ? Model.Item.GetBoolean("ShowUnitsSelector") : false; 61 bool hideInventory = !string.IsNullOrEmpty(Model.Item.GetString("HideInventory")) ? Model.Item.GetBoolean("HideInventory") : false; 62 bool hideStockState = !string.IsNullOrEmpty(Model.Item.GetString("HideStockState")) ? Model.Item.GetBoolean("HideStockState") : false; 63 64 string buttonSize = Model.Item.GetRawValueString("ButtonSize", "regular"); 65 string inputSize = string.Empty; 66 67 switch (buttonSize) 68 { 69 case "small": 70 inputSize = " input-group-sm"; 71 buttonSize = " btn-sm"; 72 break; 73 case "regular": 74 buttonSize = string.Empty; 75 break; 76 case "large": 77 inputSize = " input-group-lg"; 78 buttonSize = " btn-lg"; 79 break; 80 } 81 82 string ecomCountryCode = !string.IsNullOrEmpty(Pageview.Area.EcomCountryCode) ? Pageview.Area.EcomCountryCode : ""; 83 var countryVat = Services.Countries.GetCountry(ecomCountryCode).Vat > 0 ? Services.Countries.GetCountry(ecomCountryCode).Vat : 0; 84 var productToShow = Services.Products.GetProductById(product.Id, product.VariantId, product.LanguageId); 85 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 86 string shipId = ecomCountryCode.IsNotNullOrEmpty() ? ShippingBasedOnProductSetting.GetShippingId(ecomCountryCode, productToShow) : ""; 87 var shippingFeeAmount = string.Empty; 88 89 if (!string.IsNullOrEmpty(ecomCountryCode) && shipId != null) 90 { 91 shippingFeeAmount = ShippingBasedOnProductSetting.GetShippingAmount(shipId, countryVat, productToShow, currency); 92 } 93 94 var deliveryCost = Translate("Levering fra") + " " + currency + " " + shippingFeeAmount; 95 var deliveryName = ShippingBasedOnProductSetting.GetShippingName(shipId, product.LanguageId); 96 string iconPath = "/Files/icons/"; 97 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService")); 98 99 } 100 101 @if (!hideAddToCart && product.Id != null && product.StockLevel > 0 && !product.Discontinued) 102 { 103 if (!url.Contains("LayoutTemplate")) 104 { 105 url += url.Contains("?") ? "&LayoutTemplate=Swift_MiniCart.cshtml" : "?LayoutTemplate=Swift_MiniCart.cshtml"; 106 } 107 108 string disableAddToCart = (product.StockLevel <= 0) ? "disabled" : ""; 109 bool isNeverOutOfStock = product.NeverOutOfstock; 110 bool isDiscontinued = product.Discontinued; 111 disableAddToCart = isDiscontinued ? "disabled" : disableAddToCart; 112 disableAddToCart = isNeverOutOfStock ? "" : disableAddToCart; 113 114 string whenVariantsExist = Model.Item.GetRawValueString("WhenVariantsExist", "hide"); 115 116 string flexFill = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "flex-fill" : ""; 117 string fullWidth = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "w-100" : ""; 118 string addToCartIcon = Model.Item.GetRawValueString("Icon", iconPath + "shopping-cart.svg"); 119 string addToCartLabel = !addToCartIcon.Contains("_none") ? "<span class=\"icon-2\">" + ReadFile(addToCartIcon) + "</span>" : ""; 120 addToCartLabel += !addToCartIcon.Contains("_none") && !Model.Item.GetBoolean("HideButtonText") ? " " : ""; 121 addToCartLabel += !Model.Item.GetBoolean("HideButtonText") ? Translate("Add to cart") : ""; 122 123 if (product.VariantInfo.VariantInfo == null || whenVariantsExist == "disable") 124 { 125 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : product.DefaultUnitId; 126 if (string.IsNullOrEmpty(unitId) && product?.UnitOptions != null) 127 { 128 if (product.UnitOptions.FirstOrDefault<UnitOptionViewModel>() != null) 129 { 130 unitId = product.UnitOptions.FirstOrDefault<UnitOptionViewModel>().Id; 131 } 132 } 133 134 string minQty = product.PurchaseMinimumQuantity != 1 ? "min=\"" + product.PurchaseMinimumQuantity.ToString() + "\"" : "min=\"1\""; 135 string stepQty = product.PurchaseQuantityStep > 1 ? product.PurchaseQuantityStep.ToString() : "1"; 136 string valueQty = product.PurchaseMinimumQuantity > product.PurchaseQuantityStep ? product.PurchaseMinimumQuantity.ToString() : stepQty; 137 string qtyValidCheck = stepQty != "1" ? "onkeyup=\"swift.Cart.QuantityValidate(event)\"" : ""; 138 disableAddToCart = product.VariantInfo.VariantInfo != null && string.IsNullOrEmpty(product.VariantId) ? "disabled" : disableAddToCart; 139 string imagePathHidden = product?.DefaultImage.Value.ToString() ?? ""; 140 imagePathHidden = "/Admin/Public/GetImage.ashx?image=" + imagePathHidden + "&width=" + 350 + "&Format=WebP&Quality=70"; 141 142 if (unitsSelector && product.UnitOptions.Count > 0) 143 { 144 <form method="post" action="/Default.aspx?ID=@(Pageview.Page.ID)&ProductId=@product.Id" id="UnitSelectorForm_@(product.Id)_@(product.VariantId)_@Model.ID"> 145 <input type="hidden" name="redirect" value="false"> 146 <input type="hidden" name="VariantID" value="@product.VariantId"> 147 <input type="hidden" name="UnitID" class="js-unit-id" value="@unitId"> 148 </form> 149 } 150 151 <div class="d-flex @horizontalAlign @fullWidth item_@Model.Item.SystemName.ToLower()"> 152 <form method="post" action="@url" class="@fullWidth" style="z-index: 1"> 153 <input type="hidden" name="redirect" value="false"> 154 <input type="hidden" name="ProductId" value="@product.Id"> 155 <input type="hidden" name="ProductName" value="@product.Name"> 156 <input type="hidden" name="ProductVariantName" value="@product.VariantName"> 157 <input type="hidden" name="ProductCurrency" value="@Dynamicweb.Ecommerce.Common.Context.Currency.Code"> 158 <input type="hidden" name="ProductPrice" value="@product.Price.Price"> 159 <input type="hidden" name="ProductReferer" value="component_ProductAddToCart"> 160 @* #38 EA: sbj *@ 161 <input type="hidden" name="ProductPriceFormatted" value="@product.Price.PriceFormatted"> 162 <input type="hidden" name="ProductUnit" value="@Translate("stk.", "stk.")"> 163 <input type="hidden" name="ProductTotalText" value="@Translate("I alt", "I alt")"> 164 <input type="hidden" name="ProductDeliveryCost" value="@deliveryCost"> 165 <input type="hidden" name="ProductDeliveryName" value="@deliveryName"> 166 <input type="hidden" name="ProductImage" value="@imagePathHidden"> 167 <input type="hidden" name="cartcmd" value="add"> 168 @{ 169 string cartUrl = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("EasyFlowCart")); 170 double totalAddedPrice = 0; 171 } 172 <input type="hidden" name="cartpage" value="@cartUrl"> 173 @* #38 EA: end *@ 174 175 @if (!string.IsNullOrEmpty(product.VariantId)) 176 { 177 <input type="hidden" name="VariantId" value="@product.VariantId"> 178 } 179 180 @if (quantitySelector || (!anonymousUser && showFavoritesSelectorMasterProduct && product.VariantInfo.VariantInfo != null) || (!anonymousUser && favoritesSelector)) 181 { 182 <div class="d-flex flex-row w-100"> 183 @if (!anonymousUser) 184 { 185 if (favoritesSelector && product.VariantInfo.VariantInfo == null) 186 { 187 @RenderPartial("Components/ToggleFavorite.cshtml", product) 188 } 189 else if (showFavoritesSelectorMasterProduct) 190 { 191 @RenderPartial("Components/ToggleFavorite.cshtml", product) 192 } 193 } 194 195 <div class="input-group input-primary-button-group flex-nowrap@(inputSize)"> 196 <div class="me-3 d-flex flex-nowrap bg-light efa-mod"> 197 <div class="btn border-0" id="minus-btn" onclick="quantityBtn('Quantity_@(product.Id)_@product.VariantId', 'minus')"> 198 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-dash-lg" viewBox="0 0 16 16"> 199 <path fill-rule="evenodd" d="M2 8a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11A.5.5 0 0 1 2 8Z" /> 200 </svg> 201 </div> 202 <div class="d-flex align-items-center"> 203 <input id="Quantity_@(product.Id)_@product.VariantId" name="Quantity" value="@valueQty" step="@stepQty" @minQty class="form-control p-0 bg-light border-0 fc-green quantity_selector efa-mod" type="number" style="max-width: 50px;" onkeydown="swift.Cart.UpdateOnEnterKey(event)" @disableAddToCart> 204 </div> 205 <div class="btn border-0" id="plus-btn" onclick="quantityBtn('Quantity_@(product.Id)_@product.VariantId', 'plus')"> 206 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plus-lg" viewBox="0 0 16 16"> 207 <path fill-rule="evenodd" d="M8 2a.5.5 0 0 1 .5.5v5h5a.5.5 0 0 1 0 1h-5v5a.5.5 0 0 1-1 0v-5h-5a.5.5 0 0 1 0-1h5v-5A.5.5 0 0 1 8 2Z" /> 208 </svg> 209 </div> 210 <script type="text/javascript"> 211 function quantityBtn(id, symbol) { 212 var value = parseInt(document.getElementById(id).value, 10); 213 var step = parseInt(document.getElementById(id).step, 10); 214 value = isNaN(value) ? 0 : value; 215 switch (symbol) { 216 case "minus": 217 value = value - step; 218 break; 219 case "plus": 220 value = value + step; 221 break; 222 } 223 document.getElementById(id).value = value; 224 UpdateQuantity(); 225 } 226 </script> 227 </div> 228 229 @if (unitsSelector && product.UnitOptions.Count > 0) 230 { 231 string selectedUnitName = !string.IsNullOrEmpty(unitId) && product?.UnitOptions != null ? unitId : product.UnitOptions.FirstOrDefault<UnitOptionViewModel>().Name; 232 233 foreach (var unitOption in product.UnitOptions) 234 { 235 if (unitOption.Id == unitId) 236 { 237 selectedUnitName = unitOption.Name; 238 } 239 } 240 241 <input type="hidden" id="Unit_@(product.Id)_@product.VariantId" name="UnitID" value="@unitId" /> 242 <div class="dropdown"> 243 <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> 244 @selectedUnitName 245 </button> 246 <ul class="dropdown-menu"> 247 @foreach (var unitOption in product.UnitOptions) 248 { 249 var selectedUnit = unitOption.Id == unitId ? "selected" : ""; 250 251 <li> 252 <button type="button" class="btn dropdown-item" data-value="@unitOption.Id" onclick="document.querySelector('#UnitSelectorForm_@(product.Id)_@(product.VariantId)_@Model.ID').querySelector('.js-unit-id').value = this.getAttribute('data-value'); 253 document.querySelector('#Unit_@(product.Id)_@product.VariantId').value = this.getAttribute('data-value'); 254 swift.PageUpdater.Update(document.querySelector('#UnitSelectorForm_@(product.Id)_@(product.VariantId)_@Model.ID'))"> 255 <span>@unitOption.Name</span> 256 <span> 257 @if (unitOption.StockLevel > 0) 258 { 259 if (!Model.Item.GetBoolean("HideInventory")) 260 { 261 <span class="text-success">@unitOption.StockLevel @Translate("In stock")</span> 262 } 263 else 264 { 265 <span class="text-success">@Translate("In stock")</span> 266 } 267 } 268 else 269 { 270 <span class="text-danger">@Translate("Out of Stock")</span> 271 } 272 </span> 273 </button> 274 </li> 275 } 276 </ul> 277 </div> 278 } 279 280 <button type="button" onclick="swift.Cart.Update(event)" data-container="product" class="btn btn-primary @(buttonSize) @flexFill js-add-to-cart-button addToCart" style="white-space: nowrap" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)_@Pageview.CurrentParagraph.ID"> 281 @if (!Model.Item.GetBoolean("HideButtonText")) 282 { 283 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 284 @addToCartLabel 285 </span> 286 } 287 else 288 { 289 @addToCartLabel 290 } 291 </button> 292 293 </div> 294 @if (stepQty != "1") 295 { 296 <div class="invalid-feedback d-none"> 297 @Translate("Please select a quantity that is dividable by") @stepQty 298 </div> 299 } 300 </div> 301 } 302 else 303 { 304 <div class="d-flex flex-row w-100" style="z-index: 1;"> 305 @if (!anonymousUser) 306 { 307 if (favoritesSelector && product.VariantInfo.VariantInfo == null) 308 { 309 @RenderPartial("Components/ToggleFavorite.cshtml", product) 310 } 311 else if (showFavoritesSelectorMasterProduct) 312 { 313 @RenderPartial("Components/ToggleFavorite.cshtml", product) 314 } 315 } 316 <input id="Quantity_@(product.Id)_@product.VariantId" name="Quantity" value="@valueQty" type="hidden" @disableAddToCart> 317 318 @if (unitsSelector && product.UnitOptions.Count > 0) 319 { 320 string selectedUnitName = !string.IsNullOrEmpty(unitId) && product?.UnitOptions != null ? unitId : product.UnitOptions.FirstOrDefault<UnitOptionViewModel>().Name; 321 322 foreach (var unitOption in product.UnitOptions) 323 { 324 if (unitOption.Id == unitId) 325 { 326 selectedUnitName = unitOption.Name; 327 } 328 } 329 330 <input type="hidden" id="Unit_@(product.Id)_@product.VariantId" name="UnitID" value="@unitId" /> 331 <div class="dropdown"> 332 <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> 333 @selectedUnitName 334 </button> 335 <ul class="dropdown-menu"> 336 @foreach (var unitOption in product.UnitOptions) 337 { 338 var selectedUnit = unitOption.Id == unitId ? "selected" : ""; 339 340 <li> 341 <button type="button" class="btn dropdown-item" data-value="@unitOption.Id" onclick="document.querySelector('#UnitSelectorForm_@(product.Id)_@(product.VariantId)_@Model.ID').querySelector('.js-unit-id').value = this.getAttribute('data-value'); 342 document.querySelector('#Unit_@(product.Id)_@product.VariantId').value = this.getAttribute('data-value'); 343 swift.PageUpdater.Update(document.querySelector('#UnitSelectorForm_@(product.Id)_@(product.VariantId)_@Model.ID'))"> 344 <span>@unitOption.Name</span> 345 <span> 346 @if (unitOption.StockLevel > 0) 347 { 348 if (!Model.Item.GetBoolean("HideInventory")) 349 { 350 <span class="small text-success">@unitOption.StockLevel @Translate("In stock")</span> 351 } 352 else 353 { 354 <span class="small text-success">@Translate("In stock")</span> 355 } 356 } 357 else 358 { 359 <span class="small text-danger">@Translate("Out of Stock")</span> 360 } 361 </span> 362 </button> 363 </li> 364 } 365 </ul> 366 </div> 367 } 368 369 <button type="button" onclick="swift.Cart.Update(event)" data-container="product" class="btn btn-primary@(buttonSize) @flexFill js-add-to-cart-button addToCart" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)_@Pageview.CurrentParagraph.ID"> 370 @if (!Model.Item.GetBoolean("HideButtonText")) 371 { 372 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 373 @addToCartLabel 374 </span> 375 } 376 else 377 { 378 @addToCartLabel 379 } 380 </button> 381 </div> 382 } 383 </form> 384 </div> 385 } 386 else if (whenVariantsExist == "modal") 387 { 388 string buttonText = Translate("Select"); 389 390 string variantSelectorServicePageId = !string.IsNullOrEmpty(Model.Item.GetString("VariantSelectorServicePageId")) ? Model.Item.GetLink("VariantSelectorServicePageId").PageId.ToString() : ""; 391 variantSelectorServicePageId = variantSelectorServicePageId != "" ? variantSelectorServicePageId : GetPageIdByNavigationTag("VariantSelectorService").ToString(); 392 393 <div class="d-flex @horizontalAlign w-100 item_@Model.Item.SystemName.ToLower()"> 394 @if (!anonymousUser && showFavoritesSelectorMasterProduct) 395 { 396 @RenderPartial("Components/ToggleFavorite.cshtml", product) 397 } 398 <form action="/Default.aspx?ID=@variantSelectorServicePageId" data-response-target-element="DynamicModalContent" data-preloader="inline" style="z-index: 1" class="@fullWidth"> 399 <input type="hidden" name="ProductID" value="@product.Id"> 400 <input type="hidden" name="QuantitySelector" value="@quantitySelector.ToString()"> 401 <input type="hidden" name="HideInventory" value="@hideInventory.ToString()"> 402 <input type="hidden" name="HideStockState" value="@hideStockState.ToString()"> 403 <input type="hidden" name="VariantSelectorServicePage" value="@variantSelectorServicePageId"> 404 <input type="hidden" name="ViewType" value="ModalContent"> 405 <button type="button" onclick="swift.PageUpdater.Update(event)" class="btn btn-primary@(buttonSize) @fullWidth" title="@Translate("Select")" data-bs-toggle="modal" data-bs-target="#DynamicModal" id="OpenVariantSelectorModal@(product.Id)_@Pageview.CurrentParagraph.ID">@buttonText</button> 406 </form> 407 </div> 408 } 409 } 410 else if (Pageview.IsVisualEditorMode) 411 { 412 <div class="alert alert-dark m-0">@Translate("No products available")</div> 413 } 414 @* #38 EA: sbj *@ 415 <div id="p_cartNotificationModalProduct" class="modal" tabindex="-1" aria-labelledby="p_cartNotificationModalProductTitel" aria-hidden="true"> 416 @{ 417 string modelId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ModelID")) ? Dynamicweb.Context.Current.Request.Form.Get("ModelID") : product.Id; 418 419 string scrollBarForceMobile = Dynamicweb.Context.Current.Request.Form.Get("NavigationShowScrollbar") != string.Empty ? "--swiffy-slider-track-height:0.5rem !important;" : string.Empty; 420 bool hideSliderNavigation = false; 421 422 int itemsShown = 3; 423 424 string imageTheme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ImageTheme")) ? Dynamicweb.Context.Current.Request.Form.Get("ImageTheme") : ""; 425 string imageOutlineStyle = imageTheme == string.Empty ? "border: 1px solid transparent;" : string.Empty; 426 string imageThemePadding = imageTheme != string.Empty ? "p-3" : string.Empty; 427 428 string imagePath = product?.DefaultImage.Value.ToString() ?? ""; 429 imagePath = "/Admin/Public/GetImage.ashx?image=" + imagePath + "&width=" + 350 + "&Format=WebP&Quality=70"; 430 431 string ratio = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ImageAspectRatio")) ? Dynamicweb.Context.Current.Request.Form.Get("ImageAspectRatio") : ""; 432 string ratioCssClass = ratio != "" ? "ratio" : ""; 433 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio : ""; 434 435 string saleBadgeType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType") : ""; 436 string saleBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName") : ""; 437 string newBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName") : ""; 438 int newPublicationDays = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) ? Convert.ToInt32(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) : 0; 439 string campaignBadgesValues = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues")) ? Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues") : ""; 440 441 var badgeParms = new Dictionary<string, object>(); 442 badgeParms.Add("saleBadgeType", saleBadgeType); 443 badgeParms.Add("saleBadgeCssClassName", saleBadgeCssClassName); 444 badgeParms.Add("newBadgeCssClassName", newBadgeCssClassName); 445 badgeParms.Add("campaignBadgesValues", campaignBadgesValues); 446 badgeParms.Add("newPublicationDays", newPublicationDays); 447 448 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(saleBadgeCssClassName) && saleBadgeCssClassName != "none" ? true : false; 449 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(newBadgeCssClassName) && newBadgeCssClassName != "none" ? true : false; 450 DateTime createdDate = product.Created.Value; 451 452 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 453 showBadges = (newBadgeEnabled && newPublicationDays == 0) || (newBadgeEnabled && (createdDate.AddDays(newPublicationDays) > DateTime.Now)) ? true : showBadges; 454 showBadges = !string.IsNullOrEmpty(campaignBadgesValues) ? true : showBadges; 455 456 var shopPageId = GetPageIdByNavigationTag("Shop"); 457 458 //string url = !string.IsNullOrEmpty(orderId) ? $"/Default.aspx?OrderID={orderId}" : "/Default.aspx"; 459 460 Dynamicweb.Frontend.LinkViewModel checkoutAnonymousPageId = Model.Item.GetLink("CheckoutAnonymousPageLink"); 461 string checkoutAnonymousPageUrl = checkoutAnonymousPageId?.Url; 462 Dynamicweb.Frontend.LinkViewModel checkoutUserPageId = Model.Item.GetLink("CheckoutUserPageLink"); 463 string checkoutUserPageUrl = checkoutUserPageId?.Url; 464 string checkoutUrl = Pageview.User == null ? checkoutAnonymousPageUrl : checkoutUserPageUrl; 465 int quoteCheckoutPageLink = Model.Item?.GetLink("QuoteCheckoutPageLink") != null ? Model.Item.GetLink("QuoteCheckoutPageLink").PageId : 0; 466 467 string orderId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("OrderID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("OrderID") : ""; 468 string OrderUrl = !string.IsNullOrEmpty(orderId) ? $"/Default.aspx?OrderID={orderId}" : "/Default.aspx"; 469 var productCounter = 1; 470 471 bool relatedExist = false; 472 foreach (var relatedGroup in product.RelatedGroups) 473 { 474 if (relatedGroup.Id == "Addon") 475 { 476 if (relatedGroup.Products.Count > 0) 477 { 478 relatedExist = true; 479 } 480 } 481 } 482 483 } 484 @*<script type="module" src="/Files/Templates/Designs/Swift/Assets/js/swiffy-slider.js"></script> 485 <script type="module"> 486 swift.AssetLoader.Load('/Files/Templates/Designs/Swift/Assets/css/swiffy-slider.min.css', 'css'); 487 </script>*@ 488 <div class="modal-dialog theme plus-primary modal-xl"> 489 <div class="modal-content rounded-0 container"> 490 <div class="row"> 491 <div class="col-12 col-xl-7 p-0 border-bottom border-lg-none"> 492 <div class="modal-header w-100 text-center"> 493 <h3 class="modal-title w-100" id="p_cartNotificationModalProductTitel">@Translate("Følgende er tilføjet til indkøbslisten", "Følgende er tilføjet til indkøbslisten")</h3> 494 <button type="button" class="btn-close position-absolute m-0 end-0 me-3 d-block d-xl-none" data-bs-dismiss="modal" aria-label="Close"></button> 495 </div> 496 <div id="p_cartNotificationModalBody" class="modal-body"> 497 <div class="container-fluid"> 498 <div class="row"> 499 <div class="@(imageTheme) col-12" style="@imageOutlineStyle"> 500 <div class="@(ratioCssClass) col-4 col-xl-6 m-auto position-relative" style="@ratioVariable"> 501 @if (showBadges) 502 { 503 <div class="position-absolute top-0 left-0 p-1 p-lg-2" style="z-index: 2"> 504 @{ 505 @RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms) 506 } 507 </div> 508 } 509 <img loading="lazy" decoding="async" src="@imagePath" class="h-100 w-100 @(imageThemePadding)" style="object-fit: contain;" alt="@product.Name" id="p_cartNotificationModalProduct_Image"> 510 </div> 511 </div> 512 <div class="d-flex flex-wrap py-3 col-12 gap-md-3"> 513 <div class="col-12 col-md-auto info"> 514 <div class="fc-dark efa-mod"><strong id="p_cartNotificationModalProduct_Name"></strong></div> 515 <div class="fs-5 fw-bold fc-dark efa-mod" id="p_cartNotificationModalProduct_Price"></div> 516 <div class="fs-8 fc-grey efa-mod" id="p_cartNotificationModalProduct_DeliveryCost"></div> 517 <div class="fs-8 fc-grey efa-mod" id="p_cartNotificationModalProduct_DeliveryName"></div> 518 <div id="p_cartNotificationModalProduct_Quantity"></div> 519 </div> 520 <div class="col-12 col-lg action align-self-end"> 521 <div class="col-12 d-flex mt-3"> 522 <a id="p_cartNotificationModalProduct_Button" class="btn btn-primary flex-fill" href="">@Translate("Gå til indkøbslisten", "Gå til indkøbslisten")</a> 523 </div> 524 </div> 525 </div> 526 </div> 527 </div> 528 </div> 529 </div> 530 <div class="col-12 col-xl-5 p-0"> 531 <div class="modal-header w-100 text-center"> 532 <h3 class="modal-title text-center w-100">@Translate("Add-on products", "Tilbehør")</h3> 533 <button type="button" class="btn-close position-absolute m-0 end-0 me-3 d-none d-xl-block" data-bs-dismiss="modal" aria-label="Close"></button> 534 </div> 535 @if (relatedExist) 536 { 537 <div class="modal-body"> 538 <div id="addonsList" class="list grid gap-3 overflow-auto"> 539 @{ 540 foreach (RelatedGroupViewModel relatedGroup in product.RelatedGroups.Where(x => x.Id == "Addon")) 541 { 542 foreach (ProductInfoViewModel relatedProduct in relatedGroup.Products) 543 { 544 <div class="elements g-col-6 g-col-xl-12 align-self-end"> 545 @RenderAddons(relatedProduct, productCounter) 546 </div> 547 productCounter += 1; 548 } 549 } 550 } 551 552 </div> 553 </div> 554 } 555 </div> 556 </div> 557 </div> 558 </div> 559 </div> 560 561 @helper RenderProduct(ProductInfoViewModel relatedProduct) 562 { 563 var relProduct = relatedProduct.GetProduct(); 564 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 565 bool anonymousUser = Pageview.User == null; 566 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); 567 bool showFavoritesSelectorMasterProduct = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ShowFavoritesSelectorMasterProduct")) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form.Get("ShowFavoritesSelectorMasterProduct")) : false; 568 569 string ratio = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ImageAspectRatio")) ? Dynamicweb.Context.Current.Request.Form.Get("ImageAspectRatio") : ""; 570 string ratioCssClass = ratio != "" ? "ratio" : ""; 571 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio : ""; 572 573 string theme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("Theme")) ? Dynamicweb.Context.Current.Request.Form.Get("Theme") : ""; 574 string themePadding = theme != string.Empty ? "p-3" : string.Empty; 575 string imageTheme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ImageTheme")) ? Dynamicweb.Context.Current.Request.Form.Get("ImageTheme") : ""; 576 string imageOutlineStyle = imageTheme == string.Empty ? "border: 1px solid transparent;" : string.Empty; 577 string imageThemePadding = imageTheme != string.Empty ? "p-3" : string.Empty; 578 string ContentPadding = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ContentPadding")) ? Dynamicweb.Context.Current.Request.Form.Get("ContentPadding") : ""; 579 580 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 581 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 582 583 string variantIdForLink = !string.IsNullOrEmpty(relProduct.VariantId) ? $"&VariantID={relProduct.VariantId}" : ""; 584 variantIdForLink = string.IsNullOrEmpty(variantIdForLink) && !string.IsNullOrEmpty(relProduct.DefaultVariantId) ? $"&VariantID={relProduct.DefaultVariantId}" : variantIdForLink; 585 586 string link = "Default.aspx?ID=" + GetPageIdByNavigationTag("Shop"); 587 link += $"&GroupID={relProduct.PrimaryOrDefaultGroup.Id}"; 588 link += $"&ProductID={relProduct.Id}"; 589 link += variantIdForLink; 590 link = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(link); 591 592 string imagePath = relProduct?.DefaultImage.Value.ToString() ?? ""; 593 imagePath = "/Admin/Public/GetImage.ashx?image=" + imagePath + "&width=" + 350 + "&Format=WebP&Quality=70"; 594 595 string saleBadgeType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType") : ""; 596 string saleBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName") : ""; 597 string newBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName") : ""; 598 int newPublicationDays = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) ? Convert.ToInt32(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) : 0; 599 string campaignBadgesValues = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues")) ? Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues") : ""; 600 601 var badgeParms = new Dictionary<string, object>(); 602 badgeParms.Add("saleBadgeType", saleBadgeType); 603 badgeParms.Add("saleBadgeCssClassName", saleBadgeCssClassName); 604 badgeParms.Add("newBadgeCssClassName", newBadgeCssClassName); 605 badgeParms.Add("campaignBadgesValues", campaignBadgesValues); 606 badgeParms.Add("newPublicationDays", newPublicationDays); 607 608 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(saleBadgeCssClassName) && saleBadgeCssClassName != "none" ? true : false; 609 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(newBadgeCssClassName) && newBadgeCssClassName != "none" ? true : false; 610 DateTime createdDate = relProduct.Created.Value; 611 bool showBadges = saleBadgeEnabled && relProduct.Discount.Price != 0 ? true : false; 612 showBadges = (newBadgeEnabled && newPublicationDays == 0) || (newBadgeEnabled && (createdDate.AddDays(newPublicationDays) > DateTime.Now)) ? true : showBadges; 613 showBadges = !string.IsNullOrEmpty(campaignBadgesValues) ? true : showBadges; 614 615 string disableAddToCart = (relProduct.StockLevel <= 0) ? "disabled" : ""; 616 bool isNeverOutOfStock = relProduct.NeverOutOfstock; 617 disableAddToCart = isNeverOutOfStock ? "" : disableAddToCart; 618 619 string iconPath = "/Files/icons/"; 620 string addToCartIcon = Model.Item.GetRawValueString("Icon", iconPath + "shopping-cart.svg"); 621 string addToCartLabel = !addToCartIcon.Contains("_none") ? "<span class=\"icon-2\">" + ReadFile(addToCartIcon) + "</span>" : ""; 622 addToCartLabel += !addToCartIcon.Contains("_none") && !Model.Item.GetBoolean("HideButtonText") ? " " : ""; 623 addToCartLabel += !Model.Item.GetBoolean("HideButtonText") ? Translate("Add to cart") : ""; 624 string flexFill = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "flex-fill" : ""; 625 string buttonSize = Model.Item.GetRawValueString("ButtonSize", "regular"); 626 string inputSize = string.Empty; 627 628 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("EasyFlowCart")); 629 if (!url.Contains("LayoutTemplate")) 630 { 631 url += url.Contains("?") ? "&LayoutTemplate=Swift_MiniCart.cshtml" : "?LayoutTemplate=Swift_MiniCart.cshtml"; 632 } 633 string cartUrl = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("EasyFlowCart")); 634 string imagePathHidden = relProduct?.DefaultImage.Value.ToString() ?? ""; 635 imagePathHidden = "/Admin/Public/GetImage.ashx?image=" + imagePathHidden + "&width=" + 350 + "&Format=WebP&Quality=70"; 636 637 switch (buttonSize) 638 { 639 case "small": 640 inputSize = " input-group-sm"; 641 buttonSize = " btn-sm"; 642 break; 643 case "regular": 644 buttonSize = string.Empty; 645 break; 646 case "large": 647 inputSize = " input-group-lg"; 648 buttonSize = " btn-lg"; 649 break; 650 } 651 652 string ecomCountryCode = !string.IsNullOrEmpty(Pageview.Area.EcomCountryCode) ? Pageview.Area.EcomCountryCode : ""; 653 var countryVat = Services.Countries.GetCountry(ecomCountryCode).Vat > 0 ? Services.Countries.GetCountry(ecomCountryCode).Vat : 0; 654 var productToShow = Services.Products.GetProductById(relProduct.Id, relProduct.VariantId, relProduct.LanguageId); 655 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 656 string shipId = ecomCountryCode.IsNotNullOrEmpty() ? ShippingBasedOnProductSetting.GetShippingId(ecomCountryCode, productToShow) : ""; 657 var shippingFeeAmount = string.Empty; 658 659 if (!string.IsNullOrEmpty(ecomCountryCode) && shipId != null) 660 { 661 shippingFeeAmount = ShippingBasedOnProductSetting.GetShippingAmount(shipId, countryVat, productToShow, currency); 662 } 663 664 var deliveryCost = Translate("Levering fra") + " " + currency + " " + shippingFeeAmount; 665 var deliveryName = ShippingBasedOnProductSetting.GetShippingName(shipId, relProduct.LanguageId); 666 667 668 <div class="text-decoration-none d-block h-100"> 669 <div class="h-100 d-flex flex-column justify-content-between@(theme)"> 670 @{ 671 FieldValueViewModel plusDesignerModalIndikator; 672 relProduct.ProductFields.TryGetValue("PlusDesignerLinkEA", out plusDesignerModalIndikator); 673 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") ? "target=\"_blank\"" : string.Empty; 674 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") ? "rel=\"noopener\"" : string.Empty; 675 676 if (!string.IsNullOrEmpty(plusDesignerModalIndikator.Value.ToString())) 677 { 678 <div class="plus-designer__container" style="position: absolute; left: 0; bottom: 10px; background: #fff; border: 1px solid #228B64; border-left: none; z-index: 100; width: 75%; max-width: 200px; "> 679 <object> 680 <a href="@plusDesignerModalIndikator.Value" @target @rel class="text-decoration-none"> 681 <div class="plus-designer__inner p-1 ps-3"> 682 <p class="m-0 opacity-75 fs-7">Try me in</p> 683 <div class="plus-designer__image-container d-flex w-100"> 684 <img class="" src="/Files/Templates/Designs/Swift/Assets/Images/plusdesignerlogo.svg" alt="Alternate Text" style="width:90%" /> 685 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right" style="width:10%"><polyline points="9 18 15 12 9 6"></polyline></svg> 686 </div> 687 </div> 688 </a> 689 </object> 690 </div> 691 692 } 693 694 } 695 <div class="@(imageTheme)" style="@imageOutlineStyle"> 696 <div class="@(ratioCssClass) position-relative m-auto mw200 efa-mod" style="@ratioVariable"> 697 @if (showBadges) 698 { 699 <div class="position-absolute top-0 left-0 p-1 p-lg-2" style="z-index: 2"> 700 @{ 701 @RenderPartial("Components/EcommerceBadge.cshtml", relProduct, badgeParms) 702 } 703 </div> 704 } 705 <img loading="lazy" decoding="async" src="@imagePath" class="h-100 w-100 @(imageThemePadding)" style="object-fit: contain;" alt="@relProduct.Name"> 706 </div> 707 </div> 708 <div class="flex-fill p-3 pb-0 d-flex flex-column justify-content-between @themePadding"> 709 <h3 class="h6 opacity-85">@relProduct.Name @relProduct.VariantName</h3> 710 711 @if (!hidePrice) 712 { 713 <div> 714 <p class="h6 m-0"> 715 @if (showPricesWithVat == "false" && !neverShowVat) 716 { 717 if (relProduct.Price.Price != relProduct.PriceBeforeDiscount.Price) 718 { 719 <span class="text-decoration-line-through opacity-75 me-1"> 720 @relProduct.PriceBeforeDiscount.PriceWithoutVatFormatted 721 </span> 722 } 723 } 724 else 725 { 726 if (relProduct.Price.Price != relProduct.PriceBeforeDiscount.Price) 727 { 728 <span class="text-decoration-line-through opacity-75 me-1"> 729 @relProduct.PriceBeforeDiscount.PriceFormatted 730 </span> 731 } 732 } 733 734 @if (showPricesWithVat == "false" && !neverShowVat) 735 { 736 <span class="text-price fw-bold">@relProduct.Price.PriceWithoutVatFormatted</span> 737 } 738 else 739 { 740 <span class="text-price fw-bold">@relProduct.Price.PriceFormatted</span> 741 } 742 </p> 743 744 <div class="fs-8 text-black-50 text-start"> 745 <p>@Translate("Levering fra") @currency @shippingFeeAmount</p> 746 </div> 747 @if (showPricesWithVat == "false" && !neverShowVat) 748 { 749 <small class="opacity-85 fst-normal">@relProduct.Price.PriceWithVatFormatted @Translate("Incl. VAT")</small> 750 } 751 752 </div> 753 } 754 </div> 755 <div class="d-flex gap-4 p-3 pt-0"> 756 @{ 757 string stepQty = relProduct.PurchaseQuantityStep > 1 ? relProduct.PurchaseQuantityStep.ToString() : "1"; 758 string valueQty = relProduct.PurchaseMinimumQuantity > relProduct.PurchaseQuantityStep ? relProduct.PurchaseMinimumQuantity.ToString() : stepQty; 759 } 760 <form method="post" action="@url"> 761 <input type="hidden" name="redirect" value="false"> 762 <input type="hidden" name="ProductId" value="@relProduct.Id"> 763 <input type="hidden" name="ProductName" value="@relProduct.Name"> 764 <input type="hidden" name="ProductCurrency" value="@Dynamicweb.Ecommerce.Common.Context.Currency.Code"> 765 <input type="hidden" name="ProductReferer" value="product_list_listview"> 766 <input type="hidden" name="ProductPrice" value="@relProduct.Price.PriceFormatted"> 767 <input type="hidden" name="cartcmd" value="add"> 768 @* #38 EA: sbj *@ 769 <input type="hidden" name="ProductPriceFormatted" value="@relProduct.Price.PriceFormatted"> 770 <input type="hidden" name="ProductUnit" value="@Translate("stk.", "stk.")"> 771 <input type="hidden" name="ProductTotalText" value="@Translate("I alt", "I alt")"> 772 <input type="hidden" name="ProductDeliveryCost" value="@deliveryCost"> 773 <input type="hidden" name="ProductDeliveryName" value="@deliveryName"> 774 <input type="hidden" name="ProductImage" value="@imagePathHidden"> 775 <input type="hidden" name="cartpage" value="@cartUrl"> 776 <input id="Quantity_@(relProduct.Id)_@relProduct.VariantId" name="Quantity" value="@valueQty" type="hidden" @disableAddToCart> 777 <div class="d-flex gap-3 p-3 pt-0"> 778 <a href="@link" class="btn btn-secondary flex-fill">@Translate("View more")</a> 779 <a onclick="swift.Cart.Update(event)" data-container="productRel" class="btn btn-primary @(buttonSize) @flexFill flex-fill js-add-to-cart-button addToCart" style="white-space: nowrap" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(relProduct.Id)_@Pageview.CurrentParagraph.ID" data-bs-dismiss="modal"> 780 @if (!Model.Item.GetBoolean("HideButtonText")) 781 { 782 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 783 @addToCartLabel 784 </span> 785 } 786 else 787 { 788 @addToCartLabel 789 } 790 </a> 791 </div> 792 </form> 793 </div> 794 795 </div> 796 797 </div> 798 799 } 800 801 @helper RenderAddons(ProductInfoViewModel relatedProduct, int productCounter) { 802 var relProduct = relatedProduct.GetProduct(); 803 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 804 bool anonymousUser = Pageview.User == null; 805 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); 806 bool showFavoritesSelectorMasterProduct = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ShowFavoritesSelectorMasterProduct")) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form.Get("ShowFavoritesSelectorMasterProduct")) : false; 807 808 string ratio = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ImageAspectRatio")) ? Dynamicweb.Context.Current.Request.Form.Get("ImageAspectRatio") : ""; 809 string ratioCssClass = ratio != "" ? "ratio" : ""; 810 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio : ""; 811 812 string theme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("Theme")) ? Dynamicweb.Context.Current.Request.Form.Get("Theme") : ""; 813 string themePadding = theme != string.Empty ? "p-3" : string.Empty; 814 string imageTheme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ImageTheme")) ? Dynamicweb.Context.Current.Request.Form.Get("ImageTheme") : ""; 815 string imageOutlineStyle = imageTheme == string.Empty ? "border: 1px solid transparent;" : string.Empty; 816 string imageThemePadding = imageTheme != string.Empty ? "p-3" : string.Empty; 817 string ContentPadding = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ContentPadding")) ? Dynamicweb.Context.Current.Request.Form.Get("ContentPadding") : ""; 818 819 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 820 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 821 822 string variantIdForLink = !string.IsNullOrEmpty(relProduct.VariantId) ? $"&VariantID={relProduct.VariantId}" : ""; 823 variantIdForLink = string.IsNullOrEmpty(variantIdForLink) && !string.IsNullOrEmpty(relProduct.DefaultVariantId) ? $"&VariantID={relProduct.DefaultVariantId}" : variantIdForLink; 824 825 string link = "Default.aspx?ID=" + GetPageIdByNavigationTag("Shop"); 826 link += $"&GroupID={relProduct.PrimaryOrDefaultGroup.Id}"; 827 link += $"&ProductID={relProduct.Id}"; 828 link += variantIdForLink; 829 link = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(link); 830 831 string imagePath = relProduct?.DefaultImage.Value.ToString() ?? ""; 832 imagePath = "/Admin/Public/GetImage.ashx?image=" + imagePath + "&width=" + 350 + "&Format=WebP&Quality=70"; 833 834 string saleBadgeType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType") : ""; 835 string saleBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName") : ""; 836 string newBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName") : ""; 837 int newPublicationDays = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) ? Convert.ToInt32(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) : 0; 838 string campaignBadgesValues = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues")) ? Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues") : ""; 839 840 var badgeParms = new Dictionary<string, object>(); 841 badgeParms.Add("saleBadgeType", saleBadgeType); 842 badgeParms.Add("saleBadgeCssClassName", saleBadgeCssClassName); 843 badgeParms.Add("newBadgeCssClassName", newBadgeCssClassName); 844 badgeParms.Add("campaignBadgesValues", campaignBadgesValues); 845 badgeParms.Add("newPublicationDays", newPublicationDays); 846 847 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(saleBadgeCssClassName) && saleBadgeCssClassName != "none" ? true : false; 848 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(newBadgeCssClassName) && newBadgeCssClassName != "none" ? true : false; 849 DateTime createdDate = relProduct.Created.Value; 850 bool showBadges = saleBadgeEnabled && relProduct.Discount.Price != 0 ? true : false; 851 showBadges = (newBadgeEnabled && newPublicationDays == 0) || (newBadgeEnabled && (createdDate.AddDays(newPublicationDays) > DateTime.Now)) ? true : showBadges; 852 showBadges = !string.IsNullOrEmpty(campaignBadgesValues) ? true : showBadges; 853 854 string disableAddToCart = (relProduct.StockLevel <= 0) ? "disabled" : ""; 855 bool isNeverOutOfStock = relProduct.NeverOutOfstock; 856 disableAddToCart = isNeverOutOfStock ? "" : disableAddToCart; 857 858 string iconPath = "/Files/icons/"; 859 string addToCartIcon = Model.Item.GetRawValueString("Icon", iconPath + "shopping-cart.svg"); 860 string addToCartLabel = !addToCartIcon.Contains("_none") ? "<span class=\"icon-2\">" + ReadFile(addToCartIcon) + "</span>" : ""; 861 addToCartLabel += !addToCartIcon.Contains("_none") && !Model.Item.GetBoolean("HideButtonText") ? " " : ""; 862 addToCartLabel += !Model.Item.GetBoolean("HideButtonText") ? Translate("Add to cart") : ""; 863 string flexFill = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "flex-fill" : ""; 864 string buttonSize = Model.Item.GetRawValueString("ButtonSize", "regular"); 865 string inputSize = string.Empty; 866 867 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("EasyFlowCart")); 868 if (!url.Contains("LayoutTemplate")) 869 { 870 url += url.Contains("?") ? "&LayoutTemplate=Swift_MiniCart.cshtml" : "?LayoutTemplate=Swift_MiniCart.cshtml"; 871 } 872 string cartUrl = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("EasyFlowCart")); 873 string imagePathHidden = relProduct?.DefaultImage.Value.ToString() ?? ""; 874 imagePathHidden = "/Admin/Public/GetImage.ashx?image=" + imagePathHidden + "&width=" + 350 + "&Format=WebP&Quality=70"; 875 876 switch (buttonSize) 877 { 878 case "small": 879 inputSize = " input-group-sm"; 880 buttonSize = " btn-sm"; 881 break; 882 case "regular": 883 buttonSize = string.Empty; 884 break; 885 case "large": 886 inputSize = " input-group-lg"; 887 buttonSize = " btn-lg"; 888 break; 889 } 890 891 string ecomCountryCode = !string.IsNullOrEmpty(Pageview.Area.EcomCountryCode) ? Pageview.Area.EcomCountryCode : ""; 892 var countryVat = Services.Countries.GetCountry(ecomCountryCode).Vat > 0 ? Services.Countries.GetCountry(ecomCountryCode).Vat : 0; 893 var productToShow = Services.Products.GetProductById(relProduct.Id, relProduct.VariantId, relProduct.LanguageId); 894 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 895 string shipId = ecomCountryCode.IsNotNullOrEmpty() ? ShippingBasedOnProductSetting.GetShippingId(ecomCountryCode, productToShow) : ""; 896 var shippingFeeAmount = string.Empty; 897 898 if (!string.IsNullOrEmpty(ecomCountryCode) && shipId != null) 899 { 900 shippingFeeAmount = ShippingBasedOnProductSetting.GetShippingAmount(shipId, countryVat, productToShow, currency); 901 } 902 903 var deliveryCost = Translate("Levering fra") + " " + currency + " " + shippingFeeAmount; 904 var deliveryName = ShippingBasedOnProductSetting.GetShippingName(shipId, relProduct.LanguageId); 905 string stepQty = relProduct.PurchaseQuantityStep > 1 ? relProduct.PurchaseQuantityStep.ToString() : "1"; 906 string valueQty = relProduct.PurchaseMinimumQuantity > relProduct.PurchaseQuantityStep ? relProduct.PurchaseMinimumQuantity.ToString() : stepQty; 907 908 relProduct.ProductFields.TryGetValue("ProductNextBackorderDate", out FieldValueViewModel backInStockDateValue); 909 DateTime backInstockDate = backInStockDateValue.Value != null? DateTime.Parse(backInStockDateValue.Value.ToString()) : DateTime.Today.AddDays(-1); 910 bool hasBackInstockDate = backInStockDateValue != null && backInstockDate >= DateTime.Today; 911 bool hasExpectedDelivery = relProduct.ExpectedDelivery != null && relProduct.ExpectedDelivery >= DateTime.Today; 912 string expectedDeliveryDate = hasBackInstockDate ? backInstockDate.ToShortDateString() : relProduct.ExpectedDelivery?.ToShortDateString() ?? ""; 913 914 <div class="element w-100 d-flex"> 915 916 <div class="w-100 row m-0 align-items-end"> 917 <div class="product-info col ps-lg-0"> 918 <div class="col-3 image-container pe-2"> 919 <img class="h-100 w-100" src="@imagePath" alt="" style="object-fit: cover;"/> 920 </div> 921 <div> 922 <div><strong>@relProduct.Name</strong></div> 923 @if (!hidePrice) 924 { 925 <div> 926 <p class="h6 m-0"> 927 @if (showPricesWithVat == "false" && !neverShowVat) 928 { 929 if (relProduct.Price.Price != relProduct.PriceBeforeDiscount.Price) 930 { 931 <span class="text-decoration-line-through opacity-75 me-1"> 932 @relProduct.PriceBeforeDiscount.PriceWithoutVatFormatted 933 </span> 934 } 935 } 936 else 937 { 938 if (relProduct.Price.Price != relProduct.PriceBeforeDiscount.Price) 939 { 940 <span class="text-decoration-line-through opacity-75 me-1"> 941 @relProduct.PriceBeforeDiscount.PriceFormatted 942 </span> 943 } 944 } 945 946 @if (showPricesWithVat == "false" && !neverShowVat) 947 { 948 <span class="text-price fw-bold">@relProduct.Price.PriceWithoutVatFormatted</span> 949 } 950 else 951 { 952 <span class="text-price fw-bold">@relProduct.Price.PriceFormatted</span> 953 } 954 </p> 955 956 <div class="fs-8 mt-1"> 957 @if(!string.IsNullOrWhiteSpace(relProduct.StockStatus)) { 958 <p class="m-0">@relProduct.StockStatus</p> 959 } 960 @if(!string.IsNullOrWhiteSpace(relProduct.StockDeliveryText)) { 961 <p class="m-0">@relProduct.StockDeliveryText</p> 962 } 963 @if (hasExpectedDelivery || hasBackInstockDate) 964 { 965 <div class="m-0"> 966 <span>@Translate("Expected in stock"): </span> 967 <span>@expectedDeliveryDate</span> 968 </div> 969 } 970 </div> 971 972 973 <div class="fs-8 text-black-50 text-start"> 974 <p class="m-0">@Translate("Levering fra") @currency @shippingFeeAmount</p> 975 </div> 976 @if (showPricesWithVat == "false" && !neverShowVat) 977 { 978 <small class="opacity-85 fst-normal">@relProduct.Price.PriceWithVatFormatted @Translate("Incl. VAT")</small> 979 } 980 981 </div> 982 } 983 </div> 984 </div> 985 <div class="action col-auto px-3 ps-lg-0 w-100 w-lg-auto"> 986 <form method="post" action="@url"> 987 <input type="hidden" name="redirect" value="false"> 988 <input type="hidden" name="ProductId" value="@relProduct.Id"> 989 <input type="hidden" name="ProductName" value="@relProduct.Name"> 990 <input type="hidden" name="ProductCurrency" value="@Dynamicweb.Ecommerce.Common.Context.Currency.Code"> 991 <input type="hidden" name="ProductReferer" value="product_list_listview"> 992 <input type="hidden" name="ProductPrice" value="@relProduct.Price.PriceFormatted"> 993 <input type="hidden" name="cartcmd" value="add"> 994 @* #38 EA: sbj *@ 995 <input type="hidden" name="ProductPriceFormatted" value="@relProduct.Price.PriceFormatted"> 996 <input type="hidden" name="ProductUnit" value="@Translate("stk.", "stk.")"> 997 <input type="hidden" name="ProductTotalText" value="@Translate("I alt", "I alt")"> 998 <input type="hidden" name="ProductDeliveryCost" value="@deliveryCost"> 999 <input type="hidden" name="ProductDeliveryName" value="@deliveryName"> 1000 <input type="hidden" name="ProductImage" value="@imagePathHidden"> 1001 <input type="hidden" name="cartpage" value="@cartUrl"> 1002 @if (relProduct.StockLevel > 0) { 1003 <div class="d-flex flex-nowrap w-100 mb-2 bg-light efa-mod" style="height:40px;"> 1004 <div class="d-flex align-items-center justify-content-center btn border-0" id="minus-btn" onclick="quantityBtn('Quantity_@(relProduct.Id)_@relProduct.VariantId', 'minus')" style="width:calc(100%/3);"> 1005 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-dash-lg" viewBox="0 0 16 16"> 1006 <path fill-rule="evenodd" d="M2 8a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11A.5.5 0 0 1 2 8Z" /> 1007 </svg> 1008 </div> 1009 <div class="d-flex align-items-center justify-content-center" style="width:calc(100%/3);"> 1010 <input id="Quantity_@(relProduct.Id)_@relProduct.VariantId" name="Quantity" value="1" step="1" min="1" class="form-control p-0 bg-light border-0 fc-green quantity_selector efa-mod" style="max-width:40px;" type="number" onkeydown="swift.Cart.UpdateOnEnterKey(event)" @disableAddToCart> 1011 </div> 1012 <div class="d-flex align-items-center justify-content-center btn border-0" id="plus-btn" onclick="quantityBtn('Quantity_@(relProduct.Id)_@relProduct.VariantId', 'plus')" style="width:calc(100%/3);"> 1013 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plus-lg" viewBox="0 0 16 16"> 1014 <path fill-rule="evenodd" d="M8 2a.5.5 0 0 1 .5.5v5h5a.5.5 0 0 1 0 1h-5v5a.5.5 0 0 1-1 0v-5h-5a.5.5 0 0 1 0-1h5v-5A.5.5 0 0 1 8 2Z" /> 1015 </svg> 1016 </div> 1017 <script type="text/javascript"> 1018 function quantityBtn(id, symbol) { 1019 var idValue = document.getElementById(id).value; 1020 var value = parseInt(idValue, 10); 1021 var step = 1; 1022 value = isNaN(value) ? 0 : value; 1023 switch (symbol) { 1024 case "minus": 1025 value = value - step; 1026 break; 1027 case "plus": 1028 value = value + step; 1029 break; 1030 } 1031 console.log(value); 1032 if (value > 0) { 1033 document.getElementById(id).value = value; 1034 } 1035 //UpdateQuantity(); 1036 } 1037 </script> 1038 </div> 1039 <a onclick="swift.Cart.Update(event)" data-container="productRel" class="btn btn-primary @(buttonSize) @flexFill w-100 w-lg-auto flex-fill js-add-to-cart-button addToCart" style="white-space: nowrap" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(relProduct.Id)_@Pageview.CurrentParagraph.ID"> 1040 @if (!Model.Item.GetBoolean("HideButtonText")) 1041 { 1042 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 1043 @addToCartLabel 1044 </span> 1045 } 1046 else 1047 { 1048 @addToCartLabel 1049 } 1050 </a> 1051 1052 } else { 1053 <div class="w-100 efa-mod" style="height:40px;"> 1054 @*<button name="notify-cookie" data-href="@link" type="button" class="btn btn-primary flex-fill h-100 js-add-to-cart-button" title="@Translate("Produkt notifikations label")" id="AddCookie@(relProduct.Id)"> 1055 <span class="icon-2 d-flex gap-2 align-items-center justify-content-center">@ReadFile(iconPath + "envelope.svg")</span> 1056 </button>*@ 1057 <a href="@link" class="btn btn-secondary flex-fill view-more-btn w-100"><div class=""><span>@Translate("View more")</span></div></a> 1058 </div> 1059 } 1060 </form> 1061 </div> 1062 </div> 1063 </div> 1064 } 1065 1066 <script type="text/javascript"> 1067 document.addEventListener("update.swift.cart", function (event) { 1068 var e = event; 1069 var button = "addToCart"; 1070 var target = e.detail.parentEvent.target; 1071 while (!target.classList.contains(button)) { 1072 target = target.parentElement; 1073 } 1074 if (target.getAttribute("data-container") == "product") { 1075 var cartNotificationProduct = document.querySelector("#p_cartNotificationModalProduct"); 1076 var modalProduct = new bootstrap.Modal(cartNotificationProduct); 1077 //var modalProduct = new bootstrap.Modal(cartNotificationProduct); 1078 var data = Object.fromEntries(event.detail.formData.entries()); 1079 var price = data.ProductPrice; 1080 if (price.includes(",")) { 1081 price = price.replace(/,/g, "."); 1082 price = parseFloat(price).toFixed(2); 1083 } 1084 1085 var quantity = data.Quantity; 1086 var detailsPrice = data.ProductPrice; 1087 var totalprice = data.ProductPrice.includes(",") ? data.ProductPrice : detailsPrice.concat("", ",00");; 1088 if (quantity > 1) { 1089 var total = price * quantity; 1090 var totalpriceCalc = parseFloat(total).toFixed(2); 1091 totalpriceCalc = totalpriceCalc.toString(); 1092 if (totalpriceCalc.includes(".")) { 1093 totalprice = totalpriceCalc.replace(".", ","); 1094 } 1095 else { 1096 totalprice = totalpriceCalc.concat("", ",00"); 1097 } 1098 } else { 1099 1100 } 1101 1102 var details = data.ProductPrice.includes(",") ? data.ProductPrice : detailsPrice.concat("", ",00"); 1103 document.querySelector("#p_cartNotificationModalProduct_Button").href = data.cartpage; 1104 document.querySelector("#p_cartNotificationModalProduct_Quantity").innerHTML = data.Quantity + " " + data.ProductUnit; 1105 document.querySelector("#p_cartNotificationModalProduct_Name").innerHTML = data.ProductName; 1106 document.querySelector("#p_cartNotificationModalProduct_Price").innerHTML = data.ProductCurrency + " " + details; 1107 document.querySelector("#p_cartNotificationModalProduct_DeliveryCost").innerHTML = data.ProductDeliveryCost; 1108 document.querySelector("#p_cartNotificationModalProduct_DeliveryName").innerHTML = data.ProductDeliveryName; 1109 document.querySelector("#p_cartNotificationModalProduct_Image").src = data.ProductImage; 1110 document.querySelector("#p_cartNotificationModalProduct_Image").alt = data.ProductName; 1111 if (document.querySelector("#p_cartNotificationModal_Related")) { 1112 if (!document.querySelector("#p_cartNotificationModal_Related").classList.contains('d-md-block', 'd-lg-block', 'd-xl-block')) { 1113 document.querySelector("#p_cartNotificationModal_Related").classList.add('d-md-block', 'd-lg-block', 'd-xl-block'); 1114 } 1115 } 1116 modalProduct.show(); 1117 } 1118 //if (target.getAttribute("data-container") == "productRel") { 1119 // modalProduct.toggle(); 1120 // var cartNotificationProduct = document.querySelector("#p_cartNotificationModalProduct"); 1121 // var data = Object.fromEntries(event.detail.formData.entries()); 1122 // //var modalProduct = new bootstrap.Modal(cartNotificationProduct); 1123 // var price = data.ProductPrice; 1124 // if (price.includes(",")) { 1125 // price = price.replace(/,/g, "."); 1126 // price = parseFloat(price).toFixed(2); 1127 // } 1128 1129 // var quantity = data.Quantity; 1130 // var detailsPrice = data.ProductPrice; 1131 // var totalprice = data.ProductPrice.includes(",") ? data.ProductPrice : detailsPrice.concat("", ",00");; 1132 // if (quantity > 1) { 1133 // var total = price * quantity; 1134 // var totalpriceCalc = parseFloat(total).toFixed(2); 1135 // totalpriceCalc = totalpriceCalc.toString(); 1136 // if (totalpriceCalc.includes(".")) { 1137 // totalprice = totalpriceCalc.replace(".", ","); 1138 // } 1139 // else { 1140 // totalprice = totalpriceCalc.concat("", ",00"); 1141 // } 1142 // } else { 1143 1144 // } 1145 1146 // var details = data.ProductPrice.includes(",") ? data.ProductPrice : detailsPrice.concat("", ",00"); 1147 // document.querySelector("#p_cartNotificationModalProduct_Button").href = data.cartpage; 1148 // document.querySelector("#p_cartNotificationModalProduct_Quantity").innerHTML = data.Quantity + " " + data.ProductUnit; 1149 // document.querySelector("#p_cartNotificationModalProduct_Name").innerHTML = data.ProductName; 1150 // document.querySelector("#p_cartNotificationModalProduct_Price").innerHTML = data.ProductCurrency + " " + details; 1151 // document.querySelector("#p_cartNotificationModalProduct_DeliveryCost").innerHTML = data.ProductDeliveryCost; 1152 // document.querySelector("#p_cartNotificationModalProduct_DeliveryName").innerHTML = data.ProductDeliveryName; 1153 // document.querySelector("#p_cartNotificationModalProduct_Image").src = data.ProductImage; 1154 // document.querySelector("#p_cartNotificationModalProduct_Image").alt = data.ProductName; 1155 // document.querySelector("#p_cartNotificationModal_Related").classList.remove('d-md-block', 'd-lg-block', 'd-xl-block'); 1156 // modalProduct.show(); 1157 //} 1158 var data = Object.fromEntries(event.detail.formData.entries()); 1159 dataLayer.push({ ecommerce: null }); // Clear the previous ecommerce object. 1160 dataLayer.push({ 1161 event: "add_to_cart", 1162 ecommerce: { 1163 currency: data.ProductCurrency, 1164 value: data.ProductPrice, 1165 items: [ 1166 { 1167 item_id: data.ProductId, 1168 item_name: data.ProductName, 1169 affiliation: "Plus.dk", 1170 coupon: "", 1171 discount: "", 1172 index: 0, 1173 item_brand: "PLUS", 1174 item_category: "", 1175 item_category2: "", 1176 item_category3: "", 1177 item_category4: "", 1178 item_category5: "", 1179 item_list_id: data.item_list_name, 1180 item_list_name: "", 1181 item_variant: data.item_variant, 1182 location_id: "", 1183 price: data.ProductPrice, 1184 quantity: data.Quantity 1185 } 1186 ] 1187 } 1188 }); 1189 let addonsListHeight = 0; 1190 let addonList = document.querySelector("#addonsList"); 1191 let addonListElems = addonList.children; 1192 console.log(addonListElems); 1193 if (addonListElems.length > 3) { 1194 for (var i = 0; 3 > i; i++) { 1195 console.log(addonListElems[i].clientHeight); 1196 addonsListHeight = addonsListHeight + addonListElems[i].clientHeight + 16; 1197 } 1198 addonList.style.maxHeight = addonsListHeight + "px"; 1199 } 1200 }); 1201 </script> 1202 @* #38 EA: end *@ 1203
Error executing template "Designs/Swift/Paragraph/Swift_RelatedProducts_EA.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_2f8814d24d624371b6b17431b40cb58d.Execute() in C:\inetpub\wwwroot\plus-prod\Files\Templates\Designs\Swift\Paragraph\Swift_RelatedProducts_EA.cshtml:line 212
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Core 3 @using Dynamicweb.Ecommerce.ProductCatalog 4 @using System 5 @using System.Collections.Generic 6 @using System.Linq 7 8 @{ 9 bool productViewModelFound = false; 10 ProductViewModel product = new ProductViewModel(); 11 12 ProductViewModelSettings productSetting = new ProductViewModelSettings 13 { 14 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID, 15 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code, 16 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2, 17 ShopId = Pageview.Area.EcomShopId 18 }; 19 20 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 21 { 22 productViewModelFound = true; 23 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 24 } 25 if (Pageview.IsVisualEditorMode && !productViewModelFound) 26 { 27 if (Pageview.Item["DummyProduct"] != null) 28 { 29 productViewModelFound = true; 30 string dummyProductId = ""; 31 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 32 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 33 if (productList.Products != null) 34 { 35 foreach (var p in productList.Products) { dummyProductId = p.Id; } 36 ProductViewModel dummyProduct = dummyProductId != "" ? ViewModelFactory.CreateView(productSetting, dummyProductId) : new ProductViewModel(); 37 product = dummyProduct; 38 } 39 else 40 { 41 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id); 42 } 43 } 44 else if (Pageview.Item["DummyProduct"] == null) 45 { 46 productViewModelFound = true; 47 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id); 48 } 49 } 50 51 string title = Model?.Item?.GetString("Title") != null ? Model.Item.GetString("Title") : Translate("Products"); 52 string customID = Model?.Item?.GetString("Id") != null ? Model.Item.GetString("Title") : Translate("Products"); 53 string customSys = Model?.Item?.GetString("SystemName") != null ? Model.Item.GetString("SystemName") : Translate("Products"); 54 55 string campaignValues = Model.Item.GetRawValueString("CampaignBadges", string.Empty); 56 57 //Styling 58 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h3"); 59 string subtitleFontSize = Model.Item.GetRawValueString("SubtitleFontSize", "fs-5"); 60 string buttonStyle = Model.Item.GetRawValueString("ButtonStyle", ""); 61 buttonStyle = buttonStyle == "primary" ? " btn-primary" : buttonStyle; 62 buttonStyle = buttonStyle == "secondary" ? " btn-secondary" : buttonStyle; 63 buttonStyle = buttonStyle == "link" ? " btn-link" : buttonStyle; 64 string maxWidth = Model.Item.GetRawValueString("TextReadability", ""); 65 maxWidth = maxWidth == "max-width-on" ? " mw-75ch" : maxWidth; 66 maxWidth = maxWidth == "max-width-off" ? "" : maxWidth; 67 string productsCount = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ProductsCount").ToString()) ? Model.Item.GetRawValueString("ProductsCount").ToString() : ""; 68 69 string generalTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("GeneralTheme")) ? " theme " + Model.Item.GetRawValueString("GeneralTheme").Replace(" ", "").Trim().ToLower() : ""; 70 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 71 string imageTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : ""; 72 73 //Link generation 74 string pageId = Model.Item.GetLink("ProductSliderServicePage") != null ? Model.Item.GetLink("ProductSliderServicePage").PageId.ToString() : ""; 75 string servicePageByNavigationTag = GetPageIdByNavigationTag("ProductSliderService") != 0 ? GetPageIdByNavigationTag("ProductSliderService").ToString() : ""; 76 pageId = pageId == "" ? servicePageByNavigationTag : pageId; 77 78 string url = "/Default.aspx?ID=" + pageId; 79 if (!url.Contains("LayoutTemplate")) 80 { 81 url += url.Contains("?") ? "&LayoutTemplate=Designs/Swift/Swift_PageClean.cshtml" : "?LayoutTemplate=Designs/Swift/Swift_PageClean.cshtml"; 82 } 83 if (Pageview.IsVisualEditorMode) 84 { 85 url += "&VisualEdit=True"; 86 } 87 88 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsLazyLoadingForProductInfoEnabled; 89 if (isLazyLoadingForProductInfoEnabled) 90 { 91 url += "&getproductinfo=true"; 92 } 93 94 //Source type 95 string sourceType = Model.Item.GetRawValueString("RelationType", "trending"); 96 IList<string> relateFromGroupIds = new List<string> { }; 97 IList<string> relateFromProductIds = new List<string> { }; 98 99 //--- VARIANTS --- 100 ProductListViewModel productsToRelateToVariants = Model.Item.GetValue<ProductListViewModel>("ProductsToRelateToVariants"); 101 if (productsToRelateToVariants != null && sourceType == "variants") 102 { 103 foreach (var productSelection in productsToRelateToVariants.Products) 104 { 105 relateFromProductIds.Add(productSelection.Id); 106 } 107 } 108 109 //--- MOST SOLD --- 110 IList<ProductGroupViewModel> groupsToRelateToMostSold = Model.Item.GetValue<IList<ProductGroupViewModel>>("GroupsToRelateToMostSold"); 111 if (groupsToRelateToMostSold != null && sourceType == "most-sold") 112 { 113 foreach (var fromGroup in groupsToRelateToMostSold) 114 { 115 relateFromGroupIds.Add(fromGroup.Id); 116 } 117 } 118 119 //--- TRENDING --- 120 IList<ProductGroupViewModel> groupsToRelateToTrending = Model.Item.GetValue<IList<ProductGroupViewModel>>("GroupsToRelateToTrending"); 121 if (groupsToRelateToTrending != null && sourceType == "trending") 122 { 123 foreach (var fromGroup in groupsToRelateToTrending) 124 { 125 relateFromGroupIds.Add(fromGroup.Id); 126 } 127 } 128 129 //--- LATEST --- 130 IList<ProductGroupViewModel> groupsToRelateToLatest = Model.Item.GetValue<IList<ProductGroupViewModel>>("GroupsToRelateToLatest"); 131 if (groupsToRelateToLatest != null && sourceType == "latest") 132 { 133 foreach (var fromGroup in groupsToRelateToLatest) 134 { 135 relateFromGroupIds.Add(fromGroup.Id); 136 } 137 } 138 139 //--- FREQUENTLY BOUGHT --- 140 ProductListViewModel productsToRelateTo = Model.Item.GetValue<ProductListViewModel>("ProductsToRelateTo"); 141 if (productsToRelateTo != null && sourceType == "frequently") 142 { 143 foreach (var fromProduct in productsToRelateTo.Products) 144 { 145 relateFromProductIds.Add(fromProduct.Id); 146 } 147 } 148 149 //--- SELECTED PRODUCTS --- 150 ProductListViewModel products = Model.Item.GetValue<ProductListViewModel>("Products"); 151 if (products != null && sourceType == "selected") 152 { 153 foreach (var productSelection in products.Products) 154 { 155 relateFromProductIds.Add(productSelection.Id); 156 } 157 } 158 159 //--- RELATED PRODUCTS --- 160 if (sourceType == "related-products") 161 { 162 ProductListViewModel selectedRelationProduct = Model.Item.GetValue<ProductListViewModel>("ProductsToRelateTo2"); 163 164 if (selectedRelationProduct?.Products != null) 165 { 166 if (selectedRelationProduct.Products.Count > 0) 167 { 168 int productCount = 0; 169 foreach (var selectedProduct in selectedRelationProduct.Products) 170 { 171 if (productCount == 0) 172 { 173 product = selectedProduct; 174 productCount++; 175 } 176 } 177 } 178 } 179 180 if (product?.RelatedGroups != null) 181 { 182 foreach (var group in product.RelatedGroups) 183 { 184 foreach (var relatedProduct in group.Products) 185 { 186 relateFromProductIds.Add(relatedProduct.ProductId); 187 } 188 } 189 } 190 } 191 192 //--- RELATION GROUP --- 193 if (sourceType == "selected-group") 194 { 195 var relationGroupToShow = Model.Item.GetString("RelationGroupToShow"); 196 197 if (product?.RelatedGroups != null) 198 { 199 foreach (var group in product.RelatedGroups) 200 { 201 if (group.Id == relationGroupToShow) 202 { 203 foreach (var relatedProduct in group.Products) 204 { 205 relateFromProductIds.Add(relatedProduct.ProductId); 206 } 207 } 208 } 209 } 210 } 211 //Create group id collection and products id collection strings 212 string groupIds = productViewModelFound ? product.PrimaryOrDefaultGroup.Id : string.Join(",", relateFromGroupIds); 213 string productIds = productViewModelFound && relateFromProductIds.Count == 0 ? product.Id : string.Join(",", relateFromProductIds); 214 215 //Set the parameters to the url 216 string linkParameters = ""; 217 linkParameters += sourceType != "related-products" ? "&GroupId=" + groupIds : ""; 218 linkParameters += !string.IsNullOrEmpty(productIds) ? "&MainProductId=" + productIds : ""; 219 var productListPageId = GetPageIdByNavigationTag("Shop"); 220 string link = "/Default.aspx?ID=" + productListPageId + linkParameters; 221 222 // Slider settings (documentation: swiffyslider.com/configuration) 223 string navigationStyle = $"{Model.Item.GetRawValueString("NavigationStyle", "slider-nav-round")}"; 224 string navigationPlacement = $"{Model.Item.GetRawValueString("NavigationPlacement", "slider-nav-on-slides")}"; 225 string indicatorStyle = $"{Model.Item.GetRawValueString("IndicatorStyle", "slider-indicators-hidden")}"; 226 string revealSlides = Model.Item.GetRawValueString("RevealSlides", "no-reveal") == "reveal" ? "slider-item-reveal" : string.Empty; 227 string navigationAlwaysVisible = (Model.Item.GetBoolean("NavigationAlwaysVisible")) ? "slider-nav-visible" : string.Empty; 228 string navigationVisibleOnTouch = (Model.Item.GetBoolean("NavigationVisibleOnTouch")) ? "slider-nav-touch" : string.Empty; 229 string navigationShowScrollbar = (Model.Item.GetBoolean("NavigationShowScrollbar")) ? "slider-nav-scrollbar" : string.Empty; 230 string navigationSmall = (Model.Item.GetBoolean("NavigationSmall")) ? "slider-nav-sm" : string.Empty; 231 string navigationInvertColors = (Model.Item.GetBoolean("NavigationInvertColors")) ? "slider-nav-dark" : string.Empty; 232 string navigationSlideEntirePage = (Model.Item.GetBoolean("NavigationSlideEntirePage")) ? "slider-nav-page" : string.Empty; 233 string navigationNoLoop = (Model.Item.GetBoolean("NavigationNoLoop")) ? "slider-nav-noloop" : string.Empty; 234 string indicatorsOutsideSlider = (Model.Item.GetBoolean("IndicatorsOutsideSlider") && indicatorStyle != string.Empty) ? "slider-indicators-outside" : string.Empty; 235 string indicatorsHighlightActive = (Model.Item.GetBoolean("IndicatorsHighlightActive")) ? "slider-indicators-highlight" : string.Empty; 236 string indicatorsInvertColors = (Model.Item.GetBoolean("IndicatorsInvertedColors")) ? "slider-indicators-dark" : string.Empty; 237 string indicatorsVisibleOnSmallDevices = (Model.Item.GetBoolean("IndicatorsVisibleOnSmallDevices")) ? "slider-indicators-sm" : string.Empty; 238 bool showFavoritesSelectorMasterProduct = Model.Item.GetBoolean("ShowFavoritesSelectorMasterProduct"); 239 var bagdeItems = Model.Item?.GetItems("Badges") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 240 241 bool productsFound = true; 242 if (string.IsNullOrEmpty(groupIds) && string.IsNullOrEmpty(productIds)) 243 { 244 if (Pageview.IsVisualEditorMode) 245 { 246 productIds = product.Id; 247 sourceType = "selected"; 248 } 249 else 250 { 251 productsFound = false; 252 } 253 } 254 } 255 256 @*Container element for the request*@ 257 @if (productsFound) 258 { 259 <form method="post" action="@url" id="RelatedProductsForm_@Model.ID" data-response-target-element="RelatedProducts_@Model.ID" data-preloader="inline" data-update-url="false" class="test_@Model.ID item_@Model.Item.SystemName.ToLower()"> 260 <input type="hidden" name="ModelID" value="@Model.ID"> 261 <input type="hidden" name="ModelProductID" value="@product.Id"> 262 <input type="hidden" name="ModelProductLanguageID" value="@product.LanguageId"> 263 @{ 264 if (product?.RelatedGroups != null && product?.RelatedGroups.Count > 1) 265 { 266 267 var sortNumber = 1; 268 foreach (var group in product.RelatedGroups) 269 { 270 var sortID = group.Id; 271 <input type="hidden" name="@sortID" value="@sortNumber"> 272 sortNumber++; 273 } 274 } 275 } 276 277 @*--- SLIDER SETTINGS ---*@ 278 <input type="hidden" name="NavigationStyle" value="@navigationStyle"> 279 <input type="hidden" name="NavigationPlacement" value="@navigationPlacement"> 280 <input type="hidden" name="IndicatorStyle" value="@indicatorStyle"> 281 <input type="hidden" name="RevealSlides" value="@revealSlides"> 282 <input type="hidden" name="NavigationAlwaysVisible" value="@(navigationAlwaysVisible)"> 283 <input type="hidden" name="NavigationVisibleOnTouch" value="@(navigationVisibleOnTouch)"> 284 <input type="hidden" name="NavigationShowScrollbar" value="@(navigationShowScrollbar)"> 285 <input type="hidden" name="NavigationSmall" value="@(navigationSmall)"> 286 <input type="hidden" name="NavigationInvertColors" value="@(navigationInvertColors)"> 287 <input type="hidden" name="NavigationNoLoop" value="@(navigationNoLoop)"> 288 <input type="hidden" name="NavigationSlideEntirePage" value="@(navigationSlideEntirePage)"> 289 <input type="hidden" name="IndicatorsOutsideSlider" value="@(indicatorsOutsideSlider)"> 290 <input type="hidden" name="IndicatorsHighlightActive" value="@(indicatorsHighlightActive)"> 291 <input type="hidden" name="IndicatorsInvertColors" value="@(indicatorsInvertColors)"> 292 <input type="hidden" name="IndicatorsVisibleOnSmallDevices" value="@(indicatorsVisibleOnSmallDevices)"> 293 <input type="hidden" name="ShowFavoritesSelectorMasterProduct" value="@(showFavoritesSelectorMasterProduct.ToString())"> 294 295 @*--- VARIANTS ---*@ 296 @if (sourceType == "variants") 297 { 298 <input type="hidden" name="isVariant" value="true"> 299 <input type="hidden" name="MainProductID" id="MainProductID_@Model.ID" value="@productIds"> 300 } 301 302 @*--- MOST SOLD ---*@ 303 @if (sourceType == "most-sold") 304 { 305 <input type="hidden" name="SortBy" value="OrderCount"> 306 if (groupIds != "") 307 { 308 <input type="hidden" name="GroupId" value="@groupIds"> 309 } 310 } 311 312 @*--- TRENDING ---*@ 313 @if (sourceType == "trending") 314 { 315 <input type="hidden" name="SortBy" value="OrderCountGrowth"> 316 if (groupIds != "") 317 { 318 <input type="hidden" name="GroupId" value="@groupIds"> 319 } 320 } 321 322 @*--- FREQUENTLY BOUGHT ---*@ 323 @if (sourceType == "frequently" && !string.IsNullOrEmpty(productIds)) 324 { 325 <input type="hidden" name="BoughtWithProductIds" value="[@productIds]"> 326 } 327 328 @*--- LATEST ---*@ 329 @if (sourceType == "latest") 330 { 331 <input type="hidden" name="SortBy" value="Created"> 332 <input type="hidden" name="GroupId" value="@groupIds"> 333 } 334 335 @*--- SELECTED PRODUCTS ---*@ 336 @if (sourceType == "selected") 337 { 338 <input type="hidden" name="MainProductID" id="MainProductID_@Model.ID" value="@productIds"> 339 } 340 341 @*--- RELATED PRODUCTS ---*@ 342 @if (sourceType == "related-products") 343 { 344 <input type="hidden" name="MainProductID" id="MainProductID_@Model.ID" value="@productIds"> 345 } 346 347 @*--- RELATION GROUP ---*@ 348 @if (sourceType == "selected-group") 349 { 350 <input type="hidden" name="MainProductID" id="MainProductID_@Model.ID" value="@productIds"> 351 <input type="hidden" name="RelationGroup" value="@Model.Item.GetString("RelationGroupToShow")"> 352 } 353 354 @* General parameters *@ 355 <input type="hidden" name="Link" value="@link"> 356 <input type="hidden" name="HideTitle" value="@Model.Item.GetString("HideTitle")"> 357 <input type="hidden" name="SliderCollectionID" id="SliderCollectionID_@Model.ID" value="@customID"> 358 <input type="hidden" name="SortOrder" value="DESC"> 359 360 @if (Model.Item.GetInt32("ProductsCount") != 0) 361 { 362 <input type="hidden" name="PageSize" value="@Model.Item.GetInt32("ProductsCount")"> 363 } 364 <input type="hidden" name="HeadingTitle" id="RelatedProductsTitle_@Model.ID" value="@title"> 365 @if (!string.IsNullOrEmpty(Model.Item.GetString("Subtitle"))) 366 { 367 <input type="hidden" name="Subtitle" value="@Model.Item.GetString("Subtitle")"> 368 } 369 @if (!string.IsNullOrEmpty(Model.Item.GetString("LinkText"))) 370 { 371 <input type="hidden" name="LinkText" value="@Model.Item.GetString("LinkText")"> 372 } 373 @if (!string.IsNullOrEmpty(Model.Item.GetString("ImageAspectRatio"))) 374 { 375 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 376 ratio = ratio != "0" ? ratio : ""; 377 <input type="hidden" name="ImageAspectRatio" value="@ratio"> 378 } 379 @if (!string.IsNullOrEmpty(Model.Item.GetString("Layout"))) 380 { 381 <input type="hidden" name="Layout" value="@Model.Item.GetRawValueString("Layout")"> 382 } 383 @if (titleFontSize != "") 384 { 385 <input type="hidden" name="TitleFontSize" value="@titleFontSize"> 386 } 387 @if (subtitleFontSize != "") 388 { 389 <input type="hidden" name="SubtitleFontSize" value="@subtitleFontSize"> 390 } 391 @if (buttonStyle != "") 392 { 393 <input type="hidden" name="ButtonStyle" value="@buttonStyle"> 394 } 395 @if (generalTheme != "") 396 { 397 <input type="hidden" name="GeneralTheme" value="@generalTheme"> 398 } 399 @if (theme != "") 400 { 401 <input type="hidden" name="Theme" value="@theme"> 402 } 403 @if (imageTheme != "") 404 { 405 <input type="hidden" name="ImageTheme" value="@imageTheme"> 406 } 407 @if (!string.IsNullOrEmpty(Model.Item.GetString("ContentPadding"))) 408 { 409 string contentPadding = Model.Item.GetRawValueString("ContentPadding"); 410 <input type="hidden" name="ContentPadding" value="@contentPadding"> 411 } 412 <input type="hidden" name="TextReadability" value="@maxWidth"> 413 <input type="hidden" name="ParentColumnSize" id="ParentColumnSize_@Model.ID" value="12"> 414 415 @*--- PLUS BADGES ---*@ 416 @{ 417 var count = 0; 418 foreach (var badge in bagdeItems) 419 { 420 count++; 421 <input type="hidden" name="Plusbadge-title_@count" value="@badge.GetString("Title")"> 422 <input type="hidden" name="Plusbadge-image_@count" value="@badge.GetString("Image")"> 423 } 424 } 425 <input type="hidden" name="Plusbadge-totalCount" value="@count"> 426 427 <input type="hidden" name="SaleBadgeType" value="@Model.Item.GetRawValue("SaleBadgeType")"> 428 <input type="hidden" name="SaleBadgeCssClassName" value="@Model.Item.GetRawValue("SaleBadgeDesign")"> 429 <input type="hidden" name="NewBadgeCssClassName" value="@Model.Item.GetRawValue("NewBadgeDesign")"> 430 <input type="hidden" name="NewPublicationDays" value="@Model.Item.GetInt32("NewPublicationDays")"> 431 432 @if (campaignValues != "") 433 { 434 <input type="hidden" name="CampaignBadgesValues" value="@campaignValues"> 435 } 436 </form> 437 438 <script type="module" src="~/Files/Templates/Designs/Swift/Assets/js/swiffy-slider.js"></script> 439 <script type="module"> 440 swift.AssetLoader.Load('/Files/Templates/Designs/Swift/Assets/css/swiffy-slider.min.css', 'css'); 441 </script> 442 443 if (Pageview.IsVisualEditorMode) 444 { 445 <div class="alert alert-info" role="alert"> 446 <span>@Translate("Product slider: Edit this column to configure")</span> 447 </div> 448 } 449 450 if (sourceType != "related-products") 451 { 452 if (productIds != product.Id) 453 { 454 <div class="w-100 h-100"> 455 <div id="RelatedProducts_@Model.ID" class="h-100 swift_product_slider_container"></div> 456 </div> 457 } 458 } 459 if (sourceType != "selected-group") 460 { 461 <div class="w-100 h-100"> 462 <div id="RelatedProducts_@Model.ID" class="g-col-12 h-100 swift_product_slider_container"></div> 463 </div> 464 } 465 else if (product?.RelatedGroups != null) 466 { 467 @* Create multiple slider containers, if type is Product relation *@ 468 @* Sorting product related groups so Addon *@ 469 product.RelatedGroups.Sort((u1, u2) => u1.Id.CompareTo(u2.Id)); 470 471 <div class="grid w-100 h-100@(generalTheme)" style="grid-row-gap: 4rem"> 472 @foreach (var group in product.RelatedGroups) 473 { 474 <div id="RelatedProducts_@(Model.ID)_@group.Id" class="g-col-12 h-100 swift_product_slider_container"></div> 475 } 476 </div> 477 } 478 479 @* Initialize *@ 480 if (sourceType != "related-products") 481 { 482 <script type="module"> 483 if (document.querySelector("#RelatedProducts_@Model.ID").closest("[data-col-size]")) { 484 document.querySelector("#ParentColumnSize_@Model.ID").value = document.querySelector("#RelatedProducts_@Model.ID").closest("[data-col-size]").getAttribute("data-col-size"); 485 } 486 swift.PageUpdater.Update(document.querySelector("#RelatedProductsForm_@Model.ID")).then(function () { 487 setTimeout(function() { 488 const isVisualEditor = @(Converter.ToString(Pageview.IsVisualEditorMode).ToLowerInvariant()); 489 const productSliderContainer = document.querySelector(".swift_product_slider_container"); 490 491 if (productSliderContainer && productSliderContainer.innerHTML !== "") { 492 productSliderContainer.classList.remove("d-none"); 493 } 494 else if (!isVisualEditor) { 495 productSliderContainer.closest("[class*=column]").classList.add("d-none"); 496 } 497 }, 150); 498 }); 499 </script> 500 } 501 else if (product?.RelatedGroups != null) 502 { 503 @* Create multiple sliders, if type is Product relation *@ 504 foreach (var group in product.RelatedGroups) 505 { 506 IList<string> fromProductIds = new List<string> { }; 507 508 foreach (var relatedProduct in group.Products) 509 { 510 fromProductIds.Add(relatedProduct.ProductId); 511 } 512 <script type="module"> 513 document.querySelector("#ParentColumnSize_@Model.ID").value = document.querySelector("#RelatedProducts_@(Model.ID)_@group.Id").closest("[data-col-size]").getAttribute("data-col-size"); 514 document.querySelector("#MainProductID_@Model.ID").value = "@string.Join(",", fromProductIds)"; 515 document.querySelector("#RelatedProductsTitle_@Model.ID").value = "@group.Name"; 516 document.querySelector("#SliderCollectionID_@Model.ID").value = "@group.Id"; 517 document.querySelector("#RelatedProductsForm_@Model.ID").setAttribute("data-response-target-element", "RelatedProducts_@(Model.ID)_@group.Id"); 518 519 swift.PageUpdater.Update(document.querySelector("#RelatedProductsForm_@Model.ID")); 520 </script> 521 } 522 } 523 } 524
Error executing template "Designs/Swift/Paragraph/Swift_RelatedProducts_EA.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_2f8814d24d624371b6b17431b40cb58d.Execute() in C:\inetpub\wwwroot\plus-prod\Files\Templates\Designs\Swift\Paragraph\Swift_RelatedProducts_EA.cshtml:line 212
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Core 3 @using Dynamicweb.Ecommerce.ProductCatalog 4 @using System 5 @using System.Collections.Generic 6 @using System.Linq 7 8 @{ 9 bool productViewModelFound = false; 10 ProductViewModel product = new ProductViewModel(); 11 12 ProductViewModelSettings productSetting = new ProductViewModelSettings 13 { 14 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID, 15 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code, 16 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2, 17 ShopId = Pageview.Area.EcomShopId 18 }; 19 20 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 21 { 22 productViewModelFound = true; 23 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 24 } 25 if (Pageview.IsVisualEditorMode && !productViewModelFound) 26 { 27 if (Pageview.Item["DummyProduct"] != null) 28 { 29 productViewModelFound = true; 30 string dummyProductId = ""; 31 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 32 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 33 if (productList.Products != null) 34 { 35 foreach (var p in productList.Products) { dummyProductId = p.Id; } 36 ProductViewModel dummyProduct = dummyProductId != "" ? ViewModelFactory.CreateView(productSetting, dummyProductId) : new ProductViewModel(); 37 product = dummyProduct; 38 } 39 else 40 { 41 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id); 42 } 43 } 44 else if (Pageview.Item["DummyProduct"] == null) 45 { 46 productViewModelFound = true; 47 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id); 48 } 49 } 50 51 string title = Model?.Item?.GetString("Title") != null ? Model.Item.GetString("Title") : Translate("Products"); 52 string customID = Model?.Item?.GetString("Id") != null ? Model.Item.GetString("Title") : Translate("Products"); 53 string customSys = Model?.Item?.GetString("SystemName") != null ? Model.Item.GetString("SystemName") : Translate("Products"); 54 55 string campaignValues = Model.Item.GetRawValueString("CampaignBadges", string.Empty); 56 57 //Styling 58 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h3"); 59 string subtitleFontSize = Model.Item.GetRawValueString("SubtitleFontSize", "fs-5"); 60 string buttonStyle = Model.Item.GetRawValueString("ButtonStyle", ""); 61 buttonStyle = buttonStyle == "primary" ? " btn-primary" : buttonStyle; 62 buttonStyle = buttonStyle == "secondary" ? " btn-secondary" : buttonStyle; 63 buttonStyle = buttonStyle == "link" ? " btn-link" : buttonStyle; 64 string maxWidth = Model.Item.GetRawValueString("TextReadability", ""); 65 maxWidth = maxWidth == "max-width-on" ? " mw-75ch" : maxWidth; 66 maxWidth = maxWidth == "max-width-off" ? "" : maxWidth; 67 string productsCount = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ProductsCount").ToString()) ? Model.Item.GetRawValueString("ProductsCount").ToString() : ""; 68 69 string generalTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("GeneralTheme")) ? " theme " + Model.Item.GetRawValueString("GeneralTheme").Replace(" ", "").Trim().ToLower() : ""; 70 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 71 string imageTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : ""; 72 73 //Link generation 74 string pageId = Model.Item.GetLink("ProductSliderServicePage") != null ? Model.Item.GetLink("ProductSliderServicePage").PageId.ToString() : ""; 75 string servicePageByNavigationTag = GetPageIdByNavigationTag("ProductSliderService") != 0 ? GetPageIdByNavigationTag("ProductSliderService").ToString() : ""; 76 pageId = pageId == "" ? servicePageByNavigationTag : pageId; 77 78 string url = "/Default.aspx?ID=" + pageId; 79 if (!url.Contains("LayoutTemplate")) 80 { 81 url += url.Contains("?") ? "&LayoutTemplate=Designs/Swift/Swift_PageClean.cshtml" : "?LayoutTemplate=Designs/Swift/Swift_PageClean.cshtml"; 82 } 83 if (Pageview.IsVisualEditorMode) 84 { 85 url += "&VisualEdit=True"; 86 } 87 88 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsLazyLoadingForProductInfoEnabled; 89 if (isLazyLoadingForProductInfoEnabled) 90 { 91 url += "&getproductinfo=true"; 92 } 93 94 //Source type 95 string sourceType = Model.Item.GetRawValueString("RelationType", "trending"); 96 IList<string> relateFromGroupIds = new List<string> { }; 97 IList<string> relateFromProductIds = new List<string> { }; 98 99 //--- VARIANTS --- 100 ProductListViewModel productsToRelateToVariants = Model.Item.GetValue<ProductListViewModel>("ProductsToRelateToVariants"); 101 if (productsToRelateToVariants != null && sourceType == "variants") 102 { 103 foreach (var productSelection in productsToRelateToVariants.Products) 104 { 105 relateFromProductIds.Add(productSelection.Id); 106 } 107 } 108 109 //--- MOST SOLD --- 110 IList<ProductGroupViewModel> groupsToRelateToMostSold = Model.Item.GetValue<IList<ProductGroupViewModel>>("GroupsToRelateToMostSold"); 111 if (groupsToRelateToMostSold != null && sourceType == "most-sold") 112 { 113 foreach (var fromGroup in groupsToRelateToMostSold) 114 { 115 relateFromGroupIds.Add(fromGroup.Id); 116 } 117 } 118 119 //--- TRENDING --- 120 IList<ProductGroupViewModel> groupsToRelateToTrending = Model.Item.GetValue<IList<ProductGroupViewModel>>("GroupsToRelateToTrending"); 121 if (groupsToRelateToTrending != null && sourceType == "trending") 122 { 123 foreach (var fromGroup in groupsToRelateToTrending) 124 { 125 relateFromGroupIds.Add(fromGroup.Id); 126 } 127 } 128 129 //--- LATEST --- 130 IList<ProductGroupViewModel> groupsToRelateToLatest = Model.Item.GetValue<IList<ProductGroupViewModel>>("GroupsToRelateToLatest"); 131 if (groupsToRelateToLatest != null && sourceType == "latest") 132 { 133 foreach (var fromGroup in groupsToRelateToLatest) 134 { 135 relateFromGroupIds.Add(fromGroup.Id); 136 } 137 } 138 139 //--- FREQUENTLY BOUGHT --- 140 ProductListViewModel productsToRelateTo = Model.Item.GetValue<ProductListViewModel>("ProductsToRelateTo"); 141 if (productsToRelateTo != null && sourceType == "frequently") 142 { 143 foreach (var fromProduct in productsToRelateTo.Products) 144 { 145 relateFromProductIds.Add(fromProduct.Id); 146 } 147 } 148 149 //--- SELECTED PRODUCTS --- 150 ProductListViewModel products = Model.Item.GetValue<ProductListViewModel>("Products"); 151 if (products != null && sourceType == "selected") 152 { 153 foreach (var productSelection in products.Products) 154 { 155 relateFromProductIds.Add(productSelection.Id); 156 } 157 } 158 159 //--- RELATED PRODUCTS --- 160 if (sourceType == "related-products") 161 { 162 ProductListViewModel selectedRelationProduct = Model.Item.GetValue<ProductListViewModel>("ProductsToRelateTo2"); 163 164 if (selectedRelationProduct?.Products != null) 165 { 166 if (selectedRelationProduct.Products.Count > 0) 167 { 168 int productCount = 0; 169 foreach (var selectedProduct in selectedRelationProduct.Products) 170 { 171 if (productCount == 0) 172 { 173 product = selectedProduct; 174 productCount++; 175 } 176 } 177 } 178 } 179 180 if (product?.RelatedGroups != null) 181 { 182 foreach (var group in product.RelatedGroups) 183 { 184 foreach (var relatedProduct in group.Products) 185 { 186 relateFromProductIds.Add(relatedProduct.ProductId); 187 } 188 } 189 } 190 } 191 192 //--- RELATION GROUP --- 193 if (sourceType == "selected-group") 194 { 195 var relationGroupToShow = Model.Item.GetString("RelationGroupToShow"); 196 197 if (product?.RelatedGroups != null) 198 { 199 foreach (var group in product.RelatedGroups) 200 { 201 if (group.Id == relationGroupToShow) 202 { 203 foreach (var relatedProduct in group.Products) 204 { 205 relateFromProductIds.Add(relatedProduct.ProductId); 206 } 207 } 208 } 209 } 210 } 211 //Create group id collection and products id collection strings 212 string groupIds = productViewModelFound ? product.PrimaryOrDefaultGroup.Id : string.Join(",", relateFromGroupIds); 213 string productIds = productViewModelFound && relateFromProductIds.Count == 0 ? product.Id : string.Join(",", relateFromProductIds); 214 215 //Set the parameters to the url 216 string linkParameters = ""; 217 linkParameters += sourceType != "related-products" ? "&GroupId=" + groupIds : ""; 218 linkParameters += !string.IsNullOrEmpty(productIds) ? "&MainProductId=" + productIds : ""; 219 var productListPageId = GetPageIdByNavigationTag("Shop"); 220 string link = "/Default.aspx?ID=" + productListPageId + linkParameters; 221 222 // Slider settings (documentation: swiffyslider.com/configuration) 223 string navigationStyle = $"{Model.Item.GetRawValueString("NavigationStyle", "slider-nav-round")}"; 224 string navigationPlacement = $"{Model.Item.GetRawValueString("NavigationPlacement", "slider-nav-on-slides")}"; 225 string indicatorStyle = $"{Model.Item.GetRawValueString("IndicatorStyle", "slider-indicators-hidden")}"; 226 string revealSlides = Model.Item.GetRawValueString("RevealSlides", "no-reveal") == "reveal" ? "slider-item-reveal" : string.Empty; 227 string navigationAlwaysVisible = (Model.Item.GetBoolean("NavigationAlwaysVisible")) ? "slider-nav-visible" : string.Empty; 228 string navigationVisibleOnTouch = (Model.Item.GetBoolean("NavigationVisibleOnTouch")) ? "slider-nav-touch" : string.Empty; 229 string navigationShowScrollbar = (Model.Item.GetBoolean("NavigationShowScrollbar")) ? "slider-nav-scrollbar" : string.Empty; 230 string navigationSmall = (Model.Item.GetBoolean("NavigationSmall")) ? "slider-nav-sm" : string.Empty; 231 string navigationInvertColors = (Model.Item.GetBoolean("NavigationInvertColors")) ? "slider-nav-dark" : string.Empty; 232 string navigationSlideEntirePage = (Model.Item.GetBoolean("NavigationSlideEntirePage")) ? "slider-nav-page" : string.Empty; 233 string navigationNoLoop = (Model.Item.GetBoolean("NavigationNoLoop")) ? "slider-nav-noloop" : string.Empty; 234 string indicatorsOutsideSlider = (Model.Item.GetBoolean("IndicatorsOutsideSlider") && indicatorStyle != string.Empty) ? "slider-indicators-outside" : string.Empty; 235 string indicatorsHighlightActive = (Model.Item.GetBoolean("IndicatorsHighlightActive")) ? "slider-indicators-highlight" : string.Empty; 236 string indicatorsInvertColors = (Model.Item.GetBoolean("IndicatorsInvertedColors")) ? "slider-indicators-dark" : string.Empty; 237 string indicatorsVisibleOnSmallDevices = (Model.Item.GetBoolean("IndicatorsVisibleOnSmallDevices")) ? "slider-indicators-sm" : string.Empty; 238 bool showFavoritesSelectorMasterProduct = Model.Item.GetBoolean("ShowFavoritesSelectorMasterProduct"); 239 var bagdeItems = Model.Item?.GetItems("Badges") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 240 241 bool productsFound = true; 242 if (string.IsNullOrEmpty(groupIds) && string.IsNullOrEmpty(productIds)) 243 { 244 if (Pageview.IsVisualEditorMode) 245 { 246 productIds = product.Id; 247 sourceType = "selected"; 248 } 249 else 250 { 251 productsFound = false; 252 } 253 } 254 } 255 256 @*Container element for the request*@ 257 @if (productsFound) 258 { 259 <form method="post" action="@url" id="RelatedProductsForm_@Model.ID" data-response-target-element="RelatedProducts_@Model.ID" data-preloader="inline" data-update-url="false" class="test_@Model.ID item_@Model.Item.SystemName.ToLower()"> 260 <input type="hidden" name="ModelID" value="@Model.ID"> 261 <input type="hidden" name="ModelProductID" value="@product.Id"> 262 <input type="hidden" name="ModelProductLanguageID" value="@product.LanguageId"> 263 @{ 264 if (product?.RelatedGroups != null && product?.RelatedGroups.Count > 1) 265 { 266 267 var sortNumber = 1; 268 foreach (var group in product.RelatedGroups) 269 { 270 var sortID = group.Id; 271 <input type="hidden" name="@sortID" value="@sortNumber"> 272 sortNumber++; 273 } 274 } 275 } 276 277 @*--- SLIDER SETTINGS ---*@ 278 <input type="hidden" name="NavigationStyle" value="@navigationStyle"> 279 <input type="hidden" name="NavigationPlacement" value="@navigationPlacement"> 280 <input type="hidden" name="IndicatorStyle" value="@indicatorStyle"> 281 <input type="hidden" name="RevealSlides" value="@revealSlides"> 282 <input type="hidden" name="NavigationAlwaysVisible" value="@(navigationAlwaysVisible)"> 283 <input type="hidden" name="NavigationVisibleOnTouch" value="@(navigationVisibleOnTouch)"> 284 <input type="hidden" name="NavigationShowScrollbar" value="@(navigationShowScrollbar)"> 285 <input type="hidden" name="NavigationSmall" value="@(navigationSmall)"> 286 <input type="hidden" name="NavigationInvertColors" value="@(navigationInvertColors)"> 287 <input type="hidden" name="NavigationNoLoop" value="@(navigationNoLoop)"> 288 <input type="hidden" name="NavigationSlideEntirePage" value="@(navigationSlideEntirePage)"> 289 <input type="hidden" name="IndicatorsOutsideSlider" value="@(indicatorsOutsideSlider)"> 290 <input type="hidden" name="IndicatorsHighlightActive" value="@(indicatorsHighlightActive)"> 291 <input type="hidden" name="IndicatorsInvertColors" value="@(indicatorsInvertColors)"> 292 <input type="hidden" name="IndicatorsVisibleOnSmallDevices" value="@(indicatorsVisibleOnSmallDevices)"> 293 <input type="hidden" name="ShowFavoritesSelectorMasterProduct" value="@(showFavoritesSelectorMasterProduct.ToString())"> 294 295 @*--- VARIANTS ---*@ 296 @if (sourceType == "variants") 297 { 298 <input type="hidden" name="isVariant" value="true"> 299 <input type="hidden" name="MainProductID" id="MainProductID_@Model.ID" value="@productIds"> 300 } 301 302 @*--- MOST SOLD ---*@ 303 @if (sourceType == "most-sold") 304 { 305 <input type="hidden" name="SortBy" value="OrderCount"> 306 if (groupIds != "") 307 { 308 <input type="hidden" name="GroupId" value="@groupIds"> 309 } 310 } 311 312 @*--- TRENDING ---*@ 313 @if (sourceType == "trending") 314 { 315 <input type="hidden" name="SortBy" value="OrderCountGrowth"> 316 if (groupIds != "") 317 { 318 <input type="hidden" name="GroupId" value="@groupIds"> 319 } 320 } 321 322 @*--- FREQUENTLY BOUGHT ---*@ 323 @if (sourceType == "frequently" && !string.IsNullOrEmpty(productIds)) 324 { 325 <input type="hidden" name="BoughtWithProductIds" value="[@productIds]"> 326 } 327 328 @*--- LATEST ---*@ 329 @if (sourceType == "latest") 330 { 331 <input type="hidden" name="SortBy" value="Created"> 332 <input type="hidden" name="GroupId" value="@groupIds"> 333 } 334 335 @*--- SELECTED PRODUCTS ---*@ 336 @if (sourceType == "selected") 337 { 338 <input type="hidden" name="MainProductID" id="MainProductID_@Model.ID" value="@productIds"> 339 } 340 341 @*--- RELATED PRODUCTS ---*@ 342 @if (sourceType == "related-products") 343 { 344 <input type="hidden" name="MainProductID" id="MainProductID_@Model.ID" value="@productIds"> 345 } 346 347 @*--- RELATION GROUP ---*@ 348 @if (sourceType == "selected-group") 349 { 350 <input type="hidden" name="MainProductID" id="MainProductID_@Model.ID" value="@productIds"> 351 <input type="hidden" name="RelationGroup" value="@Model.Item.GetString("RelationGroupToShow")"> 352 } 353 354 @* General parameters *@ 355 <input type="hidden" name="Link" value="@link"> 356 <input type="hidden" name="HideTitle" value="@Model.Item.GetString("HideTitle")"> 357 <input type="hidden" name="SliderCollectionID" id="SliderCollectionID_@Model.ID" value="@customID"> 358 <input type="hidden" name="SortOrder" value="DESC"> 359 360 @if (Model.Item.GetInt32("ProductsCount") != 0) 361 { 362 <input type="hidden" name="PageSize" value="@Model.Item.GetInt32("ProductsCount")"> 363 } 364 <input type="hidden" name="HeadingTitle" id="RelatedProductsTitle_@Model.ID" value="@title"> 365 @if (!string.IsNullOrEmpty(Model.Item.GetString("Subtitle"))) 366 { 367 <input type="hidden" name="Subtitle" value="@Model.Item.GetString("Subtitle")"> 368 } 369 @if (!string.IsNullOrEmpty(Model.Item.GetString("LinkText"))) 370 { 371 <input type="hidden" name="LinkText" value="@Model.Item.GetString("LinkText")"> 372 } 373 @if (!string.IsNullOrEmpty(Model.Item.GetString("ImageAspectRatio"))) 374 { 375 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 376 ratio = ratio != "0" ? ratio : ""; 377 <input type="hidden" name="ImageAspectRatio" value="@ratio"> 378 } 379 @if (!string.IsNullOrEmpty(Model.Item.GetString("Layout"))) 380 { 381 <input type="hidden" name="Layout" value="@Model.Item.GetRawValueString("Layout")"> 382 } 383 @if (titleFontSize != "") 384 { 385 <input type="hidden" name="TitleFontSize" value="@titleFontSize"> 386 } 387 @if (subtitleFontSize != "") 388 { 389 <input type="hidden" name="SubtitleFontSize" value="@subtitleFontSize"> 390 } 391 @if (buttonStyle != "") 392 { 393 <input type="hidden" name="ButtonStyle" value="@buttonStyle"> 394 } 395 @if (generalTheme != "") 396 { 397 <input type="hidden" name="GeneralTheme" value="@generalTheme"> 398 } 399 @if (theme != "") 400 { 401 <input type="hidden" name="Theme" value="@theme"> 402 } 403 @if (imageTheme != "") 404 { 405 <input type="hidden" name="ImageTheme" value="@imageTheme"> 406 } 407 @if (!string.IsNullOrEmpty(Model.Item.GetString("ContentPadding"))) 408 { 409 string contentPadding = Model.Item.GetRawValueString("ContentPadding"); 410 <input type="hidden" name="ContentPadding" value="@contentPadding"> 411 } 412 <input type="hidden" name="TextReadability" value="@maxWidth"> 413 <input type="hidden" name="ParentColumnSize" id="ParentColumnSize_@Model.ID" value="12"> 414 415 @*--- PLUS BADGES ---*@ 416 @{ 417 var count = 0; 418 foreach (var badge in bagdeItems) 419 { 420 count++; 421 <input type="hidden" name="Plusbadge-title_@count" value="@badge.GetString("Title")"> 422 <input type="hidden" name="Plusbadge-image_@count" value="@badge.GetString("Image")"> 423 } 424 } 425 <input type="hidden" name="Plusbadge-totalCount" value="@count"> 426 427 <input type="hidden" name="SaleBadgeType" value="@Model.Item.GetRawValue("SaleBadgeType")"> 428 <input type="hidden" name="SaleBadgeCssClassName" value="@Model.Item.GetRawValue("SaleBadgeDesign")"> 429 <input type="hidden" name="NewBadgeCssClassName" value="@Model.Item.GetRawValue("NewBadgeDesign")"> 430 <input type="hidden" name="NewPublicationDays" value="@Model.Item.GetInt32("NewPublicationDays")"> 431 432 @if (campaignValues != "") 433 { 434 <input type="hidden" name="CampaignBadgesValues" value="@campaignValues"> 435 } 436 </form> 437 438 <script type="module" src="~/Files/Templates/Designs/Swift/Assets/js/swiffy-slider.js"></script> 439 <script type="module"> 440 swift.AssetLoader.Load('/Files/Templates/Designs/Swift/Assets/css/swiffy-slider.min.css', 'css'); 441 </script> 442 443 if (Pageview.IsVisualEditorMode) 444 { 445 <div class="alert alert-info" role="alert"> 446 <span>@Translate("Product slider: Edit this column to configure")</span> 447 </div> 448 } 449 450 if (sourceType != "related-products") 451 { 452 if (productIds != product.Id) 453 { 454 <div class="w-100 h-100"> 455 <div id="RelatedProducts_@Model.ID" class="h-100 swift_product_slider_container"></div> 456 </div> 457 } 458 } 459 if (sourceType != "selected-group") 460 { 461 <div class="w-100 h-100"> 462 <div id="RelatedProducts_@Model.ID" class="g-col-12 h-100 swift_product_slider_container"></div> 463 </div> 464 } 465 else if (product?.RelatedGroups != null) 466 { 467 @* Create multiple slider containers, if type is Product relation *@ 468 @* Sorting product related groups so Addon *@ 469 product.RelatedGroups.Sort((u1, u2) => u1.Id.CompareTo(u2.Id)); 470 471 <div class="grid w-100 h-100@(generalTheme)" style="grid-row-gap: 4rem"> 472 @foreach (var group in product.RelatedGroups) 473 { 474 <div id="RelatedProducts_@(Model.ID)_@group.Id" class="g-col-12 h-100 swift_product_slider_container"></div> 475 } 476 </div> 477 } 478 479 @* Initialize *@ 480 if (sourceType != "related-products") 481 { 482 <script type="module"> 483 if (document.querySelector("#RelatedProducts_@Model.ID").closest("[data-col-size]")) { 484 document.querySelector("#ParentColumnSize_@Model.ID").value = document.querySelector("#RelatedProducts_@Model.ID").closest("[data-col-size]").getAttribute("data-col-size"); 485 } 486 swift.PageUpdater.Update(document.querySelector("#RelatedProductsForm_@Model.ID")).then(function () { 487 setTimeout(function() { 488 const isVisualEditor = @(Converter.ToString(Pageview.IsVisualEditorMode).ToLowerInvariant()); 489 const productSliderContainer = document.querySelector(".swift_product_slider_container"); 490 491 if (productSliderContainer && productSliderContainer.innerHTML !== "") { 492 productSliderContainer.classList.remove("d-none"); 493 } 494 else if (!isVisualEditor) { 495 productSliderContainer.closest("[class*=column]").classList.add("d-none"); 496 } 497 }, 150); 498 }); 499 </script> 500 } 501 else if (product?.RelatedGroups != null) 502 { 503 @* Create multiple sliders, if type is Product relation *@ 504 foreach (var group in product.RelatedGroups) 505 { 506 IList<string> fromProductIds = new List<string> { }; 507 508 foreach (var relatedProduct in group.Products) 509 { 510 fromProductIds.Add(relatedProduct.ProductId); 511 } 512 <script type="module"> 513 document.querySelector("#ParentColumnSize_@Model.ID").value = document.querySelector("#RelatedProducts_@(Model.ID)_@group.Id").closest("[data-col-size]").getAttribute("data-col-size"); 514 document.querySelector("#MainProductID_@Model.ID").value = "@string.Join(",", fromProductIds)"; 515 document.querySelector("#RelatedProductsTitle_@Model.ID").value = "@group.Name"; 516 document.querySelector("#SliderCollectionID_@Model.ID").value = "@group.Id"; 517 document.querySelector("#RelatedProductsForm_@Model.ID").setAttribute("data-response-target-element", "RelatedProducts_@(Model.ID)_@group.Id"); 518 519 swift.PageUpdater.Update(document.querySelector("#RelatedProductsForm_@Model.ID")); 520 </script> 521 } 522 } 523 } 524