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

System.NullReferenceException: Objektreferencen er ikke indstillet til en forekomst af et objekt.
   ved Dynamicweb.Ecommerce.ProductCatalog.ProductCatalogFrontend.RenderProduct(String productId, String variantId, String groupId, ProductCatalogSettings settings)
   ved Dynamicweb.Ecommerce.ProductCatalog.ProductCatalogFrontend.GetContent()
   ved Dynamicweb.Frontend.Content.GetModuleOutput(Paragraph paragraph, PageView pageview)

Error executing template "Designs/Swift/Paragraph/Swift_ProductStock.cshtml"
System.NullReferenceException: Objektreferencen er ikke indstillet til en forekomst af et objekt.
   ved CompiledRazorTemplates.Dynamic.RazorEngine_05caf394585043689f403e4b5c93e606.Execute() i C:\inetpub\wwwroot\plus-prod\Files\Templates\Designs\Swift\Paragraph\Swift_ProductStock.cshtml:linje 41
   ved RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   ved RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   ved RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   ved RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   ved Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   ved Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   ved 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 @if (product.StockLevel > 0) 100 { 101 if (!Model.Item.GetBoolean("HideInventory")) 102 { 103 @*<div class="text-success">@product.StockLevel @Translate("In stock")</div>*@ 104 <div class="text-success">@Translate("In stock")</div> 105 106 } 107 else 108 { 109 <div class="text-success">@Translate("In stock")</div> 110 } 111 } 112 else 113 { 114 <div class="text-danger">@Translate("Out of Stock")</div> 115 116 if (hasExpectedDelivery || hasBackInstockDate) 117 { 118 <div> 119 <span>@Translate("Expected in stock"): </span> 120 <span>@expectedDeliveryDate</span> 121 </div> 122 } 123 } 124 </div> 125 } 126 } else if (Pageview.IsVisualEditorMode) { 127 <div class="alert alert-info">@Translate("No products available")</div> 128 } 129 } 130
Error executing template "Designs/Swift/Paragraph/Swift_ProductCertificates_EA.cshtml"
System.NullReferenceException: Objektreferencen er ikke indstillet til en forekomst af et objekt.
   ved CompiledRazorTemplates.Dynamic.RazorEngine_b9209e6972914a9f85146d6e0f546182.Execute() i C:\inetpub\wwwroot\plus-prod\Files\Templates\Designs\Swift\Paragraph\Swift_ProductCertificates_EA.cshtml:linje 43
   ved RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   ved RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   ved RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   ved RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   ved Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   ved Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   ved 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_ProductAddToCart.cshtml"
