Error executing template "Designs/Swift/Paragraph/Swift_ProductListFacets.cshtml"
System.ArgumentNullException: Value cannot be null.
Parameter name: source
   at System.Linq.Enumerable.Count[TSource](IEnumerable`1 source)
   at CompiledRazorTemplates.Dynamic.RazorEngine_58fea4cea6b44ccb8aa05edea1dcac2e.<>c__DisplayClass0_0.<RenderForm>b__0(TextWriter __razor_helper_writer) in C:\Dynamicweb\Solutions\Production\Files\Templates\Designs\Swift\Paragraph\Swift_ProductListFacets.cshtml:line 217
   at CompiledRazorTemplates.Dynamic.RazorEngine_58fea4cea6b44ccb8aa05edea1dcac2e.Execute() in C:\Dynamicweb\Solutions\Production\Files\Templates\Designs\Swift\Paragraph\Swift_ProductListFacets.cshtml:line 75
   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.Frontend.Navigation 4 @using Dynamicweb.Environment 5 @using Dynamicweb.Core.Encoders 6 7 @{ 8 ProductListViewModel productList = new ProductListViewModel(); 9 10 if (Dynamicweb.Context.Current.Items.Contains("ProductList")) 11 { 12 productList = (ProductListViewModel)Dynamicweb.Context.Current.Items["ProductList"]; 13 } 14 15 string url = "/Default.aspx?ID=" + Model.PageID; 16 if (!url.Contains("LayoutTemplate")) 17 { 18 url += url.Contains("?") ? "&LayoutTemplate=Designs/Swift/Swift_PageClean.cshtml" : "?LayoutTemplate=Designs/Swift/Swift_PageClean.cshtml"; 19 } 20 21 string groupId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID") : ""; 22 23 if (groupId != "") 24 { 25 url += url.Contains("?") ? "&GroupID=" + groupId : ""; 26 } 27 28 bool facetsFound = false; 29 int selectedFacetsCount = 0; 30 31 if (productList.FacetGroups != null) 32 { 33 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups) 34 { 35 foreach (FacetViewModel facet in facetGroup.Facets) 36 { 37 if (facet.Options.Count() > 0) 38 { 39 facetsFound = true; 40 41 foreach (FacetOptionViewModel option in facet.Options) 42 { 43 if (option.Selected) 44 { 45 selectedFacetsCount++; 46 } 47 } 48 } 49 } 50 } 51 } 52 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 53 contentPadding = Model.Item.GetRawValueString("ContentPadding", "") == "none" ? " px-0 py-2" : contentPadding; 54 contentPadding = Model.Item.GetRawValueString("ContentPadding", "") == "small" ? " px-3 py-2" : contentPadding; 55 56 bool enableSorting = Model.Item.GetBoolean("SortByNameAZ"); 57 enableSorting = Model.Item.GetBoolean("SortByNameZA") || enableSorting == true ? true : false; 58 enableSorting = Model.Item.GetBoolean("SortByNewest") || enableSorting == true ? true : false; 59 enableSorting = Model.Item.GetBoolean("SortByLowestPrice") || enableSorting == true ? true : false; 60 enableSorting = Model.Item.GetBoolean("SortByHighestPrice") || enableSorting == true ? true : false; 61 62 string layout = Model.Item.GetRawValueString("Layout", "vertical"); 63 } 64 65 @if (facetsFound || Model.Item.GetBoolean("EnableGroupNavigation") || enableSorting) 66 { 67 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 68 string modalTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ModalTheme")) ? " theme " + Model.Item.GetRawValueString("ModalTheme").Replace(" ", "").Trim().ToLower() : ""; 69 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 70 string selectedFacetsLabel = selectedFacetsCount > 0 ? "(" + selectedFacetsCount + ")" : ""; 71 72 //Desktop 73 if (layout == "vertical") { 74 <form method="post" action="@url" data-response-target-element="content" id="FacetsForm_Desktop" class="d-none d-lg-block h-100 @theme"> 75 @RenderForm(productList, "desktop", enableSorting, layout) 76 </form> 77 } 78 if (layout == "horizontal") { 79 contentPadding = Model.Item.GetRawValueString("ContentPadding", "") == "small" ? " p-3" : contentPadding; 80 81 <div class="@theme @contentPadding h-100"> 82 <form method="post" action="@url" data-response-target-element="content" id="FacetsForm_Desktop" class="d-none d-lg-flex gap-3 flex-row flex-wrap"> 83 @RenderForm(productList, "desktop", enableSorting, layout) 84 85 @if (selectedFacetsCount > 0) { 86 <button type="button" class="btn btn-clean btn-sm me-sm-1 me-lg-2" onclick="swift.ProductList.ResetFacets(event)"><span class="icon-2">@ReadFile(iconPath + "rotate-ccw.svg")</span> @Translate("Clear filters")</button> 87 } 88 </form> 89 </div> 90 } 91 92 //Mobile 93 <div class="d-block d-lg-none mt-lg-0@(theme)"> 94 <button type="button" class="btn btn-primary w-100 d-flex" data-bs-toggle="modal" data-bs-target="#FacetsModal"> 95 <span class="flex-fill text-start"> 96 @Translate("Filter") @selectedFacetsLabel 97 </span> 98 <span class="icon-2 position-relative" style="top: 5px"> 99 @ReadFile(iconPath + "sliders.svg") 100 </span> 101 </button> 102 103 <form method="post" action="@url" data-response-target-element="content" class="modal" id="FacetsModal" tabindex="-1" aria-hidden="false"> 104 <div class="modal-dialog modal-fullscreen"> 105 <div class="modal-content"> 106 <div class="modal-header@(modalTheme)"> 107 <h5 class="modal-title">@Translate("Filters and sorting")</h5> 108 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 109 </div> 110 <div class="modal-body@(modalTheme)"> 111 @RenderForm(productList, "mobile", enableSorting) 112 </div> 113 <div class="modal-footer d-flex@(modalTheme)"> 114 @if (selectedFacetsCount != 0) 115 { 116 <button type="button" class="btn btn-secondary flex-fill" onclick="swift.ProductList.ResetFacets(event)">@Translate("Clear") (@selectedFacetsCount)</button> 117 } 118 <button type="button" class="btn btn-primary flex-fill" onclick="location.reload();">@Translate("Update")</button> 119 </div> 120 </div> 121 </div> 122 </form> 123 </div> 124 } 125 else 126 { 127 if (Pageview.IsVisualEditorMode) 128 { 129 <div class="alert alert-dark m-0" role="alert"> 130 <span>@Translate("Facets: The facets selectors will be shown here, if any")</span> 131 </div> 132 } 133 else 134 { 135 <div class="alert alert-dark m-0"> 136 @Translate("No filters are available") 137 </div> 138 } 139 } 140 141 @helper RenderForm(ProductListViewModel productList, string deviceType, bool enableSorting, string layout = "vertical") 142 { 143 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 144 145 string groupId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID") : ""; 146 string pageSize = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("PageSize")) ? Dynamicweb.Context.Current.Request.QueryString.Get("PageSize") : productList.PageSize.ToString(); 147 148 string groupsTheme = ""; 149 string extraBottomMargin = ""; 150 if (deviceType != "mobile") 151 { 152 groupsTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("FacetGroupsTheme")) ? " theme " + Model.Item.GetRawValueString("FacetGroupsTheme").Replace(" ", "").Trim().ToLower() : ""; 153 extraBottomMargin = !string.IsNullOrEmpty(groupsTheme) ? "mb-3" : ""; 154 } 155 156 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 157 contentPadding = contentPadding == "none" ? " px-0 py-2" : contentPadding; 158 contentPadding = contentPadding == "small" ? " px-3 py-2" : contentPadding; 159 160 161 if (productList?.Group?.Id != null) 162 { 163 <input type="hidden" name="GroupId" value="@productList.Group.Id" /> 164 } 165 166 <input type="hidden" name="PageSize" value="@pageSize" /> 167 168 if (Model.Item.GetBoolean("EnableGroupNavigation")) 169 { 170 var navigationSettings = new NavigationSettings(); 171 navigationSettings.StartLevel = 2; 172 navigationSettings.Parameters.Add("ID", deviceType); 173 navigationSettings.Parameters.Add("HideTexts", false); 174 navigationSettings.Parameters.Add("HideIcons", true); 175 navigationSettings.Parameters.Add("ContentPadding", contentPadding); 176 navigationSettings.ExpandMode = ExpandMode.All; 177 178 if (layout == "vertical") { 179 navigationSettings.StopLevel = 10; 180 181 <div class="border-bottom@(contentPadding)@(@groupsTheme)"> 182 <div class="d-flex@(contentPadding)" data-bs-toggle="collapse" data-bs-target="#ProductGroupNavigation_@deviceType" role="button" aria-expanded="true" aria-controls="ProductGroupNavigation_@deviceType"> 183 <h2 class="opacity-85 m-0 flex-fill h6">@Translate("Navigation")</h2> 184 <div class="my-auto collapse-chevron-icon"></div> 185 </div> 186 <div class="collapse show" id="ProductGroupNavigation_@deviceType"> 187 @Navigation.RenderNavigation("Navigation/Vertical.cshtml", navigationSettings) 188 </div> 189 </div> 190 } 191 } 192 193 if (enableSorting) 194 { 195 if (layout == "vertical") { 196 <div class="border-bottom@(contentPadding)@(groupsTheme)"> 197 <h2 class="opacity-85 m-0 my-2 flex-fill h6">@Translate("Sort by")</h2> 198 <div class="d-flex flex-column gap-2"> 199 @RenderSorting(deviceType) 200 </div> 201 </div> 202 } 203 if (layout == "horizontal") { 204 <button class="btn @(groupsTheme) dropdown-toggle" type="button" id="#SortBy_@deviceType" data-bs-toggle="dropdown" aria-expanded="false"> 205 @Translate("Sort by") 206 </button> 207 <div class="dropdown-menu p-3 @(groupsTheme)" aria-labelledby="#SortBy_@deviceType" style="min-width: 280px"> 208 <div class="d-flex flex-column gap-2"> 209 @RenderSorting(deviceType) 210 </div> 211 </div> 212 } 213 } 214 215 int groupCount = 0; 216 int maxGroups = 8; 217 int totalGroups = productList.FacetGroups.Count(); 218 219 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups) 220 { 221 string border = groupCount != totalGroups ? "border-bottom" : ""; 222 223 foreach (FacetViewModel facet in facetGroup.Facets) 224 { 225 if (facet.Options.Count() > 0) 226 { 227 if (layout == "vertical") { 228 <div class="@border@(contentPadding)@(@groupsTheme)"> 229 <div class="d-flex" data-bs-toggle="collapse" data-bs-target="#FacetGroup_@facet.Name.Replace(" ", "")_@deviceType" role="button" aria-expanded="true" aria-controls="FacetGroup_@facet.Name.Replace(" ", "")_@deviceType"> 230 <h2 class="opacity-85 m-0 flex-fill h6 my-2">@Translate(facet.Name)</h2> 231 <div class="my-auto collapse-chevron-icon"></div> 232 </div> 233 <div class="collapse show" id="FacetGroup_@facet.Name.Replace(" ", "")_@deviceType"> 234 @foreach (FacetOptionViewModel facetOption in facet.Options) 235 { 236 string renderType = facet.RenderType; 237 238 if (renderType == "Colors") 239 { 240 @RenderColorOption(facet, facetOption) 241 } 242 else 243 { 244 @RenderCheckboxOption(facet, facetOption) 245 } 246 } 247 </div> 248 </div> 249 } 250 if (layout == "horizontal") { 251 string hideSelector = groupCount < maxGroups ? "" : "d-none"; 252 int selectedFacetsInGroup = 0; 253 254 foreach (FacetOptionViewModel option in facet.Options) 255 { 256 if (option.Selected) 257 { 258 selectedFacetsInGroup++; 259 } 260 } 261 262 string label = selectedFacetsInGroup > 0 ? facet.Name + "<span class=\"badge bg-dark opacity-50 ms-2\">" + selectedFacetsInGroup + "</span>" : facet.Name; 263 264 <div class="dropdown @hideSelector js-facets-selector"> 265 <button class="btn @(groupsTheme) dropdown-toggle" type="button" id="#FacetGroup_@facet.Name.Replace(" ", "")_@deviceType" data-bs-toggle="dropdown" aria-expanded="false"> 266 @label 267 </button> 268 <div class="dropdown-menu p-3 @(groupsTheme)" aria-labelledby="#FacetGroup_@facet.Name.Replace(" ", "")_@deviceType" style="min-width: 280px"> 269 @foreach (FacetOptionViewModel facetOption in facet.Options) 270 { 271 string renderType = facet.RenderType; 272 273 if (renderType == "Colors") 274 { 275 @RenderColorOption(facet, facetOption) 276 } 277 else 278 { 279 @RenderCheckboxOption(facet, facetOption) 280 } 281 } 282 </div> 283 </div> 284 } 285 286 groupCount++; 287 } 288 } 289 } 290 291 if ((groupCount > maxGroups) && layout == "horizontal") { 292 <button type="button" class="btn @(groupsTheme)" onclick="this.closest('form').querySelectorAll('.js-facets-selector').forEach(function (selector) { selector.classList.remove('d-none'); }); this.classList.add('d-none');"><span class="icon-2">@ReadFile(iconPath + "sliders.svg")</span> @Translate("All filters")</button> 293 } 294 } 295 296 @helper RenderSorting(string deviceType) { 297 string sortBySelection = Dynamicweb.Context.Current.Request?.Form["SortBy"] ?? "NameForSort"; 298 sortBySelection = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SortBy")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SortBy") : sortBySelection; 299 string sortNameSelectedAZ = sortBySelection.ToLower() == "nameforsort" ? "checked" : ""; 300 string sortNameSelectedZA = sortBySelection.ToLower() == "-nameforsort" ? "checked" : ""; 301 string sortPriceLowSelected = sortBySelection.ToLower() == "price" ? "checked" : ""; 302 string sortPriceHighSelected = sortBySelection.ToLower() == "-price" ? "checked" : ""; 303 string sortNewSelected = sortBySelection.ToLower() == "-created" ? "checked" : ""; 304 string sortMostSoldSelected = sortBySelection.ToLower() == "-ordercount" ? "checked" : ""; 305 306 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 307 bool anonymousUser = Pageview.User == null; 308 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser; 309 310 if (Model.Item.GetBoolean("SortByNameAZ")) 311 { 312 <div class="form-check"> 313 <input class="form-check-input" onchange="swift.ProductList.Update(event); loadPage2()" type="radio" name="SortBy" value="NameForSort" id="SortByNameAZ_@deviceType" @sortNameSelectedAZ style="border-style: solid; border-width: thin"> 314 <label class="form-check-label" for="SortByNameAZ_@deviceType"> 315 @Translate("Name (A-Z)") 316 </label> 317 </div> 318 } 319 if (Model.Item.GetBoolean("SortByNameZA")) 320 { 321 <div class="form-check"> 322 <input class="form-check-input" onchange="swift.ProductList.Update(event); loadPage2()" type="radio" name="SortBy" value="-NameForSort" id="SortByNameZA_@deviceType" @sortNameSelectedZA style="border-style: solid; border-width: thin"> 323 <label class="form-check-label" for="SortByNameZA_@deviceType"> 324 @Translate("Name (Z-A)") 325 </label> 326 </div> 327 } 328 if (Model.Item.GetBoolean("SortByNewest")) 329 { 330 <div class="form-check" onchange="loadPage()"> 331 <input class="form-check-input" onchange="swift.ProductList.Update(event); loadPage2()" type="radio" name="SortBy" value="-created" id="SortByNew_@deviceType" @sortNewSelected style="border-style: solid; border-width: thin"> 332 <label class="form-check-label" for="SortByNew_@deviceType"> 333 @Translate("Newest") 334 </label> 335 </div> 336 } 337 if (!hidePrice) 338 { 339 if (Model.Item.GetBoolean("SortByLowestPrice")) 340 { 341 <div class="form-check"> 342 <input class="form-check-input" onchange="swift.ProductList.Update(event); loadPage2()" type="radio" name="SortBy" value="Price" id="SortByPriceLow_@deviceType" @sortPriceLowSelected style="border-style: solid; border-width: thin"> 343 <label class="form-check-label" for="SortByPriceLow_@deviceType"> 344 @Translate("Lowest price") 345 </label> 346 </div> 347 } 348 if (Model.Item.GetBoolean("SortByHighestPrice")) 349 { 350 <div class="form-check"> 351 <input class="form-check-input" onchange="swift.ProductList.Update(event); loadPage2()" type="radio" name="SortBy" value="-Price" id="SortByPriceHigh_@deviceType" @sortPriceHighSelected style="border-style: solid; border-width: thin"> 352 <label class="form-check-label" for="SortByPriceHigh_@deviceType"> 353 @Translate("Highest price") 354 </label> 355 </div> 356 } 357 } 358 if (Model.Item.GetBoolean("SortByMostSold")) 359 { 360 <div class="form-check"> 361 <input class="form-check-input" onchange="swift.ProductList.Update(event); loadPage2()" type="radio" name="SortBy" value="-OrderCount" id="SortByMostSold_@deviceType" @sortMostSoldSelected style="border-style: solid; border-width: thin"> 362 <label class="form-check-label" for="SortByMostSold_@deviceType"> 363 @Translate("Most sold") 364 </label> 365 </div> 366 } 367 } 368 369 @helper RenderCheckboxOption(FacetViewModel facet, FacetOptionViewModel facetOption) 370 { 371 string facetLabel = HtmlEncoder.HtmlEncode(facetOption.Label); 372 string disabled = facetOption.Count <= 0 ? "disabled" : ""; 373 string selected = facetOption.Selected ? "checked" : ""; 374 375 if (facetLabel.ToLower() == "true") 376 { 377 facetLabel = Translate("Yes"); 378 } 379 380 if (facetLabel.ToLower() == "false") 381 { 382 facetLabel = Translate("No"); 383 } 384 385 <label class="form-check mt-1" @disabled> 386 <input type="checkbox" onclick="swift.ProductList.Update(event)" class="form-check-input" name="@facet.QueryParameter" value="[@facetOption.Value]" data-filter-value="@facetLabel" @selected> 387 <span class="form-check-label d-flex align-items-center"> 388 <span class="flex-fill">@facetLabel </span> 389 @if (facet.FacetType.ToLower() == "field") { 390 <small class="opacity-85">@facetOption.Count</small> 391 } 392 </span> 393 </label> 394 } 395 396 @helper RenderColorOption(FacetViewModel facet, FacetOptionViewModel facetOption) 397 { 398 string facetLabel = HtmlEncoder.HtmlEncode(facetOption.Label); 399 string disabled = facetOption.Count <= 0 ? "disabled" : ""; 400 string selected = facetOption.Selected ? "checked" : ""; 401 402 string image = facetOption.Value; 403 string colorCode = facetOption.Value; 404 405 var variantOption = Dynamicweb.Ecommerce.Services.VariantOptions.GetVariantOption(facetOption.Value.ToString(), Dynamicweb.Ecommerce.Common.Context.LanguageID); 406 if (variantOption != null) 407 { 408 image = variantOption.LargeImage; 409 colorCode = variantOption.Color; 410 } 411 412 <div class="colorbox"> 413 <input type="checkbox" onclick="swift.ProductList.Update(event)" class="@disabled @selected" name="@facet.QueryParameter" value="[@facetOption.Value]" data-filter-value="@facetLabel" @selected title="@facetOption.Label"> 414 @if (colorCode.Contains("#")) 415 { 416 <span class="colorbox-background" style="background-color: @colorCode"></span> 417 } 418 else 419 { 420 <img class="colorbox-background" src="/Admin/Public/GetImage.ashx?width=25&height=25&image=@image" /> 421 } 422 </div> 423 } 424
By clicking 'Accept All' you consent that we may collect information about you for various purposes, including: Functionality, Statistics and Marketing