Filtrér udvalget:

Variant: Farve sort
Kan farvetilpasses

Variant: Farve sort

100,00 kr. OutOfStock
Overflade: Rustfri
Overflade: Rustfri
Error executing template "/Designs/Swift-v2/Paragraph/Custom_ProductColorConfigBadge.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_c6aae1b27861463eb8188214401f3db4.<>c.<ExecuteAsync>b__0_0(String vc)
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at CompiledRazorTemplates.Dynamic.RazorEngine_c6aae1b27861463eb8188214401f3db4.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Frontend 4 5 @{ 6 const string ralVariantOptionId = "VO1872"; 7 ProductViewModel? product = null; 8 if (Dynamicweb.Context.Current?.Items.Contains("ProductDetails") == true) 9 { 10 product = Dynamicweb.Context.Current.Items["ProductDetails"] as ProductViewModel; 11 } 12 else if (Pageview?.Page.Item?["DummyProduct"] != null && Pageview.IsVisualEditorMode) 13 { 14 PageInfoViewModel pageViewModel = ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 15 ProductListViewModel? productList = pageViewModel.Item?.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 16 17 if (productList?.Products != null) 18 { 19 product = productList.Products[0]; 20 } 21 } 22 } 23 24 @if (product != null) 25 { 26 bool hasRalColorVariantOption = product.VariantCombinations().FirstOrDefault(vc => vc.Contains(ralVariantOptionId)) != null; 27 if (hasRalColorVariantOption == true) 28 { 29 <div class="position-absolute top-0 left-0 p-2"> 30 <span class="badge rounded-pill color_gradient fw-normal fs-7 text-uppercase">@Translate("Kan farvetilpasses")</span> 31 </div> 32 } 33 } 34 else if (Pageview?.IsVisualEditorMode == true) 35 { 36 <div class="alert alert-dark m-0" role="alert"> 37 <span>@Translate("HasRalColorVariantOption")</span> 38 </div> 39 } 40 41

Overflade: Rustfri