System.NullReferenceException: Objektreferencen er ikke indstillet til en forekomst af et objekt.
   ved Dynamicweb.Ecommerce.Products.ProductService.GetProductFieldValue(Product product, String productFieldSystemName)
   ved Plus.CustomModules.Helpers.ShippingBasedOnProductSetting.GetShippingId(String eComCountryCode, Product productToShow)
   ved CompiledRazorTemplates.Dynamic.RazorEngine_d0fd5a9b1e4b4a5abc5f2d77392ed07e.Execute() i C:\inetpub\wwwroot\plus-prod\Files\Templates\Designs\Swift\Paragraph\Swift_ProductAddToCart.cshtml:linje 86
   ved RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   ved RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   ved RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   ved RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   ved Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   ved Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   ved 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 97 } 98 99 @if (!hideAddToCart && product.Id != null && product.StockLevel > 0 && !product.Discontinued) 100 { 101 string iconPath = "/Files/icons/"; 102 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService")); 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 bool relatedExist = false; 459 foreach (var relatedGroup in product.RelatedGroups) 460 { 461 if (relatedGroup.Id == "Addon") 462 { 463 if (relatedGroup.Products.Count > 0) 464 { 465 relatedExist = true; 466 } 467 } 468 } 469 470 } 471 <script type="module" src="/Files/Templates/Designs/Swift/Assets/js/swiffy-slider.js"></script> 472 <script type="module"> 473 swift.AssetLoader.Load('/Files/Templates/Designs/Swift/Assets/css/swiffy-slider.min.css', 'css'); 474 </script> 475 <div class="modal-dialog theme plus-primary modal-xl"> 476 <div class="modal-content rounded-0"> 477 <div class="modal-header w-100 text-center"> 478 <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> 479 <button type="button" class="btn-close position-absolute m-0 end-0 me-3" data-bs-dismiss="modal" aria-label="Close"></button> 480 </div> 481 <div id="p_cartNotificationModalBody" class="modal-body"> 482 <div class="container-fluid"> 483 <div class="row"> 484 <div class="col-12 col-md-6 col-lg-3 m-auto me-lg-0 @(imageTheme)" style="@imageOutlineStyle"> 485 <div class="@(ratioCssClass) position-relative" style="@ratioVariable"> 486 @if (showBadges) 487 { 488 <div class="position-absolute top-0 left-0 p-1 p-lg-2" style="z-index: 2"> 489 @{ 490 @RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms) 491 } 492 </div> 493 } 494 <img loading="lazy" decoding="async" src="@imagePath" class="h-100 w-100 @(imageThemePadding)" style="object-fit: contain;" alt="@product.Name" id="p_cartNotificationModalProduct_Image"> 495 </div> 496 </div> 497 <div class="col-12 col-md-6 col-lg-4 m-auto ms-lg-0 d-flex align-content-between flex-wrap"> 498 <div class="col-12 ms-auto fc-dark efa-mod"><strong id="p_cartNotificationModalProduct_Name"></strong></div> 499 <div class="col-12 ms-auto"> 500 <div class="col-12 ms-auto fs-5 fw-bold fc-dark efa-mod" id="p_cartNotificationModalProduct_Price"></div> 501 502 <div class="fs-8 fc-grey efa-mod text-start"> 503 <p class="" id="p_cartNotificationModalProduct_DeliveryCost">@deliveryCost</p> 504 </div> 505 <div class="fs-8 fc-grey efa-mod text-start"> 506 <p class="" id="p_cartNotificationModalProduct_DeliveryName">@deliveryName</p> 507 </div> 508 509 <div class="col-12 d-flex flex-wrap mb-3 ms-auto" id="p_cartNotificationModalProduct_Quantity"></div> 510 <div class="col-12 d-flex mb-2"> 511 <a id="p_cartNotificationModalProduct_Button" class="btn btn-primary flex-fill" href="">@Translate("Gå til indkøbslisten", "Gå til indkøbslisten")</a> 512 </div> 513 <div class="col-12 d-flex"> 514 <div class="btn btn-secondary col-12" data-bs-dismiss="modal">@Translate("Continue shopping")</div> 515 </div> 516 </div> 517 </div> 518 </div> 519 </div> 520 </div> 521 522 @if (relatedExist) 523 { 524 <div class="modal-footer d-none d-md-block d-lg-block d-xl-block" id="p_cartNotificationModal_Related"> 525 <div class="modal-title w-100 text-center"> 526 <h3>@Translate("Add-on products", "Tilbehør")</h3> 527 </div> 528 <div class="container-fluid"> 529 <div class="row"> 530 <div class="col-12 m-auto"> 531 <div id="slider_@(modelId)" class="swiffy-slider slider-item-show@(itemsShown) slider-nav-visible" style="--swiffy-slider-nav-light:var(--swift-foreground-color); --swiffy-slider-nav-dark:var(--swift-background-color); @(scrollBarForceMobile)"> 532 <ul class="slider-container"> 533 @{ 534 foreach (RelatedGroupViewModel relatedGroup in product.RelatedGroups.Where(x => x.Id == "Addon")) 535 { 536 foreach (ProductInfoViewModel relatedProduct in relatedGroup.Products) 537 { 538 <li> 539 @RenderProduct(relatedProduct) 540 </li> 541 } 542 } 543 } 544 545 </ul> 546 <button type="button" title="@Translate("Previous slide")" class="slider-nav" style="z-index: 2;"> 547 <span class="visually-hidden">@Translate("Previous slide")</span> 548 </button> 549 <button type="button" title="@Translate("Next slide")" class="slider-nav slider-nav-next" style="z-index: 2;"> 550 <span class="visually-hidden">@Translate("Next slide")</span> 551 </button> 552 553 </div> 554 <script type="module"> 555 swiffyslider.initSlider(document.querySelector('#slider_@(modelId)')); 556 </script> 557 </div> 558 </div> 559 </div> 560 </div> 561 } 562 </div> 563 </div> 564 </div> 565 566 @helper RenderProduct(ProductInfoViewModel relatedProduct) 567 { 568 var relProduct = relatedProduct.GetProduct(); 569 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 570 bool anonymousUser = Pageview.User == null; 571 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); 572 bool showFavoritesSelectorMasterProduct = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ShowFavoritesSelectorMasterProduct")) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.Form.Get("ShowFavoritesSelectorMasterProduct")) : false; 573 574 string ratio = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ImageAspectRatio")) ? Dynamicweb.Context.Current.Request.Form.Get("ImageAspectRatio") : ""; 575 string ratioCssClass = ratio != "" ? "ratio" : ""; 576 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio : ""; 577 578 string theme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("Theme")) ? Dynamicweb.Context.Current.Request.Form.Get("Theme") : ""; 579 string themePadding = theme != string.Empty ? "p-3" : string.Empty; 580 string imageTheme = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ImageTheme")) ? Dynamicweb.Context.Current.Request.Form.Get("ImageTheme") : ""; 581 string imageOutlineStyle = imageTheme == string.Empty ? "border: 1px solid transparent;" : string.Empty; 582 string imageThemePadding = imageTheme != string.Empty ? "p-3" : string.Empty; 583 string ContentPadding = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("ContentPadding")) ? Dynamicweb.Context.Current.Request.Form.Get("ContentPadding") : ""; 584 585 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 586 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 587 588 string variantIdForLink = !string.IsNullOrEmpty(relProduct.VariantId) ? $"&VariantID={relProduct.VariantId}" : ""; 589 variantIdForLink = string.IsNullOrEmpty(variantIdForLink) && !string.IsNullOrEmpty(relProduct.DefaultVariantId) ? $"&VariantID={relProduct.DefaultVariantId}" : variantIdForLink; 590 591 string link = "Default.aspx?ID=" + GetPageIdByNavigationTag("Shop"); 592 link += $"&GroupID={relProduct.PrimaryOrDefaultGroup.Id}"; 593 link += $"&ProductID={relProduct.Id}"; 594 link += variantIdForLink; 595 link = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(link); 596 597 string imagePath = relProduct?.DefaultImage.Value.ToString() ?? ""; 598 imagePath = "/Admin/Public/GetImage.ashx?image=" + imagePath + "&width=" + 350 + "&Format=WebP&Quality=70"; 599 600 string saleBadgeType = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeType") : ""; 601 string saleBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("SaleBadgeCssClassName") : ""; 602 string newBadgeCssClassName = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName")) ? Dynamicweb.Context.Current.Request.Form.Get("NewBadgeCssClassName") : ""; 603 int newPublicationDays = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) ? Convert.ToInt32(Dynamicweb.Context.Current.Request.Form.Get("NewPublicationDays")) : 0; 604 string campaignBadgesValues = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues")) ? Dynamicweb.Context.Current.Request.Form.Get("CampaignBadgesValues") : ""; 605 606 var badgeParms = new Dictionary<string, object>(); 607 badgeParms.Add("saleBadgeType", saleBadgeType); 608 badgeParms.Add("saleBadgeCssClassName", saleBadgeCssClassName); 609 badgeParms.Add("newBadgeCssClassName", newBadgeCssClassName); 610 badgeParms.Add("campaignBadgesValues", campaignBadgesValues); 611 badgeParms.Add("newPublicationDays", newPublicationDays); 612 613 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(saleBadgeCssClassName) && saleBadgeCssClassName != "none" ? true : false; 614 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(newBadgeCssClassName) && newBadgeCssClassName != "none" ? true : false; 615 DateTime createdDate = relProduct.Created.Value; 616 bool showBadges = saleBadgeEnabled && relProduct.Discount.Price != 0 ? true : false; 617 showBadges = (newBadgeEnabled && newPublicationDays == 0) || (newBadgeEnabled && (createdDate.AddDays(newPublicationDays) > DateTime.Now)) ? true : showBadges; 618 showBadges = !string.IsNullOrEmpty(campaignBadgesValues) ? true : showBadges; 619 620 string disableAddToCart = (relProduct.StockLevel <= 0) ? "disabled" : ""; 621 bool isNeverOutOfStock = relProduct.NeverOutOfstock; 622 disableAddToCart = isNeverOutOfStock ? "" : disableAddToCart; 623 624 string iconPath = "/Files/icons/"; 625 string addToCartIcon = Model.Item.GetRawValueString("Icon", iconPath + "shopping-cart.svg"); 626 string addToCartLabel = !addToCartIcon.Contains("_none") ? "<span class=\"icon-2\">" + ReadFile(addToCartIcon) + "</span>" : ""; 627 addToCartLabel += !addToCartIcon.Contains("_none") && !Model.Item.GetBoolean("HideButtonText") ? " " : ""; 628 addToCartLabel += !Model.Item.GetBoolean("HideButtonText") ? Translate("Add to cart") : ""; 629 string flexFill = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "flex-fill" : ""; 630 string buttonSize = Model.Item.GetRawValueString("ButtonSize", "regular"); 631 string inputSize = string.Empty; 632 633 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("EasyFlowCart")); 634 if (!url.Contains("LayoutTemplate")) 635 { 636 url += url.Contains("?") ? "&LayoutTemplate=Swift_MiniCart.cshtml" : "?LayoutTemplate=Swift_MiniCart.cshtml"; 637 } 638 string cartUrl = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("EasyFlowCart")); 639 string imagePathHidden = relProduct?.DefaultImage.Value.ToString() ?? ""; 640 imagePathHidden = "/Admin/Public/GetImage.ashx?image=" + imagePathHidden + "&width=" + 350 + "&Format=WebP&Quality=70"; 641 642 switch (buttonSize) 643 { 644 case "small": 645 inputSize = " input-group-sm"; 646 buttonSize = " btn-sm"; 647 break; 648 case "regular": 649 buttonSize = string.Empty; 650 break; 651 case "large": 652 inputSize = " input-group-lg"; 653 buttonSize = " btn-lg"; 654 break; 655 } 656 657 string ecomCountryCode = !string.IsNullOrEmpty(Pageview.Area.EcomCountryCode) ? Pageview.Area.EcomCountryCode : ""; 658 var countryVat = Services.Countries.GetCountry(ecomCountryCode).Vat > 0 ? Services.Countries.GetCountry(ecomCountryCode).Vat : 0; 659 var productToShow = Services.Products.GetProductById(relProduct.Id, relProduct.VariantId, relProduct.LanguageId); 660 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 661 string shipId = ecomCountryCode.IsNotNullOrEmpty() ? ShippingBasedOnProductSetting.GetShippingId(ecomCountryCode, productToShow) : ""; 662 var shippingFeeAmount = string.Empty; 663 664 if (!string.IsNullOrEmpty(ecomCountryCode) && shipId != null) 665 { 666 shippingFeeAmount = ShippingBasedOnProductSetting.GetShippingAmount(shipId, countryVat, productToShow, currency); 667 } 668 669 var deliveryCost = Translate("Levering fra") + " " + currency + " " + shippingFeeAmount; 670 var deliveryName = ShippingBasedOnProductSetting.GetShippingName(shipId, relProduct.LanguageId); 671 672 673 <div class="text-decoration-none d-block h-100"> 674 <div class="h-100 d-flex flex-column justify-content-between@(theme)"> 675 @{ 676 FieldValueViewModel plusDesignerModalIndikator; 677 relProduct.ProductFields.TryGetValue("PlusDesignerLinkEA", out plusDesignerModalIndikator); 678 string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") ? "target=\"_blank\"" : string.Empty; 679 string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") ? "rel=\"noopener\"" : string.Empty; 680 681 if (!string.IsNullOrEmpty(plusDesignerModalIndikator.Value.ToString())) 682 { 683 <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; "> 684 <object> 685 <a href="@plusDesignerModalIndikator.Value" @target @rel class="text-decoration-none"> 686 <div class="plus-designer__inner p-1 ps-3"> 687 <p class="m-0 opacity-75 fs-7">Try me in</p> 688 <div class="plus-designer__image-container d-flex w-100"> 689 <img class="" src="/Files/Templates/Designs/Swift/Assets/Images/plusdesignerlogo.svg" alt="Alternate Text" style="width:90%" /> 690 <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> 691 </div> 692 </div> 693 </a> 694 </object> 695 </div> 696 697 } 698 699 } 700 <div class="@(imageTheme)" style="@imageOutlineStyle"> 701 <div class="@(ratioCssClass) position-relative m-auto mw200 efa-mod" style="@ratioVariable"> 702 @if (showBadges) 703 { 704 <div class="position-absolute top-0 left-0 p-1 p-lg-2" style="z-index: 2"> 705 @{ 706 @RenderPartial("Components/EcommerceBadge.cshtml", relProduct, badgeParms) 707 } 708 </div> 709 } 710 <img loading="lazy" decoding="async" src="@imagePath" class="h-100 w-100 @(imageThemePadding)" style="object-fit: contain;" alt="@relProduct.Name"> 711 </div> 712 </div> 713 <div class="flex-fill p-3 pb-0 d-flex flex-column justify-content-between @themePadding"> 714 <h3 class="h6 opacity-85">@relProduct.Name @relProduct.VariantName</h3> 715 716 @if (!hidePrice) 717 { 718 <div> 719 <p class="h6 m-0"> 720 @if (showPricesWithVat == "false" && !neverShowVat) 721 { 722 if (relProduct.Price.Price != relProduct.PriceBeforeDiscount.Price) 723 { 724 <span class="text-decoration-line-through opacity-75 me-1"> 725 @relProduct.PriceBeforeDiscount.PriceWithoutVatFormatted 726 </span> 727 } 728 } 729 else 730 { 731 if (relProduct.Price.Price != relProduct.PriceBeforeDiscount.Price) 732 { 733 <span class="text-decoration-line-through opacity-75 me-1"> 734 @relProduct.PriceBeforeDiscount.PriceFormatted 735 </span> 736 } 737 } 738 739 @if (showPricesWithVat == "false" && !neverShowVat) 740 { 741 <span class="text-price fw-bold">@relProduct.Price.PriceWithoutVatFormatted</span> 742 } 743 else 744 { 745 <span class="text-price fw-bold">@relProduct.Price.PriceFormatted</span> 746 } 747 </p> 748 749 <div class="fs-8 text-black-50 text-start"> 750 <p>@Translate("Levering fra") @currency @shippingFeeAmount</p> 751 </div> 752 @if (showPricesWithVat == "false" && !neverShowVat) 753 { 754 <small class="opacity-85 fst-normal">@relProduct.Price.PriceWithVatFormatted @Translate("Incl. VAT")</small> 755 } 756 757 </div> 758 } 759 </div> 760 <div class="d-flex gap-4 p-3 pt-0"> 761 @{ 762 string stepQty = relProduct.PurchaseQuantityStep > 1 ? relProduct.PurchaseQuantityStep.ToString() : "1"; 763 string valueQty = relProduct.PurchaseMinimumQuantity > relProduct.PurchaseQuantityStep ? relProduct.PurchaseMinimumQuantity.ToString() : stepQty; 764 } 765 <form method="post" action="@url"> 766 <input type="hidden" name="redirect" value="false"> 767 <input type="hidden" name="ProductId" value="@relProduct.Id"> 768 <input type="hidden" name="ProductName" value="@relProduct.Name"> 769 <input type="hidden" name="ProductCurrency" value="@Dynamicweb.Ecommerce.Common.Context.Currency.Code"> 770 <input type="hidden" name="ProductReferer" value="product_list_listview"> 771 <input type="hidden" name="ProductPrice" value="@relProduct.Price.PriceFormatted"> 772 <input type="hidden" name="cartcmd" value="add"> 773 @* #38 EA: sbj *@ 774 <input type="hidden" name="ProductPriceFormatted" value="@relProduct.Price.PriceFormatted"> 775 <input type="hidden" name="ProductUnit" value="@Translate("stk.", "stk.")"> 776 <input type="hidden" name="ProductTotalText" value="@Translate("I alt", "I alt")"> 777 <input type="hidden" name="ProductDeliveryCost" value="@deliveryCost"> 778 <input type="hidden" name="ProductDeliveryName" value="@deliveryName"> 779 <input type="hidden" name="ProductImage" value="@imagePathHidden"> 780 <input type="hidden" name="cartpage" value="@cartUrl"> 781 <input id="Quantity_@(relProduct.Id)_@relProduct.VariantId" name="Quantity" value="@valueQty" type="hidden" @disableAddToCart> 782 <div class="d-flex gap-3 p-3 pt-0"> 783 <a href="@link" class="btn btn-secondary flex-fill">@Translate("View more")</a> 784 <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"> 785 @if (!Model.Item.GetBoolean("HideButtonText")) 786 { 787 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 788 @addToCartLabel 789 </span> 790 } 791 else 792 { 793 @addToCartLabel 794 } 795 </a> 796 </div> 797 </form> 798 </div> 799 800 </div> 801 802 </div> 803 804 } 805 806 <script type="text/javascript"> 807 document.addEventListener("update.swift.cart", function (event) { 808 var e = event; 809 var button = "addToCart"; 810 var target = e.detail.parentEvent.target; 811 while (!target.classList.contains(button)) { 812 target = target.parentElement; 813 } 814 var cartNotificationProduct = document.querySelector("#p_cartNotificationModalProduct"); 815 var modalProduct = new bootstrap.Modal(cartNotificationProduct); 816 if (target.getAttribute("data-container") == "product") { 817 //var modalProduct = new bootstrap.Modal(cartNotificationProduct); 818 var data = Object.fromEntries(event.detail.formData.entries()); 819 var price = data.ProductPrice; 820 if (price.includes(",")) { 821 price = price.replace(/,/g, "."); 822 price = parseFloat(price).toFixed(2); 823 } 824 825 var quantity = data.Quantity; 826 var detailsPrice = data.ProductPrice; 827 var totalprice = data.ProductPrice.includes(",") ? data.ProductPrice : detailsPrice.concat("", ",00");; 828 if (quantity > 1) { 829 var total = price * quantity; 830 var totalpriceCalc = parseFloat(total).toFixed(2); 831 totalpriceCalc = totalpriceCalc.toString(); 832 if (totalpriceCalc.includes(".")) { 833 totalprice = totalpriceCalc.replace(".", ","); 834 } 835 else { 836 totalprice = totalpriceCalc.concat("", ",00"); 837 } 838 } else { 839 840 } 841 842 var details = data.ProductPrice.includes(",") ? data.ProductPrice : detailsPrice.concat("", ",00"); 843 document.querySelector("#p_cartNotificationModalProduct_Button").href = data.cartpage; 844 document.querySelector("#p_cartNotificationModalProduct_Quantity").innerHTML = data.Quantity + " " + data.ProductUnit; 845 document.querySelector("#p_cartNotificationModalProduct_Name").innerHTML = data.ProductName; 846 document.querySelector("#p_cartNotificationModalProduct_Price").innerHTML = data.ProductCurrency + " " + details; 847 document.querySelector("#p_cartNotificationModalProduct_DeliveryCost").innerHTML = data.ProductDeliveryCost; 848 document.querySelector("#p_cartNotificationModalProduct_DeliveryName").innerHTML = data.ProductDeliveryName; 849 document.querySelector("#p_cartNotificationModalProduct_Image").src = data.ProductImage; 850 document.querySelector("#p_cartNotificationModalProduct_Image").alt = data.ProductName; 851 if (document.querySelector("#p_cartNotificationModal_Related")) { 852 if (!document.querySelector("#p_cartNotificationModal_Related").classList.contains('d-md-block', 'd-lg-block', 'd-xl-block')) { 853 document.querySelector("#p_cartNotificationModal_Related").classList.add('d-md-block', 'd-lg-block', 'd-xl-block'); 854 } 855 } 856 modalProduct.show(); 857 } 858 if (target.getAttribute("data-container") == "productRel") { 859 modalProduct.toggle(); 860 //var cartNotificationProduct = document.querySelector("#p_cartNotificationModalProduct"); 861 var data = Object.fromEntries(event.detail.formData.entries()); 862 //var modalProduct = new bootstrap.Modal(cartNotificationProduct); 863 var price = data.ProductPrice; 864 if (price.includes(",")) { 865 price = price.replace(/,/g, "."); 866 price = parseFloat(price).toFixed(2); 867 } 868 869 var quantity = data.Quantity; 870 var detailsPrice = data.ProductPrice; 871 var totalprice = data.ProductPrice.includes(",") ? data.ProductPrice : detailsPrice.concat("", ",00");; 872 if (quantity > 1) { 873 var total = price * quantity; 874 var totalpriceCalc = parseFloat(total).toFixed(2); 875 totalpriceCalc = totalpriceCalc.toString(); 876 if (totalpriceCalc.includes(".")) { 877 totalprice = totalpriceCalc.replace(".", ","); 878 } 879 else { 880 totalprice = totalpriceCalc.concat("", ",00"); 881 } 882 } else { 883 884 } 885 886 var details = data.ProductPrice.includes(",") ? data.ProductPrice : detailsPrice.concat("", ",00"); 887 document.querySelector("#p_cartNotificationModalProduct_Button").href = data.cartpage; 888 document.querySelector("#p_cartNotificationModalProduct_Quantity").innerHTML = data.Quantity + " " + data.ProductUnit; 889 document.querySelector("#p_cartNotificationModalProduct_Name").innerHTML = data.ProductName; 890 document.querySelector("#p_cartNotificationModalProduct_Price").innerHTML = data.ProductCurrency + " " + details; 891 document.querySelector("#p_cartNotificationModalProduct_DeliveryCost").innerHTML = data.ProductDeliveryCost; 892 document.querySelector("#p_cartNotificationModalProduct_DeliveryName").innerHTML = data.ProductDeliveryName; 893 document.querySelector("#p_cartNotificationModalProduct_Image").src = data.ProductImage; 894 document.querySelector("#p_cartNotificationModalProduct_Image").alt = data.ProductName; 895 document.querySelector("#p_cartNotificationModal_Related").classList.remove('d-md-block', 'd-lg-block', 'd-xl-block'); 896 modalProduct.show(); 897 } 898 var data = Object.fromEntries(event.detail.formData.entries()); 899 dataLayer.push({ ecommerce: null }); // Clear the previous ecommerce object. 900 dataLayer.push({ 901 event: "add_to_cart", 902 ecommerce: { 903 currency: data.ProductCurrency, 904 value: data.ProductPrice, 905 items: [ 906 { 907 item_id: data.ProductId, 908 item_name: data.ProductName, 909 affiliation: "Plus.dk", 910 coupon: "", 911 discount: "", 912 index: 0, 913 item_brand: "PLUS", 914 item_category: "", 915 item_category2: "", 916 item_category3: "", 917 item_category4: "", 918 item_category5: "", 919 item_list_id: data.item_list_name, 920 item_list_name: "", 921 item_variant: data.item_variant, 922 location_id: "", 923 price: data.ProductPrice, 924 quantity: data.Quantity 925 } 926 ] 927 } 928 }); 929 }); 930 </script> 931 @* #38 EA: end *@ 932
Error executing template "Designs/Swift/Paragraph/Swift_RelatedProducts_EA.cshtml"
System.NullReferenceException: Objektreferencen er ikke indstillet til en forekomst af et objekt.
   ved CompiledRazorTemplates.Dynamic.RazorEngine_b0d03cea61954c1ca3f58a1f4a5c7cc6.Execute() i C:\inetpub\wwwroot\plus-prod\Files\Templates\Designs\Swift\Paragraph\Swift_RelatedProducts_EA.cshtml:linje 212
   ved RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   ved RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   ved RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   ved RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   ved Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   ved Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   ved 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 <div class="w-100 h-100"> 453 <div id="RelatedProducts_@Model.ID" class="h-100 swift_product_slider_container"></div> 454 </div> 455 } 456 if (sourceType != "selected-group") 457 { 458 <div class="w-100 h-100"> 459 <div id="RelatedProducts_@Model.ID" class="g-col-12 h-100 swift_product_slider_container"></div> 460 </div> 461 } 462 else if (product?.RelatedGroups != null) 463 { 464 @* Create multiple slider containers, if type is Product relation *@ 465 @* Sorting product related groups so Addon *@ 466 product.RelatedGroups.Sort((u1, u2) => u1.Id.CompareTo(u2.Id)); 467 468 <div class="grid w-100 h-100@(generalTheme)" style="grid-row-gap: 4rem"> 469 @foreach (var group in product.RelatedGroups) 470 { 471 <div id="RelatedProducts_@(Model.ID)_@group.Id" class="g-col-12 h-100 swift_product_slider_container"></div> 472 } 473 </div> 474 } 475 476 @* Initialize *@ 477 if (sourceType != "related-products") 478 { 479 <script type="module"> 480 if (document.querySelector("#RelatedProducts_@Model.ID").closest("[data-col-size]")) { 481 document.querySelector("#ParentColumnSize_@Model.ID").value = document.querySelector("#RelatedProducts_@Model.ID").closest("[data-col-size]").getAttribute("data-col-size"); 482 } 483 swift.PageUpdater.Update(document.querySelector("#RelatedProductsForm_@Model.ID")).then(function () { 484 setTimeout(function() { 485 const isVisualEditor = @(Converter.ToString(Pageview.IsVisualEditorMode).ToLowerInvariant()); 486 const productSliderContainer = document.querySelector(".swift_product_slider_container"); 487 488 if (productSliderContainer && productSliderContainer.innerHTML !== "") { 489 productSliderContainer.classList.remove("d-none"); 490 } 491 else if (!isVisualEditor) { 492 productSliderContainer.closest("[class*=column]").classList.add("d-none"); 493 } 494 }, 150); 495 }); 496 </script> 497 } 498 else if (product?.RelatedGroups != null) 499 { 500 @* Create multiple sliders, if type is Product relation *@ 501 foreach (var group in product.RelatedGroups) 502 { 503 IList<string> fromProductIds = new List<string> { }; 504 505 foreach (var relatedProduct in group.Products) 506 { 507 fromProductIds.Add(relatedProduct.ProductId); 508 } 509 <script type="module"> 510 document.querySelector("#ParentColumnSize_@Model.ID").value = document.querySelector("#RelatedProducts_@(Model.ID)_@group.Id").closest("[data-col-size]").getAttribute("data-col-size"); 511 document.querySelector("#MainProductID_@Model.ID").value = "@string.Join(",", fromProductIds)"; 512 document.querySelector("#RelatedProductsTitle_@Model.ID").value = "@group.Name"; 513 document.querySelector("#SliderCollectionID_@Model.ID").value = "@group.Id"; 514 document.querySelector("#RelatedProductsForm_@Model.ID").setAttribute("data-response-target-element", "RelatedProducts_@(Model.ID)_@group.Id"); 515 516 swift.PageUpdater.Update(document.querySelector("#RelatedProductsForm_@Model.ID")); 517 </script> 518 } 519 } 520 } 521
Error executing template "Designs/Swift/Paragraph/Swift_RelatedProducts_EA.cshtml"
System.NullReferenceException: Objektreferencen er ikke indstillet til en forekomst af et objekt.
   ved CompiledRazorTemplates.Dynamic.RazorEngine_b0d03cea61954c1ca3f58a1f4a5c7cc6.Execute() i C:\inetpub\wwwroot\plus-prod\Files\Templates\Designs\Swift\Paragraph\Swift_RelatedProducts_EA.cshtml:linje 212
   ved RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   ved RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   ved RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   ved RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   ved Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   ved Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   ved 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 <div class="w-100 h-100"> 453 <div id="RelatedProducts_@Model.ID" class="h-100 swift_product_slider_container"></div> 454 </div> 455 } 456 if (sourceType != "selected-group") 457 { 458 <div class="w-100 h-100"> 459 <div id="RelatedProducts_@Model.ID" class="g-col-12 h-100 swift_product_slider_container"></div> 460 </div> 461 } 462 else if (product?.RelatedGroups != null) 463 { 464 @* Create multiple slider containers, if type is Product relation *@ 465 @* Sorting product related groups so Addon *@ 466 product.RelatedGroups.Sort((u1, u2) => u1.Id.CompareTo(u2.Id)); 467 468 <div class="grid w-100 h-100@(generalTheme)" style="grid-row-gap: 4rem"> 469 @foreach (var group in product.RelatedGroups) 470 { 471 <div id="RelatedProducts_@(Model.ID)_@group.Id" class="g-col-12 h-100 swift_product_slider_container"></div> 472 } 473 </div> 474 } 475 476 @* Initialize *@ 477 if (sourceType != "related-products") 478 { 479 <script type="module"> 480 if (document.querySelector("#RelatedProducts_@Model.ID").closest("[data-col-size]")) { 481 document.querySelector("#ParentColumnSize_@Model.ID").value = document.querySelector("#RelatedProducts_@Model.ID").closest("[data-col-size]").getAttribute("data-col-size"); 482 } 483 swift.PageUpdater.Update(document.querySelector("#RelatedProductsForm_@Model.ID")).then(function () { 484 setTimeout(function() { 485 const isVisualEditor = @(Converter.ToString(Pageview.IsVisualEditorMode).ToLowerInvariant()); 486 const productSliderContainer = document.querySelector(".swift_product_slider_container"); 487 488 if (productSliderContainer && productSliderContainer.innerHTML !== "") { 489 productSliderContainer.classList.remove("d-none"); 490 } 491 else if (!isVisualEditor) { 492 productSliderContainer.closest("[class*=column]").classList.add("d-none"); 493 } 494 }, 150); 495 }); 496 </script> 497 } 498 else if (product?.RelatedGroups != null) 499 { 500 @* Create multiple sliders, if type is Product relation *@ 501 foreach (var group in product.RelatedGroups) 502 { 503 IList<string> fromProductIds = new List<string> { }; 504 505 foreach (var relatedProduct in group.Products) 506 { 507 fromProductIds.Add(relatedProduct.ProductId); 508 } 509 <script type="module"> 510 document.querySelector("#ParentColumnSize_@Model.ID").value = document.querySelector("#RelatedProducts_@(Model.ID)_@group.Id").closest("[data-col-size]").getAttribute("data-col-size"); 511 document.querySelector("#MainProductID_@Model.ID").value = "@string.Join(",", fromProductIds)"; 512 document.querySelector("#RelatedProductsTitle_@Model.ID").value = "@group.Name"; 513 document.querySelector("#SliderCollectionID_@Model.ID").value = "@group.Id"; 514 document.querySelector("#RelatedProductsForm_@Model.ID").setAttribute("data-response-target-element", "RelatedProducts_@(Model.ID)_@group.Id"); 515 516 swift.PageUpdater.Update(document.querySelector("#RelatedProductsForm_@Model.ID")); 517 </script> 518 } 519 } 520 } 521