Error executing template "Designs/Swift/Paragraph/Custom_ProductListGridView.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at CompiledRazorTemplates.Dynamic.RazorEngine_1d2d8781a25e4c72b52f522f3eb6a1fe.<ExecuteAsync>g__RenderProductList|0_0()
at CompiledRazorTemplates.Dynamic.RazorEngine_1d2d8781a25e4c72b52f522f3eb6a1fe.ExecuteAsync()
at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader)
at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.DynamicWrapperService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineServiceExtensions.RunCompile(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
at RazorEngine.Templating.RazorEngineServiceExtensions.RunCompile(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineServiceExtensions.RunCompile(IRazorEngineService service, String templateSource, String name, Type modelType, Object model, DynamicViewBag viewBag)
at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 @using Scantruck.Website.Custom.ViewModels 4 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 5 @using System.Linq 6 @using Dynamicweb.Environment 7 @using Application.Extensions 8 9 @functions 10 { 11 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 12 string liveInfoClass = ""; 13 string productInfoFeed = ""; 14 15 string showPricesWithVat = ""; 16 bool neverShowVat = false; 17 18 bool isDetailPage = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID")); 19 20 ProductListViewModel productList = new ProductListViewModel(); 21 } 22 23 @{ 24 if (Dynamicweb.Context.Current.Items.Contains("ProductList")) 25 { 26 productList = (ProductListViewModel)Dynamicweb.Context.Current.Items["ProductList"]; 27 } 28 29 showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 30 neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 31 32 if (isLazyLoadingForProductInfoEnabled) 33 { 34 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 35 { 36 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 37 if (!string.IsNullOrEmpty(productInfoFeed)) 38 { 39 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 40 } 41 } 42 liveInfoClass = "js-live-info"; 43 } 44 45 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 46 string themePadding = theme != string.Empty ? "p-3" : string.Empty; 47 } 48 49 @if (!isDetailPage) 50 { 51 if (!string.IsNullOrEmpty(theme)) 52 { 53 <div class="h-100@(theme) @themePadding item_@Model.Item.SystemName.ToLower()" @productInfoFeed> 54 @{ 55 RenderProductList(); 56 } 57 </div> 58 } 59 else 60 { 61 <div class="item_@Model.Item.SystemName.ToLower()" @productInfoFeed> 62 @{ 63 RenderProductList(); 64 } 65 </div> 66 } 67 } 68 69 @{ 70 void RenderProductList() 71 { 72 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 73 bool anonymousUser = Pageview.User == null; 74 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 75 76 string productTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ProductTheme")) ? " theme " + Model.Item.GetRawValueString("ProductTheme").Replace(" ", "").Trim().ToLower() : ""; 77 string productThemePadding = productTheme != string.Empty ? "p-3" : string.Empty; 78 79 string url = Dynamicweb.Context.Current.Request.RawUrl; 80 bool hideFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("HideFavoritesSelector")) ? Model.Item.GetBoolean("HideFavoritesSelector") : false; 81 string staticVariantsLayout = Model.Item.GetRawValueString("StaticVariantsLayout", "hide"); 82 83 string groupId = productList?.Group?.Id != null ? productList.Group.Id : ""; 84 85 var badgeParms = new Dictionary<string, object>(); 86 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 87 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 88 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 89 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 90 badgeParms.Add("campaignBadgesValues", Model.Item.GetRawValueString("CampaignBadges")); 91 92 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 93 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 94 95 string googleTagManagerID = Pageview.AreaSettings.GetString("GoogleTagManagerID"); 96 string googleAnalyticsMeasurementID = Pageview.AreaSettings.GetString("GoogleAnalyticsMeasurementID"); 97 var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); 98 bool allowTracking = cookieOptInLevel == CookieOptInLevel.All || (cookieOptInLevel == CookieOptInLevel.Functional && CookieManager.GetCookieOptInCategories().Contains("Statistical")); 99100 var favoriteParameters = new Dictionary<string, object>(); 101 if (!anonymousUser && !hideFavoritesSelector) 102 { 103 int defaultFavoriteListId = 0; 104105 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 106 if (favoreiteLists.Count() == 1) 107 { 108 foreach (FavoriteList list in favoreiteLists) 109 { 110 defaultFavoriteListId = list.ListId; 111 } 112 } 113114 favoriteParameters.Add("ListId", defaultFavoriteListId); 115 } 116117 if (productList.TotalProductsCount > 0) 118 { 119 int pageSizeSetting = 30; 120 int pageSize = productList.PageSize; 121 pageSize += pageSizeSetting; 122123 int loadedProducts = productList.PageSize > productList.TotalProductsCount ? productList.TotalProductsCount : productList.PageSize; 124125 <div class="custom-product-grid grid grid-1 grid-md-2 grid-xl-3"> 126127 @if ((!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) || !string.IsNullOrWhiteSpace(googleTagManagerID)) && allowTracking) 128 { 129 <script> 130 gtag("event", "view_item_list", { 131 item_list_id: "product_list_gridview", 132 item_list_name: "Product list (Gridview)", 133 items: [ 134 @foreach (ProductViewModel product in productList.Products) 135 { 136 <text>{ 137 item_id: "@product.Number", 138 item_name: "@Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(product.Name)", 139 currency: "@product.Price.CurrencyCode", 140 price: @PriceViewModelExtensions.ToStringInvariant(product.Price) 141 },</text> 142 } 143 ] 144 }); 145 </script> 146 } 147148 @foreach (CustomProductViewModel product in productList.Products) 149 { 150 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 151152 string imagePath = product.HasImages ? product.DefaultImage.Value : product.GetCustomDefaultImage(Pageview.AreaID); 153154 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 155 ratio = ratio != "0" ? ratio : ""; 156 string ratioCssClass = ratio != "" ? " ratio" : ""; 157 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio : ""; 158159 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + 480 + "&image=" + imagePath + "&format=webp"; 160 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + 640 + "&image=" + imagePath + "&format=webp"; 161 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + 640 + "&image=" + imagePath + "&format=webp"; 162163 string imageTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : ""; 164 string imageThemePadding = imageTheme != string.Empty ? "p-3" : string.Empty; 165 string imageOutlineStyle = imageTheme == string.Empty ? "style=\"border: 1px solid transparent\"" : string.Empty; 166167 string imageId = "ProductImage_" + product.Id + product.VariantId; 168 string priceId = "ProductPrice_" + product.Id + product.VariantId; 169170 @* Alternative image *@ 171 var supportedImageFormats = new string[] { ".jpg", ".webp", ".png", ".gif" }; 172 string defaultImage = product.DefaultImage != null ? product.DefaultImage.Value : ""; 173 var selectedAssetCategories = Model.Item.GetRawValueString("AlternativeImageAssets"); 174 IEnumerable<MediaViewModel> alternativeImagesList = product.AssetCategories.Where(x => selectedAssetCategories.Contains(x.SystemName)).SelectMany(x => x.Assets); 175176 if (alternativeImagesList.FirstOrDefault() != null) 177 { 178 alternativeImagesList = alternativeImagesList.OrderByDescending(x => x.Value.Equals(defaultImage)); 179180 if (alternativeImagesList.First().Value == defaultImage) 181 { 182 alternativeImagesList = alternativeImagesList.Skip(1); 183 } 184 } 185186 string alternativeImage = alternativeImagesList.FirstOrDefault() != null ? alternativeImagesList.FirstOrDefault().Value : ""; 187 alternativeImage = !string.IsNullOrEmpty(alternativeImage) ? "/Admin/Public/GetImage.ashx?width=" + 640 + "&image=" + alternativeImage + "&format=webp" : ""; 188189 @* Badges *@ 190 DateTime createdDate = product.Created.Value; 191 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 192 showBadges = (newBadgeEnabled && Model.Item.GetInt32("NewPublicationDays") == 0) || (newBadgeEnabled && (createdDate.AddDays(Model.Item.GetInt32("NewPublicationDays")) > DateTime.Now)) ? true : showBadges; 193 showBadges = !string.IsNullOrEmpty(Model.Item.GetRawValueString("CampaignBadges")) ? true : showBadges; 194195 @* Main features *@ 196 IEnumerable<string> selectedDisplayGroups = Model.Item.GetRawValueString("MainFeatures").Split(',').ToList(); 197 List<CategoryFieldViewModel> mainFeatures = new List<CategoryFieldViewModel>(); 198199 foreach (var selection in selectedDisplayGroups) 200 { 201 foreach (CategoryFieldViewModel group in product.FieldDisplayGroups.Values) 202 { 203 if (selection == group.Id) 204 { 205 mainFeatures.Add(group); 206 } 207 } 208 } 209210 <article class="position-relative@(productTheme) product-list-item js-product @liveInfoClass" data-product-id="@product.Id" data-variant-id="@product.VariantId" itemscope itemtype="https://schema.org/Product"> 211 @if (!anonymousUser) 212 { 213 if (!hideFavoritesSelector) 214 { 215 <div class="position-absolute top-0 end-0 my-3" style="z-index: 2"> 216 @RenderPartial("Components/ToggleFavorite.cshtml", product, favoriteParameters) 217 </div> 218 } 219 } 220221 @if (showBadges) 222 { 223 <div class="position-absolute top-0 left-0 p-1 p-lg-2 ps-0 ps-lg-0" style="z-index: 2"> 224 @RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms) 225 </div> 226 } 227228 <div class="d-flex flex-column d-block h-100"> 229 @{ 230 string clickProductLink = string.Empty; 231 if ((!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) || !string.IsNullOrWhiteSpace(googleTagManagerID)) && allowTracking) 232 { 233 clickProductLink = "onclick=\"return clickProductLink('" + @product.Id + "', '" + @Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(product.Name) + "', '" + @Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(product.VariantName) + "', '" + @product.Price.CurrencyCode + "', '" + @PriceViewModelExtensions.ToStringInvariant(product.Price) + "')\""; 234 } 235 } 236 <a href="@link" class="text-decoration-none d-flex flex-column" @clickProductLink> 237 @if ((!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) || !string.IsNullOrWhiteSpace(googleTagManagerID)) && allowTracking) 238 { 239 <script> 240 function clickProductLink(productId, productName, productVariant, productCurrency, productPrice) { 241 if (typeof gtag !== "undefined") { 242 gtag("event", "select_item", { 243 item_list_id: "product_list_gridview", 244 item_list_name: "Product list (Gridview)", 245 items: [ 246 { 247 item_id: productId, 248 item_name: productName, 249 currency: productCurrency, 250 item_list_id: "product_list_gridview", 251 item_list_name: "Product list (Gridview)", 252 item_variant: productVariant, 253 price: productPrice 254 } 255 ] 256 }); 257 } 258 } 259 </script> 260 } 261262 <div class="swiper-slide custom-product-slider__item"> 263 <div class="custom-product-slider__item-iner"> 264 <a href="@link" class="custom-product-slider__item-name"> 265 @product.Name 266 @if (!string.IsNullOrEmpty(product.VariantName)) 267 { 268 <text>(@product.VariantName)</text> 269 } 270 </a> 271 @if (!string.IsNullOrEmpty(imagePathFallBack)) 272 { 273 <a href="@link" class="custom-product-slider__item-media @(!product.HasImages ? "use-image-overlay" : "")"> 274 <picture> 275 <img src="@imagePath" alt="@product.Name"> 276 </picture> 277 <div class="custom-product-slider__item-media-overlay"> 278 </div> 279 @if (!product.HasImages) 280 { 281 <div class="custom-product-slider__item-media-overlay__text"> 282 <svg width="50" height="46" viewBox="0 0 50 46" fill="none" xmlns="http://www.w3.org/2000/svg"> 283 <path d="M7.6375 1.1141C7.47284 0.928488 7.27298 0.777405 7.0495 0.669606C6.82602 0.561807 6.58337 0.499435 6.33561 0.486106C6.08784 0.472777 5.8399 0.508755 5.60615 0.591956C5.37239 0.675157 5.15747 0.803926 4.97385 0.970799C4.79023 1.13767 4.64156 1.33933 4.53644 1.56409C4.43133 1.78884 4.37187 2.03222 4.36151 2.28013C4.35116 2.52803 4.39011 2.77553 4.4761 3.00827C4.5621 3.24101 4.69344 3.45436 4.8625 3.63597L7.12422 6.12504H6.25C4.75816 6.12504 3.32742 6.71767 2.27252 7.77256C1.21763 8.82745 0.625 10.2582 0.625 11.75V38C0.625 39.4919 1.21763 40.9226 2.27252 41.9775C3.32742 43.0324 4.75816 43.625 6.25 43.625H41.2164L42.3625 44.886C42.5272 45.0716 42.727 45.2227 42.9505 45.3305C43.174 45.4383 43.4166 45.5006 43.6644 45.514C43.9122 45.5273 44.1601 45.4913 44.3939 45.4081C44.6276 45.3249 44.8425 45.1961 45.0261 45.0293C45.2098 44.8624 45.3584 44.6607 45.4636 44.436C45.5687 44.2112 45.6281 43.9678 45.6385 43.7199C45.6488 43.472 45.6099 43.2245 45.5239 42.9918C45.4379 42.7591 45.3066 42.5457 45.1375 42.3641L7.6375 1.1141ZM19.7453 20.0071L28.4172 29.5438C27.389 30.1736 26.2057 30.5047 25 30.5C23.7821 30.4999 22.5882 30.1609 21.552 29.5209C20.5158 28.8808 19.6781 27.9651 19.1327 26.876C18.5874 25.787 18.3558 24.5677 18.464 23.3546C18.5722 22.1415 19.0159 20.9824 19.7453 20.0071ZM6.25 39.875C5.75272 39.875 5.27581 39.6775 4.92418 39.3259C4.57254 38.9742 4.375 38.4973 4.375 38V11.75C4.375 11.2528 4.57254 10.7758 4.92418 10.4242C5.27581 10.0726 5.75272 9.87504 6.25 9.87504H10.5344L17.193 17.2016C15.903 18.697 15.0696 20.5313 14.7917 22.4865C14.5138 24.4417 14.8032 26.4356 15.6255 28.2312C16.4477 30.0267 17.7682 31.5484 19.43 32.6154C21.0919 33.6824 23.0251 34.2497 25 34.25C27.1362 34.2454 29.2187 33.5807 30.9625 32.3469L37.8063 39.875H6.25ZM49.375 11.75V36.5938C49.375 37.0911 49.1775 37.568 48.8258 37.9196C48.4742 38.2712 47.9973 38.4688 47.5 38.4688C47.0027 38.4688 46.5258 38.2712 46.1742 37.9196C45.8225 37.568 45.625 37.0911 45.625 36.5938V11.75C45.625 11.2528 45.4275 10.7758 45.0758 10.4242C44.7242 10.0726 44.2473 9.87504 43.75 9.87504H36.25C35.9416 9.87485 35.6381 9.79861 35.3662 9.65307C35.0943 9.50753 34.8626 9.29718 34.6914 9.04066L31.4945 4.25004H18.4937C18.1914 4.62495 17.7564 4.86916 17.2789 4.93203C16.8014 4.9949 16.318 4.87162 15.929 4.58773C15.5399 4.30384 15.275 3.88113 15.1892 3.40721C15.1033 2.9333 15.2032 2.44453 15.468 2.04222L15.9367 1.3391C16.1078 1.08105 16.3401 0.869372 16.6128 0.722961C16.8856 0.57655 17.1904 0.499962 17.5 0.500035H32.5C32.8088 0.499835 33.1128 0.575891 33.3851 0.721449C33.6574 0.867007 33.8896 1.07756 34.0609 1.33441L37.2531 6.12504H43.75C45.2418 6.12504 46.6726 6.71767 47.7275 7.77256C48.7824 8.82745 49.375 10.2582 49.375 11.75Z" fill="white" /> 284 </svg> 285286 <h2>@Translate("Image coming soon")</h2> 287 </div> 288289 } 290 <div class="custom-product-slider__item-tags"> 291292 <div class="custom-product-slider__item-link"> 293 <span class="text">@Translate("Se produkt")</span> 294 <span class="icon"> 295 <svg viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg"> 296 <path d="M0.9875 11.6029L15.5915 11.6029L8.8835 18.3109L10.5875 20.0029L20.1875 10.4029L10.5875 0.802928L8.8955 2.49493L15.5915 9.20293L0.9875 9.20293L0.9875 11.6029Z" fill="currentColor" /> 297 </svg> 298 </span> 299 </div> 300 </div> 301 </a> 302 } 303 @if (product.Price.Price > 0) 304 { 305 <div class="custom-product-slider__item-price"> 306 <span class="custom-product-slider__item-price-text">Ekskl. moms</span> 307 <span class="custom-product-slider__item-price-value"> 308 @product.Price.PriceWithoutVat.ToString("N2") @product.Price.CurrencyCode @*ATTENTION: Shows the Price in whole numbers with commas*@ 309 </span> 310 </div> 311 } 312313314 @if (mainFeatures.Count > 0) 315 { 316317 <div class="custom-product-slider__item-specs"> 318 @foreach (CategoryFieldViewModel mainFeatureGroup in mainFeatures) 319 { 320 foreach (var fieldViewModel in mainFeatureGroup.Fields.Take(5)) 321 { 322 var field = fieldViewModel.Value; 323 string fieldValue = field?.Value is object ? field.Value.ToString() : ""; 324325 if (fieldValue != "") 326 { 327 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; 328 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; 329330 if (!string.IsNullOrEmpty(fieldValue)) 331 { 332 <div class="custom-product-slider__item-specs-line"> 333 @if (field.SystemName == "ProductNumber") 334 { 335 <span class="name">@Translate("Product Number")</span> 336 <span class="value">@fieldValue.ToString()</span> 337 } 338 else 339 { 340 if (field.Type == "Double") 341 { 342 <span class="name">@field.Name</span> 343 <span class="value">@StringFormatExtensions.FormatDecimal(fieldValue.ToString(), Pageview.Area.CultureInfo.ToString())</span> 344 } 345 else 346 { 347 <span class="name">@field.Name</span> 348 <span class="value">@fieldValue.ToString()</span> 349 } 350 } 351 </div> 352 } 353 } 354 } 355 } 356 </div> 357358 } 359 </div> 360 </div> 361 </a> 362 </div> 363 </article> 364 } 365 </div> 366367 <div class="my-3" id="LoadMoreButton"> 368 <div class="text-center d-flex flex-column gap-3"> 369 @if (productList.PageCount != 1) 370 { 371 string sortBySelection = Dynamicweb.Context.Current.Request?.Form["SortBy"] ?? ""; 372 sortBySelection = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SortBy")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SortBy") : sortBySelection; 373 string mainProductId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("MainProductID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("MainProductID") : ""; 374375 string searchQuery = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("q")) ? Dynamicweb.Context.Current.Request.QueryString.Get("q") : ""; 376 string searchLayout = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SearchLayout")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SearchLayout") : ""; 377 string groupInQuery = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID") : ""; 378379 <form method="get" action="@url" data-response-target-element="content" class="w-100"> 380 @foreach (FacetGroupViewModel facetGroup in productList.FacetGroups) 381 { 382 foreach (FacetViewModel facetItem in facetGroup.Facets) 383 { 384 foreach (FacetOptionViewModel facetOption in facetItem.Options) 385 { 386 if (facetOption.Selected) 387 { 388 <input type="hidden" name="@facetItem.QueryParameter" value="[@facetOption.Value]"> 389 } 390 } 391 } 392 } 393394 <input type="hidden" name="PageSize" value="@pageSize"> 395 <input type="hidden" name="SortBy" value="@sortBySelection"> 396 <input type="hidden" name="RequestType" value="UpdateList"> 397398 @if (!string.IsNullOrEmpty(searchQuery)) 399 { 400 <input type="hidden" name="q" value="@searchQuery"> 401 <input type="hidden" name="SearchLayout" value="@searchLayout"> 402 } 403404 @if (!string.IsNullOrEmpty(mainProductId)) 405 { 406 <input type="hidden" name="MainProductID" value="@mainProductId"> 407 } 408409 @if (!string.IsNullOrEmpty(groupInQuery)) 410 { 411 <input type="hidden" name="GroupID" value="@groupInQuery"> 412 } 413414 @{ 415 string nextPageLink = "/Default.aspx?ID=" + Pageview.Page.ID + "&PageSize=" + pageSize + "&SortBy=" + sortBySelection; 416417 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups) 418 { 419 foreach (FacetViewModel facetItem in facetGroup.Facets) 420 { 421 foreach (FacetOptionViewModel facetOption in facetItem.Options) 422 { 423 if (facetOption.Selected) 424 { 425 nextPageLink += "&" + facetItem.QueryParameter + "=[" + facetOption.Value + "]"; 426 } 427 } 428 } 429 } 430431 nextPageLink += !string.IsNullOrEmpty(searchQuery) ? "&q=" + searchQuery : ""; 432 } 433434 <a href="@nextPageLink" class="btn btn-primary custom-product-list-filter__load-more" onclick="loadNextMoreProducts(event)" id="LoadMoreButton_@Model.ID">@Translate("Load more products")</a> 435 </form> 436 } 437 </div> 438 </div> 439 } 440 else 441 { 442 if (!Pageview.IsVisualEditorMode) 443 { 444 <div class="alert m-0 d-flex flex-column align-items-center justify-content-center"> 445 <h4>@Translate("Search Unsuccessful")</h4> 446 <p>@Translate("Sorry, we couldn't find any products that match your search criteria. Please try adjusting your filters.")</p> 447 <button class="btn btn-primary scantruck custom-product-list-filter__load-more" onclick="resetParams()">@Translate("Clear Filters")</button> 448 </div> 449450 } 451 else 452 { 453 <div class="alert m-0" role="alert"> 454 <span>@Translate("Product list: The list will be shown here, if any")</span> 455 </div> 456 } 457 } 458 } 459 } 460461 <script> 462 function resetParams() { 463 const url = new URL(window.location.href); 464 url.search = ""; 465 console.log(url.href) 466 window.location.replace(url.href) 467 } 468469 </script> 470471 <script> 472 async function loadNextMoreProducts(event) { 473 event.preventDefault(); 474475 addOverlayAndSpinner(event.target); 476477 const urlString = window.location.href; 478479 const url = new URL(urlString); 480481 const params = url.searchParams; 482483 if (params.has("PageSize")) { 484 let pageSize = parseInt(params.get("PageSize"), 10); 485486 pageSize += 24; // Increase PageSize by 24 487 params.set("PageSize", pageSize.toString()); 488 } else { 489 params.set("PageSize", "48"); 490 } 491492 params.set("RequestType", "UpdateList"); 493 params.set("LayoutTemplate", "Swift_PageClean.cshtml"); 494495 const fetchUrl = url.toString(); 496497 params.delete('RequestType'); 498 params.delete('LayoutTemplate'); 499500 const updateUrl = url.toString(); 501502 const response = await fetch(fetchUrl); 503504 if (response.ok) { 505 updateList(response, event, updateUrl); 506 } 507 } 508509 async function updateList(response, event, newUrl) { 510 const html = await response.text(); 511 const container = document.querySelector('#' + event.target.closest('form').dataset.responseTargetElement); 512513 container.innerHTML = html; 514515 document.querySelectorAll('input[type="range"]').forEach(input => { 516 if (input.id.indexOf('min') > -1) { 517 fillSlider(input, document.getElementById(input.id.replace('min', 'max'))); 518 } 519 }) 520521 window.history.replaceState({}, "", decodeURI(newUrl)) 522 } 523524 function addOverlayAndSpinner(target) { 525 const overlay = document.createElement('div'); 526 overlay.className = 'preloader-overlay'; 527 overlay.setAttribute('id', 'overlay'); 528529 const spinner = document.createElement('div'); 530 spinner.className = 'spinner-border'; 531 spinner.style.top = document.documentElement.scrollTop + 'px'; 532533 overlay.appendChild(spinner); 534535 target.closest('form').parentNode.insertBefore(overlay, target.closest('form')); 536 } 537 </script> 538

Prisforespørgsel

Udfyld formularen og send dine spørgsmål eller kommentarer til Scantruck.
Herefter vender vi tilbage med pris og svar på dine spørgsmål.