Error executing template "/Designs/Swift-v2/Paragraph/Custom_ProductVariantOptions.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_02efc646dc904cf9aef61f155f6640b8.<>c.<ExecuteAsync>b__0_0(String vc)
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at CompiledRazorTemplates.Dynamic.RazorEngine_02efc646dc904cf9aef61f155f6640b8.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.Linq 3 @using Dynamicweb.Ecommerce.ProductCatalog 4 @using Dynamicweb.Ecommerce.Variants 5 @using Dynamicweb.Frontend 6 7 @functions { 8 9 //Find contrast color (white, black) 10 private static string GetContrastColor(string hexString) 11 { 12 System.Drawing.Color bg = System.Drawing.ColorTranslator.FromHtml(hexString); 13 int nThreshold = 105; 14 int bgDelta = Convert.ToInt32((bg.R * 0.299) + (bg.G * 0.587) + (bg.B * 0.114)); 15 string foreColor = (255 - bgDelta < nThreshold) ? "#333" : "#fff"; 16 return foreColor; 17 } 18 19 //Collect all variant images 20 private static Dictionary<string, string> GetVariantImages(List<VariantInfoViewModel> variantInfo, Dictionary<string, string> list) 21 { 22 foreach (var variantGroup in variantInfo) 23 { 24 if (variantGroup.Image?.Value != null && !list.ContainsKey(variantGroup.OptionID)) 25 { 26 list.Add(variantGroup.OptionID, variantGroup.Image.Value); 27 } 28 29 if (variantGroup.VariantInfo != null) 30 { 31 GetVariantImages(variantGroup.VariantInfo, list); 32 } 33 } 34 35 return list; 36 } 37 38 private string? GetDefaultOrVariantGroupValue(string variantGroupId, string itemField, string itemFieldDefaultValue, Dictionary<string, string>? fieldValueMapping) 39 { 40 if (!string.IsNullOrEmpty(variantGroupId)) 41 { 42 string? itemFieldValue = Model.Item?.GetRawValueString(itemField, itemFieldDefaultValue); 43 string itemFieldParameter = GetViewParameterString(itemField); 44 itemFieldValue = string.IsNullOrEmpty(itemFieldValue) && !string.IsNullOrEmpty(itemFieldParameter) ? itemFieldParameter : itemFieldValue; 45 46 if (fieldValueMapping != null && !string.IsNullOrEmpty(itemFieldValue) && fieldValueMapping.Any()) 47 { 48 itemFieldValue = fieldValueMapping.GetValueOrDefault(itemFieldValue, itemFieldValue); 49 } 50 51 // If no variantGroup (i.e. Visual Editor), return default value 52 if (string.IsNullOrEmpty(variantGroupId)) return itemFieldValue; 53 54 string? showVariantGroups = Model.Item?.GetString("ShowVariantGroupOptions", "all"); 55 var selectedVariantGroupsList = Model.Item?.GetItems("VariantGroups") ?? new List<ItemViewModel>(); 56 // If no exceptions or settings are all the same, return default value 57 if (showVariantGroups == "all" || !selectedVariantGroupsList.Any()) return itemFieldValue; 58 59 // Get specific value for variant group 60 foreach (var selectedVariantGroupListItem in selectedVariantGroupsList) 61 { 62 var variantGroups = selectedVariantGroupListItem.GetList("VariantGroups")?.GetRawValue().OfType<string>().ToList(); 63 if (variantGroups != null && variantGroups.Any(s => s.Equals(variantGroupId))==false) continue; 64 65 itemFieldValue = selectedVariantGroupListItem.GetRawValueString(itemField, itemFieldDefaultValue); 66 itemFieldValue = fieldValueMapping != null && fieldValueMapping.TryGetValue(itemFieldValue, out string? value) ? value : itemFieldValue; 67 } 68 69 return itemFieldValue; 70 } 71 else 72 { 73 return string.Empty; 74 } 75 } 76 77 } 78 79 @{ 80 ProductViewModel? product = null; 81 if (Dynamicweb.Context.Current?.Items.Contains("ProductDetails") == true) 82 { 83 product = Dynamicweb.Context.Current.Items["ProductDetails"] as ProductViewModel; 84 } 85 else if (Pageview?.Page.Item?["DummyProduct"] != null && Pageview.IsVisualEditorMode) 86 { 87 PageInfoViewModel pageViewModel = ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 88 ProductListViewModel? productList = pageViewModel.Item?.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 89 90 if (productList?.Products != null) 91 { 92 product = productList.Products[0]; 93 } 94 } 95 } 96 97 @if (product != null) 98 { 99 List<VariantGroupViewModel>? productVariantGroups = product.VariantGroups(); 100 101 const string ralVariantOptionId = "VO1872"; 102 bool hasRalColorVariantOption = product.VariantCombinations().FirstOrDefault(vc => vc.Contains(ralVariantOptionId)) != null; 103 104 if (productVariantGroups.Any() && product.VariantInfo?.VariantInfo != null) 105 { 106 string[] variantId = product.VariantId.Split('.'); 107 int groupNumber = 1; 108 109 Dictionary<string, string> variantImages = new Dictionary<string, string>(); 110 variantImages = GetVariantImages(product.VariantInfo.VariantInfo, variantImages); 111 112 <div class="w-100 border-bottom"> 113 <div class="p-2"> 114 115 @foreach (VariantGroupViewModel variantGroup in productVariantGroups) 116 { 117 if (groupNumber > 1) 118 { 119 continue; 120 } 121 122 VariantGroupViewModel group = variantGroup; 123 string? horizontalAlign = GetDefaultOrVariantGroupValue(variantGroup.Id, "HorizontalAlignment", "", new Dictionary<string, string> { { "center", "justify-content-center" }, { "end", "justify-content-end" } }); 124 <div class="d-flex gap-2 @horizontalAlign flex-wrap js-variant-group" data-group-id="@groupNumber"> 125 @foreach (VariantOptionViewModel? option in group.Options) 126 { 127 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 128 129 VariantGroupDisplayType displayType = group.DisplayType; 130 displayType = displayType == VariantGroupDisplayType.NothingSelected && !string.IsNullOrEmpty(option.Color) ? VariantGroupDisplayType.VariantColor : displayType; 131 displayType = displayType == VariantGroupDisplayType.NothingSelected && string.IsNullOrEmpty(option.OptionImage.Value) && string.IsNullOrEmpty(option.Color) ? VariantGroupDisplayType.VariantName : displayType; 132 displayType = displayType == VariantGroupDisplayType.NothingSelected && !string.IsNullOrEmpty(option.OptionImage.Value) ? VariantGroupDisplayType.VariantOptionImage : displayType; 133 134 string contrastColor = string.Empty; 135 if (!string.IsNullOrEmpty(option.Color)) 136 { 137 contrastColor = GetContrastColor(option.Color); 138 } 139 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%" } }); 140 buttonAspectRatio = buttonAspectRatio == string.Empty ? "--bs-aspect-ratio:100%" : buttonAspectRatio; 141 string? buttonLayout = GetDefaultOrVariantGroupValue(variantGroup.Id, "ButtonLayout", "rounded-circle", new Dictionary<string, string> { { "round", "rounded-circle" }, { "square", "rounded-0" }, { "square-rounded", "rounded-3" } }); 142 143 string btnWidth = displayType == VariantGroupDisplayType.VariantColor || displayType == VariantGroupDisplayType.VariantImage || displayType == VariantGroupDisplayType.VariantOptionImage ? $"style=\"width:1.25em\"" : string.Empty; 144 145 string btnClasses = string.Empty; 146 btnClasses = displayType == VariantGroupDisplayType.VariantColor ? $"overflow-hidden colorbox-auto p-0 {buttonLayout}" : btnClasses; 147 btnClasses = displayType == VariantGroupDisplayType.VariantImage ? $"overflow-hidden p-0 {buttonLayout}" : btnClasses; 148 btnClasses = displayType == VariantGroupDisplayType.VariantOptionImage ? $"overflow-hidden colorbox-auto {buttonLayout} p-0" : btnClasses; 149 150 string borderClass = string.Empty; 151 if (!string.IsNullOrEmpty(contrastColor) && contrastColor != "#fff") 152 { 153 154 borderClass = " custom-variant-border"; 155 } 156 btnClasses = string.Concat(btnClasses, borderClass); 157 158 159 @switch (displayType) 160 { 161 case VariantGroupDisplayType.VariantName: 162 <span class="badge rounded-pill color_dark fw-normal fs-8 text-uppercase">@(option.Name)</span> 163 break; 164 165 default: 166 <button type="button" class="btn @btnClasses d-inline-block variant-option js-variant-option @active" @btnWidth data-variant-id="@option.Id" id="@(product.Id)_@(option.Id)_@Pageview?.CurrentParagraph?.ID"> 167 <div class="@(displayType == VariantGroupDisplayType.VariantName ? string.Empty : "ratio")" style="@(buttonAspectRatio)"> 168 @switch (displayType) 169 { 170 case VariantGroupDisplayType.VariantOptionImage: 171 if (!string.IsNullOrEmpty(option.OptionImage.Value)) 172 { 173 <img style="object-fit:cover;--variantoption-check-color:@(contrastColor)" src="/Admin/Public/GetImage.ashx?image=@(option.OptionImage.Value)&width=64&format=webp" alt=""> 174 } 175 else if (!string.IsNullOrEmpty(option.Color)) 176 { 177 <span class="" style="background-color:@(option.Color);--variantoption-check-color:@(contrastColor)"><span class="visually-hidden">@option.Color</span></span> 178 } 179 else 180 { 181 <span class="d-flex align-items-center justify-content-center">@(option.Name)</span> 182 } 183 break; 184 185 case VariantGroupDisplayType.VariantImage: 186 variantImages.TryGetValue(option.Id, out string? variantImage); 187 <img style="object-fit:contain" src="/Admin/Public/GetImage.ashx?image=@(variantImage)&width=64&format=webp" alt=""> 188 break; 189 190 case VariantGroupDisplayType.VariantColor: 191 <span style="background-color:@(option.Color);--variantoption-check-color:@(contrastColor)"> 192 <span class="visually-hidden">@option.Color</span> 193 </span> 194 break; 195 } 196 </div> 197 </button> 198 break; 199 } 200 201 202 } 203 204 @if (hasRalColorVariantOption == true) 205 { 206 <button type="button" class="btn overflow-hidden color_gradient colorbox-auto p-0 rounded-circle d-inline-block variant-option" style="width:1.25em"> 207 <div class="ratio color_gradient-bg" style="--bs-aspect-ratio:100%"> 208 <span class="visually-hidden">@Translate("Kan farvetilpasses")</span> 209 </div> 210 </button> 211 } 212 213 </div> 214 groupNumber++; 215 } 216 217 </div> 218 </div> 219 } 220 } 221 222 223 else if (Pageview?.IsVisualEditorMode == true) 224 { 225 <div class="alert alert-dark m-0" role="alert"> 226 <span>@Translate("The variant selector will be shown here, if any variants are available")</span> 227 </div> 228 } 229 230 231
5.000,00 kr. På lager
AE håndtørrer, hvid
AE håndtørrer, hvid

AE håndtørrer, hvid

5.658,00 kr. På lager
Drypfang til desinfektionsdispensere, sort
Drypfang til desinfektionsdispensere, sort

Drypfang til desinfektionsdispensere, sort

486,67 kr. På lager
5 L flydende håndsæbe
5 L flydende håndsæbe

5 L flydende håndsæbe

206,34 kr. På lager
AA håndtørrer, hvid
AA håndtørrer, hvid

AA håndtørrer, hvid

5.734,88 kr. På lager
Indbygget håndtørrer
Indbygget håndtørrer

Indbygget håndtørrer

5,99 kr. På lager
Mini håndtørrer, hvid
Mini håndtørrer, hvid

Mini håndtørrer, hvid

2.917,15 kr. På lager
Maxi håndtørrer, hvid
Maxi håndtørrer, hvid

Maxi håndtørrer, hvid

4.003,65 kr. På lager
Insektfanger CRI CRI, aktionsradius 15-18 m
Insektfanger CRI CRI, aktionsradius 15-18 m

Insektfanger CRI CRI, aktionsradius 15-18 m

4.278,86 kr. På lager
Insektfanger CRI CRI, aktionsradius: 10-12 m
Insektfanger CRI CRI, aktionsradius: 10-12 m

Insektfanger CRI CRI, aktionsradius: 10-12 m

2.487,88 kr. På lager
Insektfanger CRI CRI, aktionsradius 10-12 m
Insektfanger CRI CRI, aktionsradius 10-12 m

Insektfanger CRI CRI, aktionsradius 10-12 m

1.260,75 kr. På lager
12 af 334 produkter
Vis flere produkter