piacenza

2.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 CompiledRazorTemplates.Dynamic.RazorEngine_3361a32ba6c541d1bffb427d319e8c7e.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() ?? false; 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 == null || currentOptionProduct.Stock <= 0; 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 = !string.IsNullOrEmpty(product.VariantId)? product.VariantId.Split(".") : new string[0]; 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 && validSizesByColorId != null && validSizesByColorId.ContainsKey(option.Id) 344 ? $"data-validvariants=\"{string.Join(",", validSizesByColorId[option.Id])}\"" 345 : string.Empty)> 346 <div class="@(displayType == VariantGroupDisplayType.VariantName ? string.Empty : "ratio")" style="@(buttonAspectRatio)"> 347 348 @switch (displayType) 349 { 350 case VariantGroupDisplayType.VariantOptionImage: 351 if (!string.IsNullOrEmpty(option.OptionImage.Value)) 352 { 353 <img style="object-fit:cover;--variantoption-check-color:@(contrastColor)" src="/Admin/Public/GetImage.ashx?image=@(option.OptionImage.Value)&width=64&format=webp"> 354 } 355 else if (!string.IsNullOrEmpty(option.Color)) 356 { 357 <span class="" style="background-color:@(option.Color);--variantoption-check-color:@(contrastColor)"><span class="visually-hidden">@option.Color</span></span> 358 } 359 else 360 { 361 <span class="d-flex align-items-center justify-content-center">@(option.Name)</span> 362 } 363 break; 364 365 case VariantGroupDisplayType.VariantImage: 366 string variantImage = string.Empty; 367 variantImages.TryGetValue(option.Id, out variantImage); 368 <img class="theme" style="object-fit:contain" src="/Admin/Public/GetImage.ashx?image=@(variantImage)&width=64&format=webp"> 369 break; 370 371 case VariantGroupDisplayType.VariantColor: 372 contrastColor = GetContrastColor(option.Color); 373 <span class="" style="background-color:@(option.Color);--variantoption-check-color:@(contrastColor)"><span class="visually-hidden">@option.Color</span></span> 374 break; 375 376 case VariantGroupDisplayType.VariantName: 377 <span class="d-flex align-items-center justify-content-center">@(option.Name)</span> 378 break; 379 380 } 381 </div> 382 </button> 383 } 384 } 385 else 386 { 387 <select class="form-select" id="VariantDropdown_@variantGroup.Id" aria-label="@variantGroup.Name" onchange="swift.VariantSelector.OptionClick(event)"> 388 @if (string.IsNullOrEmpty(product.VariantId)) 389 { 390 <option value="" class="variant-option js-variant-option" data-variant-id="">@Translate("Nothing selected")</option> 391 } 392 393 @foreach (var option in variantGroup.Options) 394 { 395 string active = variantId != null && variantId.Contains(option.Id) ? "active" : ""; 396 var selected = variantId != null && variantId.Contains(option.Id) ? "selected" : ""; 397 var value = $"{product.Id}_{option.Id}"; 398 399 <option value="@(value)" class="variant-option js-variant-option @active" data-variant-id="@option.Id" id="@(value)_@(Pageview.CurrentParagraph.ID)" @selected>@option.Name</option> 400 } 401 </select> 402 } 403 </div> 404 </div> 405 406 groupNumber++; 407 } 408 </form> 409 410 <script type="module"> 411 swift.VariantSelector.init(); 412 </script> 413 } 414 else if (Pageview.IsVisualEditorMode) 415 { 416 string horizontalAlign = GetDefaultOrVariantGroupValue("", "HorizontalAlignment", "", new Dictionary<string, string> { { "center", "justify-content-center" }, { "end", "justify-content-end" } }); 417 string horizontalTextAlign = GetDefaultOrVariantGroupValue("", "HorizontalAlignment", "", new Dictionary<string, string> { { "center", "text-center" }, { "end", "text-end" } }); 418 419 <form class="d-flex flex-column js-variant-selector @itemId" data-combinations="VO1,VO2,VO3,VO4"> 420 <div> 421 @if (!hideGroupHeaders) 422 { 423 <h3 class="h6 @horizontalTextAlign">@Translate("Sizes")</h3> 424 } 425 <div class="mb-3 @horizontalAlign js-variant-group" data-group-id="0"> 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="VO1" id="@(product.Id)_VO1_@Pageview.CurrentParagraph.ID">S</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="VO2" id="@(product.Id)_VO2_@Pageview.CurrentParagraph.ID">M</button> 428 <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> 429 <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> 430 </div> 431 </div> 432 </form> 433 434 <script type="module"> 435 swift.VariantSelector.init(); 436 </script> 437 } 438 } 439 else if (Pageview.IsVisualEditorMode) 440 { 441 <div class="alert alert-dark m-0" role="alert"> 442 <span>@Translate("No products available")</span> 443 </div> 444 } 445 @*CUSTOM CODE*@ 446 <style> 447 .disabled-option { 448 pointer-events: none; 449 opacity: 0.5; 450 cursor: not-allowed; 451 } 452 </style> 453 454 <script> 455 document.addEventListener('DOMContentLoaded', () => { 456 457 function selectFirstSizeIfNone(target) { 458 const context = target || document; 459 const sizeGroup = context.querySelector('.js-variant-group[data-group-id="2"]'); 460 if (!sizeGroup) return; 461 462 const activeSize = sizeGroup.querySelector('.js-variant-option.active'); 463 if (!activeSize) { 464 const firstSizeButton = sizeGroup.querySelector('.js-variant-option[data-variant-id]'); 465 if (firstSizeButton) { 466 467 setTimeout(() => firstSizeButton.click(), 1); 468 } 469 } 470 } 471 const hideInactiveVariants = () => { 472 const elements = document.querySelectorAll('.variant-option.in-active:not(option)'); 473 elements.forEach(element => { 474 const validVariants = element.dataset.validvariants ? element.dataset.validvariants.split(',') : ''; 475 if (validVariants.length > 0) { 476 element.classList.remove('in-active'); 477 return; 478 } else { 479 element.classList.add('disabled-option'); 480 } 481 482 }); 483 } 484 hideInactiveVariants(); 485 486 selectFirstSizeIfNone(); 487 488 489 document.addEventListener("updated.swift.pageupdater", (e) => { 490 selectFirstSizeIfNone(e.target); 491 hideInactiveVariants(); 492 }); 493 494 }); 495 </script> 496 @*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

Piacenza:

  • Fransk lommeåbning
  • Paspolerede baglommer
  • Klassisk pasform
  • Bæltestropper

Detaljer

Specifikationer

Baglommer Paspolerede baglommer
Bukselukning Lukkes med lynlås, hægte og knap
Pasform Regular
Materiale Uld
Artikel 42134
Farve-kode leverandør 12 mørkegrå
Model uldbukser

Om brandet

Hiltl

Hiltl har fem faste værdier: De gør brug af det fineste stof i Europa, alle deres produkter produceres i Europa, de har en stor passion for detaljer, de går ind for 100% slow fashion, og sidst men ikke mindst, så fremstiller de skræddersyet produkter af høj kvalitet.

Lign. produkter