Filter:

Error executing template "/Designs/Swift/Paragraph/Swift_ProductListFacets_Custom.cshtml"
System.IO.IOException: The process cannot access the file 'D:\dynamicweb.net\Solutions\twodayco3\evasolo.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Translations.xml' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   at Dynamicweb.Rendering.Translation.Source.WriteDocument(XmlDocument document)
   at Dynamicweb.Rendering.Translation.Source.Save()
   at Dynamicweb.Rendering.Translation.Source.UpdateTranslationSource(Source source, IEnumerable`1 newKeys, String designName, IEnumerable`1 cultures)
   at Dynamicweb.Rendering.Template.TranslateText(String text, String defaultValue, String cultureName)
   at Dynamicweb.Rendering.TemplateBase`1.Translate(String text, String defaultValue)
   at CompiledRazorTemplates.Dynamic.RazorEngine_c1b0767df89240cf83e66edfda2fc218.<>c__DisplayClass3_0.<RenderForm>b__2(FacetOptionViewModel i) in D:\dynamicweb.net\Solutions\twodayco3\evasolo.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Paragraph\Swift_ProductListFacets_Custom.cshtml:line 377
   at System.Linq.EnumerableSorter`2.ComputeKeys(TElement[] elements, Int32 count)
   at System.Linq.EnumerableSorter`1.Sort(TElement[] elements, Int32 count)
   at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__1.MoveNext()
   at CompiledRazorTemplates.Dynamic.RazorEngine_c1b0767df89240cf83e66edfda2fc218.<>c__DisplayClass3_0.<RenderForm>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\twodayco3\evasolo.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Paragraph\Swift_ProductListFacets_Custom.cshtml:line 377
   at CompiledRazorTemplates.Dynamic.RazorEngine_c1b0767df89240cf83e66edfda2fc218.Execute() in D:\dynamicweb.net\Solutions\twodayco3\evasolo.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Paragraph\Swift_ProductListFacets_Custom.cshtml:line 151
   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 3 @using Dynamicweb.Ecommerce.ProductCatalog 4 @using Dynamicweb.Frontend.Navigation 5 @using Dynamicweb.Environment 6 @using Dynamicweb.Core.Encoders 7 @using System.Web 8 9 @* TODO: REFACTURE/UPGRADE TO SWIFT (v1.25.0) *@ 10 @* CUSTOM FUNCTIONS - TODO: MOVE TO BE/PROJECT *@ 11 12 @functions 13 { 14 public class GroupFacetRelation 15 { 16 public string group { set; get; } 17 public string field { set; get; } 18 } 19 20 public List<GroupFacetRelation> GroupFacetRelations(ProductListViewModel model = null) 21 { 22 var groupFacetRelations = new List<GroupFacetRelation>() { }; 23 24 if (model != null && model.FacetGroups != null && model.FacetGroups.Any()) 25 { 26 if (model.Group == null) // NOTE: All top level groups is returned null in model (GroupID is not defined). 27 { 28 model.Group = new ProductGroupViewModel(); 29 model.Group.Id = Dynamicweb.Ecommerce.Services.ProductGroups.GetToplevelGroups(Pageview.Area.EcomLanguageId).FirstOrDefault(i => i.Name == Pageview.Page.MenuText)?.Id; // NOTE: Reference; page name = group name. 30 } 31 32 var sql = "SELECT GroupFacetRelationFacetGroup, GroupFacetRelationFacetField FROM EcomGroupFacetRelation WHERE GroupFacetRelationRepository = 'SwiftProducts' AND GroupFacetRelationGroupId = {0} AND (GroupFacetRelationFacetGroup IN ({1}) OR GroupFacetRelationFacetField IS NULL)"; 33 Dynamicweb.Data.CommandBuilder cb = Dynamicweb.Data.CommandBuilder.Create(sql, model.Group.Id, model.FacetGroups.Select(i => i.Name)); 34 35 using (var dr = Dynamicweb.Data.Database.CreateDataReader(cb)) 36 { 37 while (dr.Read()) 38 { 39 groupFacetRelations.Add(new GroupFacetRelation 40 { 41 group = Convert.ToString(dr["GroupFacetRelationFacetGroup"]), 42 field = Convert.ToString(dr["GroupFacetRelationFacetField"]) 43 }); 44 } 45 } 46 } 47 48 return groupFacetRelations; 49 } 50 51 public bool GroupFacetRelationEnable(List<GroupFacetRelation> groupFacetRelations, string group, string field) 52 { 53 // If GroupFacetRelationFacetGroup not exists = Show 54 // If GroupFacetRelationFacetGroup exists and GroupFacetRelationFacetField is empty = Hide 55 // If GroupFacetRelationFacetGroup exists and GroupFacetRelationFacetField equal FacetField = Show 56 // If GroupFacetRelationFacetGroup exists and GroupFacetRelationFacetField not equal FacetField = Hide 57 58 if (!groupFacetRelations.Any(i => i.group == group)) return true; 59 else if (groupFacetRelations.Any(i => i.group == group && i.field == field)) return true; 60 return false; 61 } 62 } 63 64 @{ 65 ProductListViewModel productList = new ProductListViewModel(); 66 67 if (Dynamicweb.Context.Current.Items.Contains("ProductList")) 68 { 69 productList = (ProductListViewModel)Dynamicweb.Context.Current.Items["ProductList"]; 70 } 71 72 // CUSTOM 73 var groupFacetRelations = GroupFacetRelations(productList); 74 75 string url = Pageview.SearchFriendlyUrl; 76 url = url.LastIndexOf("?") != -1 ? url.Substring(0, url.LastIndexOf("?")) : url; 77 78 //Fix for non-friendly urls 79 if (Dynamicweb.Context.Current.Request.QueryString.Get("GroupID") != null) 80 { 81 string groupId = Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"); 82 url += "?GroupID=" + groupId; 83 } 84 85 if (!url.Contains("LayoutTemplate")) 86 { 87 url += url.Contains("?") ? "&LayoutTemplate=Designs/Swift/Swift_PageClean.cshtml" : "?LayoutTemplate=Designs/Swift/Swift_PageClean.cshtml"; 88 } 89 90 bool facetsFound = false; 91 int selectedFacetsCount = 0; 92 93 if (productList.FacetGroups != null) 94 { 95 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups) 96 { 97 foreach (FacetViewModel facet in facetGroup.Facets) 98 { 99 if (facet.Options.Count() > 0 && GroupFacetRelationEnable(groupFacetRelations, facetGroup.Name, facet.FacetField)) 100 { 101 facetsFound = true; 102 103 foreach (FacetOptionViewModel option in facet.Options) 104 { 105 if (option.Selected) 106 { 107 selectedFacetsCount++; 108 } 109 } 110 } 111 } 112 } 113 } 114 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 115 contentPadding = Model.Item.GetRawValueString("ContentPadding", "") == "none" ? " px-0 py-2" : contentPadding; 116 contentPadding = Model.Item.GetRawValueString("ContentPadding", "") == "small" ? " px-3 py-2" : contentPadding; 117 118 bool enableSorting = Model.Item.GetBoolean("SortByNameAZ"); 119 enableSorting = Model.Item.GetBoolean("SortByNameZA") || enableSorting == true ? true : false; 120 enableSorting = Model.Item.GetBoolean("SortByNewest") || enableSorting == true ? true : false; 121 enableSorting = Model.Item.GetBoolean("SortByLowestPrice") || enableSorting == true ? true : false; 122 enableSorting = Model.Item.GetBoolean("SortByHighestPrice") || enableSorting == true ? true : false; 123 124 string layout = Model.Item.GetRawValueString("Layout", "vertical"); 125 } 126 127 @if (productList.TotalProductsCount > 0 && (facetsFound || Model.Item.GetBoolean("EnableGroupNavigation") || enableSorting)) 128 { 129 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 130 string modalTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ModalTheme")) ? " theme " + Model.Item.GetRawValueString("ModalTheme").Replace(" ", "").Trim().ToLower() : ""; 131 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 132 string selectedFacetsLabel = selectedFacetsCount > 0 ? "(" + selectedFacetsCount + ")" : ""; 133 134 //Desktop 135 if (layout == "vertical") 136 { 137 <form method="post" action="@url" data-response-target-element="content" id="FacetsForm_Desktop_@Model.ID" class="d-none d-lg-block h-100 @theme item_@Model.Item.SystemName.ToLower()"> 138 @{ 139 @RenderForm(productList, "desktop", enableSorting, groupFacetRelations, layout) 140 } 141 </form> 142 } 143 if (layout == "horizontal") 144 { 145 contentPadding = Model.Item.GetRawValueString("ContentPadding", "") == "small" ? " p-3" : contentPadding; 146 147 148 <div class="@theme @contentPadding h-100"> 149 <form method="post" action="@url" data-response-target-element="content" id="FacetsForm_Desktop_@Model.ID" class="d-none d-lg-flex gap-3 flex-row flex-wrap item_@Model.Item.SystemName.ToLower()"> 150 @{ 151 @RenderForm(productList, "desktop", enableSorting, groupFacetRelations, layout) 152 } 153 154 @if (selectedFacetsCount > 0) 155 { 156 <button type="button" class="btn 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> 157 } 158 </form> 159 </div> 160 } 161 162 //Mobile 163 <div class="d-block d-lg-none mt-lg-0 @(contentPadding)@(theme) FacetsForm_Mobile_@Model.Item.SystemName.ToLower()_@Model.ID"> 164 <button type="button" class="btn btn-primary w-100" data-bs-toggle="modal" data-bs-target="#FacetsModal"> 165 <span class="d-flex align-items-center"> 166 <span class="flex-grow-1 text-start"> 167 @Translate("Filter") @selectedFacetsLabel 168 </span> 169 <span class="icon-2"> 170 @ReadFile(iconPath + "sliders.svg") 171 </span> 172 </span> 173 </button> 174 175 <form method="post" action="@url" data-response-target-element="content" class="modal" id="FacetsModal" tabindex="-1" aria-hidden="false"> 176 <div class="modal-dialog modal-fullscreen"> 177 <div class="modal-content"> 178 <div class="modal-header@(modalTheme)"> 179 <h5 class="modal-title">@Translate("Filters and sorting")</h5> 180 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="document.querySelector('body').style = ''"></button> 181 </div> 182 <div class="modal-body@(modalTheme)"> 183 @{ 184 @RenderForm(productList, "mobile", enableSorting, groupFacetRelations) 185 } 186 </div> 187 <div class="modal-footer d-flex@(modalTheme)"> 188 @if (selectedFacetsCount != 0) 189 { 190 <button type="button" class="btn btn-secondary flex-fill" onclick="swift.ProductList.ResetFacets(event)">@Translate("Clear") (@selectedFacetsCount)</button> 191 } 192 <button type="button" class="btn btn-primary flex-fill" onclick="location.reload();">@Translate("Update")</button> 193 </div> 194 </div> 195 </div> 196 </form> 197 </div> 198 } 199 else 200 { 201 if (Pageview.IsVisualEditorMode) 202 { 203 <div class="alert alert-dark m-0" role="alert"> 204 <span>@Translate("Facets: The facets selectors will be shown here, if any")</span> 205 </div> 206 } 207 else if (productList.TotalProductsCount > 0) 208 { 209 <div class="alert alert-dark m-0" id="NoFiltersAlert_@Model.ID"> 210 @Translate("No filters are available") 211 </div> 212 } 213 } 214 215 @* CUSTOM parameter *@ 216 @helper RenderForm(ProductListViewModel productList, string deviceType, bool enableSorting, List<GroupFacetRelation> groupFacetRelations, string layout = "vertical") 217 { 218 string groupId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID") : ""; 219 220 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 221 string pageSize = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("PageSize")) ? Dynamicweb.Context.Current.Request.QueryString.Get("PageSize") : productList.PageSize.ToString(); 222 223 string searchQuery = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("q")) ? Dynamicweb.Context.Current.Request.QueryString.Get("q") : ""; 224 string searchLayout = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SearchLayout")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SearchLayout") : ""; 225 226 string groupsTheme = ""; 227 string extraBottomMargin = ""; 228 if (deviceType != "mobile") 229 { 230 groupsTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("FacetGroupsTheme")) ? " theme " + Model.Item.GetRawValueString("FacetGroupsTheme").Replace(" ", "").Trim().ToLower() : ""; 231 extraBottomMargin = !string.IsNullOrEmpty(groupsTheme) ? "mb-3" : ""; 232 } 233 234 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 235 contentPadding = contentPadding == "none" ? " px-0 py-2" : contentPadding; 236 contentPadding = contentPadding == "small" ? " px-3 py-2" : contentPadding; 237 238 <input type="hidden" name="PageSize" value="@pageSize"> 239 240 if (!string.IsNullOrEmpty(searchQuery)) 241 { 242 <input type="hidden" name="q" value="@searchQuery"> 243 <input type="hidden" name="SearchLayout" value="@searchLayout"> 244 } 245 246 if (Model.Item.GetBoolean("EnableGroupNavigation")) 247 { 248 int startLevel = Convert.ToInt32(Model.Item.GetRawValueString("GroupNavigationStartLevel", "2")); 249 int stopLevel = Convert.ToInt32(Model.Item.GetRawValueString("GroupNavigationStopLevel", "9")); 250 251 var navigationSettings = new NavigationSettings(); 252 navigationSettings.StartLevel = startLevel; 253 navigationSettings.StopLevel = stopLevel; 254 navigationSettings.Parameters.Add("ID", deviceType); 255 navigationSettings.Parameters.Add("HideTexts", false); 256 navigationSettings.Parameters.Add("HideIcons", true); 257 navigationSettings.Parameters.Add("ContentPadding", contentPadding); 258 navigationSettings.ExpandMode = ExpandMode.All; 259 navigationSettings.Parameters.Add("menu-id", "product-list-facets"); 260 261 if (layout == "vertical") 262 { 263 // CUSTOM css 264 <div class="border-bottom d-none d-lg-block py-2@(@groupsTheme)"> 265 <div class="d-flex@(contentPadding)" data-bs-toggle="collapse" data-bs-target="#ProductGroupNavigation_@(deviceType)_@Model.ID" role="button" aria-expanded="true" aria-controls="ProductGroupNavigation_@(deviceType)_@Model.ID"> 266 <h2 class="opacity-85 m-0 flex-fill h6">@Translate("Navigation")</h2> 267 <div class="my-auto collapse-chevron-icon"></div> 268 </div> 269 <div class="collapse show" id="ProductGroupNavigation_@(deviceType)_@Model.ID"> 270 @Navigation.RenderNavigation("Navigation/Vertical.cshtml", navigationSettings) 271 </div> 272 </div> 273 } 274 } 275 276 if (enableSorting) 277 { 278 if (layout == "vertical") 279 { 280 <div class="border-bottom@(contentPadding)@(groupsTheme)"> 281 <h2 class="opacity-85 m-0 my-2 flex-fill h6">@Translate("Sort by")</h2> 282 <div class="d-flex flex-column gap-2" id="SortBy_@(deviceType)_@Model.ID"> 283 @{ 284 @RenderSorting(deviceType) 285 } 286 </div> 287 </div> 288 } 289 if (layout == "horizontal") 290 { 291 <button class="btn @(groupsTheme) dropdown-toggle" type="button" id="SortBy_@(deviceType)_@Model.ID" data-bs-toggle="dropdown" aria-expanded="false"> 292 @Translate("Sort by") 293 </button> 294 <div class="dropdown-menu p-3 @(groupsTheme)" aria-labelledby="SortBy_@(deviceType)_@Model.ID" style="min-width: 280px"> 295 <div class="d-flex flex-column gap-2"> 296 @{ 297 @RenderSorting(deviceType) 298 } 299 </div> 300 </div> 301 } 302 } 303 304 int groupCount = 0; 305 int maxGroups = 8; 306 int totalGroups = productList?.FacetGroups != null ? productList.FacetGroups.Count() : 0; 307 308 if (productList.FacetGroups != null) 309 { 310 foreach (FacetGroupViewModel facetGroup in productList.FacetGroups) 311 { 312 string border = groupCount != totalGroups ? "border-bottom" : ""; 313 314 foreach (FacetViewModel facet in facetGroup.Facets) 315 { 316 string collapseClass = string.Empty; 317 string showClass = " show"; 318 string ariaExpanded = "true"; 319 var expandedFacetGroups = Model.Item.GetRawValueString("ExpandFacetGroups", "all"); 320 321 if (expandedFacetGroups != "all" && System.Text.RegularExpressions.Regex.IsMatch(expandedFacetGroups, "([0-9])")) 322 { 323 if (groupCount >= Dynamicweb.Core.Converter.ToInt32(expandedFacetGroups)) 324 { 325 collapseClass = " collapsed"; 326 showClass = string.Empty; 327 ariaExpanded = "false"; 328 } 329 } 330 331 if (facet.Options.Count() > 0 && facet.RenderType != "OnSale" && GroupFacetRelationEnable(groupFacetRelations, facetGroup.Name, facet.FacetField)) 332 { 333 if (layout == "vertical") 334 { 335 <div class="@border@(contentPadding)@(@groupsTheme)"> 336 <div class="d-flex@(collapseClass)" data-bs-toggle="collapse" data-bs-target="#FacetGroup_@facet.QueryParameter.ToLower()_@(deviceType)_@Model.ID" role="button" aria-expanded="@ariaExpanded" aria-controls="FacetGroup_@facet.QueryParameter.ToLower()_@(deviceType)_@Model.ID"> 337 <h2 class="opacity-85 m-0 flex-fill h6 my-2">@Translate("Custom:Facet." + facet.Name, facet.Name)</h2> 338 <div class="my-auto collapse-chevron-icon"></div> 339 </div> 340 <div class="collapse@(showClass)" id="FacetGroup_@facet.QueryParameter.ToLower()_@(deviceType)_@Model.ID"> 341 @foreach (FacetOptionViewModel facetOption in facet.Options.OrderBy(i => Translate("Custom:FacetOption." + i.Label, i.Label))) 342 { 343 string renderType = facet.RenderType; 344 345 if (renderType == "Colors") 346 { 347 @RenderColorOption(facet, facetOption) 348 } 349 else 350 { 351 @RenderCheckboxOption(facet, facetOption) 352 } 353 } 354 </div> 355 </div> 356 } 357 if (layout == "horizontal") 358 { 359 string hideSelector = groupCount < maxGroups ? "" : "d-none"; 360 int selectedFacetsInGroup = 0; 361 362 foreach (FacetOptionViewModel option in facet.Options) 363 { 364 if (option.Selected) 365 { 366 selectedFacetsInGroup++; 367 } 368 } 369 370 string label = selectedFacetsInGroup > 0 ? Translate("Custom:Facet." + facet.Name, facet.Name) + "<span class=\"badge bg-dark opacity-50 text-white ms-2\">" + selectedFacetsInGroup + "</span>" : Translate("Custom:Facet." + facet.Name, facet.Name); 371 // CUSTOM: removed dropdown css class to prevent hover dropdown 372 <div class="@hideSelector js-facets-selector"> 373 <button class="btn @(groupsTheme) dropdown-toggle" type="button" id="FacetGroup_@facet.Name.Replace(" ", "")_@(deviceType)_@Model.ID" data-bs-toggle="dropdown" aria-expanded="false"> 374 @label 375 </button> 376 <div class="dropdown-menu p-3 @(groupsTheme)" aria-labelledby="FacetGroup_@facet.Name.Replace(" ", "")_@(deviceType)_@Model.ID" style="min-width: 280px"> 377 @foreach (FacetOptionViewModel facetOption in facet.Options.OrderBy(i => Translate("Custom:FacetOption." + i.Label, i.Label))) 378 { 379 string renderType = facet.RenderType; 380 381 if (renderType == "Colors") 382 { 383 @RenderColorOption(facet, facetOption) 384 } 385 else 386 { 387 @RenderCheckboxOption(facet, facetOption) 388 } 389 } 390 </div> 391 </div> 392 } 393 394 groupCount++; 395 } 396 else if (facet.Options.Count() > 0 && facet.RenderType == "OnSale") 397 { 398 var contextCurrency = Smartpage.EvaSolo.CampaignPrices.Helpers.OnSaleHelper.GetOnSaleParameterValue(); 399 400 if (facet.Options.Where(o => o.Count > 0 && o.Value == contextCurrency).Any()) 401 { 402 if (layout == "vertical") 403 { 404 <div class="@border@(contentPadding)@(@groupsTheme)"> 405 <div class="d-flex@(collapseClass)" data-bs-toggle="collapse" data-bs-target="#FacetGroup_@facet.Name.Replace(" ", "")_@(deviceType)_@Model.ID" role="button" aria-expanded="@ariaExpanded" aria-controls="FacetGroup_@facet.Name.Replace(" ", "")_@(deviceType)_@Model.ID"> 406 <h2 class="opacity-85 m-0 flex-fill h6 my-2">@Translate("Custom:Facet." + facet.Name, facet.Name)</h2> 407 <div class="my-auto collapse-chevron-icon"></div> 408 </div> 409 <div class="collapse@(showClass)" id="FacetGroup_@facet.Name.Replace(" ", "")_@(deviceType)_@Model.ID"> 410 @foreach (FacetOptionViewModel facetOption in facet.Options.Where(o => o.Value == contextCurrency)) 411 { 412 @RenderOnSaleOption(facet, facetOption) 413 } 414 </div> 415 </div> 416 } 417 if (layout == "horizontal") 418 { 419 string hideSelector = groupCount < maxGroups ? "" : "d-none"; 420 int selectedFacetsInGroup = Context.Current.Request.GetBoolean(facet.QueryParameter) ? 1 : 0; 421 422 string label = selectedFacetsInGroup > 0 ? Translate("Custom:Facet." + facet.Name, facet.Name) + "<span class=\"badge bg-dark opacity-50 text-white ms-2\">" + selectedFacetsInGroup + "</span>" : Translate("Custom:Facet." + facet.Name, facet.Name); 423 // CUSTOM: removed dropdown css class to prevent hover dropdown 424 <div class="@hideSelector js-facets-selector"> 425 <button class="btn @(groupsTheme) dropdown-toggle" type="button" id="FacetGroup_@facet.Name.Replace(" ", "")_@(deviceType)_@Model.ID" data-bs-toggle="dropdown" aria-expanded="false"> 426 @label 427 </button> 428 <div class="dropdown-menu p-3 @(groupsTheme)" aria-labelledby="FacetGroup_@facet.Name.Replace(" ", "")_@(deviceType)_@Model.ID" style="min-width: 280px"> 429 @foreach (FacetOptionViewModel facetOption in facet.Options.Where(o => o.Value == contextCurrency)) 430 { 431 @RenderOnSaleOption(facet, facetOption) 432 } 433 </div> 434 </div> 435 } 436 437 groupCount++; 438 } 439 } 440 } 441 } 442 } 443 444 if ((groupCount > maxGroups) && layout == "horizontal") 445 { 446 <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> 447 } 448 } 449 450 @helper RenderSorting(string deviceType) 451 { 452 var sortByPriceKey = $"ProductPrice|{Dynamicweb.Ecommerce.Common.Context.Currency.Code}|{Dynamicweb.Ecommerce.Common.Context.Country.Code2}|WithVAT"; 453 454 string sortBySelection = Dynamicweb.Context.Current.Request?.Form["SortBy"] ?? ""; 455 sortBySelection = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("SortBy")) ? Dynamicweb.Context.Current.Request.QueryString.Get("SortBy") : sortBySelection; 456 string sortNameSelectedRelevance = sortBySelection.ToLower() == "" || sortBySelection.ToLower() == "relevance" ? "checked" : ""; 457 string sortNameSelectedAZ = sortBySelection.ToLower() == "nameforsort" ? "checked" : ""; 458 string sortNameSelectedZA = sortBySelection.ToLower() == "-nameforsort" ? "checked" : ""; 459 string sortPriceLowSelected = sortBySelection.ToLower() == $"{sortByPriceKey.ToLower()}" ? "checked" : ""; 460 string sortPriceHighSelected = sortBySelection.ToLower() == $"-{sortByPriceKey.ToLower()}" ? "checked" : ""; 461 string sortNewSelected = sortBySelection.ToLower() == "-created" ? "checked" : ""; 462 string sortMostSoldSelected = sortBySelection.ToLower() == "-ordercount" ? "checked" : ""; 463 464 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 465 bool anonymousUser = Pageview.User == null; 466 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser; 467 468 if (Model.Item.GetBoolean("SortByRelevance")) 469 { 470 <div class="form-check"> 471 <input class="form-check-input" onchange="swift.ProductList.Update(event)" type="radio" name="SortBy" value="" id="SortByRelevance_@(deviceType)_@Model.ID" @sortNameSelectedRelevance> 472 <label class="form-check-label" for="SortByRelevance_@(deviceType)_@Model.ID"> 473 @Translate("Relevance") 474 </label> 475 </div> 476 } 477 if (Model.Item.GetBoolean("SortByNameAZ")) 478 { 479 <div class="form-check"> 480 <input class="form-check-input" onchange="swift.ProductList.Update(event)" type="radio" name="SortBy" value="NameForSort" id="SortByNameAZ_@(deviceType)_@Model.ID" @sortNameSelectedAZ> 481 <label class="form-check-label" for="SortByNameAZ_@(deviceType)_@Model.ID"> 482 @Translate("Name (A-Z)") 483 </label> 484 </div> 485 } 486 if (Model.Item.GetBoolean("SortByNameZA")) 487 { 488 <div class="form-check"> 489 <input class="form-check-input" onchange="swift.ProductList.Update(event)" type="radio" name="SortBy" value="-NameForSort" id="SortByNameZA_@(deviceType)_@Model.ID" @sortNameSelectedZA> 490 <label class="form-check-label" for="SortByNameZA_@(deviceType)_@Model.ID"> 491 @Translate("Name (Z-A)") 492 </label> 493 </div> 494 } 495 if (Model.Item.GetBoolean("SortByNewest")) 496 { 497 <div class="form-check"> 498 <input class="form-check-input" onchange="swift.ProductList.Update(event)" type="radio" name="SortBy" value="-created" id="SortByNew_@(deviceType)_@Model.ID" @sortNewSelected> 499 <label class="form-check-label" for="SortByNew_@(deviceType)_@Model.ID"> 500 @Translate("Newest") 501 </label> 502 </div> 503 } 504 if (!hidePrice) 505 { 506 507 if (Model.Item.GetBoolean("SortByLowestPrice")) 508 { 509 <div class="form-check"> 510 <input class="form-check-input" onchange="swift.ProductList.Update(event)" type="radio" name="SortBy" value="@(sortByPriceKey)" id="SortByPriceLow_@(deviceType)_@Model.ID" @sortPriceLowSelected> 511 <label class="form-check-label" for="SortByPriceLow_@(deviceType)_@Model.ID"> 512 @Translate("Lowest price") 513 </label> 514 </div> 515 } 516 if (Model.Item.GetBoolean("SortByHighestPrice")) 517 { 518 <div class="form-check"> 519 <input class="form-check-input" onchange="swift.ProductList.Update(event)" type="radio" name="SortBy" value="-@(sortByPriceKey)" id="SortByPriceHigh_@(deviceType)_@Model.ID" @sortPriceHighSelected> 520 <label class="form-check-label" for="SortByPriceHigh_@(deviceType)_@Model.ID"> 521 @Translate("Highest price") 522 </label> 523 </div> 524 } 525 } 526 if (Model.Item.GetBoolean("SortByMostSold")) 527 { 528 <div class="form-check"> 529 <input class="form-check-input" onchange="swift.ProductList.Update(event)" type="radio" name="SortBy" value="-OrderCount" id="SortByMostSold_@(deviceType)_@Model.ID" @sortMostSoldSelected> 530 <label class="form-check-label" for="SortByMostSold_@(deviceType)_@Model.ID"> 531 @Translate("Most sold") 532 </label> 533 </div> 534 } 535 } 536 537 @helper RenderCheckboxOption(FacetViewModel facet, FacetOptionViewModel facetOption) 538 { 539 string facetLabel = HtmlEncoder.HtmlEncode(facetOption.Label); 540 string disabled = facetOption.Count <= 0 ? "disabled" : ""; 541 string selected = facetOption.Selected ? "checked" : ""; 542 543 if (facetLabel.ToLower() == "true") 544 { 545 facetLabel = Translate("Yes"); 546 facetOption.Label = facetLabel; 547 } 548 549 if (facetLabel.ToLower() == "false") 550 { 551 facetLabel = Translate("No"); 552 facetOption.Label = facetLabel; 553 } 554 555 <label class="form-check mt-1" @disabled> 556 <input type="checkbox" onclick="swift.ProductList.Update(event)" class="form-check-input" name="@facet.QueryParameter" value="[@facetOption.Value]" data-filter-value="@facetLabel" @selected> 557 <span class="form-check-label d-flex align-items-center"> 558 <span class="flex-fill">@Translate("Custom:FacetOption." + facetOption.Label, facetOption.Label) </span> 559 @if (facet.FacetType.ToLower() == "field") 560 { 561 <small class="opacity-85">@facetOption.Count</small> 562 } 563 </span> 564 </label> 565 } 566 567 @helper RenderColorOption(FacetViewModel facet, FacetOptionViewModel facetOption) 568 { 569 string facetLabel = HtmlEncoder.HtmlEncode(facetOption.Label); 570 string disabled = facetOption.Count <= 0 ? "disabled" : ""; 571 string selected = facetOption.Selected ? "checked" : ""; 572 573 string image = facetOption.Value; 574 string colorCode = facetOption.Value; 575 576 var variantOption = Dynamicweb.Ecommerce.Services.VariantOptions.GetVariantOption(facetOption.Value.ToString()); 577 if (variantOption != null) 578 { 579 image = variantOption.LargeImage; 580 colorCode = variantOption.Color; 581 } 582 583 <div class="colorbox"> 584 <label> 585 <input type="checkbox" onclick="swift.ProductList.Update(event)" class="@disabled @selected" name="@facet.QueryParameter" value="[@facetOption.Value]" data-filter-value="@facetLabel" @selected title="@HtmlEncoder.HtmlAttributeEncode(facetOption.Label)"> 586 @if (colorCode.Contains("#")) 587 { 588 <span class="colorbox-background" style="background-color: @colorCode"></span> 589 <span class="visually-hidden">@Translate("Custom:FacetOption." + facetOption.Label, facetOption.Label)</span> 590 } 591 else 592 { 593 <img class="colorbox-background" src="/Admin/Public/GetImage.ashx?width=25&height=25&image=@image"> 594 <span class="visually-hidden">@Translate("Custom:FacetOption." + facetOption.Label, facetOption.Label)</span> 595 } 596 </label> 597 </div> 598 } 599 600 @helper RenderOnSaleOption(FacetViewModel facet, FacetOptionViewModel facetOption) 601 { 602 facetOption.Label = Translate("Custom:Facet.Label.OnSale", "Yes"); 603 facetOption.Value = "True"; 604 605 string facetLabel = HtmlEncoder.HtmlEncode(facetOption.Label); 606 string selected = Context.Current.Request.GetBoolean(facet.QueryParameter) ? "checked" : ""; 607 608 <label class="form-check mt-1"> 609 <input type="checkbox" onclick="swift.ProductList.Update(event)" class="form-check-input" name="@facet.QueryParameter" value="@facetOption.Value" data-filter-value="@facetLabel" @selected> 610 <span class="form-check-label d-flex align-items-center"> 611 <span class="flex-fill">@facetOption.Label </span> 612 @if (facet.FacetType.ToLower() == "field") 613 { 614 <small class="opacity-85">@facetOption.Count</small> 615 } 616 </span> 617 </label> 618 } 619

249,95 kr. OutOfStock
1296 out of 2686 products
Load more products