go walk

1.000,00 kr. OutOfStock
Error executing template "Designs/Swift/Components/VariantSelector_Custom.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at Dynamicweb.Ecommerce.Products.ProductExtentions.GetIsVariantMaster(Product product)
   at CompiledRazorTemplates.Dynamic.RazorEngine_f495584c1b034519a1279cb0bf0e05a8.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.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, 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 System.Collections.Generic 3 @using System.Linq 4 @using Dynamicweb.Ecommerce.ProductCatalog 5 @using Dynamicweb.Ecommerce.Variants 6 @using Dynamicweb.Frontend 7 @using Dynamicweb.Ecommerce.Products 8 9 @functions { 10 //Find contrast color (white, black) 11 public static string GetContrastColor(string hexString) 12 { 13 System.Drawing.Color bg = System.Drawing.ColorTranslator.FromHtml(hexString); 14 15 int nThreshold = 105; 16 int bgDelta = Convert.ToInt32((bg.R * 0.299) + (bg.G * 0.587) + 17 (bg.B * 0.114)); 18 19 string foreColor = (255 - bgDelta < nThreshold) ? "#333" : "#fff"; 20 return foreColor; 21 } 22 23 public string GetLayoutForVariantGroup(string variantGroupId) 24 { 25 string showVariantGroups = Model.Item?.GetRawValueString("ShowVariantGroupOptions"); 26 var selectedVariantGroupsList = Model.Item?.GetItems("VariantGroups") ?? new List<ItemViewModel>(); 27 bool showAllVariantGroupsDefault = string.IsNullOrEmpty(showVariantGroups) || selectedVariantGroupsList == null || !selectedVariantGroupsList.Any(); 28 string defaultVariantGroupLayout = Model.Item?.GetRawValueString("DefaultVariantGroupLayout"); 29 defaultVariantGroupLayout = !string.IsNullOrEmpty(defaultVariantGroupLayout) ? defaultVariantGroupLayout : "button"; 30 31 if (showAllVariantGroupsDefault) return defaultVariantGroupLayout; 32 33 foreach (var selectedVariantGroupListItem in selectedVariantGroupsList) 34 { 35 var variantGroups = selectedVariantGroupListItem.GetList("VariantGroups").GetRawValue().OfType<string>().ToList(); 36 if (variantGroups.Any(s => s.Equals(variantGroupId))) return selectedVariantGroupListItem.GetRawValueString("VariantGroupLayout"); 37 } 38 39 return defaultVariantGroupLayout; 40 } 41 42 //Collect all variant images 43 public static Dictionary<string, string> GetVariantImages(List<VariantInfoViewModel> variantInfo, Dictionary<string, string> list) 44 { 45 foreach (var variantGroup in variantInfo) 46 { 47 if (variantGroup.Image?.Value != null && !list.ContainsKey(variantGroup.OptionID)) 48 { 49 list.Add(variantGroup.OptionID, variantGroup.Image.Value); 50 } 51 52 if (variantGroup.VariantInfo != null) 53 { 54 GetVariantImages(variantGroup.VariantInfo, list); 55 } 56 } 57 58 return list; 59 } 60 61 private string GetDefaultOrVariantGroupValue(string variantGroupId, string itemField, string itemFieldDefaultValue, Dictionary<string, string> fieldValueMapping) 62 { 63 if (!string.IsNullOrEmpty(variantGroupId)) 64 { 65 string itemFieldValue = Model.Item?.GetRawValueString(itemField, itemFieldDefaultValue); 66 string itemFieldParameter = GetViewParameterString(itemField); 67 itemFieldValue = string.IsNullOrEmpty(itemFieldValue) && !string.IsNullOrEmpty(itemFieldParameter) ? itemFieldParameter : itemFieldValue; 68 69 if (fieldValueMapping != null && !string.IsNullOrEmpty(itemFieldValue) && fieldValueMapping.Any()) 70 { 71 itemFieldValue = fieldValueMapping.ContainsKey(itemFieldValue) ? fieldValueMapping[itemFieldValue] : itemFieldValue; 72 } 73 74 // If no variantGroup (i.e. Visual Editor), return default value 75 if (string.IsNullOrEmpty(variantGroupId)) return itemFieldValue; 76 77 string showVariantGroups = Model.Item?.GetString("ShowVariantGroupOptions", "all"); 78 var selectedVariantGroupsList = Model.Item?.GetItems("VariantGroups") ?? new List<ItemViewModel>(); 79 // If no exceptions or settings are all the same, return default value 80 if (showVariantGroups == "all" || selectedVariantGroupsList == null || !selectedVariantGroupsList.Any()) return itemFieldValue; 81 82 // Get specific value for variant group 83 foreach (var selectedVariantGroupListItem in selectedVariantGroupsList) 84 { 85 var variantGroups = selectedVariantGroupListItem.GetList("VariantGroups").GetRawValue().OfType<string>().ToList(); 86 if (!variantGroups.Any(s => s.Equals(variantGroupId))) continue; 87 88 itemFieldValue = selectedVariantGroupListItem.GetRawValueString(itemField, itemFieldDefaultValue); 89 itemFieldValue = fieldValueMapping.ContainsKey(itemFieldValue) ? fieldValueMapping[itemFieldValue] : itemFieldValue; 90 } 91 92 return itemFieldValue; 93 } 94 else 95 { 96 return string.Empty; 97 } 98 } 99 100 private bool GetDefaultOrVariantGroupValue(string variantGroupId, string itemField) 101 { 102 if (!string.IsNullOrEmpty(variantGroupId)) 103 { 104 bool itemFieldValue = Model.Item?.GetBoolean(itemField) ?? false; 105 106 // If no variantGroup (i.e. Visual Editor), return default value 107 if (string.IsNullOrEmpty(variantGroupId)) return itemFieldValue; 108 109 string showVariantGroups = Model.Item?.GetString("ShowVariantGroupOptions", "all"); 110 var selectedVariantGroupsList = Model.Item?.GetItems("VariantGroups") ?? new List<ItemViewModel>(); 111 // If no exceptions or settings are all the same, return default value 112 if (showVariantGroups == "all" || selectedVariantGroupsList == null || !selectedVariantGroupsList.Any()) return itemFieldValue; 113 114 // Get specific value for variant group 115 foreach (var selectedVariantGroupListItem in selectedVariantGroupsList) 116 { 117 var variantGroups = selectedVariantGroupListItem.GetList("VariantGroups").GetRawValue().OfType<string>().ToList(); 118 if (!variantGroups.Any(s => s.Equals(variantGroupId))) continue; 119 120 itemFieldValue = selectedVariantGroupListItem.GetBoolean(itemField); 121 } 122 123 return itemFieldValue; 124 } 125 else 126 { 127 return false; 128 } 129 } 130 } 131 132 @{ 133 ProductViewModel product = null; 134 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 135 { 136 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 137 } 138 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 139 { 140 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 141 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 142 143 if (productList?.Products is object) 144 { 145 product = productList.Products[0]; 146 } 147 } 148 //CUSTOM CODE 149 string baseURL = string.Empty; 150 } 151 152 @if ((product is object)) 153 { 154 155 bool hideGroupHeaders = !string.IsNullOrEmpty(Model?.Item?.GetString("HideGroupHeaders")) ? Model.Item.GetBoolean("HideGroupHeaders") : false; 156 var productVariantGroups = product.VariantGroups(); 157 158 string itemId = Model?.Item?.SystemName != null ? $"item_{Model.Item.SystemName.ToLower()}" : string.Empty; 159 160 bool isModalSelector = Model?.Item == null; 161 string target = isModalSelector ? "data-response-target-element=\"DynamicModalContent\"" : string.Empty; 162 163 string variantSelectorServicePageId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("VariantSelectorServicePage")) ? Dynamicweb.Context.Current.Request.Form.Get("VariantSelectorServicePage") : string.Empty; 164 string formAction = isModalSelector ? $"action=\"/Default.aspx?ID={variantSelectorServicePageId}\"" : string.Empty; 165 166 string getProductInfo = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["getproductinfo"]) ? Dynamicweb.Context.Current.Request.Form["getproductinfo"] : string.Empty; 167 168 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 169 { 170 string[] variantId = product.VariantId.Split('.'); 171 int groupNumber = 1; 172 173 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 174 string variantUrl = string.Empty; 175 if (!string.IsNullOrEmpty(product.VariantId) && !isModalSelector) 176 { 177 variantUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl($"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}&VariantID={product.VariantId}"); 178 } 179 // CUSTOM CODE 180 baseURL = $"/Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}&VariantID="; 181 Dictionary<string, string> variantImages = new Dictionary<string, string>(); 182 variantImages = GetVariantImages(product.VariantInfo.VariantInfo, variantImages); 183 184 <form @formAction class="d-flex flex-column gap-2 js-variant-selector @itemId" @target data-combinations="@string.Join(",", product.VariantCombinations())" data-base-url="@baseUrl" data-friendly-url="@variantUrl"> 185 @if (isModalSelector) 186 { 187 <input type="hidden" name="productId" value="@product.Id"> 188 <input type="hidden" name="variantid" value="@product.VariantId"> 189 <input type="hidden" name="QuantitySelector" value="true"> 190 <input type="hidden" name="VariantSelectorServicePage" value="@variantSelectorServicePageId"> 191 <input type="hidden" name="ViewType" value="ModalContent"> 192 193 if (GetViewParameter("ButtonLayout") != null) 194 { 195 <input type="hidden" name="ButtonLayout" value="@GetViewParameter("ButtonLayout")"> 196 } 197 198 if (GetViewParameter("ButtonAspectRatio") != null) 199 { 200 <input type="hidden" name="ButtonAspectRatio" value="@GetViewParameter("ButtonAspectRatio")"> 201 } 202 203 if (!string.IsNullOrEmpty(getProductInfo)) 204 { 205 <input type="hidden" name="getproductinfo" value="@getProductInfo"> 206 } 207 } 208 209 @foreach (var variantGroup in productVariantGroups) 210 { 211 VariantGroupViewModel group = variantGroup; 212 string variantGroupLayout = GetLayoutForVariantGroup(variantGroup.Id) ?? "button"; 213 string horizontalAlign = GetDefaultOrVariantGroupValue(variantGroup.Id, "HorizontalAlignment", "", new Dictionary<string, string> { { "center", "justify-content-center" }, { "end", "justify-content-end" } }); 214 string horizontalTextAlign = GetDefaultOrVariantGroupValue(variantGroup.Id, "HorizontalAlignment", "", new Dictionary<string, string> { { "center", "text-center" }, { "end", "text-end" } }); 215 bool showSelectedOptionName = GetDefaultOrVariantGroupValue(variantGroup.Id, "ShowSelectedOptionName"); 216 217 <div> 218 @if (!hideGroupHeaders) 219 { 220 <h3 class="h6 @horizontalTextAlign"> 221 @group.Name 222 223 @if (showSelectedOptionName) 224 { 225 string selectedOptionName = group.Options.FirstOrDefault(opt => variantId.Contains(opt.Id))?.Name ?? string.Empty; 226 <span class="fw-light px-1 swift-selected-option-name">@selectedOptionName</span> 227 } 228 </h3> 229 } 230 <div class="d-flex gap-2 @horizontalAlign flex-wrap js-variant-group" data-group-id="@groupNumber"> 231 @if (variantGroupLayout == "button") 232 { 233 234 foreach (var option in group.Options) 235 { 236 @* CUSTOM CODE *@ 237 string productColor = product.VariantId.Split('.').FirstOrDefault() ?? ""; 238 string productSize = option.Id.Split('.').LastOrDefault() ?? ""; 239 string variantCombination = productColor + "." + productSize; 240 Product currentOptionProduct = Dynamicweb.Ecommerce.Services.Products.GetProductById(product.Id, variantCombination, Pageview.Area.EcomLanguageId); 241 242 bool isVariantMaster = currentOptionProduct.GetIsVariantMaster(); 243 244 Dictionary<string, bool> hasValidVariantOptionsByMaster = new Dictionary<string, bool>(); 245 Dictionary<string, List<string>> validSizesByColorId = new Dictionary<string, List<string>>(); 246 if (isVariantMaster) 247 { 248 var allVariantsOfMasterProduct = Dynamicweb.Ecommerce.Services.Products.GetProductsAndVariantsByProduct(currentOptionProduct).ToList(); 249 List<string> validVariantsList = new List<string>(); 250 251 foreach (var variant in allVariantsOfMasterProduct) 252 { 253 var colorId = variant.VariantId.Split('.').First() ?? ""; 254 if (!string.IsNullOrEmpty(colorId) && !hasValidVariantOptionsByMaster.ContainsKey(colorId)) 255 { 256 hasValidVariantOptionsByMaster[colorId] = false; 257 foreach (var variantProduct in allVariantsOfMasterProduct) 258 { 259 if (variantProduct.VariantId.Contains(colorId)) 260 { 261 if (variantProduct.Stock > 0) 262 { 263 if (!validSizesByColorId.ContainsKey(colorId)) 264 { 265 validSizesByColorId.Add(colorId, new List<string>()); 266 } 267 hasValidVariantOptionsByMaster[colorId] = true; 268 validSizesByColorId[colorId].Add(variantProduct.VariantId); 269 } 270 } 271 } 272 } 273 274 } 275 276 277 } 278 279 bool isOptionProductOutOfStock = currentOptionProduct.Stock <= 0 ? true : false; 280 var skipMaster = true; 281 282 foreach (var item in hasValidVariantOptionsByMaster) 283 { 284 if (item.Value) 285 { 286 if (option.Id.Contains(item.Key)) 287 { 288 skipMaster = false; 289 } 290 291 } 292 } 293 294 if (isVariantMaster && skipMaster) 295 { 296 continue; 297 } 298 299 if (!isVariantMaster && currentOptionProduct.Stock <= 0) 300 { 301 continue; 302 } 303 304 if (isVariantMaster && !validSizesByColorId.ContainsKey(option.Id)) 305 { 306 continue; 307 } 308 309 @* END OF CUSTOM CODE *@ 310 311 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 312 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 313 string contrastColor = string.Empty; 314 string buttonAspectRatio = GetDefaultOrVariantGroupValue(variantGroup.Id, "ButtonAspectRatio", "100%", new Dictionary<string, string> { { "100%", "--bs-aspect-ratio:100%" }, { "56%", "--bs-aspect-ratio:56%" }, { "177%", "--bs-aspect-ratio:177%" }, { "75%", "--bs-aspect-ratio:75%" }, { "133%", "--bs-aspect-ratio:133%" } }); 315 buttonAspectRatio = buttonAspectRatio == string.Empty ? "--bs-aspect-ratio:100%" : buttonAspectRatio; 316 317 string buttonLayout = GetDefaultOrVariantGroupValue(variantGroup.Id, "ButtonLayout", "rounded-circle", new Dictionary<string, string> { { "round", "rounded-circle" }, { "square", "rounded-0" }, { "square-rounded", "rounded-3" } }); 318 string buttonTextLayout = GetDefaultOrVariantGroupValue(variantGroup.Id, "ButtonTextLayout", "", new Dictionary<string, string> { { "default", "" }, { "square", "rounded-0" }, { "square-rounded", "rounded-3" } }); 319 var displayType = group.DisplayType; 320 displayType = displayType == VariantGroupDisplayType.NothingSelected && !string.IsNullOrEmpty(option.Color) ? VariantGroupDisplayType.VariantColor : displayType; 321 displayType = displayType == VariantGroupDisplayType.NothingSelected && string.IsNullOrEmpty(option.OptionImage.Value) && string.IsNullOrEmpty(option.Color) ? VariantGroupDisplayType.VariantName : displayType; 322 displayType = displayType == VariantGroupDisplayType.NothingSelected && !string.IsNullOrEmpty(option.OptionImage.Value) ? VariantGroupDisplayType.VariantOptionImage : displayType; 323 324 var btnWidth = displayType == VariantGroupDisplayType.VariantColor || displayType == VariantGroupDisplayType.VariantImage || displayType == VariantGroupDisplayType.VariantOptionImage ? $"style=\"width:64px\"" : string.Empty; 325 var btnClasses = string.Empty; 326 327 btnClasses = displayType == VariantGroupDisplayType.VariantColor ? $"overflow-hidden colorbox colorbox-auto p-0 border {buttonLayout}" : btnClasses; 328 btnClasses = displayType == VariantGroupDisplayType.VariantImage ? $"overflow-hidden p-0 {buttonLayout}" : btnClasses; 329 btnClasses = displayType == VariantGroupDisplayType.VariantOptionImage ? $"overflow-hidden colorbox colorbox-auto {buttonLayout} p-0" : btnClasses; 330 btnClasses = displayType == VariantGroupDisplayType.VariantName ? $"btn-secondary {buttonTextLayout}" : btnClasses; 331 332 var variantOptions = product.VariantId.Split("."); 333 334 string? selectedVariant = variantOptions.LastOrDefault(); 335 string? selectedMasterVariant = variantOptions.FirstOrDefault(); 336 337 <button type="button" 338 class="btn @btnClasses d-inline-block variant-option js-variant-option @active @(isVariantMaster ? "is-master" : string.Empty) @(isOptionProductOutOfStock ? "product-out-of-stock" : string.Empty)" @btnWidth 339 onclick="swift.VariantSelector.OptionClick(event)" 340 data-selected-master-variant="@selectedMasterVariant" 341 data-selectedvariant="@selectedVariant" 342 data-variant-id="@option.Id" id="@(product.Id)_@(option.Id)_@Pageview.CurrentParagraph.ID" 343 @(isVariantMaster ? "data-validvariants=" + string.Join(",", validSizesByColorId[option.Id]) : string.Empty)> 344 <div class="@(displayType == VariantGroupDisplayType.VariantName ? string.Empty : "ratio")" style="@(buttonAspectRatio)"> 345 346 @switch (displayType) 347 { 348 case VariantGroupDisplayType.VariantOptionImage: 349 if (!string.IsNullOrEmpty(option.OptionImage.Value)) 350 { 351 <img style="object-fit:cover;--variantoption-check-color:@(contrastColor)" src="/Admin/Public/GetImage.ashx?image=@(option.OptionImage.Value)&width=64&format=webp"> 352 } 353 else if (!string.IsNullOrEmpty(option.Color)) 354 { 355 <span class="" style="background-color:@(option.Color);--variantoption-check-color:@(contrastColor)"><span class="visually-hidden">@option.Color</span></span> 356 } 357 else 358 { 359 <span class="d-flex align-items-center justify-content-center">@(option.Name)</span> 360 } 361 break; 362 363 case VariantGroupDisplayType.VariantImage: 364 string variantImage = string.Empty; 365 variantImages.TryGetValue(option.Id, out variantImage); 366 <img class="theme" style="object-fit:contain" src="/Admin/Public/GetImage.ashx?image=@(variantImage)&width=64&format=webp"> 367 break; 368 369 case VariantGroupDisplayType.VariantColor: 370 contrastColor = GetContrastColor(option.Color); 371 <span class="" style="background-color:@(option.Color);--variantoption-check-color:@(contrastColor)"><span class="visually-hidden">@option.Color</span></span> 372 break; 373 374 case VariantGroupDisplayType.VariantName: 375 <span class="d-flex align-items-center justify-content-center">@(option.Name)</span> 376 break; 377 378 } 379 </div> 380 </button> 381 } 382 } 383 else 384 { 385 <select class="form-select" id="VariantDropdown_@variantGroup.Id" aria-label="@variantGroup.Name" onchange="swift.VariantSelector.OptionClick(event)"> 386 @if (string.IsNullOrEmpty(product.VariantId)) 387 { 388 <option value="" class="variant-option js-variant-option" data-variant-id="">@Translate("Nothing selected")</option> 389 } 390 391 @foreach (var option in variantGroup.Options) 392 { 393 string active = variantId != null && variantId.Contains(option.Id) ? "active" : ""; 394 var selected = variantId != null && variantId.Contains(option.Id) ? "selected" : ""; 395 var value = $"{product.Id}_{option.Id}"; 396 397 <option value="@(value)" class="variant-option js-variant-option @active" data-variant-id="@option.Id" id="@(value)_@(Pageview.CurrentParagraph.ID)" @selected>@option.Name</option> 398 } 399 </select> 400 } 401 </div> 402 </div> 403 404 groupNumber++; 405 } 406 </form> 407 408 <script type="module"> 409 swift.VariantSelector.init(); 410 </script> 411 } 412 else if (Pageview.IsVisualEditorMode) 413 { 414 string horizontalAlign = GetDefaultOrVariantGroupValue("", "HorizontalAlignment", "", new Dictionary<string, string> { { "center", "justify-content-center" }, { "end", "justify-content-end" } }); 415 string horizontalTextAlign = GetDefaultOrVariantGroupValue("", "HorizontalAlignment", "", new Dictionary<string, string> { { "center", "text-center" }, { "end", "text-end" } }); 416 417 <form class="d-flex flex-column js-variant-selector @itemId" data-combinations="VO1,VO2,VO3,VO4"> 418 <div> 419 @if (!hideGroupHeaders) 420 { 421 <h3 class="h6 @horizontalTextAlign">@Translate("Sizes")</h3> 422 } 423 <div class="mb-3 @horizontalAlign js-variant-group" data-group-id="0"> 424 <button type="button" class="btn btn-secondary d-inline-block mb-2 variant-option js-variant-option" onclick="swift.VariantSelector.OptionClick(event)" data-variant-id="VO1" id="@(product.Id)_VO1_@Pageview.CurrentParagraph.ID">S</button> 425 <button type="button" class="btn btn-secondary d-inline-block mb-2 variant-option js-variant-option" onclick="swift.VariantSelector.OptionClick(event)" data-variant-id="VO2" id="@(product.Id)_VO2_@Pageview.CurrentParagraph.ID">M</button> 426 <button type="button" class="btn btn-secondary d-inline-block mb-2 variant-option js-variant-option" onclick="swift.VariantSelector.OptionClick(event)" data-variant-id="VO3" id="@(product.Id)_VO3_@Pageview.CurrentParagraph.ID">L</button> 427 <button type="button" class="btn btn-secondary d-inline-block mb-2 variant-option js-variant-option" onclick="swift.VariantSelector.OptionClick(event)" data-variant-id="VO4" id="@(product.Id)_VO4_@Pageview.CurrentParagraph.ID">XL</button> 428 </div> 429 </div> 430 </form> 431 432 <script type="module"> 433 swift.VariantSelector.init(); 434 </script> 435 } 436 } 437 else if (Pageview.IsVisualEditorMode) 438 { 439 <div class="alert alert-dark m-0" role="alert"> 440 <span>@Translate("No products available")</span> 441 </div> 442 } 443 @*CUSTOM CODE*@ 444 <style> 445 .disabled-option { 446 pointer-events: none; 447 opacity: 0.5; 448 cursor: not-allowed; 449 } 450 </style> 451 452 <script> 453 document.addEventListener('DOMContentLoaded', () => { 454 455 function selectFirstSizeIfNone(target) { 456 const context = target || document; 457 const sizeGroup = context.querySelector('.js-variant-group[data-group-id="2"]'); 458 if (!sizeGroup) return; 459 460 const activeSize = sizeGroup.querySelector('.js-variant-option.active'); 461 if (!activeSize) { 462 const firstSizeButton = sizeGroup.querySelector('.js-variant-option[data-variant-id]'); 463 if (firstSizeButton) { 464 465 setTimeout(() => firstSizeButton.click(), 1); 466 } 467 } 468 } 469 const hideInactiveVariants = () => { 470 const elements = document.querySelectorAll('.variant-option.in-active:not(option)'); 471 elements.forEach(element => { 472 const validVariants = element.dataset.validvariants ? element.dataset.validvariants.split(',') : ''; 473 if (validVariants.length > 0) { 474 element.classList.remove('in-active'); 475 return; 476 } else { 477 element.classList.add('disabled-option'); 478 } 479 480 }); 481 } 482 hideInactiveVariants(); 483 484 selectFirstSizeIfNone(); 485 486 487 document.addEventListener("updated.swift.pageupdater", (e) => { 488 selectFirstSizeIfNone(e.target); 489 hideInactiveVariants(); 490 }); 491 492 }); 493 </script> 494 @*END OF CUSTOM CODE*@
Ikke på lager
• Hvis varen er på lager, så findes den også i vores fysiske butik - Vester Voldgade 5, 1552 København

Hvorfor skal du handle på troelstrup.com?

Få fri fragt

30 dages returret

Bliv en del af Troelstrup Exclusive

Beskrivelse

Yderligere information

Overdel lavet i mesh.

Skechers Hands Free Slip-ins gør det nemt at tage skoen på, uden at skulle binde dem op eller bruge skohorn.

Skoen har en udtagelig Arch Fit indersål, der er designet til at give svangstøtte.

Detaljer

Specifikationer

Såler Gummi
Artikel 216602
Farve-kode leverandør nvy navy
Model sneaker

Om brandet

Skechers

Skechers er kendt for deres komfortable fodtøj, der kombinerer innovative teknologier med moderne design. Deres sko tilbyder en afslappet og funktionel løsning til daglig brug og en aktiv livsstil.

Lign. produkter