Seler 24 mm bred elastik

250,00 kr. InStock
Error executing template "Designs/Swift/Components/VariantSelector_Custom.cshtml"
System.Collections.Generic.KeyNotFoundException: The given key 'multi11' was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at CompiledRazorTemplates.Dynamic.RazorEngine_b3548f6122b644cfa849a8fa4e79c239.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 string hackyUrl = string.Empty; 149 } 150 151 @if ((product is object)) 152 { 153 154 bool hideGroupHeaders = !string.IsNullOrEmpty(Model?.Item?.GetString("HideGroupHeaders")) ? Model.Item.GetBoolean("HideGroupHeaders") : false; 155 var productVariantGroups = product.VariantGroups(); 156 157 string itemId = Model?.Item?.SystemName != null ? $"item_{Model.Item.SystemName.ToLower()}" : string.Empty; 158 159 bool isModalSelector = Model?.Item == null; 160 string target = isModalSelector ? "data-response-target-element=\"DynamicModalContent\"" : string.Empty; 161 162 string variantSelectorServicePageId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("VariantSelectorServicePage")) ? Dynamicweb.Context.Current.Request.Form.Get("VariantSelectorServicePage") : string.Empty; 163 string formAction = isModalSelector ? $"action=\"/Default.aspx?ID={variantSelectorServicePageId}\"" : string.Empty; 164 165 string getProductInfo = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form["getproductinfo"]) ? Dynamicweb.Context.Current.Request.Form["getproductinfo"] : string.Empty; 166 167 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 168 { 169 string[] variantId = product.VariantId.Split('.'); 170 int groupNumber = 1; 171 172 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 173 string variantUrl = string.Empty; 174 if (!string.IsNullOrEmpty(product.VariantId) && !isModalSelector) 175 { 176 variantUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl($"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}&VariantID={product.VariantId}"); 177 //hackyUrl = $"/Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}&VariantID="; 178 } 179 hackyUrl = $"/Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}&VariantID="; 180 Dictionary<string, string> variantImages = new Dictionary<string, string>(); 181 variantImages = GetVariantImages(product.VariantInfo.VariantInfo, variantImages); 182 183 <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"> 184 @if (isModalSelector) 185 { 186 <input type="hidden" name="productId" value="@product.Id"> 187 <input type="hidden" name="variantid" value="@product.VariantId"> 188 <input type="hidden" name="QuantitySelector" value="true"> 189 <input type="hidden" name="VariantSelectorServicePage" value="@variantSelectorServicePageId"> 190 <input type="hidden" name="ViewType" value="ModalContent"> 191 192 if (GetViewParameter("ButtonLayout") != null) 193 { 194 <input type="hidden" name="ButtonLayout" value="@GetViewParameter("ButtonLayout")"> 195 } 196 197 if (GetViewParameter("ButtonAspectRatio") != null) 198 { 199 <input type="hidden" name="ButtonAspectRatio" value="@GetViewParameter("ButtonAspectRatio")"> 200 } 201 202 if (!string.IsNullOrEmpty(getProductInfo)) 203 { 204 <input type="hidden" name="getproductinfo" value="@getProductInfo"> 205 } 206 } 207 208 @foreach (var variantGroup in productVariantGroups) 209 { 210 VariantGroupViewModel group = variantGroup; 211 string variantGroupLayout = GetLayoutForVariantGroup(variantGroup.Id) ?? "button"; 212 string horizontalAlign = GetDefaultOrVariantGroupValue(variantGroup.Id, "HorizontalAlignment", "", new Dictionary<string, string> { { "center", "justify-content-center" }, { "end", "justify-content-end" } }); 213 string horizontalTextAlign = GetDefaultOrVariantGroupValue(variantGroup.Id, "HorizontalAlignment", "", new Dictionary<string, string> { { "center", "text-center" }, { "end", "text-end" } }); 214 bool showSelectedOptionName = GetDefaultOrVariantGroupValue(variantGroup.Id, "ShowSelectedOptionName"); 215 216 <div> 217 @if (!hideGroupHeaders) 218 { 219 <h3 class="h6 @horizontalTextAlign"> 220 @group.Name 221 222 @if (showSelectedOptionName) 223 { 224 string selectedOptionName = group.Options.FirstOrDefault(opt => variantId.Contains(opt.Id))?.Name ?? string.Empty; 225 <span class="fw-light px-1 swift-selected-option-name">@selectedOptionName</span> 226 } 227 </h3> 228 } 229 <div class="d-flex gap-2 @horizontalAlign flex-wrap js-variant-group" data-group-id="@groupNumber"> 230 @if (variantGroupLayout == "button") 231 { 232 233 foreach (var option in group.Options) 234 { 235 @* CUSTOM CODE *@ 236 string productColor = product.VariantId.Split('.').FirstOrDefault() ?? ""; 237 string productSize = option.Id.Split('.').LastOrDefault() ?? ""; 238 string variantCombination = productColor + "." + productSize; 239 Product currentOptionProduct = Dynamicweb.Ecommerce.Services.Products.GetProductById(product.Id, variantCombination, Pageview.Area.EcomLanguageId); 240 241 bool isVariantMaster = currentOptionProduct.GetIsVariantMaster(); 242 243 Dictionary<string, bool> hasValidVariantOptionsByMaster = new Dictionary<string, bool>(); 244 Dictionary<string, List<string>> validSizesByColorId = new Dictionary<string, List<string>>(); 245 if(isVariantMaster) 246 { 247 var allVariantsOfMasterProduct = Dynamicweb.Ecommerce.Services.Products.GetProductsAndVariantsByProduct(currentOptionProduct).ToList(); 248 List<string> validVariantsList = new List<string>(); 249 250 foreach (var variant in allVariantsOfMasterProduct) 251 { 252 var colorId = variant.VariantId.Split('.').First() ?? ""; 253 if (!string.IsNullOrEmpty(colorId) && !hasValidVariantOptionsByMaster.ContainsKey(colorId)) 254 { 255 hasValidVariantOptionsByMaster[colorId] = false; 256 foreach (var variantProduct in allVariantsOfMasterProduct) 257 { 258 if (variantProduct.VariantId.Contains(colorId)) 259 { 260 261 if(variantProduct.Stock > 0) 262 { 263 hasValidVariantOptionsByMaster[colorId] = true; 264 //validVariantsList.Add(); 265 if (!validSizesByColorId.ContainsKey(colorId)) 266 { 267 validSizesByColorId.Add(colorId, new List<string>()); 268 } 269 validSizesByColorId[colorId].Add(variantProduct.VariantId); 270 } 271 } 272 } 273 } 274 //if (!string.IsNullOrEmpty(itemColor) && !validVariantsInMaster.ContainsKey(itemColor)) { 275 276 // } 277 278 } 279 280 281 } 282 283 bool isOptionProductOutOfStock = currentOptionProduct.Stock <= 0 ? true : false; 284 var skipMaster = true; 285 286 foreach (var item in hasValidVariantOptionsByMaster) 287 { 288 if (item.Value) 289 { 290 if(option.Id.Contains(item.Key)) 291 { 292 skipMaster = false; 293 } 294 295 } 296 } 297 298 if(isVariantMaster && skipMaster) 299 { 300 continue; 301 } 302 303 if (!isVariantMaster && currentOptionProduct.Stock <= 0) { continue; } 304 @* END OF CUSTOM CODE *@ 305 306 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 307 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 308 string contrastColor = string.Empty; 309 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%" } }); 310 buttonAspectRatio = buttonAspectRatio == string.Empty ? "--bs-aspect-ratio:100%" : buttonAspectRatio; 311 312 string buttonLayout = GetDefaultOrVariantGroupValue(variantGroup.Id, "ButtonLayout", "rounded-circle", new Dictionary<string, string> { { "round", "rounded-circle" }, { "square", "rounded-0" }, { "square-rounded", "rounded-3" } }); 313 string buttonTextLayout = GetDefaultOrVariantGroupValue(variantGroup.Id, "ButtonTextLayout", "", new Dictionary<string, string> { { "default", "" }, { "square", "rounded-0" }, { "square-rounded", "rounded-3" } }); 314 var displayType = group.DisplayType; 315 displayType = displayType == VariantGroupDisplayType.NothingSelected && !string.IsNullOrEmpty(option.Color) ? VariantGroupDisplayType.VariantColor : displayType; 316 displayType = displayType == VariantGroupDisplayType.NothingSelected && string.IsNullOrEmpty(option.OptionImage.Value) && string.IsNullOrEmpty(option.Color) ? VariantGroupDisplayType.VariantName : displayType; 317 displayType = displayType == VariantGroupDisplayType.NothingSelected && !string.IsNullOrEmpty(option.OptionImage.Value) ? VariantGroupDisplayType.VariantOptionImage : displayType; 318 319 var btnWidth = displayType == VariantGroupDisplayType.VariantColor || displayType == VariantGroupDisplayType.VariantImage || displayType == VariantGroupDisplayType.VariantOptionImage ? $"style=\"width:64px\"" : string.Empty; 320 var btnClasses = string.Empty; 321 322 btnClasses = displayType == VariantGroupDisplayType.VariantColor ? $"overflow-hidden colorbox colorbox-auto p-0 border {buttonLayout}" : btnClasses; 323 btnClasses = displayType == VariantGroupDisplayType.VariantImage ? $"overflow-hidden p-0 {buttonLayout}" : btnClasses; 324 btnClasses = displayType == VariantGroupDisplayType.VariantOptionImage ? $"overflow-hidden colorbox colorbox-auto {buttonLayout} p-0" : btnClasses; 325 btnClasses = displayType == VariantGroupDisplayType.VariantName ? $"btn-secondary {buttonTextLayout}" : btnClasses; 326 327 var variantOptions = product.VariantId.Split("."); 328 329 string? selectedVariant = variantOptions.LastOrDefault(); 330 string? selectedMasterVariant = variantOptions.FirstOrDefault(); 331 332 <button type="button" 333 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 334 onclick="swift.VariantSelector.OptionClick(event)" 335 data-selected-master-variant="@selectedMasterVariant" 336 data-selectedvariant="@selectedVariant" 337 data-variant-id="@option.Id" id="@(product.Id)_@(option.Id)_@Pageview.CurrentParagraph.ID" 338 @(isVariantMaster ? "data-validvariants=" + string.Join(",", validSizesByColorId[option.Id]) : string.Empty)> 339 <div class="@(displayType == VariantGroupDisplayType.VariantName ? string.Empty : "ratio")" style="@(buttonAspectRatio)"> 340 341 @switch (displayType) 342 { 343 case VariantGroupDisplayType.VariantOptionImage: 344 if (!string.IsNullOrEmpty(option.OptionImage.Value)) 345 { 346 <img style="object-fit:cover;--variantoption-check-color:@(contrastColor)" src="/Admin/Public/GetImage.ashx?image=@(option.OptionImage.Value)&width=64&format=webp"> 347 } 348 else if (!string.IsNullOrEmpty(option.Color)) 349 { 350 <span class="" style="background-color:@(option.Color);--variantoption-check-color:@(contrastColor)"><span class="visually-hidden">@option.Color</span></span> 351 } 352 else 353 { 354 <span class="d-flex align-items-center justify-content-center">@(option.Name)</span> 355 } 356 break; 357 358 case VariantGroupDisplayType.VariantImage: 359 string variantImage = string.Empty; 360 variantImages.TryGetValue(option.Id, out variantImage); 361 <img class="theme" style="object-fit:contain" src="/Admin/Public/GetImage.ashx?image=@(variantImage)&width=64&format=webp"> 362 break; 363 364 case VariantGroupDisplayType.VariantColor: 365 contrastColor = GetContrastColor(option.Color); 366 <span class="" style="background-color:@(option.Color);--variantoption-check-color:@(contrastColor)"><span class="visually-hidden">@option.Color</span></span> 367 break; 368 369 case VariantGroupDisplayType.VariantName: 370 <span class="d-flex align-items-center justify-content-center">@(option.Name)</span> 371 break; 372 373 } 374 </div> 375 </button> 376 } 377 } 378 else 379 { 380 <select class="form-select" id="VariantDropdown_@variantGroup.Id" aria-label="@variantGroup.Name" onchange="swift.VariantSelector.OptionClick(event)"> 381 @if (string.IsNullOrEmpty(product.VariantId)) 382 { 383 <option value="" class="variant-option js-variant-option" data-variant-id="">@Translate("Nothing selected")</option> 384 } 385 386 @foreach (var option in variantGroup.Options) 387 { 388 string active = variantId != null && variantId.Contains(option.Id) ? "active" : ""; 389 var selected = variantId != null && variantId.Contains(option.Id) ? "selected" : ""; 390 var value = $"{product.Id}_{option.Id}"; 391 392 <option value="@(value)" class="variant-option js-variant-option @active" data-variant-id="@option.Id" id="@(value)_@(Pageview.CurrentParagraph.ID)" @selected>@option.Name</option> 393 } 394 </select> 395 } 396 </div> 397 </div> 398 399 groupNumber++; 400 } 401 </form> 402 403 <script type="module"> 404 swift.VariantSelector.init(); 405 </script> 406 } 407 else if (Pageview.IsVisualEditorMode) 408 { 409 string horizontalAlign = GetDefaultOrVariantGroupValue("", "HorizontalAlignment", "", new Dictionary<string, string> { { "center", "justify-content-center" }, { "end", "justify-content-end" } }); 410 string horizontalTextAlign = GetDefaultOrVariantGroupValue("", "HorizontalAlignment", "", new Dictionary<string, string> { { "center", "text-center" }, { "end", "text-end" } }); 411 412 <form class="d-flex flex-column js-variant-selector @itemId" data-combinations="VO1,VO2,VO3,VO4"> 413 <div> 414 @if (!hideGroupHeaders) 415 { 416 <h3 class="h6 @horizontalTextAlign">@Translate("Sizes")</h3> 417 } 418 <div class="mb-3 @horizontalAlign js-variant-group" data-group-id="0"> 419 <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> 420 <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> 421 <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> 422 <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> 423 </div> 424 </div> 425 </form> 426 427 <script type="module"> 428 swift.VariantSelector.init(); 429 </script> 430 } 431 } 432 else if (Pageview.IsVisualEditorMode) 433 { 434 <div class="alert alert-dark m-0" role="alert"> 435 <span>@Translate("No products available")</span> 436 </div> 437 } 438 @*CUSTOM CODE*@ 439 <style> 440 /* .variant-option.in-active:not(option) { 441 display: none !important; 442 } */ 443 444 /* button.is-master { 445 display: block !important; 446 } */ 447 /* .product-out-of-stock:not(.is-master) { 448 pointer-events: none; 449 opacity: 0.5; 450 cursor: not-allowed; 451 border: .0833rem solid #ff0000; 452 } */ 453 454 .disabled-option { 455 pointer-events: none; 456 opacity: 0.5; 457 cursor: not-allowed; 458 } 459 </style> 460 461 <script> 462 463 // function checkOptionActiveStatus(optionButtons) { 464 // return Array.from(optionButtons).some(button => button.classList.contains('active')); 465 // } 466 //console.log('@hackyUrl'); 467 document.addEventListener('DOMContentLoaded', () => { 468 addButtonEventListeners(); 469 hideInactiveVariants(); 470 }) 471 const hideInactiveVariants = () => { 472 const elements = document.querySelectorAll('.variant-option.in-active:not(option)'); 473 console.log(elements); 474 elements.forEach(element => { 475 const validVariants = element.dataset.validvariants ? element.dataset.validvariants.split(',') : ''; 476 //console.log(validVariants.length) 477 if (validVariants.length > 0) { 478 479 // console.log(validVariants) 480 element.classList.remove('in-active'); 481 return; 482 } else { 483 element.classList.add('disabled-option'); 484 console.log("length not equal 1") 485 486 } 487 // else 488 // { 489 490 //} 491 492 }); 493 } 494 const addButtonEventListeners = () => { 495 496 var colorButtons = document.querySelectorAll('div[data-group-id="1"] button'); 497 var sizeButtons = document.querySelectorAll('div[data-group-id="2"] button'); 498 499 const baseUrl = "@hackyUrl"; 500 colorButtons.forEach(button => { 501 button.addEventListener('click', (event) => { 502 console.log("baseURL when clicked: " + baseUrl); 503 console.log("product ID when clicked: " + '@(product.Id)'); 504 var href = window.location.href; 505 var hrefQueryString = window.location.pathname; 506 console.log("HREF when clicked: " + href); 507 const target = button.dataset.variantId + "." + button.dataset.selectedvariant; 508 509 let tempTarget = target; 510 const validVariants = button.dataset.validvariants.split(','); 511 var isValidCombination = (validVariants.includes(target)); 512 513 if (!isValidCombination) { 514 //Redirect to 515 const newTarget = validVariants[0]; 516 tempTarget = newTarget; 517 } 518 hideInactiveVariants(); 519 if (baseUrl.length === 0 || baseUrl === null) { 520 console.log("BaseUrl is null or empty: " + href + "/?variantId=" + tempTarget); 521 console.log("Query string: " + hrefQueryString); 522 window.location.href = href + "/?variantId=" + tempTarget; 523 524 } 525 else 526 { 527 const redirectUrl = baseUrl + tempTarget; 528 window.location.href = redirectUrl; 529 console.log("tempTarget:" + tempTarget); 530 console.log("redirectUrl: " + redirectUrl); 531 } 532 //console.log(tempTarget); 533 }); 534 }); 535 536 sizeButtons.forEach(button => { 537 button.addEventListener('click', (event) => { 538 539 var size = button.dataset.variantId; 540 var color = button.dataset.selectedMasterVariant; 541 var target = color + "." + size; 542 const redirectUrl = baseUrl + target; 543 544 window.location.href = redirectUrl; 545 }); 546 547 }); 548 549 } 550 551 var masterProductOptionButtons = document.querySelectorAll('div[data-group-id="1"] button'); 552 553 554 555 556 557 window.addEventListener('load', function () { 558 559 var masterProductOptionButtons = document.querySelectorAll('div[data-group-id="1"] button'); 560 var variantProductOptionButtons = document.querySelectorAll('div[data-group-id="2"] button'); 561 //clickFirstOptionButton(masterProductOptionButtons); 562 //clickFirstOptionButton(variantProductOptionButtons); 563 }); 564 565 function clickFirstOptionButton(listOfOptionButtons) { 566 if (listOfOptionButtons.length > 0) { 567 const isAnyButtonActive = Array.from(listOfOptionButtons).some(button => 568 button.classList.contains('active') 569 ); 570 if (!isAnyButtonActive) { 571 listOfOptionButtons[0].click(); 572 } 573 } 574 } 575 576 //document.addEventListener('DOMContentLoaded', hideInactiveVariants); 577 578 //const observer = new MutationObserver(hideInactiveVariants); 579 //observer.observe(document.body, { 580 // childList: true, 581 // subtree: true 582 //}); 583 584 //setInterval(hideInactiveVariants, 1000); 585 586 </script> 587
4 På lager

Suppler med:

Hvorfor skal du handle på troelstrup.com?

Få fri fragt

30 dags returret

Bliv en del af Troelstrup Exclusive

Beskrivelse

Yderligere information

Seler 24 mm bred elastik fra Philipsons. Klassiske smalle seler med klips fra Philipsons. Selerne er 120 cm lange og 2,4 cm i bredden. Selerne er justbare. Perfekt tilbehør til dit formelle outfit.

Detaljer

Specifikationer

Materiale Bomuld Hør
Artikel 241
Farve-kode leverandør 08
Model seler

Om brandet

Mest solgte