Error executing template "Designs/Swift/Paragraph/Swift_ProductListGridView.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at CompiledRazorTemplates.Dynamic.RazorEngine_85878219bcbc461f87e899adc8915356.<RenderProductList>b__6_0(TextWriter __razor_helper_writer) in F:\Web\Custom\Files\Templates\Designs\Swift\Paragraph\Swift_ProductListGridView.cshtml:line 467
at CompiledRazorTemplates.Dynamic.RazorEngine_85878219bcbc461f87e899adc8915356.Execute() in F:\Web\Custom\Files\Templates\Designs\Swift\Paragraph\Swift_ProductListGridView.cshtml:line 53
at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel>
2 @using Dynamicweb.Ecommerce.ProductCatalog
3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites
4 @using System.Linq
5 @using Dynamicweb.Core
6
7 @functions
8 {
9 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsLazyLoadingForProductInfoEnabled;
10 string liveInfoClass = "";
11 string productInfoFeed = "";
12
13 string showPricesWithVat = "";
14 bool neverShowVat = false;
15
16 ProductListViewModel productList = new ProductListViewModel();
17 }
18 @{
19 if (Dynamicweb.Context.Current.Items.Contains("ProductList"))
20 {
21 productList = (ProductListViewModel)Dynamicweb.Context.Current.Items["ProductList"];
22 }
23
24 showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower();
25 neverShowVat = string.IsNullOrEmpty(showPricesWithVat);
26
27 if (isLazyLoadingForProductInfoEnabled)
28 {
29 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed"))
30 {
31 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString();
32 if (!string.IsNullOrEmpty(productInfoFeed))
33 {
34 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\"";
35 }
36 }
37 liveInfoClass = "js-live-info";
38 }
39
40 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
41 string themePadding = theme != string.Empty ? "p-3" : string.Empty;
42 }
43
44 @if (!string.IsNullOrEmpty(theme))
45 {
46 <div class="h-100@(theme) @themePadding item_@Model.Item.SystemName.ToLower()" @productInfoFeed>
47 @RenderProductList()
48 </div>
49 }
50 else
51 {
52 <div class="pt-3 item_@Model.Item.SystemName.ToLower()" @productInfoFeed>
53 @RenderProductList()
54 </div>
55 }
56
57 @helper RenderProductList ()
58 {
59 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", "");
60 bool anonymousUser = Pageview.User == null;
61 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable();
62
63 string detailsPageLink = Dynamicweb.Context.Current.Items["DetailsPageLink"] != null ? Dynamicweb.Context.Current.Items["DetailsPageLink"].ToString() : "";
64 string productTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ProductTheme")) ? " theme " + Model.Item.GetRawValueString("ProductTheme").Replace(" ", "").Trim().ToLower() : "";
65 string productThemePadding = productTheme != string.Empty ? "p-3" : string.Empty;
66
67 string url = Dynamicweb.Context.Current.Request.RawUrl;
68 bool hideFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("HideFavoritesSelector")) ? Model.Item.GetBoolean("HideFavoritesSelector") : false;
69 string staticVariantsLayout = Model.Item.GetRawValueString("StaticVariantsLayout", "hide");
70
71 string groupId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID") : "";
72
73 var badgeParms = new Dictionary<string, object>();
74 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType"));
75 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign"));
76 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign"));
77 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays"));
78 badgeParms.Add("campaignBadgesValues", Model.Item.GetRawValueString("CampaignBadges"));
79
80 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false;
81 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false;
82
83 var favoriteParameters = new Dictionary<string, object>();
84 if (!anonymousUser && !hideFavoritesSelector)
85 {
86 int defaultFavoriteListId = 0;
87
88 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists();
89 if (favoreiteLists.Count() == 1) {
90 foreach (FavoriteList list in favoreiteLists) {
91 defaultFavoriteListId = list.ListId;
92 }
93 }
94
95 favoriteParameters.Add("ListId", defaultFavoriteListId);
96 }
97
98 if (productList.TotalProductsCount > 0) {
99 int pageSizeSetting = 30;
100 int pageSize = productList.PageSize;
101 pageSize += pageSizeSetting;
102
103 int loadedProducts = productList.PageSize > productList.TotalProductsCount ? productList.TotalProductsCount : productList.PageSize;
104
105 //REMOVE BEFORE RELEASE
106 Dynamicweb.Ecommerce.Common.Context.CartContext = Dynamicweb.Ecommerce.Orders.OrderContext.GetOrderContextById("ORDERCONTEXT2");
107
108 <div class="grid grid-2 grid-lg-3">
109 @foreach (ProductViewModel product in productList.Products)
110 {
111 var defaultGroupId = product.PrimaryOrDefaultGroup.Id;
112 var selectedDetailPage = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(defaultGroupId)?.Meta.PrimaryPage ?? string.Empty;
113
114 string link = string.IsNullOrEmpty(selectedDetailPage) ? $"{detailsPageLink}&groupid={defaultGroupId}" : selectedDetailPage;
115 link += "&productid=" + product.Id;
116 link += !string.IsNullOrEmpty(product.VariantId) ? "&variantid=" + product.VariantId : "";
117
118 string imagePath = product?.DefaultImage?.Value ?? "";
119 imagePath = Dynamicweb.Context.Current.Server.UrlEncode(imagePath);
120
121 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", "");
122 ratio = ratio != "0" ? ratio : "";
123 string ratioCssClass = ratio != "" ? " ratio" : "";
124 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio : "";
125
126 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + 480 + "&image=" + imagePath + "&format=webp";
127 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + 640 + "&image=" + imagePath + "&format=webp";
128 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + 640 + "&image=" + imagePath + "&format=webp";
129
130 string imageTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : "";
131 string imageThemePadding = imageTheme != string.Empty ? "p-3" : string.Empty;
132 string imageOutlineStyle = imageTheme == string.Empty ? "style=\"border: 1px solid transparent\"" : string.Empty;
133
134 string imageId = "ProductImage_" + product.Id + product.VariantId;
135 string priceId = "ProductPrice_" + product.Id + product.VariantId;
136
137 @* Alternative image *@
138 var supportedImageFormats = new string[] { ".jpg", ".webp", ".png", ".gif" };
139 string defaultImage = product.DefaultImage != null ? product.DefaultImage.Value : "";
140 var selectedAssetCategories = Model.Item.GetRawValueString("AlternativeImageAssets");
141 IEnumerable<MediaViewModel> alternativeImagesList = product.AssetCategories.Where(x => selectedAssetCategories.Contains(x.SystemName)).SelectMany(x => x.Assets);
142
143 if (alternativeImagesList.FirstOrDefault() != null) {
144 alternativeImagesList = alternativeImagesList.OrderByDescending(x => x.Value.Equals(defaultImage));
145
146 if (alternativeImagesList.First().Value == defaultImage) {
147 alternativeImagesList = alternativeImagesList.Skip(1);
148 }
149 }
150
151 string alternativeImage = alternativeImagesList.FirstOrDefault() != null ? alternativeImagesList.FirstOrDefault().Value : "";
152 alternativeImage = !string.IsNullOrEmpty(alternativeImage) ? "/Admin/Public/GetImage.ashx?width=" + 640 + "&image=" + alternativeImage + "&format=webp" : "";
153
154 @* Badges *@
155 DateTime createdDate = product.Created.Value;
156 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false;
157 showBadges = (newBadgeEnabled && Model.Item.GetInt32("NewPublicationDays") == 0) || (newBadgeEnabled && (createdDate.AddDays(Model.Item.GetInt32("NewPublicationDays")) > DateTime.Now)) ? true : showBadges;
158 showBadges = !string.IsNullOrEmpty(Model.Item.GetRawValueString("CampaignBadges")) ? true : showBadges;
159
160 @* Main features *@
161 IEnumerable<string> selectedDisplayGroups = Model.Item.GetRawValueString("MainFeatures").Split(',').ToList();
162 List<CategoryFieldViewModel> mainFeatures = new List<CategoryFieldViewModel>();
163
164 foreach (var selection in selectedDisplayGroups)
165 {
166 foreach (CategoryFieldViewModel group in product.FieldDisplayGroups.Values)
167 {
168 if (selection == group.Id) {
169 mainFeatures.Add(group);
170 }
171 }
172 }
173
174 <article class="position-relative@(productTheme) product-list-item product @liveInfoClass" data-product-id="@product.Id" itemscope itemtype="https://schema.org/Product">
175 @if (!anonymousUser && !hideFavoritesSelector && product.VariantInfo.VariantInfo == null) {
176 <div class="position-absolute top-0 end-0 my-3" style="z-index: 2">
177 @RenderPartial("Components/ToggleFavorite.cshtml", product, favoriteParameters)
178 </div>
179 }
180
181 @if (showBadges) {
182 <div class="position-absolute top-0 left-0 p-1 p-lg-2 ps-0 ps-lg-0" style="z-index: 2">
183 @RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms)
184 </div>
185 }
186
187 <div class="d-flex flex-column d-block h-100">
188 <a href="@link" class="text-decoration-none">
189 <div class="overflow-hidden@(imageTheme)" @imageOutlineStyle>
190 <div class="ratio" style="@(ratioVariable)">
191 <div class="d-flex justify-content-center align-items-center">
192 @if (string.IsNullOrEmpty(alternativeImage)) {
193 <img
194 id="@imageId"
195 srcset="
196 @imagePathXs 480w,
197 @imagePathS 640w"
198 sizes="(min-width: 992px) 33vw, 50vw"
199 src="@imagePathFallBack"
200 loading="lazy"
201 decoding="async"
202 class="mw-100 mh-100 @imageThemePadding"
203 alt="@product.Name">
204 } else {
205 <img
206 id="@imageId"
207 src="@imagePathFallBack"
208 loading="lazy"
209 decoding="async"
210 class="mw-100 mh-100 @imageThemePadding"
211 alt="@product.Name"
212 onmouseover="this.src='@alternativeImage'"
213 onmouseout="this.src='@imagePathFallBack'">
214 }
215 </div>
216 </div>
217
218
219 <div class="position-relative">
220 @if (product.VariantInfo.VariantInfo != null && staticVariantsLayout == "images") {
221 int variantGroupCount = 0;
222 int showMaxVariantGroups = 2;
223 int showMaxVariants = 3;
224 var productVariantTheme = productTheme != "" ? productTheme : "bg-white";
225
226 <div
227 class="static-variants w-100 d-none d-lg-block position-absolute left-0 bottom-0 @productTheme"
228 id="StaticVariants_@product.Id"
229 style="pointer-events: none;">
230
231 @foreach (var variantGroup in product.VariantGroups())
232 {
233 int variantsCount = 0;
234
235 <div class="d-flex gap-2 mb-2">
236 @foreach (var variant in variantGroup.Options)
237 {
238 if (variantGroupCount < showMaxVariantGroups)
239 {
240 var optionsCount = variantGroup.Options.Count();
241
242 if (variantsCount < showMaxVariants)
243 {
244 string optionWidth = !string.IsNullOrEmpty(variant.Color) ? "w-25" : "";
245
246 <article class="static-variants-option @optionWidth @(productVariantTheme)" title="@product.Name @variant.Name" style="pointer-events: initial;">
247 @if (!string.IsNullOrEmpty(variant.Color))
248 {
249 string defaultProductImage = Dynamicweb.Context.Current.Server.UrlEncode(product.DefaultImage.Value);
250 string variantImage = Dynamicweb.Context.Current.Server.UrlEncode(variant.Image.Value);
251 string defaultPrice = !hidePrice ? product.Price.PriceFormatted : "0";
252 string variantPrice = !hidePrice ? product.Price.PriceFormatted : "0";
253
254 if (isLazyLoadingForProductInfoEnabled)
255 {
256 <figure class="figure w-100 d-block m-0" data-price-formatted="" onmouseover="switchVariantProduct('@product.Id', this.getAttribute('data-price-formatted'), '@variantImage')" onmouseout="switchVariantProduct('@product.Id', this.getAttribute('data-price-formatted'), '@defaultProductImage')">
257 <div class="d-flex align-items-center justify-content-center">
258 <img src="/admin/public/GetImage.ashx?image=@variantImage&width=75&height=75&crop=5&FillCanvas=true&format=webp&Quality=70" height="75" width="75" class="p-1 text-small" loading="lazy" decoding="async" alt="@product.Name, @variant.Name">
259 </div>
260 </figure>
261 }
262 else
263 {
264 <figure class="figure w-100 d-block m-0" onmouseover="switchVariantProduct('@product.Id', '@defaultPrice', '@variantImage')" onmouseout="switchVariantProduct('@product.Id', '@variantPrice', '@defaultProductImage')">
265 <div class="d-flex align-items-center justify-content-center">
266 <img src="/admin/public/GetImage.ashx?image=@variantImage&width=75&height=75&crop=5&FillCanvas=true&format=webp&Quality=70" height="75" width="75" class="p-1 text-small" loading="lazy" decoding="async" alt="@product.Name, @variant.Name">
267 </div>
268 </figure>
269 }
270 }
271 else
272 {
273 <div class="d-flex align-items-center justify-content-center">
274 @variant.Name
275 </div>
276 }
277 <div class="visually-hidden">
278 <h4>@Translate("Variant Name")</h4>
279 <p>@product.Name, @variant.Name</p>
280 @if (!hidePrice) {
281 <h4>@Translate("Variant Price")</h4>
282 if (isLazyLoadingForProductInfoEnabled)
283 {
284 <p><span class="text-price js-text-price"></span></p>
285 }
286 else
287 {
288 <p><span class="text-price">@product.Price.PriceFormatted</span></p>
289 }
290 }
291 </div>
292 </article>
293 }
294
295 variantsCount++;
296
297 if (variantsCount == showMaxVariants && optionsCount != showMaxVariants)
298 {
299 int left = optionsCount - showMaxVariants;
300 <div class="variant-option ms-1 d-flex justify-content-center align-items-center">
301 <span>+@left</span>
302 </div>
303 }
304 }
305 }
306
307 </div>
308
309 variantGroupCount++;
310 }
311 </div>
312 }
313 </div>
314 </div>
315 <div class="@productThemePadding">
316 <div class="flex-grow-1">
317 <h3 class="h6 mb-0 text-break">@product.Name @if (!string.IsNullOrEmpty(product.VariantName)) { <text>(@product.VariantName)</text> }</h3>
318 @if (!Model.Item.GetBoolean("HideProductNumber")) {
319 <p class="fs-7 opacity-85 mb-2">@product.Number</p>
320 }
321 @if (mainFeatures.Count > 0)
322 {
323 <ul class="p-0 lh-sm opacity-75" style="list-style-position: inside">
324 @foreach (CategoryFieldViewModel mainFeatureGroup in mainFeatures)
325 {
326 foreach (var field in mainFeatureGroup.Fields)
327 {
328 @RenderField(field.Value)
329 }
330 }
331 </ul>
332 }
333 </div>
334
335 @if (!hidePrice) {
336 string priceMin = "";
337 string priceMax = "";
338
339 <div>
340 <div>
341 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span>
342
343 @if (showPricesWithVat == "false" && !neverShowVat) {
344 if (isLazyLoadingForProductInfoEnabled)
345 {
346 <span itemprop="price" content="" class="d-none"></span>
347 <span class="text-decoration-line-through js-text-decoration-line-through opacity-75 me-3 text-price js-text-price d-none" data-show-if="LiveProductInfo.product.Price.Price != LiveProductInfo.product.PriceBeforeDiscount.Price"></span>
348 }
349 else
350 {
351 string beforePrice = product.PriceBeforeDiscount.PriceWithoutVatFormatted;
352 <span itemprop="price" content="@product.Price.PriceWithoutVat" class="d-none"></span>
353 if (product.Price.Price != product.PriceBeforeDiscount.Price) {
354 <span class="text-decoration-line-through opacity-75 me-3 text-price">@beforePrice</span>
355 }
356 }
357
358 } else {
359
360 if (isLazyLoadingForProductInfoEnabled)
361 {
362 <span itemprop="price" content="" class="d-none"></span>
363 <span class="text-decoration-line-through js-text-decoration-line-through opacity-75 me-3 text-price js-text-price d-none" data-show-if="LiveProductInfo.product.Price.Price != LiveProductInfo.product.PriceBeforeDiscount.Price"></span>
364 }
365 else
366 {
367 string beforePrice = product.PriceBeforeDiscount.PriceFormatted;
368
369 <span itemprop="price" content="@product.Price.Price" class="d-none"></span>
370 if (product.Price.Price != product.PriceBeforeDiscount.Price) {
371 <span class="text-decoration-line-through opacity-75 me-3 text-price">@beforePrice</span>
372 }
373 }
374 }
375
376 @if (showPricesWithVat == "false" && !neverShowVat) {
377 if (isLazyLoadingForProductInfoEnabled)
378 {
379 <span class="text-price js-text-price"><div class="spinner-border" role="status"></div></span>
380 }
381 else
382 {
383 string price = product.Price.PriceWithoutVatFormatted;
384 if (product?.VariantInfo?.VariantInfo != null) {
385 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : "";
386 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : "";
387 }
388 if (priceMin != priceMax) {
389 price = priceMin + " - " + priceMax;
390 }
391 <span class="text-price">@price</span>
392 }
393 } else {
394 if (isLazyLoadingForProductInfoEnabled)
395 {
396 <span class="text-price js-text-price"><div class="spinner-border" role="status"></div></span>
397 }
398 else
399 {
400 string price = product.Price.PriceFormatted;
401 if (product?.VariantInfo?.VariantInfo != null) {
402 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : "";
403 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : "";
404 }
405 if (priceMin != priceMax) {
406 price = priceMin + " - " + priceMax;
407 }
408 <span class="text-price">@price</span>
409 }
410 }
411 </div>
412 @if (showPricesWithVat == "false" && !neverShowVat) {
413 if (isLazyLoadingForProductInfoEnabled)
414 {
415 <div class="fs-7 opacity-85 text-price js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></div>
416 }
417 else
418 {
419 string price = product.Price.PriceWithVatFormatted;
420 if (product?.VariantInfo?.VariantInfo != null) {
421 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : "";
422 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : "";
423 }
424 if (priceMin != priceMax) {
425 price = priceMin + " - " + priceMax;
426 }
427 <div class="fs-7 opacity-85 text-price">@price @Translate("Incl. VAT")</div>
428 }
429 }
430 </div>
431 }
432
433 @if (product.VariantInfo.VariantInfo != null && staticVariantsLayout == "swatches") {
434 var optionCount = product.VariantInfo.VariantInfo.Count();
435 var showMaxVariants = 5;
436
437 <div class="d-flex flex-row gap-1 align-items-center">
438 @foreach (VariantInfoViewModel variant in product.VariantInfo.VariantInfo.Take(showMaxVariants))
439 {
440 <span class="colorbox colorbox-sm rounded-circle border me-1" style="background-color: @variant.OptionColor"></span>
441 }
442 @if (optionCount > showMaxVariants)
443 {
444 int left = optionCount - showMaxVariants;
445 <span class="ms-2">+@left</span>
446 }
447 </div>
448 }
449 </div>
450 </a>
451 </div>
452 </article>
453 }
454 </div>
455
456 <div class="my-3" id="LoadMoreButton">
457 <div class="text-center d-flex flex-column gap-3">
458 <div class="opacity-85">@loadedProducts @Translate("out of") @productList.TotalProductsCount @Translate("products")</div>
459 @if (productList.PageCount != 1) {
460 string sortBySelection = Dynamicweb.Context.Current.Request?.Form["SortBy"] ?? "NameForSort";
461 sortBySelection = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SortBy")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SortBy") : sortBySelection;
462
463 string searchQuery = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("q")) ? Dynamicweb.Context.Current.Request.QueryString.Get("q") : "";
464 string searchLayout = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SearchLayout")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SearchLayout") : "";
465
466 <form method="get" action="@url" data-response-target-element="content" class="w-100">
467 @foreach (FacetGroupViewModel facetGroup in productList.FacetGroups)
468 {
469 foreach (FacetViewModel facetItem in facetGroup.Facets)
470 {
471 foreach (FacetOptionViewModel facetOption in facetItem.Options)
472 {
473 if (facetOption.Selected)
474 {
475 <input type="hidden" name="@facetItem.QueryParameter" value="[@facetOption.Value]" />
476 }
477 }
478 }
479 }
480
481 @if (productList?.Group?.Id != null) {
482 <input type="hidden" name="GroupId" value="@productList.Group.Id" />
483 }
484
485 <input type="hidden" name="PageSize" value="@pageSize" />
486 <input type="hidden" name="SortBy" value="@sortBySelection" />
487 <input type="hidden" name="RequestType" value="UpdateList" />
488
489 @if (!string.IsNullOrEmpty(searchQuery)) {
490 <input type="hidden" name="q" value="@searchQuery" />
491 <input type="hidden" name="SearchLayout" value="@searchLayout" />
492 }
493
494 <button class="btn btn-primary" type="button" onclick="swift.ProductList.Update(event)">@Translate("Load more products")</button>
495 </form>
496 }
497 </div>
498 </div>
499
500 <script>
501 function switchVariantProduct(id, price, imagesrc) {
502 var productImageElement = document.querySelector("#ProductImage_" + id);
503 var productPriceElement = document.querySelector("#ProductPrice_" + id + " .text-price");
504
505 if (productPriceElement) {
506 productPriceElement.innerText = price;
507 }
508
509 if (productImageElement) {
510 productImageElement.src = imagesrc;
511
512 var imageSrcset = productImageElement.srcset;
513 imageSrcset = imageSrcset.replace(/image=.*?&/g, 'image=' + imagesrc + "&");
514
515 productImageElement.srcset = imageSrcset;
516 }
517 }
518 </script>
519 } else {
520 if (!Pageview.IsVisualEditorMode) {
521 <div class="alert alert-dark m-0">
522 @Translate("We did not find anything matching your search result")
523 </div>
524 } else {
525 <div class="alert alert-dark m-0" role="alert">
526 <span>@Translate("Product list: The list will be shown here, if any")</span>
527 </div>
528 }
529 }
530 }
531
532 @helper RenderField(FieldValueViewModel field) {
533 string fieldValue = field?.Value != null ? field.Value.ToString() : "";
534
535 if (fieldValue != "") {
536 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue;
537 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue;
538
539 if (field.Value.GetType() == typeof(System.Collections.Generic.List<FieldOptionValueViewModel>)) {
540 fieldValue = "";
541
542 foreach (FieldOptionValueViewModel option in field.Value as System.Collections.Generic.List<FieldOptionValueViewModel>) {
543 fieldValue = option.Name;
544 }
545 }
546
547 bool isColor = false;
548 if (fieldValue.Contains("#") && (Translate(field.Name) == Translate("Color") || Translate(field.Name) == Translate("Colour"))) {
549 isColor = true;
550 }
551
552 if (!string.IsNullOrEmpty(fieldValue)) {
553 if (!isColor) {
554 <li>@(field.Name): @fieldValue</li>
555 } else {
556 <li class="position-relative">
557 <span class="colorbox-sm" style="background-color: @fieldValue"></span>
558 </li>
559 }
560 }
561 }
562 }
563