Prismatch på sammenlignelige varer i DanmarkPrismatch på sammenlignelige varer i Danmark
Bestil før kl. 14.00 - så sender vi i dagBestil før kl. 14.00 - så sender vi i dag
Danmarks største udvalg inden for NO DIGDanmarks største udvalg inden for NO DIG
Vi uddanner dig, inden du tager på opgaveVi uddanner dig, inden du tager på opgave
Error executing template "Designs/Rapido/eCom/Product/NZProductView.cshtml"
System.ArgumentException: Illegal characters in path.
   at System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional)
   at System.IO.Path.GetFileName(String path)
   at System.IO.FileInfo.Init(String fileName, Boolean checkHost)
   at System.IO.FileInfo..ctor(String fileName)
   at S_DW_Lauridsen.CustomCode.DocumentInfo.FileInformation(String docCol) in C:\WEB\Projects\S_DW_Lauridsen\S_DW_Lauridsen\CustomCode\DocumentInfo.cs:line 42
   at CompiledRazorTemplates.Dynamic.RazorEngine_5528925918cd4fa9a432384d3101beca.Execute() in E:\Solutions\S_DW_Lauridsen\lauridsen-live\Files\Templates\Designs\Rapido\eCom\Product\NZProductView.cshtml:line 37
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.DynamicWrapperService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at RazorEngine.Templating.RazorEngineServiceExtensions.RunCompile(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.RunCompile(IRazorEngineService service, ITemplateSource templateSource, String name, Type modelType, Object model, DynamicViewBag viewBag)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2 @using Dynamicweb.Extensibility 3 @using Dynamicweb.Content 4 @using System; 5 @using System.Globalization; 6 @using System.Linq 7 @using System.IO 8 @using Dynamicweb.Core 9 @using System.Web 10 @using Dynamicweb.Ecommerce 11 @using Dynamicweb.Ecommerce.Discounts 12 @using Dynamicweb.Ecommerce.Orders.Discounts 13 @using Dynamicweb.Ecommerce.Products 14 @using Dynamicweb.Ecommerce.Prices 15 @using NLog; 16 @using S_DW_Lauridsen.CustomCode 17 @using Dynamicweb.Security.UserManagement 18 @using NuGet.Versioning 19 @{ 20 21 string favoritPage = String.Format("/Default.aspx?ID={0}&CC20=CreateFormList", GetPageIdByNavigationTag("CustomerFavorites").ToString()); 22 string pageId = GetGlobalValue("Global:Page.ID").ToString(); 23 string productId = GetString("Ecom:Product.ID"); 24 string uniqueId = GetString("Ecom:Product.ID") + GetString("Ecom:Product.VariantID"); 25 // Stock status 26 int stockAmount = GetInteger("Ecom:Product.AvailableAmount"); 27 string currentPrice = GetString("Ecom:Product.Discount.Price.PriceFormatted") == GetString("Ecom:Product.Price.PriceFormatted") ? GetString("Ecom:Product.Price.PriceFormatted") : GetString("Ecom:Product.Discount.Price.PriceFormatted"); 28 string hideHelpText = ""; 29 string requestQuery = GetGlobalValue("Global:Request.Query"); 30 string variantId = HttpContext.Current.Request.QueryString.Get("variantId"); 31 string feedId = pageId + "&ProductID=" + productId + "&VariantID=" + variantId + "&Feed=True&redirect=false"; 32 //CFP bool 33 bool cfp = GetBoolean("Ecom:Product:Field.CFP"); 34 35 // Documents 36 string documentValue = GetString("Ecom:Product:Field.PDF_Path"); 37 var results = DocumentInfo.FileInformation(documentValue); 38 39 40 string externalLink = GetValue("Ecom:Product:Field.ExternalLinks.Value").ToString(); 41 var testList = externalLink.Split(new string[] { "</p>" }, StringSplitOptions.RemoveEmptyEntries).ToList(); 42 43 44 45 int featuresCount = 0; 46 string brand = GetString("Ecom:Product:Field.brand"); 47 bool onlyPreviewForAnonymousUsers = Pageview.AreaSettings.GetBoolean("OnlyPreviewForAnonymous"); 48 bool onlyPreview = onlyPreviewForAnonymousUsers ? Pageview.User == null : false; 49 50 foreach (LoopItem customField in GetLoop("CustomFieldValues")) 51 { 52 if (!String.IsNullOrEmpty(customField.GetString("Product.CustomField.Value.Clean")) && customField.GetString("Product.CustomField.Name") != "CustomSticker") 53 { 54 featuresCount++; 55 } 56 } 57 58 foreach (LoopItem customField in GetLoop("ProductCategories")) 59 { 60 foreach (LoopItem field in customField.GetLoop("ProductCategoryFields")) 61 { 62 if (!String.IsNullOrEmpty(field.GetString("Ecom:Product.CategoryField.Value"))) 63 { 64 featuresCount++; 65 } 66 } 67 } 68 69 foreach (LoopItem variantgroup in GetLoop("VariantGroups")) 70 { 71 foreach (LoopItem variantoption in variantgroup.GetLoop("VariantAvailableOptions")) 72 { 73 if (variantoption.GetBoolean("Ecom:VariantOption.Selected")) 74 { 75 hideHelpText = "u-hidden"; 76 } 77 } 78 } 79 80 int relatedProductsPageSize = 4; 81 int relatedProductsColumnWidth = 3; 82 83 if (Pageview.Device.ToString() == "Mobile") 84 { 85 relatedProductsPageSize = 1; 86 relatedProductsColumnWidth = 12; 87 } 88 89 if (Pageview.Device.ToString() == "Tablet") 90 { 91 relatedProductsPageSize = 3; 92 relatedProductsColumnWidth = 4; 93 } 94 95 string pageNavTag = GetPageIdByNavigationTag("ProductsPage").ToString(); 96 string feedFullUrl = String.Format("/Default.aspx?ID={0}&PageSize={1}&ProdID={2}&feed=true", pageNavTag, relatedProductsPageSize, productId); 97 string relatedProductsFeed = String.Format("/Default.aspx?ID={0}&PageSize={1}&ProdID={2}&feed=true&RelateredeProdukter=", pageNavTag, relatedProductsPageSize, productId); 98 string productContainerId = "Product" + productId; 99 string video = GetString("Ecom:Product:Field.video"); 100 string siteURL = Dynamicweb.Context.Current.Request.Url.Scheme + "://" + Dynamicweb.Context.Current.Request.Url.Host; 101 Dynamicweb.Ecommerce.Products.Product currentProduct = Dynamicweb.Ecommerce.Services.Products.GetProductById(GetString("Ecom:Product.ID"), GetString("Ecom:Product.VariantID"), GetString("Ecom:Product.LanguageID")); 102 var imagePathValue = Dynamicweb.Ecommerce.Services.Products.GetProductFieldValue(currentProduct, "ImagePath"); 103 string imagePath = !string.IsNullOrWhiteSpace(imagePathValue.ToString()) ? "/Files/Images/Ecom/LHI_Products/Images/" + imagePathValue + ".jpg" : ""; 104 string productImage = !string.IsNullOrWhiteSpace(imagePath) ? imagePath : GetString("Ecom:Product.ImageLarge.Default.Clean"); 105 string canonicalURL = GetString("Ecom:Product.Canonical"); 106 string vismaUnitName = !string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Enhed")) ? GetString("Ecom:Product:Field.Enhed")?.ToLower() : Translate("UnitPriceTextStk"); 107 108 //gallery 109 int imagesCount = 1; 110 List<string> galleryImages = new List<string>(); 111 112 galleryImages.Add(productImage); 113 if (!string.IsNullOrWhiteSpace(video)) 114 { 115 foreach (var image in video.Split('|')) 116 { 117 string videoThumb = String.Format("https://img.youtube.com/vi/{0}/0.jpg", image); 118 galleryImages.Add(videoThumb); 119 imagesCount++; 120 } 121 } 122 123 foreach (LoopItem alternativeImage in GetLoop("Ecom:Product.AlternativeImages")) 124 { 125 if (!String.IsNullOrEmpty(alternativeImage.GetString("Ecom:Product.AlternativeImages.Image"))) 126 { 127 string fullImage = "/Admin/Public/GetImage.ashx?width=550&amp;height=550&amp;crop=5&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image=" + alternativeImage.GetString("Ecom:Product.AlternativeImages.Image"); 128 galleryImages.Add(fullImage); 129 imagesCount++; 130 } 131 } 132 133 foreach (LoopItem detail in GetLoop("Details")) 134 { 135 string fullImage = "/Admin/Public/GetImage.ashx?width=550&amp;height=550&amp;crop=5&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image=" + detail.GetString("Ecom:Product:Detail.Image.Clean"); 136 137 if (!String.IsNullOrEmpty(fullImage)) 138 { 139 galleryImages.Add(fullImage); 140 imagesCount++; 141 } 142 } 143 144 string firstImage = galleryImages.FirstOrDefault(); 145 string galleryImagesArray = string.Join(", ", galleryImages); 146 } 147 148 @* Set product canonical URL *@ 149 @SnippetStart("canonical") 150 @{ 151 string host = GetGlobalValue("Global:Request.Host"); 152 string url = GetGlobalValue("Global:Pageview.Url"); 153 int queryIndex = url.IndexOf("?", StringComparison.Ordinal); 154 if (queryIndex > -1) 155 { 156 url = url.Substring(0, queryIndex); 157 } 158 } 159 <link rel="canonical" href="https://@host@url"> 160 @SnippetEnd("canonical") 161 <!-- Trigger for the gallery modal --> 162 <input type="checkbox" id="GalleryModalTrigger" class="modal-trigger" /> 163 164 <!-- Gallery modal --> 165 <div class="modal-container"> 166 <label for="GalleryModalTrigger" id="GalleryModalOverlay" class="modal-overlay"></label> 167 <div class="modal modal--lg modal--full modal-no-bg" id="GalleryModal"> 168 <div class="modal__body"> 169 <div class="gallery-slider js-gallery-slider" data-total-images="@imagesCount" data-images="@galleryImagesArray"> 170 <div class="gallery-slider__image" data-icon-nz="play"> 171 <img id="FullImage" src="@firstImage" class="w-100 js-video-button js-gallery-image" /> 172 </div> 173 <div class="gallery-slider__image-counter" id="FullImage_counter"> 174 </div> 175 <label class="gallery-slider__close-btn" for="GalleryModalTrigger"></label> 176 177 @if (imagesCount > 1) 178 { 179 <button class="gallery-slider__previous-btn" id="FullImage_prev" onclick="Gallery.prevImage('FullImage')"></button> 180 <button class="gallery-slider__next-btn" id="FullImage_next" onclick="Gallery.nextImage('FullImage')"></button> 181 } 182 183 </div> 184 </div> 185 </div> 186 </div> 187 188 <div class="paragraph-container__grid--bleed-x paragraph-container__grid--bleed-y product-view"> 189 <div class="grid product js-product" id="productGrid"> 190 @* Image block with optional thumbs *@ 191 @if (!String.IsNullOrEmpty(productImage)) 192 { 193 <div class="grid__col-md-6 grid__col-sm-6"> 194 <div class="grid grid--bleed product-slider"> 195 @{ 196 int thumbCounter = 0; 197 } 198 <div class="grid__col-2 product-slider__thumbnails dw-mod "> 199 <div class="carousel js-carousel-container u-max-h500px dw-mod"> 200 <div class="thumb-list carousel__container dw-mod m-0"> 201 <div class="carousel__container__slide carousel__container__slide--vertical product-slider__inner dw-mod"> 202 203 @*Main image thumb*@ 204 <div class="carousel__container__slide product-slider__slide dw-mod"> 205 <div class="thumb-list__item thumb-list__item--active dw-mod js-thumb js-thumb-btn js-gallery" onmouseover="Gallery.openImage(this)" data-number="@thumbCounter" data-for="Image_@productId" data-image="/Admin/Public/GetImage.ashx?width=550&amp;height=550&amp;crop=5&DoNotUpscale=true&amp;Compression=75&amp;image=@productImage"> 206 <label for="GalleryModalTrigger"> 207 <img src="/Admin/Public/GetImage.ashx?width=100&amp;height=100&amp;crop=5&amp;DoNotUpscale=true&amp;Compression=75&amp;image=@productImage" class="js-gallery" alt="@GetString("Ecom:Product.Name")" data-for="FullImage" data-number="@thumbCounter" onclick="Gallery.openImage(this)" data-image="/Admin/Public/GetImage.ashx?width=550&amp;height=550&amp;crop=5&DoNotUpscale=true&amp;Compression=75&amp;image=@productImage"> 208 </label> 209 </div> 210 </div> 211 212 @{ thumbCounter++; } 213 214 @foreach (LoopItem alternativeImage in GetLoop("Ecom:Product.AlternativeImages")) 215 { 216 if (!String.IsNullOrEmpty(alternativeImage.GetString("Ecom:Product.AlternativeImages.Image"))) 217 { 218 string image = "/Admin/Public/GetImage.ashx?width=550&amp;height=550&amp;crop=5&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image=" + alternativeImage.GetString("Ecom:Product.AlternativeImages.Image"); 219 string thumb = "/Admin/Public/GetImage.ashx?width=100&amp;height=100&amp;crop=5&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image=" + alternativeImage.GetString("Ecom:Product.AlternativeImages.Image"); 220 221 <div class="carousel__container__slide product-slider__slide dw-mod"> 222 <div class="thumb-list__item dw-mod js-thumb-btn js-thumb js-gallery" onmouseover="Gallery.openImage(this)" data-number="@thumbCounter" data-for="Image_@productId" data-image="@image"> 223 <label for="GalleryModalTrigger"> 224 <img src="@thumb" class="js-gallery" alt="@GetString("Ecom:Product.Name")" data-for="FullImage" data-number="@thumbCounter" onclick="Gallery.openImage(this)" data-image="@image" data-src="@image"> 225 </label> 226 </div> 227 </div> 228 thumbCounter++; 229 } 230 } 231 232 @foreach (var youtubeLink in video.Split('|')) 233 { 234 if (!String.IsNullOrEmpty(youtubeLink)) 235 { 236 string image = String.Format("https://img.youtube.com/vi/{0}/0.jpg", youtubeLink.Split('?')); 237 string thumb = String.Format("https://img.youtube.com/vi/{0}/0.jpg", youtubeLink.Split('?')); 238 239 <div class="carousel__container__slide product-slider__slide dw-mod"> 240 <a class="d-block thumb-list__item has-video dw-mod js-thumb js-thumb-btn js-video-button js-gallery" data-icon-nz="play" onmouseover="Gallery.openImage(this)" data-number="@thumbCounter" data-for="Image_@productId" data-image="@image" href="@youtubeLink" data-type="youtube" data-toggle="modal"> 241 <label for="GalleryModalTrigger"> 242 <img src="@thumb" class="js-gallery" alt="@GetString("Ecom:Product.Name")" data-for="FullImage" data-number="@thumbCounter" onclick="Gallery.openImage(this)" data-image="@image" data-src="@image" data-cookieconsent="ignore"> 243 </label> 244 </a> 245 </div> 246 thumbCounter++; 247 } 248 } 249 250 @foreach (LoopItem detail in GetLoop("Details")) 251 { 252 if (!String.IsNullOrEmpty(detail.GetString("Ecom:Product:Detail.Image.Clean"))) 253 { 254 string image = "/Admin/Public/GetImage.ashx?width=550&amp;height=550&amp;crop=5&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image=" + detail.GetString("Ecom:Product:Detail.Image.Clean"); 255 string thumb = "/Admin/Public/GetImage.ashx?width=100&amp;height=100&amp;crop=5&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image=" + detail.GetString("Ecom:Product:Detail.Image.Clean"); 256 257 <div class="carousel__container__slide product-slider__slide dw-mod"> 258 <div class="thumb-list__item dw-mod js-thumb-btn js-thumb js-gallery" onmouseover="Gallery.openImage(this)" data-number="@thumbCounter" data-for="Image_@productId" data-image="@image"> 259 <label for="GalleryModalTrigger"> 260 <img src="@thumb" class="js-gallery" alt="@GetString("Ecom:Product.Name")" data-for="FullImage" data-number="@thumbCounter" onclick="Gallery.openImage(this)" data-image="@image" data-src="@image"> 261 </label> 262 </div> 263 </div> 264 thumbCounter++; 265 } 266 } 267 </div> 268 </div> 269 270 <div class="js-carousel-data" data-total-slides="@(imagesCount + 1)" data-carousel-slide-time="0" data-current-slide="0" data-direction="vertical" data-sliding-type="items" slides-in-view="6"> 271 <div class="carousel-prev-btn carousel-prev-btn--vertical dw-mod" onclick="Carousel.GetPreviousSlide(this)"></div> 272 <div class="carousel-next-btn carousel-next-btn--vertical dw-mod" onclick="Carousel.GetNextSlide(this)"></div> 273 </div> 274 275 </div> 276 </div> 277 278 <div class="grid__col-10 product-slider__large-image"> 279 <div class="stickers-container dw-mod"> 280 @{ 281 if (Converter.ToBoolean(Pageview.Area.Item["EnableSaleTags"])) 282 { 283 string contentType = Pageview.Area.Item["EcommerceSaleTagContentType"].ToString(); 284 string text = ""; 285 var currency = Dynamicweb.Ecommerce.Services.Currencies.GetDefaultCurrency(); 286 287 switch (contentType) 288 { 289 case "Name": 290 foreach (LoopItem discount in GetLoop("ProductDiscounts")) 291 { 292 text = discount.GetString("Ecom:Product.Discount.Name"); 293 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 294 } 295 break; 296 case "Amount": 297 if (GetLoop("ProductDiscounts").Count > 0) 298 { 299 text = Dynamicweb.Ecommerce.Services.Currencies.Format(currency, GetDouble("Ecom:Product.Discount.Price.Price") - GetDouble("Ecom:Product.Price.Price")); 300 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 301 } 302 break; 303 case "Percents": 304 double percents = 0; 305 foreach (LoopItem discount in GetLoop("ProductDiscounts")) 306 { 307 if (discount.GetDouble("Ecom:Product.Discount.ProductQuantity").Equals(1)) 308 { 309 percents = discount.GetDouble("Ecom:Product.Discount.PercentWithoutVAT"); 310 } 311 } 312 if (percents > 0) 313 { 314 text = Math.Round(percents, 0) + "%"; 315 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 316 } 317 break; 318 case "Amount and percents": 319 double amount = 0; 320 double percent = 0; 321 foreach (LoopItem discount in GetLoop("ProductDiscounts")) 322 { 323 if (discount.GetString("Ecom:Product.Discount.Type") == "PERCENT") 324 { 325 percent += discount.GetDouble("Ecom:Product.Discount.PercentWithoutVAT"); 326 } 327 else if (discount.GetString("Ecom:Product.Discount.Type") == "AMOUNT") 328 { 329 amount += discount.GetDouble("Ecom:Product.Discount.AmountWithVAT"); 330 } 331 } 332 if (percent > 0) 333 { 334 text = percent + "%"; 335 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 336 } 337 if (amount > 0) 338 { 339 text = Dynamicweb.Ecommerce.Services.Currencies.Format(currency, amount); 340 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 341 } 342 break; 343 default: 344 if (GetLoop("ProductDiscounts").Count > 0) 345 { 346 text = Translate("Sale!"); 347 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 348 } 349 break; 350 } 351 } 352 353 if (Converter.ToBoolean(Pageview.Area.Item["NewStickersEnable"]) && GetDate("Ecom:Product.Created").AddDays(Converter.ToDouble(Pageview.Area.Item["NewStickersExpiration"])) > DateTime.Now) 354 { 355 <div class="stickers-container__tag stickers-container__tag--new dw-mod">@Translate("New!")</div> 356 } 357 358 if (!String.IsNullOrEmpty(GetString("Ecom:Product:Field.CustomSticker.Value"))) 359 { 360 <div class="stickers-container__tag stickers-container__tag--custom dw-mod">@GetString("Ecom:Product:Field.CustomSticker.Value")</div> 361 } 362 } 363 </div> 364 365 <label for="GalleryModalTrigger" class="product__image-container"> 366 <img class="thumb-image-view product__image-container__image js-gallery-slider js-video-button dw-mod" src="/Admin/Public/GetImage.ashx?crop=5&width=550&height=550&Compression=75&image=@productImage" data-current-image="0" data-total-images="@imagesCount" data-images="@galleryImagesArray" data-src="/Admin/Public/GetImage.ashx?crop=5&width=550&height=550&Compression=75&image=@productImage" alt="@GetString("Ecom:Product.Name")" id="Image_@productId" data-for="FullImage" data-number="0" onclick="Gallery.openImageByNum(this)" /> 367 </label> 368 369 </div> 370 </div> 371 </div> 372 } 373 374 @* Primary product informations *@ 375 <div class="grid__col-12 grid__col-md-6 product__info dw-mod"> 376 <div> 377 <h1 class="product__title u-no-margin">@GetString("Ecom:Product.Name") @GetString("Ecom:Product.SelectedVariantComboName")</h1> 378 <small class="x-small text-gray-light font-weight-light">@(!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Brand")) ? String.Format("{0}: {1}", Translate("Manufacturer"), GetString("Ecom:Product:Field.Brand")) : "") @Translate("product number"): @GetString("Ecom:Product.Number") @(!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.VVSNumber")) ? String.Format("{0}: {1}", Translate("VVS nr."), GetString("Ecom:Product:Field.VVSNumber")) : "") @(!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.DBN")) ? String.Format("{0}: {1}", Translate("DB nr."), GetString("Ecom:Product:Field.DBN")) : "") </small> 379 <div> 380 @* Delivery + stock information *@ 381 @if (onlyPreview) 382 { 383 <div> 384 <h5 class="mb-2">@Translate("LoginText", "Login")</h5> 385 <label for="SignInModalTrigger" class="btn btn--primary u-no-margin sign-in-modal-trigger-button dw-mod" onclick="setTimeout(function() { document.getElementById('LoginUsername').focus() }, 10)">@Translate("Sign in")</label> 386 </div> 387 } 388 389 @* Variants *@ 390 @*@if (GetLoop("VariantGroups").Count > 0) 391 { 392 string containerId = "Variants" + productId; 393 394 <div> 395 <div id="@containerId" data-product-id="@productId"> 396 @foreach (LoopItem variantGoup in GetLoop("VariantGroups")) 397 { 398 <div> 399 <div class="u-bold">@variantGoup.GetString("Ecom:VariantGroup.Name")</div> 400 <div> 401 @foreach (LoopItem variantOption in variantGoup.GetLoop("VariantAvailableOptions")) 402 { 403 string selected = variantOption.GetBoolean("Ecom:VariantOption.Selected") ? "checked" : ""; 404 405 if (!string.IsNullOrEmpty(variantOption.GetString("Ecom:VariantOption.ImgSmall.Clean"))) 406 { 407 <img src="/Admin/Public/GetImage.ashx?width=100&amp;height=50&amp;crop=5&amp;Compression=75&amp;image=/Images/@variantOption.GetString("Ecom:VariantOption.ImgSmall.Clean")" title="@variantOption.GetString("Ecom:VariantOption.Name")" id="@productId@variantOption.GetString("Ecom:VariantOption.ID")" data-variant-id="@variantOption.GetString("Ecom:VariantOption.ID")" data-product-id="@productId" onclick="Variants.UpdateVariants(this, false, true)" class="btn btn--tag @selected" data-check="@selected" /> 408 } 409 else 410 { 411 <button type="button" data-id="@GetString("Ecom:Product.ID")" id="@productId@variantOption.GetString("Ecom:VariantOption.ID")" data-variant-id="@variantOption.GetString("Ecom:VariantOption.ID")" data-product-id="@productId" onclick="Variants.UpdateVariants(this, false, true)" class="btn btn--tag @selected" data-check="@selected">@variantOption.GetString("Ecom:VariantOption.Name")</button> 412 } 413 } 414 </div> 415 </div> 416 } 417 </div> 418 <small id="helpText_@productId" class="help-text @hideHelpText">@Translate("Please select variant!")</small> 419 </div> 420 }*@ 421 @if (GetLoop("VariantGroups").Count > 0) 422 { 423 var variantCombinationsObject = new List<Array>(); 424 foreach (LoopItem variantcomb in GetLoop("VariantStockCombinations")) 425 { 426 string[] combinations = variantcomb.GetString("Ecom:VariantStockCombination.VariantID").Split('.'); 427 variantCombinationsObject.Add(combinations); 428 } 429 430 string combinationsJson = Newtonsoft.Json.JsonConvert.SerializeObject(variantCombinationsObject).Replace("\"", "\'"); 431 432 var variantGroupsObject = new List<List<String>>(); 433 var selectedItem = new Dictionary<string, string>(); 434 string variantSelection = !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("variantId")) ? HttpContext.Current.Request.QueryString.Get("variantId").Replace(".", ",") : ""; 435 436 var selectedText = Translate("Select variant"); 437 438 foreach (LoopItem variantGroup in GetLoop("VariantGroups")) 439 { 440 var variantsObject = new List<String>(); 441 foreach (LoopItem variantOption in variantGroup.GetLoop("VariantAvailableOptions")) 442 { 443 variantsObject.Add(variantOption.GetString("Ecom:VariantOption.ID")); 444 445 446 if (variantOption.GetBoolean("Ecom:VariantOption.Selected")) 447 { 448 selectedItem.Add(variantGroup.GetString("Ecom:VariantGroup.ID"), variantOption.GetString("Ecom:VariantOption.Name")); 449 } 450 } 451 variantGroupsObject.Add(variantsObject); 452 } 453 string variantsJson = Newtonsoft.Json.JsonConvert.SerializeObject(variantGroupsObject).Replace("\"", "\'"); 454 string productGroupId = HttpContext.Current.Request["GroupId"]; 455 int variantCounter = 0; 456 457 <div class="variants-container"> 458 <div class="js-variants" data-total-variant-groups="@GetLoop("VariantGroups").Count" data-combinations="@combinationsJson" data-variants="@variantsJson" data-selection-complete="UpdatePage" data-page-id="@pageId" data-product-id="@productId" data-group-id="@productGroupId"> 459 @foreach (LoopItem variantGroup in GetLoop("VariantGroups")) 460 { 461 string groupId = variantGroup.GetString("Ecom:VariantGroup.ID"); 462 variantCounter++; 463 <div class="dropdown-container u-margin-bottom--lg"> 464 <div class="product__variant-group-name u-margin-bottom-5px dw-mod">@variantGroup.GetString("Ecom:VariantGroup.Name")</div> 465 <div class="display-value" id="displayValue-@variantCounter" onclick="toggleOptions('selectContainer-@variantCounter')"> 466 <span class="value-text" id="valueText-@variantCounter">@(selectedItem.ContainsKey(variantGroup.GetString("Ecom:VariantGroup.ID")) ? selectedItem[variantGroup.GetString("Ecom:VariantGroup.ID")] : selectedText)</span> 467 <span class="arrow arrow-down" id="arrowControl"></span> 468 </div> 469 <ul tabindex="0" class="select-container" id="selectContainer-@variantCounter" onblur="toggleOptions('selectContainer-@variantCounter')"> 470 @foreach (LoopItem variantOption in variantGroup.GetLoop("VariantAvailableOptions")) 471 { 472 string selected = variantOption.GetBoolean("Ecom:VariantOption.Selected") ? "checked" : ""; 473 474 475 476 <li value="@variantOption.GetString("Ecom:VariantOption.ID")" 477 type="button" 478 data-variant-id="@variantOption.GetString("Ecom:VariantOption.ID")" 479 onclick="MatchVariants.SelectThis(event), selected('@variantOption.GetString("Ecom:VariantOption.Name")','valueText-@variantCounter', 'selectContainer-@variantCounter')" 480 data-variant-group="@groupId" 481 class="btn btn--tag @selected js-variant-option select-option" 482 data-check="@selected">@variantOption.GetString("Ecom:VariantOption.Name")</li> 483 } 484 </ul> 485 </div> 486 } 487 </div> 488 </div> 489 } 490 491 @* BOMProducts *@ 492 @if (GetLoop("BOMProducts").Count > 0) 493 { 494 <h2 class="section-title">@Translate("Including products")</h2> 495 foreach (LoopItem BOMProductItem in GetLoop("BOMProducts")) 496 { 497 string link = "/" + BOMProductItem.GetString("Ecom:Product.LinkGroup.Clean") + (!String.IsNullOrEmpty(BOMProductItem.GetString("Ecom:Product.VariantID")) ? "&VariantID=" + BOMProductItem.GetString("Ecom:Product.VariantID") : ""); 498 <div class="grid__col--border grid"> 499 <div class="grid__cell grid__cell--align-middle-left"> 500 <a href="@link" class="u-pull--left u-margin-right"> 501 <img src="/Admin/Public/GetImage.ashx?width=50&image=@BOMProductItem.GetString("Ecom:Product.ImageSmall.Default.Clean")&Compression=99" /> 502 </a> 503 <a href="@link">@BOMProductItem.GetString("Ecom:Product.Name")</a> 504 </div> 505 </div> 506 } 507 } 508 </div> 509 </div> 510 511 @* Buy block *@ 512 <div class="w-100 mt-5"> 513 <div class="js-handlebars-root dw-mod" id="PriceAndActions" data-template="PricesAndActionsTemplate" data-json-feed="/Default.aspx?ID=@feedId"></div> 514 <input type="hidden" value="@GetString("Ecom:Product.VariantID.Extented")" name="Variant" id="Variant_@GetString("Ecom:Product.ID")" /> 515 </div> 516 <div class="mt-4">@GetString("Ecom:Product:Field.LongDescription")</div> 517 <div class="product-page__specs">@ProductPropertiesMainArea()</div> 518 </div> 519 </div> 520 521 <section class="product-page__product-info"> 522 <div class="grid__col-12 grid__col-lg-9 m-auto"> 523 <div class="nav nav-pills nav-justified"> 524 <a class="nav-item nav-link js-toggle-class js-toggle-retrigger is-active" data-target-retrigger="target-retrigger" data-target=".product-page__content--description">@Translate("Product information")</a> 525 <a class="nav-item nav-link js-toggle-class js-toggle-retrigger" data-target-retrigger="target-retrigger" data-target=".product-page__content--video">@Translate("Documents/Video")</a> 526 <a class="nav-item nav-link js-toggle-class js-toggle-retrigger" data-target-retrigger="target-retrigger" data-target=".product-page__content--accessories">@Translate("Accessories")</a> 527 </div> 528 </div> 529 530 <div class="grid__col-12 grid__col-lg-10 m-auto grid__col--bleed-x"> 531 <div class="grid product-page__content product-page__content--description js-toggle-retrigger is-active"> 532 @* Features lists *@ 533 <div class="grid__col-12 grid__col-md-6 product__features dw-mod"> 534 <h1 class="h3 section-title">@Translate("Product information")</h1> 535 @GetString("Ecom:Product.LongDescription") 536 @GetString("Ecom:Product:Field.description") 537 </div> 538 <div class="grid__col-12 grid__col-md-6 product__features dw-mod"> 539 <h1 class="h3 section-title">@Translate("Product specs")</h1> 540 <div class="product-page__specs">@ProductProperties()</div> 541 </div> 542 </div> 543 <div class="grid product-page__content product-page__content--video js-toggle-retrigger justify-content-center"> 544 <div class="grid__col-12 grid__col-md-8 p-0 p-md-4"> 545 <h1 class="h3 section-title">@Translate("Documents/Video")</h1> 546 <div class="table-responsive small order-list"> 547 <table class="table table-striped product-page-table"> 548 <thead> 549 <tr> 550 <th class="font-weight-bold border-bottom-0" scope="col">@Translate("Name")</th> 551 <th class="font-weight-bold border-bottom-0" scope="col">@Translate("Type")</th> 552 <th class="font-weight-bold border-bottom-0" scope="col">@Translate("Size")</th> 553 </tr> 554 </thead> 555 <tbody> 556 557 @foreach (var documentPath in results) 558 { 559 <tr> 560 <td scope="row"> 561 <a href="@documentPath.FilePath" target="_blank"> 562 <img src="/Files/Images/Lauridsen/icons/icon-pdf.svg" class="product-page-table__icon d-inline-block align-middle mr-3" alt="@documentPath.FileName" /> 563 <span class="d-inline-block align-middle u-underline">@documentPath.FileName</span> 564 </a> 565 </td> 566 <td>@documentPath.FileType.Replace(".pdf", "PDF")</td> 567 <td>@documentPath.FileSize.ToSize(ByteExtension.SizeUnits.KB) KB</td> 568 </tr> 569 } 570 571 572 573 @foreach (var youtubeLink in video.Split('|')) 574 { 575 if (!String.IsNullOrEmpty(youtubeLink)) 576 { 577 int thumbCounter = 0; 578 string image = String.Format("https://img.youtube.com/vi/{0}/0.jpg", youtubeLink); 579 string thumb = String.Format("https://img.youtube.com/vi/{0}/0.jpg", youtubeLink); 580 <tr> 581 <td> 582 <div class="carousel__container__slide dw-mod"> 583 <a class="d-block dw-mod js-thumb-btn js-video-button" onmouseover="Gallery.openImage(this)" data-number="@thumbCounter" data-for="Image_@productId" href="@youtubeLink" data-type="youtube" data-toggle="modal"> 584 <label for="GalleryModalTrigger"> 585 <img src="/Files/Images/Lauridsen/icons/icon-video.svg" class="product-page-table__icon d-inline-block align-middle mr-4" alt="@GetString("Ecom:Product:Field.video")" /> 586 <span class="d-inline-block align-middle u-underline">@GetString("Ecom:Product:Field.video")</span> 587 </label> 588 </a> 589 </div> 590 </td> 591 <td>@GetString("Ecom:Product:Field.video.Name")</td> 592 <td>-</td> 593 </tr> 594 thumbCounter++; 595 } 596 } 597 598 599 600 @foreach (var value in testList) 601 { 602 603 if (externalLink.IsNotNullOrEmpty() && !string.IsNullOrWhiteSpace(value)) 604 { 605 <tr> 606 <td scope="row"> 607 <i class="product-page-table__icon d-inline-block align-middle mr-3 fa fa-link fa-2x"></i> 608 <span class="d-inline-block align-middle u-underline product-external-link">@value</span> 609 </td> 610 <td>@Translate("Link")</td> 611 <td>-</td> 612 </tr> 613 } 614 } 615 </tbody> 616 </table> 617 </div> 618 </div> 619 </div> 620 <div class="grid product-page__content product-page__content--accessories js-toggle-retrigger"> 621 <h1 class="h3 section-title">@Translate("Accessories")</h1> 622 <div class="grid accessories-list dw-mod"> 623 <form name="multiForm" id="multiForm" class="accessories-list__form js-load-more-container" data-initial-load="5" method="post"> 624 <input type="hidden" name="CartCmd" id="CartCmd" value="addMulti" /> 625 @foreach (LoopItem relatedGroup in GetLoop("ProductRelatedGroups").Where(group => group.GetString("Ecom:Product:RelatedGroup.Name") == "Tilbehør" || group.GetString("Ecom:Product:RelatedGroup.Name") == "Reservedele")) 626 { 627 foreach (LoopItem relatedProduct in relatedGroup.GetLoop("RelatedProducts")) 628 { 629 Dynamicweb.Ecommerce.Products.Product currentRelatedProduct = Dynamicweb.Ecommerce.Services.Products.GetProductById(relatedProduct.GetString("Ecom:Product.ID"), relatedProduct.GetString("Ecom:Product.VariantID"), relatedProduct.GetString("Ecom:Product.LanguageID")); 630 var relatedProductImagePathValue = Dynamicweb.Ecommerce.Services.Products.GetProductFieldValue(currentRelatedProduct, "ImagePath"); 631 string imgUrl = "/Files/Images/missing_image.jpg"; 632 string relatedProductImagePath = !string.IsNullOrWhiteSpace(relatedProductImagePathValue.ToString()) ? "/Files/Images/Ecom/LHI_Products/Images/" + relatedProductImagePathValue + ".jpg" : ""; 633 string relatedProductImage = !string.IsNullOrWhiteSpace(relatedProductImagePath) ? relatedProductImagePath : relatedProduct.GetString("Ecom:Product.ImageLarge.Default.Clean"); 634 635 if (!string.IsNullOrWhiteSpace(relatedProductImage)) 636 { 637 imgUrl = relatedProductImage; 638 } 639 640 string name = relatedProduct.GetString("Ecom:Product.Name"); 641 string number = relatedProduct.GetString("Ecom:Product.Number"); 642 string price = relatedProduct.GetString("Ecom:Product.Price"); 643 string groupId = relatedProduct.GetString("Ecom:Product.PrimaryGroupID"); 644 string id = relatedProduct.GetString("Ecom:Product.ID"); 645 var stock = relatedProduct.GetInteger("Ecom:Product.Stock"); 646 string stockText = relatedProduct.GetString("Ecom:Product:Stock.Text"); 647 string shortDescription = relatedProduct.GetString("Ecom:Product.ShortDescription"); 648 649 650 string link = "Default.aspx?" + "ID=" + GetInteger("Ecom:Product.PrimaryOrCurrentPageID") + "&GroupID=" + relatedProduct.GetString("Ecom:Product.PrimaryOrFirstGroupID") + "&ProductID=" + id; 651 List<Dynamicweb.Security.UserManagement.Group> userGroups = new List<Dynamicweb.Security.UserManagement.Group>(); 652 bool userisLoggedIn = Dynamicweb.Security.UserManagement.User.IsExtranetUserLoggedIn(); 653 bool isEmpty = !userGroups.Any(); 654 655 if (isEmpty && Dynamicweb.Security.UserManagement.User.IsExtranetUserLoggedIn()) 656 { 657 userGroups = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser().Groups.ToList(); 658 } 659 660 <div class="accessories-list__item accessorie grid__col-12 grid__col--bleed-x js-load-more-item is-hidden"> 661 <div class="grid"> 662 <figure class="grid__col-sm-2 grid__col-12 accessorie__figure"> 663 <div class="stickers-container dw-mod"> 664 665 666 667 @if (Converter.ToBoolean(Pageview.Area.Item["EnableSaleTags"])) 668 { 669 string contentType = Pageview.Area.Item["EcommerceSaleTagContentType"].ToString(); 670 string text = ""; 671 var currency = Dynamicweb.Ecommerce.Services.Currencies.GetDefaultCurrency(); 672 673 674 switch (contentType) 675 { 676 case "Name": 677 foreach (LoopItem relatedDiscounts in GetLoop("ProductDiscounts")) 678 { 679 text = relatedDiscounts.GetString("Ecom:Product.Discount.Name"); 680 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 681 } 682 break; 683 case "Amount": 684 if (GetLoop("ProductDiscounts").Count > 0) 685 { 686 text = Dynamicweb.Ecommerce.Services.Currencies.Format(currency, GetDouble("Ecom:Product.Discount.Price.Price") - GetDouble("Ecom:Product.Price.Price")); 687 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 688 } 689 break; 690 case "Percents": 691 double percents = 0; 692 if (relatedProduct.GetLoop("ProductDiscounts").Count > 0) 693 { 694 foreach (LoopItem discount in relatedProduct.GetLoop("ProductDiscounts")) 695 { 696 if (discount.GetDouble("Ecom:Product.Discount.ProductQuantity") == 1) 697 { 698 percents = discount.GetDouble("Ecom:Product.Discount.PercentWithoutVAT"); 699 } 700 } 701 if (percents > 0) 702 { 703 text = Math.Round(percents, 0) + "%"; 704 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 705 } 706 707 708 } 709 break; 710 case "Amount and percents": 711 double amount = 0; 712 double percent = 0; 713 foreach (LoopItem relatedDiscounts in GetLoop("ProductDiscounts")) 714 { 715 if (relatedDiscounts.GetString("Ecom:Product.Discount.Type") == "PERCENT") 716 { 717 percent += relatedDiscounts.GetDouble("Ecom:Product.Discount.PercentWithoutVAT"); 718 } 719 else if (relatedDiscounts.GetString("Ecom:Product.Discount.Type") == "AMOUNT") 720 { 721 amount += relatedDiscounts.GetDouble("Ecom:Product.Discount.AmountWithVAT"); 722 } 723 } 724 if (percent > 0) 725 { 726 text = percent + "%"; 727 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 728 } 729 if (amount > 0) 730 { 731 text = Dynamicweb.Ecommerce.Services.Currencies.Format(currency, amount); 732 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 733 } 734 break; 735 default: 736 if (GetLoop("ProductDiscounts").Count > 0) 737 { 738 text = Translate("Sale!"); 739 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 740 } 741 break; 742 } 743 744 745 if (Converter.ToBoolean(Pageview.Area.Item["NewStickersEnable"]) && GetDate("Ecom:Product.Created").AddDays(Converter.ToDouble(Pageview.Area.Item["NewStickersExpiration"])) > DateTime.Now) 746 { 747 <div class="stickers-container__tag stickers-container__tag--new dw-mod">@Translate("New!")</div> 748 } 749 750 if (!String.IsNullOrEmpty(GetString("Ecom:Product:Field.CustomSticker.Value"))) 751 { 752 <div class="stickers-container__tag stickers-container__tag--custom dw-mod">@GetString("Ecom:Product:Field.CustomSticker.Value")</div> 753 } 754 755 } 756 </div> 757 <div class="grid__cell"> 758 <a href="@link" onclick="Scroll.SavePosition(event)" title="@name"> 759 <img class="grid__cell-img accessorie__image" 760 src="/Admin/Public/GetImage.ashx?width=350&amp;height=350&amp;crop=5&amp;Compression=75&amp;DoNotUpscale=true&amp;image=@imgUrl" 761 alt="@name" /> 762 </a> 763 </div> 764 </figure> 765 <div class="grid__col-12 grid__col-sm-4 accessorie__description"> 766 <a class="" href="@link" onclick="Scroll.SavePosition(event)" title="@name"> 767 <div class="accessorie__number"><b>Vare nr.</b> @number</div> 768 <h3 class="accessorie__name">@name</h3> 769 <div class="accessorie__text">@shortDescription</div> 770 <div class="product-list-item__stock"> 771 <div class="stock-icon ml-0 @(stock > 0 ? "stock-icon--in" : "stock-icon--not")"></div> 772 <span>@stockText</span> 773 </div> 774 <span class="product-card__quantity-alert js-product-quantity-error-@id ">@Translate("Max stock level is reached")</span> 775 </a> 776 </div> 777 778 @if (!onlyPreview) 779 { 780 List<Price> priceCollectionList = new List<Price>(); 781 List<Price> getLowestPriceList = new List<Price>(); 782 List<Price> orderedPriceList = new List<Price>(); 783 List<Price> getPriceCollection = new List<Price>(); 784 785 if (userisLoggedIn) 786 { 787 if (currentProduct.Prices.ToList().Any()) 788 { 789 priceCollectionList = currentProduct.Prices.ToList(); 790 } 791 792 string userPriceGroups = string.Empty; 793 if (userGroups.Any()) 794 { 795 <div class=" grid__col-12 grid__col-sm-3 accessorie__details" style="text-align: center"> 796 @foreach (Price priceItem in priceCollectionList.Where(priceItem => priceItem.ProductId.Equals(uniqueId))) 797 { 798 if (Int32.TryParse(priceItem.UserGroupId, out int priceUserGroupId)) 799 { 800 foreach (Dynamicweb.Security.UserManagement.Group userGroupItem in userGroups.Where(userGroup => userGroup.ID.Equals(priceUserGroupId))) 801 { 802 userPriceGroups = userGroupItem.ID.ToString(); 803 if (userPriceGroups != null && priceCollectionList != null) 804 { 805 Price getLowest = priceCollectionList.Where(priceGroup => priceGroup.UserGroupId.Contains(userPriceGroups)).OrderBy(sortQuantity => sortQuantity.Quantity).ThenBy(sortOrder => sortOrder.Amount).ToList().FirstOrDefault(); 806 getLowestPriceList.Add(getLowest); 807 getPriceCollection = priceCollectionList.Where(priceGroup => priceGroup.UserGroupId.Contains(userPriceGroups)).ToList(); 808 if (getPriceCollection.Exists(check => check.Quantity > 2) && getPriceCollection != null) 809 { 810 orderedPriceList.Add(getPriceCollection.FirstOrDefault()); 811 } 812 } 813 } 814 } 815 } 816 @if (userPriceGroups != null && getLowestPriceList.Any()) 817 { 818 string priceWithDiscount = relatedProduct.GetString("Ecom:Product.Discount.Price.PriceFormatted"); 819 820 Price getLowestPrice = getLowestPriceList.OrderBy(lowerPrice => lowerPrice.Amount).ToList().FirstOrDefault(); 821 if (getLowestPrice.Quantity < 2) 822 { 823 <div class="accessorie__price price">@priceWithDiscount</div> 824 <div class=""> 825 @Translate("UnitPriceText") @getLowestPrice.Quantity @vismaUnitName 826 </div> 827 } 828 829 List<LoopItem> priceLoop = relatedProduct.GetLoop("Product.Prices"); 830 if (priceLoop.Any(x => x.GetDouble("Ecom:Product.Prices.Quantity") > 1)) 831 { 832 <div class="js-popup"> 833 834 <a class="js-popup-trigger">@Translate("DiscountText")</a> 835 <div class="js-popup-modal popup_productrelatedview"> 836 <div class="js-popout-close nz-icon icon-nz-close-circled"></div> 837 <ul class="grid__col-12 pt-5 p-0 d-flex flex-row flex-wrap"> 838 839 @foreach (LoopItem priceItem in priceLoop.Where(x => x.GetDouble("Ecom:Product.Prices.Quantity") > 1)) 840 { 841 string relatedVismaUnitName = !string.IsNullOrWhiteSpace(priceItem.GetString("Ecom:Product:Field.Enhed")) ? priceItem.GetString("Ecom:Product:Field.Enhed")?.ToLower() : Translate("UnitPriceTextStk"); 842 <li class="grid__col-lg-6 p-0 mb-0 grid__col-12 align-items-center align-items-xl-start">@Translate("UnitPriceText") @priceItem.GetDouble("Ecom:Product.Prices.Quantity") @relatedVismaUnitName</li> 843 <li class="grid__col-lg-6 p-0 pb-3 grid__col-12 align-items-center align-items-xl-end">@priceItem.GetString("Ecom:Product.Prices.AmountFormatted")</li> 844 } 845 </ul> 846 </div> 847 </div> 848 } 849 } 850 851 </div> 852 if (getLowestPriceList.Any()) 853 { 854 855 if (relatedProduct.GetLoop("VariantGroups").Count > 0) 856 { 857 <div class="grid__col-12 grid__col-sm-3 accessorie__controls"> 858 <div class="accessorie__controls-inner"> 859 860 <a href="@link" class="btn btn-secondary dw-mod js-scroll-btn d-inline-block px-5">@Translate("Select variant")</a> 861 </div> 862 </div> 863 864 } 865 else 866 { 867 <div class="grid__col-12 grid__col-sm-3 accessorie__controls"> 868 <div class="accessorie__controls-inner"> 869 <div class="accessorie__button-container d-inline-block"> 870 <button type="button" id="CartButton_@id" class="btn btn--primary accessorie__cart" name="submit" onclick="Cart.AddToCart(event, '@id', document.getElementById('Quantity_@id').value, 'Unit_@id', 'Variant_@id');"> 871 <i class="fa fa-shopping-cart"></i> 872 <span class="u-hidden-xs u-hidden-xxs"> @Translate("Add to cart")</span> 873 </button> 874 </div> 875 876 <div class="product-card__quantity--condenced product-card__quantity accessorie__quantity"> 877 <input id="Quantity_@id" class="product-card__quantity-input pointer-events js-quantity-input" name="Quantity@accessoriesProduct.Id" data-id="@id" type="number" min="1" max="@stock" value="1"> 878 <span class="product-card__quantity-add js-product-quantity-add" data-icon-nz="chevron-up"></span> 879 <span class="product-card__quantity-subtract js-product-quantity-subtract" data-icon-nz="chevron-down"></span> 880 </div> 881 882 </div> 883 </div> 884 } 885 } 886 else 887 { 888 <div class="grid__col-12 grid__col-sm-3 accessorie__controls"> 889 <div class="accessorie__controls-inner"> 890 <div class="accessorie__button-container d-inline-block"> 891 <button type="button" id="CartButton_@id" class="btn btn-primary dw-mod js-scroll-btn d-inline-block px-5" class="btn btn-primary dw-mod js-scroll-btn d-inline-block px-5" name="submit" data-target=".js-target"> 892 <span class="u-hidden-xs u-hidden-xxs"> @Translate("CallForPrice")</span> 893 </button> 894 </div> 895 </div> 896 </div> 897 } 898 } 899 else 900 { 901 <div class=" grid__col-12 grid__col-sm-3 accessorie__details" style="text-align: center"> 902 <div class="accessorie__price price"></div> 903 <div class="accessorie__before-price before-price "></div> 904 <div class=""> 905 </div> 906 <div class="js-popup"> 907 <div class="js-popup-modal popup_productrelatedview"> 908 <div class="js-popout-close nz-icon icon-nz-close-circled"></div> 909 </div> 910 </div> 911 </div> 912 if (getLowestPriceList.Any()) 913 { 914 915 <div class="grid__col-12 grid__col-sm-3 accessorie__controls"> 916 <div class="accessorie__controls-inner"> 917 918 <div class="accessorie__button-container d-inline-block"> 919 <button type="button" id="CartButton_@id" class="btn btn--primary accessorie__cart" name="submit" onclick="Cart.AddToCart(event, '@id', document.getElementById('Quantity_@id').value, 'Unit_@id', 'Variant_@id');"> 920 <i class="fa fa-shopping-cart"></i> 921 <span class="u-hidden-xs u-hidden-xxs"> @Translate("Add to cart")</span> 922 </button> 923 </div> 924 925 <div class="product-card__quantity--condenced product-card__quantity accessorie__quantity"> 926 <input id="Quantity_@id" class="product-card__quantity-input pointer-events js-quantity-input" name="Quantity@accessoriesProduct.Id" data-id="@id" type="number" min="1" max="@stock" value="1"> 927 <span class="product-card__quantity-add js-product-quantity-add" data-icon-nz="chevron-up"></span> 928 <span class="product-card__quantity-subtract js-product-quantity-subtract" data-icon-nz="chevron-down"></span> 929 </div> 930 931 </div> 932 </div> 933 } 934 else 935 { 936 937 <div class="grid__col-12 grid__col-sm-3 accessorie__controls"> 938 <div class="accessorie__controls-inner"> 939 <div class="accessorie__button-container d-inline-block"> 940 <button type="button" id="CartButton_@id" class="btn btn-primary dw-mod js-scroll-btn d-inline-block px-5" class="btn btn-primary dw-mod js-scroll-btn d-inline-block px-5" name="submit" data-target=".js-target"> 941 <span class="u-hidden-xs u-hidden-xxs"> @Translate("CallForPrice")</span> 942 </button> 943 </div> 944 </div> 945 </div> 946 } 947 } 948 } 949 } 950 else 951 { 952 <div class="grid__col-12 grid__col-sm-6 align-items-center align-items-lg-end"> 953 <div class="grid__cell"> 954 <div class="grid__col-12 pb-0"> 955 <h5>@Translate("LoginText")</h5> 956 </div> 957 <div class="grid__col-12 pb-0"> 958 <label for="SignInModalTrigger" class="btn btn--primary u-no-margin sign-in-modal-trigger-button dw-mod" onclick="setTimeout(function() { document.getElementById('LoginUsername').focus() }, 10)">@Translate("Sign in")</label> 959 </div> 960 </div> 961 </div> 962 } 963 </div> 964 </div> 965 } 966 } 967 <div class="grid__col--bleed-y mb-6"> 968 <a class="btn btn-teritary btn--load-more js-load-more-trigger dw-mod">@Translate("Load more")</a> 969 </div> 970 </form> 971 </div> 972 </div> 973 </div> 974 </section> 975 @if (GetLoop("ProductRelatedGroups").Any()) 976 { 977 <section class="related-products"> 978 <div class="grid related-products__inner-container"> 979 980 <div class="grid__col-xs-12 related-products__headline-container"> 981 <h2 class="related-products__headline h2 section-title section-title--condensed">@Translate("Related products")</h2> 982 </div> 983 984 <div class="grid__col-12 grid__col-md-10 grid__col--bleed m-auto"> 985 <div class="grid"> 986 987 @foreach (LoopItem relatedGroup in GetLoop("ProductRelatedGroups").Where(group => group.GetString("Ecom:Product:RelatedGroup.Name") == "Relaterede produkter")) 988 { 989 foreach (LoopItem related in relatedGroup.GetLoop("RelatedProducts")) 990 { 991 Dynamicweb.Ecommerce.Products.Product currentRelatedProduct = Dynamicweb.Ecommerce.Services.Products.GetProductById(related.GetString("Ecom:Product.ID"), related.GetString("Ecom:Product.VariantID"), related.GetString("Ecom:Product.LanguageID")); 992 var relatedProductImagePathValue = Dynamicweb.Ecommerce.Services.Products.GetProductFieldValue(currentRelatedProduct, "ImagePath"); 993 string imgUrl = "/Files/Images/missing_image.jpg"; 994 string relatedProductImagePath = !string.IsNullOrWhiteSpace(relatedProductImagePathValue.ToString()) ? "/Files/Images/Ecom/LHI_Products/Images/" + relatedProductImagePathValue + ".jpg" : ""; 995 string relatedProductImage = !string.IsNullOrWhiteSpace(relatedProductImagePath) ? relatedProductImagePath : related.GetString("Ecom:Product.ImageLarge.Default.Clean"); 996 997 if (!string.IsNullOrWhiteSpace(relatedProductImage)) 998 { 999 imgUrl = relatedProductImage; 1000 } 1001 1002 string name = related.GetString("Ecom:Product.Name"); 1003 string number = related.GetString("Ecom:Product.Number"); 1004 string price = related.GetString("Ecom:Product.Price"); 1005 string groupId = related.GetString("Ecom:Product.PrimaryGroupID"); 1006 string id = related.GetString("Ecom:Product.ID"); 1007 var stock = related.GetInteger("Ecom:Product.Stock"); 1008 string stockText = related.GetString("Ecom:Product:Stock.Text"); 1009 1010 <div class="grid__col-12 grid__col-sm-6 grid__col-lg-3"> 1011 <div class="related-products__product related-product"> 1012 <a href="@related.GetString("Ecom:Product.Link.Clean")"> 1013 <div class="stickers-container dw-mod"> 1014 1015 @if (Converter.ToBoolean(Pageview.Area.Item["EnableSaleTags"])) 1016 { 1017 string contentType = Pageview.Area.Item["EcommerceSaleTagContentType"].ToString(); 1018 string text = ""; 1019 var currency = Dynamicweb.Ecommerce.Services.Currencies.GetDefaultCurrency(); 1020 1021 1022 switch (contentType) 1023 { 1024 case "Name": 1025 foreach (LoopItem relatedDiscounts in GetLoop("ProductDiscounts")) 1026 { 1027 text = relatedDiscounts.GetString("Ecom:Product.Discount.Name"); 1028 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 1029 } 1030 break; 1031 case "Amount": 1032 if (GetLoop("ProductDiscounts").Count > 0) 1033 { 1034 text = Dynamicweb.Ecommerce.Services.Currencies.Format(currency, GetDouble("Ecom:Product.Discount.Price.Price") - GetDouble("Ecom:Product.Price.Price")); 1035 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 1036 } 1037 break; 1038 case "Percents": 1039 double percents = 0; 1040 if (related.GetLoop("ProductDiscounts").Count > 0) 1041 { 1042 foreach (LoopItem discount in related.GetLoop("ProductDiscounts")) 1043 { 1044 if (discount.GetDouble("Ecom:Product.Discount.ProductQuantity") == 1) 1045 { 1046 percents = discount.GetDouble("Ecom:Product.Discount.PercentWithoutVAT"); 1047 } 1048 } 1049 if (percents > 0) 1050 { 1051 text = Math.Round(percents, 0) + "%"; 1052 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 1053 } 1054 1055 1056 } 1057 break; 1058 case "Amount and percents": 1059 double amount = 0; 1060 double percent = 0; 1061 foreach (LoopItem relatedDiscounts in GetLoop("ProductDiscounts")) 1062 { 1063 if (relatedDiscounts.GetString("Ecom:Product.Discount.Type") == "PERCENT") 1064 { 1065 percent += relatedDiscounts.GetDouble("Ecom:Product.Discount.PercentWithoutVAT"); 1066 } 1067 else if (relatedDiscounts.GetString("Ecom:Product.Discount.Type") == "AMOUNT") 1068 { 1069 amount += relatedDiscounts.GetDouble("Ecom:Product.Discount.AmountWithVAT"); 1070 } 1071 } 1072 if (percent > 0) 1073 { 1074 text = percent + "%"; 1075 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 1076 } 1077 if (amount > 0) 1078 { 1079 text = Dynamicweb.Ecommerce.Services.Currencies.Format(currency, amount); 1080 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 1081 } 1082 break; 1083 default: 1084 if (GetLoop("ProductDiscounts").Count > 0) 1085 { 1086 text = Translate("Sale!"); 1087 <div class="stickers-container__tag stickers-container__tag--sale dw-mod">@text</div> 1088 } 1089 break; 1090 } 1091 1092 1093 if (Converter.ToBoolean(Pageview.Area.Item["NewStickersEnable"]) && GetDate("Ecom:Product.Created").AddDays(Converter.ToDouble(Pageview.Area.Item["NewStickersExpiration"])) > DateTime.Now) 1094 { 1095 <div class="stickers-container__tag stickers-container__tag--new dw-mod">@Translate("New!")</div> 1096 } 1097 1098 if (!String.IsNullOrEmpty(GetString("Ecom:Product:Field.CustomSticker.Value"))) 1099 { 1100 <div class="stickers-container__tag stickers-container__tag--custom dw-mod">@GetString("Ecom:Product:Field.CustomSticker.Value")</div> 1101 } 1102 1103 } 1104 1105 1106 </div> 1107 <img class="related-product__image b-lazy" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=350&amp;height=350&amp;crop=5&amp;Compression=75&amp;DoNotUpscale=true&amp;image=@imgUrl" alt="@name" /> 1108 <h4 class="related-product__name">@name</h4> 1109 <div class="related-product__number">@Translate("product number") @number</div> 1110 1111 <div class="product-list-item__stock"> 1112 <div class="stock-icon ml-0 @(stock > 0 ? "stock-icon--in" : "stock-icon--not")"></div> 1113 <span>@stockText</span> 1114 </div> 1115 1116 <span class="product-card__quantity-alert js-product-quantity-error-@id ">@Translate("Max stock level is reached")</span> 1117 </a> 1118 1119 @if (!onlyPreview) 1120 { 1121 string priceWithDiscount = related.GetString("Ecom:Product.Discount.Price.Price"); 1122 string currencySymbol = related.GetString("Ecom:Product.Currency.Symbol"); 1123 string priceWithOutDiscount = related.GetString("Ecom:Product.Price.Price"); 1124 bool productHasDiscount = GetBoolean("Ecom:Product.HaveDiscount"); 1125 1126 <div class="related-product__button-container d-inline-block"> 1127 @if (priceWithDiscount != "0,00" || priceWithOutDiscount != "0,00") 1128 { 1129 if (GetString("Ecom:Product.Discount.TotalAmount") != "DKK 0,00") 1130 { 1131 <div class="related-product__price withdiscount">@currencySymbol @priceWithDiscount</div> 1132 } 1133 1134 else 1135 { 1136 <div class="related-product__price withoutdiscount">@currencySymbol @priceWithOutDiscount</div> 1137 } 1138 1139 List<LoopItem> priceLoop = related.GetLoop("Product.Prices"); 1140 if (priceLoop.Any(x => x.GetDouble("Ecom:Product.Prices.Quantity") > 1)) 1141 { 1142 <div class="js-popup"> 1143 <a class="js-popup-trigger">@Translate("DiscountText")</a> 1144 <div class="js-popup-modal popup_productrelatedview"> 1145 <div class="js-popout-close nz-icon icon-nz-close-circled"></div> 1146 <ul class="grid__col-12 pt-5 p-0 d-flex flex-row flex-wrap"> 1147 1148 @foreach (LoopItem priceItem in priceLoop.Where(x => x.GetDouble("Ecom:Product.Prices.Quantity") > 1)) 1149 { 1150 <li class="grid__col-lg-6 p-0 mb-0 grid__col-12 align-items-center align-items-xl-start">@Translate("UnitPriceText") @priceItem.GetDouble("Ecom:Product.Prices.Quantity") @Translate("UnitPriceTextStk")</li> 1151 <li class="grid__col-lg-6 p-0 pb-3 grid__col-12 align-items-center align-items-xl-end">@priceItem.GetString("Ecom:Product.Prices.AmountFormatted")</li> 1152 } 1153 </ul> 1154 </div> 1155 </div> 1156 } 1157 1158 if (related.GetLoop("VariantGroups").Count > 0) 1159 { 1160 <div class="related-product__controls"> 1161 1162 1163 <a href="@related.GetString("Ecom:Product.Link.Clean")" class="btn btn-secondary dw-mod js-scroll-btn d-inline-block px-5">@Translate("Select variant")</a> 1164 1165 </div> 1166 1167 } 1168 else 1169 { 1170 <div class="related-product__controls"> 1171 <div class="product-card__quantity--condenced product-card__quantity related-product__quantity"> 1172 <input id="Quantity_@id" class="product-card__quantity-input pointer-events js-quantity-input" name="Quantity@id" data-id="@id" type="number" min="1" max="@stock" value="1"> 1173 <span class="product-card__quantity-add js-product-quantity-add" data-icon-nz="chevron-up"></span> 1174 <span class="product-card__quantity-subtract js-product-quantity-subtract" data-icon-nz="chevron-down"></span> 1175 </div> 1176 <button type="button" id="CartButton_@id" class="btn btn--primary related-product__cart" name="submit" onclick="Cart.AddToCart(event, '@id', document.getElementById('Quantity_@id').value, 'Unit_@id', 'Variant_@id');"> 1177 <i class="fa fa-shopping-cart"></i> 1178 <span class="u-hidden-xs u-hidden-xxs"> @Translate("Add to cart")</span> 1179 </button> 1180 </div> 1181 } 1182 1183 1184 } 1185 else 1186 { 1187 <button type="button" id="CartButton_@id" class="btn btn-primary dw-mod js-scroll-btn d-inline-block px-5" name="submit" data-target=".js-target"> 1188 <span class="u-hidden-xs u-hidden-xxs"> @Translate("CallForPrice")</span> 1189 </button> 1190 } 1191 </div> 1192 1193 1194 } 1195 else 1196 { 1197 <div class="related-product__login-label">@Translate("LoginText")</div> 1198 <label for="SignInModalTrigger" class="btn btn--primary u-no-margin sign-in-modal-trigger-button dw-mod related-product__login" onclick="setTimeout(function () { document.getElementById('LoginUsername').focus() }, 10)">@Translate("Sign in")</label> 1199 } 1200 1201 1202 </div> 1203 </div> 1204 1205 1206 1207 1208 } 1209 1210 } 1211 1212 </div> 1213 </div> 1214 </div> 1215 </section> 1216 1217 1218 1219 } 1220 </div> 1221 1222 @* 1223 @if(GetLoop("eCom:Related.CustomersWhoSawThisAlsoSaw").Any()) 1224 { 1225 foreach (LoopItem item in GetLoop("eCom:Related.CustomersWhoSawThisAlsoSaw")) 1226 { 1227 relatedProductsFeed += item.GetString("Ecom:Product.ID"); 1228 relatedProductsFeed += ""; 1229 } 1230 1231 <div class="grid"> 1232 <div class="grid__col-12"> 1233 <div class="bg-gray bg-gray-full-width"> 1234 <h2 class="h1 section-title section-title--condensed">@Translate("ecom-related-products-3", "Related products")</h2> 1235 <div class="js-handlebars-root" id="ProductList_@productId" data-template="ProductContainer" data-pre-render-template="ProductPreRenderContainer" data-json-feed="@relatedProductsFeed" data-preloader="overlay"></div> 1236 </div> 1237 </div> 1238 </div> 1239 } 1240 *@ 1241 1242 @helper ProductPropertiesMainArea() 1243 { 1244 if (GetLoop("CustomFieldValues").Count > 0) 1245 { 1246 var visibleCount = 0; 1247 1248 <div class="specs-list specs-list--5"> 1249 <dl class="table table--clean table--compact product-page__specs-list"> 1250 @foreach (LoopItem customField in GetLoop("CustomFieldValues").Where(customField => customField.GetString("Product.CustomField.System") != "description").Where(customField => customField.GetString("Product.CustomField.System") != "LongDescription").Where(customField => customField.GetString("Product.CustomField.System") != "ShortDescription")) 1251 { 1252 string fieldValue = customField.GetString("Product.CustomField.Value.Clean"); 1253 1254 if (customField.GetLoop("Product.CustomField.Options").Count > 0) 1255 { 1256 fieldValue = ""; 1257 int count = 0; 1258 1259 foreach (LoopItem customFieldOptions in customField.GetLoop("Product.CustomField.Options").Where(customFieldOptions => !string.IsNullOrWhiteSpace(customFieldOptions.GetString("Product.CustomField.Option.Name")))) 1260 { 1261 if (customFieldOptions.GetBoolean("Product.CustomField.Option.IsSelected")) 1262 { 1263 if (count != 0) 1264 { 1265 fieldValue += ", "; 1266 } 1267 1268 fieldValue += customFieldOptions.GetString("Product.CustomField.Option.Name"); 1269 count++; 1270 } 1271 } 1272 } 1273 1274 if (fieldValue == "False") 1275 { 1276 fieldValue = Translate("No"); 1277 } 1278 1279 if (fieldValue == "True") 1280 { 1281 fieldValue = Translate("Yes"); 1282 } 1283 1284 1285 if (!String.IsNullOrEmpty(customField.GetString("Product.CustomField.Name")) 1286 && !String.IsNullOrWhiteSpace(fieldValue) 1287 && customField.GetString("Product.CustomField.Name") != "Custom sticker" 1288 && customField.GetString("Product.CustomField.Name").Contains("Produkt tekst") == true) 1289 { 1290 if (!String.IsNullOrEmpty(customField.GetString("Document.FullPath"))) 1291 { 1292 visibleCount++; 1293 <dd class="product-page__specs-value"><a href="@customField.GetString("Document.FullPath")" download title="@Translate("Download")" class="product__document"><span property="identifier">@getIconForFile(fieldValue) @Path.GetFileName(fieldValue)</span></a></dd> 1294 } 1295 else 1296 { 1297 visibleCount++; 1298 <dd class="product-page__specs-value"><span property="identifier">@fieldValue</span></dd> 1299 } 1300 } 1301 } 1302 </dl> 1303 1304 @if (visibleCount > 5) 1305 { 1306 <div class="js-load-more-specs specs-list__trigger"> 1307 <span class="specs-list__load-more">@Translate("Show more")</span> 1308 <span class="specs-list__load-less">@Translate("Show less")</span> 1309 </div> 1310 } 1311 1312 </div> 1313 } 1314 } 1315 @helper ProductProperties() 1316 { 1317 if (GetLoop("CustomFieldValues").Count > 0) 1318 { 1319 var visibleCount = 0; 1320 1321 <div class="specs-list specs-list--10"> 1322 <dl class="table table--clean table--compact product-page__specs-list"> 1323 @foreach (LoopItem customField in GetLoop("CustomFieldValues").Where(customField => customField.GetString("Product.CustomField.System") != "description").Where(customField => customField.GetString("Product.CustomField.System") != "LongDescription").Where(customField => customField.GetString("Product.CustomField.System") != "ShortDescription")) 1324 { 1325 string fieldValue = customField.GetString("Product.CustomField.Value.Clean"); 1326 1327 if (customField.GetLoop("Product.CustomField.Options").Count > 0) 1328 { 1329 fieldValue = ""; 1330 int count = 0; 1331 1332 foreach (LoopItem customFieldOptions in customField.GetLoop("Product.CustomField.Options").Where(customFieldOptions => !string.IsNullOrWhiteSpace(customFieldOptions.GetString("Product.CustomField.Option.Name")))) 1333 { 1334 if (customFieldOptions.GetBoolean("Product.CustomField.Option.IsSelected")) 1335 { 1336 if (count != 0) 1337 { 1338 fieldValue += ", "; 1339 } 1340 1341 fieldValue += customFieldOptions.GetString("Product.CustomField.Option.Name"); 1342 count++; 1343 } 1344 } 1345 } 1346 if (fieldValue == "False") 1347 { 1348 fieldValue = Translate("No"); 1349 } 1350 1351 if (fieldValue == "True") 1352 { 1353 fieldValue = Translate("Yes"); 1354 } 1355 1356 if (!String.IsNullOrEmpty(customField.GetString("Product.CustomField.Name")) 1357 && !String.IsNullOrWhiteSpace(fieldValue) 1358 && customField.GetString("Product.CustomField.Name") != "Custom sticker" 1359 && !customField.GetString("Product.CustomField.Name").Contains("Produktions ansvarlig") 1360 && !customField.GetString("Product.CustomField.Name").Contains("Video") 1361 && !customField.GetString("Product.CustomField.Name").Contains("PDF") 1362 && !customField.GetString("Product.CustomField.Name").Contains("Lokation") 1363 && !customField.GetString("Product.CustomField.Name").Contains("Status") 1364 && !customField.GetString("Product.CustomField.Name").Contains("Produktgr. (CO)") 1365 && !customField.GetString("Product.CustomField.Name").Contains("Produktprisgr. 1 (rabatgruppe)") 1366 && !customField.GetString("Product.CustomField.Name").Contains("Prisliste") 1367 && !customField.GetString("Product.CustomField.Name").Contains("Godkendelse") 1368 && !customField.GetString("Product.CustomField.Name").Contains("Salgsstatistik") 1369 && !customField.GetString("Product.CustomField.Name").Contains("ABC") 1370 && !customField.GetString("Product.CustomField.Name").Contains("Billedefilnr (LFR)") 1371 && !customField.GetString("Product.CustomField.Name").Contains("Rabat gruppe 2") 1372 && !customField.GetString("Product.CustomField.Name").Contains("Visma changed by user") 1373 && !customField.GetString("Product.CustomField.Name").Contains("Visma changed date") 1374 && customField.GetString("Product.CustomField.Value") != "0" 1375 && customField.GetString("Product.CustomField.Value") != "" 1376 && customField.GetString("Product.CustomField.Name").Contains("Produkt tekst") != true) 1377 { 1378 <dt class="product-page__specs-display" width="160">@Translate(customField.GetString("Product.CustomField.Name")): </dt> 1379 if (!String.IsNullOrEmpty(customField.GetString("Document.FullPath"))) 1380 { 1381 visibleCount++; 1382 <dd class="text-right product-page__specs-value"><a href="@customField.GetString("Document.FullPath")" download title="@Translate("Download")" class="product__document"><span property="identifier">@getIconForFile(fieldValue) @Path.GetFileName(fieldValue)</span></a></dd> 1383 } 1384 else 1385 { 1386 visibleCount++; 1387 <dd class="text-right product-page__specs-value"><span property="identifier">@fieldValue</span></dd> 1388 } 1389 } 1390 } 1391 </dl> 1392 1393 @if (visibleCount > 10) 1394 { 1395 <div class="js-load-more-specs specs-list__trigger"> 1396 <span class="specs-list__load-more">@Translate("Show more")</span> 1397 <span class="specs-list__load-less">@Translate("Show less")</span> 1398 </div> 1399 } 1400 </div> 1401 } 1402 1403 if (GetLoop("ProductCategories").Count > 0) 1404 { 1405 <dl class="product-page__specs-list"> 1406 @foreach (LoopItem categoryGroup in GetLoop("ProductCategories")) 1407 { 1408 int fieldsCount = 0; 1409 foreach (LoopItem categoryField in categoryGroup.GetLoop("ProductCategoryFields")) 1410 { 1411 if (!String.IsNullOrEmpty(categoryField.GetString("Ecom:Product.CategoryField.Value"))) 1412 { 1413 fieldsCount++; 1414 } 1415 } 1416 if (fieldsCount > 0) 1417 { 1418 <dd class="product-page__specs-display">@categoryGroup.GetString("Ecom:Product.Category.Name")</dd> 1419 1420 foreach (LoopItem categoryField in categoryGroup.GetLoop("ProductCategoryFields")) 1421 { 1422 string fieldValue = categoryField.GetString("Ecom:Product.CategoryField.Value"); 1423 1424 if (fieldValue == "False") 1425 { 1426 fieldValue = Translate("No"); 1427 } 1428 1429 if (fieldValue == "True") 1430 { 1431 fieldValue = Translate("Yes"); 1432 } 1433 1434 if (!String.IsNullOrEmpty(categoryField.GetString("Ecom:Product.CategoryField.Label")) && !String.IsNullOrEmpty(fieldValue)) 1435 { 1436 <dt class="product-page__specs-display">@categoryField.GetString("Ecom:Product.CategoryField.Label"):</dt> 1437 <dd class="text-right product-page__specs-value"><span property="identifier">@fieldValue</span></dd> 1438 } 1439 } 1440 } 1441 } 1442 </dl> 1443 } 1444 } 1445 1446 <script id="PricesAndActionsTemplate" type="text/x-template"> 1447 {{#.}} 1448 1449 @if (!onlyPreview) 1450 { 1451 if (cfp == false) 1452 { 1453 <text> 1454 {{#ifCond hasVariants "!==" "disabled"}} 1455 1456 @if (GetString("Ecom:Product.Discount.TotalAmount") != "DKK 0,00") 1457 { 1458 1459 <small class="text-gray font-weight-light">@Translate("NettoPrice")</small> 1460 <div class="text-gray font-weight-light product__price--discount {{onSale}}">{{#Discount}}{{#if @@first}}{{this.discountCurrency}} {{this.discount}}{{/if}}{{/Discount}}</div> 1461 <br /> 1462 <small class="text-gray font-weight-light">@Translate("ProductDiscount")</small> 1463 <div class="text-gray font-weight-light product__price--discount {{onSale}}">{{#Discount}}{{#if @@first}}{{this.discountCurrency}} {{this.subtractPriceWithoutDecimals}}{{/if}}{{/Discount}}</div> 1464 <br /> 1465 <small class="text-gray font-weight-light">@Translate("PriceWithDiscount")</small> 1466 1467 } 1468 1469 else 1470 { 1471 <small class="text-gray font-weight-light">@Translate("PriceWithoutDiscount")</small> 1472 } 1473 1474 @if (GetLoop("ProductDiscounts").Any()) 1475 { 1476 <div class="h1 my-3 text-gray font-weight-light">{{price}}</div> 1477 } 1478 else 1479 { 1480 <div class="h1 my-3 text-gray font-weight-light">{{price}}</div> 1481 } 1482 1483 {{/ifCond}} 1484 </text> 1485 1486 1487 } 1488 if (!String.IsNullOrEmpty(GetString("Ecom:Product:Stock.Text")) || !String.IsNullOrEmpty(GetString("Ecom:Product:Stock.DeliveryText"))) 1489 { 1490 if (GetLoop("Product.Prices").Count >= 1) 1491 { 1492 1493 var priceLoop = GetLoop("Product.Prices"); 1494 var excludedIds = "1"; 1495 var priceQuantity = priceLoop.Where(i => !excludedIds.Contains(i.GetString("Ecom:Product.Prices.Quantity"))); 1496 1497 if (GetLoop("Product.Prices").Count > 1 && priceQuantity.Any()) 1498 { 1499 1500 1501 <div class="js-popup"> 1502 <a class="js-popup-trigger">@Translate("DiscountText")</a> 1503 <div class="js-popup-modal popup_productview"> 1504 <div class="js-popout-close nz-icon icon-nz-close-circled"></div> 1505 <ul class="grid__col-12 pt-5 p-0 d-flex flex-row flex-wrap"> 1506 @* FOREACH DISCOUNT LOOP FROM JSON FEED *@ 1507 {{#each Discount}} 1508 {{#unless @@first}} 1509 <li class="grid__col-lg-6 p-0 mb-0 grid__col-12 align-items-center align-items-xl-start">@Translate("UnitPriceText") {{this.discountQuantity}} {{this.vismaUnitName}}</li> 1510 <li class="grid__col-lg-6 p-0 pb-3 grid__col-12 align-items-center align-items-xl-end">{{this.discountCurrency}} {{this.discount}}</li> 1511 {{/unless}} 1512 {{/each}} 1513 1514 </ul> 1515 </div> 1516 </div> 1517 } 1518 } 1519 <br> 1520 1521 if (!String.IsNullOrEmpty(GetString("Ecom:Product:Stock.Text")) || !String.IsNullOrEmpty(GetString("Ecom:Product:Stock.DeliveryText"))) 1522 { 1523 string stockIcon = GetInteger("Ecom:Product.Stock") > 0 ? "product__stock-icon--in" : "product__stock-icon--not"; 1524 1525 if (cfp == false) 1526 { 1527 <table class="table table--clean delivery-and-stock-info dw-mod"> 1528 <tr> 1529 <td class="u-no-padding"> 1530 <div class="stock-icon ml-0 @stockIcon"></div> 1531 <span class="font-weight-bold">@GetString("Ecom:Product:Stock.Text")</span> 1532 </td> 1533 </tr> 1534 <tr> 1535 @* 1536 @if (!String.IsNullOrEmpty(GetString("Ecom:Product:Stock.DeliveryText"))) 1537 { 1538 <td class="u-no-padding">@Translate("Shipping") @GetString("Ecom:Product:Stock.DeliveryText") @GetString("Ecom:Product:Stock.DeliveryUnit")</td> 1539 } 1540 *@ 1541 </tr> 1542 </table> 1543 } 1544 } 1545 1546 <div class="buttons-collection product__price-actions__actions dw-mod d-inline-block d-lg-flex mt-5 w-100"> 1547 1548 @if (GetBoolean("Ecom:Product:Field.CFP")) 1549 { 1550 <div class="cfp-btn-container pt-4 pt-lg-0"> 1551 <button type="button" id="CartButton_{{id}}" class="btn btn-primary dw-mod js-scroll-btn d-inline-block px-5" name="submit" data-target=".js-target">@Translate("CallForPrice")</button> 1552 </div> 1553 } 1554 1555 else 1556 { 1557 var disabledClass = String.IsNullOrWhiteSpace(variantId) && GetLoop("VariantGroups").Count > 0 ? "disabled" : ""; 1558 @* Product quantity *@ 1559 <div class="product-card__quantity product-card__quantity--condenced"> 1560 <input id="Quantity_{{id}}" class="product-card__quantity-input pointer-events js-quantity-input" data-id="{{id}}" name="Quantity" type="number" min="1" max="@stockAmount" value="1"> 1561 <span class="product-card__quantity-add js-product-quantity-add" data-icon-nz="chevron-up"></span> 1562 <span class="product-card__quantity-subtract js-product-quantity-subtract" data-icon-nz="chevron-down"></span> 1563 </div> 1564 <div class="product-btn-buy-container pt-4 pt-lg-0 pl-lg-3"> 1565 {{#ifCond hasVariants "==" "disabled"}} 1566 <a href="{{link}}" class="btn btn-secondary dw-mod js-scroll-btn d-inline-block px-5 @disabledClass">@Translate("Select variant")</a> 1567 {{else}} 1568 <button type="button" id="CartButton_{{id}}" class="btn btn-primary dw-mod d-inline-block px-5 @disabledClass" name="submit" onclick="Cart.AddToCart(event, '{{productId}}', document.getElementById('Quantity_{{id}}').value, 'Unit_{{id}}', 'Variant_{{productId}}');">@Translate("Add to cart")</button> 1569 {{/ifCond}} 1570 </div> 1571 } 1572 1573 @if (Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName"))) 1574 { 1575 string favoriteId = "Favorite" + GetString("Ecom:Product.ID"); 1576 1577 <div id="@favoriteId" class="favorites fav-product-container favorites--md d-inline-block dw-mod p-0 pl-lg-3"> 1578 <label for="FavoriteTrigger" class="btn mb-0 btn-secondary"><span class="pr-2 product__add-to-favorites"></span><small class="x-small">@Translate("Add to list")</small></label> 1579 <input type="checkbox" id="FavoriteTrigger" class="dropdown-trigger"> 1580 <div class="dropdown"> 1581 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod"> 1582 @if (GetLoop("CustomerCenter.ListTypes").Any()) 1583 { 1584 <ul class="list list--clean dw-mod"> 1585 @foreach (LoopItem listType in GetLoop("CustomerCenter.ListTypes")) 1586 { 1587 foreach (LoopItem list in listType.GetLoop("CustomerCenter.ProductLists")) 1588 { 1589 <li> 1590 @{string favLinkType = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? list.GetString("Ecom:Product.RemoveFromThisList") : list.GetString("Ecom:Product.AddToThisListAction");} 1591 @{string isInListIcon = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? "fa fa-star" : "fa fa-star-o";} 1592 <a href="@favLinkType" class="list__link dw-mod"><i class="@isInListIcon"></i> @list.GetValue("Ecom:CustomerCenter.List.Name")</a> 1593 </li> 1594 } 1595 } 1596 </ul> 1597 } 1598 1599 else 1600 { 1601 <p>@Translate("CreateFavoritList")</p><a class="btn-sm btn-primary d-block text-center" href="@favoritPage">@Translate("CreateFavoritListButton")</a> 1602 } 1603 1604 </div> 1605 <label class="dropdown-trigger-off" for="FavoriteTrigger"></label> 1606 </div> 1607 </div> 1608 } 1609 1610 1611 </div> 1612 1613 <span class="product-card__quantity-alert js-product-quantity-error-{{id}}">@Translate("Max stock level is reached")</span> 1614 } 1615 } 1616 1617 else 1618 { 1619 <button type="button" id="CartButton_{{id}}" class="u-hidden"></button> 1620 } 1621 {{/.}} 1622 </script> 1623 1624 <script id="Units" type="text/x-template"> 1625 <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent('PriceAndActions', '/Default.aspx?ID=@feedId&UnitID={{value}}')">{{name}}</div> 1626 </script> 1627 1628 1629 @* Script templates for related products *@ 1630 <script id="ProductPreRenderContainer" type="text/x-template"> 1631 <div class="u-h600px u-full-width"> 1632 <div class="grid"> 1633 <div class="grid__col-12"> 1634 <div class="pre-render-element pre-render-element--md"></div> 1635 </div> 1636 </div> 1637 </div> 1638 </script> 1639 1640 <script id="ProductContainer" type="text/x-template"> 1641 {{#.}} 1642 <div class="u-min-h400px u-full-width"> 1643 <div class="grid"> 1644 <div class="grid__col-45px grid__col--bleed-x"> 1645 <div class="grid__cell grid__cell--align-middle-left"> 1646 <button class="btn btn--condensed btn--clean {{prevdisabled}} dw-mod" onclick="HandlebarsBolt.UpdateContent('ProductList_{{groupName}}', '{{prevPage}}')" {{prevdisabled}}><i class="fa fa-chevron-left fa-2x"></i></button> 1647 </div> 1648 </div> 1649 <div class="grid__col-auto grid__col--bleed-x"> 1650 <div id="ProductsContainer" class="grid product-list dw-mod"> 1651 {{#ProductsContainer}} 1652 <div id="Product{{productId}}" class="grid__col-@relatedProductsColumnWidth product-list__list-item dw-mod"> 1653 <div class="product-list__inner"> 1654 {{#Product}} 1655 <div class="grid__cell product-list__grid-item__image dw-mod {{noImage}}"> 1656 <div class="stickers-container dw-mod"> 1657 {{#Stickers}} 1658 {{>Sticker}} 1659 {{/Stickers}} 1660 </div> 1661 <a href="{{link}}" onclick="Scroll.SavePosition(event)"><img class="grid__cell-img grid__cell-img--centered b-lazy" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=300&amp;height=300&amp;crop=5&amp;Compression=75&amp;image={{image}}" alt="{{name}}" /></a> 1662 </div> 1663 1664 <div class="grid__cell product-list__grid-item__price-info {{shortGridInfo}} dw-mod"> 1665 <a href="{{link}}" onclick="Scroll.SavePosition(event)" title="{{name}}"><h6 class="u-condensed-text">{{name}}</h6></a> 1666 <div class="item-number dw-mod">{{number}}</div> 1667 1668 @if (!onlyPreview && cfp == true) 1669 { 1670 <div class="price dw-mod">{{price}}</div> 1671 <div class="before-price {{onSale}} dw-mod">{{discount}}</div> 1672 } 1673 </div> 1674 1675 <div class="product-list__grid-item__footer dw-mod"> 1676 <div class="u-ta-center"> 1677 1678 @if (!onlyPreview && cfp == true) 1679 { 1680 <a href="{{link}}" id="CartButton_{{id}}" class="btn btn--secondary text-uppercase u-no-margin dw-mod">@Translate("View")</a> 1681 } 1682 else 1683 { 1684 <h5 class="mb-2">@Translate("LoginText", "Login")</h5> 1685 <label for="SignInModalTrigger" class="btn btn--primary u-no-margin sign-in-modal-trigger-button dw-mod" onclick="setTimeout(function () { document.getElementById('LoginUsername').focus() }, 10)">@Translate("Sign in")</label> 1686 } 1687 </div> 1688 </div> 1689 {{/Product}} 1690 </div> 1691 </div> 1692 {{/ProductsContainer}} 1693 </div> 1694 </div> 1695 1696 <div class="grid__col-45px grid__col--bleed-x"> 1697 <div class="grid__cell grid__cell--align-middle-right"> 1698 <button class="btn btn--condensed btn--clean {{nextdisabled}} dw-mod" onclick="HandlebarsBolt.UpdateContent('ProductList_{{groupName}}', '{{nextPage}}')" {{nextdisabled}}><i class="fa fa-chevron-right fa-2x"></i></button> 1699 </div> 1700 </div> 1701 1702 </div> 1703 </div> 1704 {{/.}} 1705 </script> 1706 1707 <script id="Sticker" type="text/x-template"> 1708 <div class="stickers-container__tag {{className}} dw-mod">{{text}}</div> 1709 </script> 1710 1711 @* Units templates *@ 1712 1713 <script id="UnitOption" type="text/x-template"> 1714 <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent('PriceAndActions', '{{link}}&feed=true&UnitID={{value}}&rid={{id}}')">{{name}}</div> 1715 </script> 1716 1717 1718 @*Variants data generation*@ 1719 1720 <script> 1721 document.addEventListener("DOMContentLoaded", function (event) { 1722 var variants = []; 1723 1724 document.getElementById("productGrid").addEventListener('contentLoaded', function (e) { 1725 if (e.srcElement.classList.contains("js-variants-wrap")) { 1726 Variants.SetVariantOptionStatesForProductList(e.srcElement); 1727 } 1728 }, false); 1729 1730 @foreach (LoopItem variantgroup in GetLoop("VariantGroups")) 1731 { 1732 <text>var optionsArray = [];</text> 1733 1734 foreach (LoopItem variantoption in variantgroup.GetLoop("VariantAvailableOptions")) 1735 { 1736 string variantSelection = variantoption.GetBoolean("Ecom:VariantOption.Selected") ? "checked" : ""; 1737 1738 <text> 1739 var option = new Variants.VariantOption("@uniqueId", "@GetString("Ecom:Product.ID")", "@variantoption.GetValue("Ecom:VariantOption.ID")", "@variantoption.GetString("Ecom:VariantOption.Name")", "@variantSelection", "", "@variantoption.GetString("Ecom:VariantOption.Color")", "@variantoption.GetString("Ecom:VariantOption.ImgSmall.Clean")"); 1740 optionsArray.push(option); 1741 </text> 1742 } 1743 1744 <text> 1745 var group = new Variants.VariantGroup("@GetString("Ecom:Product.ID")_@variantgroup.GetValue("Ecom:VariantGroup.ID")", "@variantgroup.GetValue("Ecom:VariantGroup.Name")", optionsArray); 1746 variants.push(group); 1747 </text> 1748 } 1749 1750 var combinations = []; 1751 @foreach (LoopItem variantcomb in GetLoop("VariantStockCombinations")) 1752 { 1753 <text> 1754 combinations.push(new Variants.CombinationItem("@variantcomb.GetValue("Ecom:VariantStockCombination.VariantID")")); 1755 </text> 1756 } 1757 1758 variants = variants.sort(function (a, b) { 1759 var firstVariantId = a.VariantOptions[0].variantId; 1760 for (var i = 0; i < combinations.length; i++) { 1761 var combinationIndex = combinations[i].id.indexOf(firstVariantId); 1762 if (combinationIndex != -1) { 1763 return combinationIndex; 1764 } 1765 } 1766 //should never happen 1767 return 0; 1768 }); 1769 1770 Variants.SetProductFeedId('@feedId'); 1771 Variants.SetProductUrl('/@GetString("Ecom:Product.VariantLinkGroup.Clean")'); 1772 1773 HandlebarsBolt.SetDataInCache(("Variants" + "@productId"), variants); 1774 HandlebarsBolt.SetDataInCache(("Combinations" + "@productId"), combinations); 1775 1776 document.getElementById("PriceAndActions").addEventListener('contentLoaded', function (e) { 1777 Variants.InitVariants(variants, combinations, "@productId", "@uniqueId"); 1778 }, false); 1779 1780 1781 Handlebars.registerHelper('compare', function (lvalue, operator, rvalue, options) { 1782 1783 var operators, result; 1784 1785 if (arguments.length < 3) { 1786 throw new Error("Handlerbars Helper 'compare' needs 2 parameters"); 1787 } 1788 1789 if (options === undefined) { 1790 options = rvalue; 1791 rvalue = operator; 1792 operator = "==="; 1793 } 1794 1795 operators = { 1796 '==': function (l, r) { return l == r; }, 1797 '===': function (l, r) { return l === r; }, 1798 '!=': function (l, r) { return l != r; }, 1799 '!==': function (l, r) { return l !== r; }, 1800 '<': function (l, r) { return l < r; }, 1801 '>': function (l, r) { return l > r; }, 1802 '<=': function (l, r) { return l <= r; }, 1803 '>=': function (l, r) { return l >= r; }, 1804 'typeof': function (l, r) { return typeof l == r; } 1805 }; 1806 1807 if (!operators[operator]) { 1808 throw new Error("Handlerbars Helper 'compare' doesn't know the operator " + operator); 1809 } 1810 1811 result = operators[operator](lvalue, rvalue); 1812 1813 if (result) { 1814 return options.fn(this); 1815 } else { 1816 return options.inverse(this); 1817 } 1818 1819 }); 1820 1821 1822 }); 1823 </script> 1824 1825 @functions { 1826 string getIconForFile(string fileName) 1827 { 1828 string ext = Path.GetExtension(fileName); 1829 string icon = ""; 1830 switch (ext.ToLower()) 1831 { 1832 case ".xls": 1833 case ".xlsx": 1834 icon = "fa-file-excel-o"; 1835 break; 1836 case ".ppt": 1837 case ".pptx": 1838 icon = "fa-file-powerpoint-o"; 1839 break; 1840 case ".doc": 1841 case ".docx": 1842 icon = "fa-file-word-o"; 1843 break; 1844 case ".jpg": 1845 case ".jpeg": 1846 case ".png": 1847 case ".gif": 1848 case ".pdf": 1849 return "<img class='product__document-icon b-lazy' src='/Files/Images/placeholder.gif' data-src='/Admin/Public/GetImage.ashx?crop=5&height=70&width=120&Compression=75&DoNotUpscale=true&image=" + fileName + "' />"; 1850 default: 1851 icon = "fa-file-o"; 1852 break; 1853 } 1854 return "<i class='fa " + icon + "'></i> "; 1855 } 1856 1857 public static string ToPascalCase(string str) 1858 { 1859 return CultureInfo.InvariantCulture.TextInfo 1860 .ToTitleCase(str.ToLowerInvariant()) 1861 .Replace("-", "") 1862 .Replace("_", "") 1863 .Replace(" ", ""); 1864 } 1865 } 1866 1867 <script type="application/ld+json"> 1868 { 1869 "@@context": "http://schema.org/", 1870 "@@type": "Product", 1871 "name": "@GetString("Ecom:Product.Name")", 1872 @if (!string.IsNullOrEmpty(GetString("Ecom:Product.ImageLarge.Default.Clean"))) 1873 { 1874 <text>"image": [ 1875 "@siteURL/Admin/Public/GetImage.ashx?width=400&height=400&crop=0&Compression=75&DoNotUpscale=true&image=@productImage", 1876 "@siteURL/Admin/Public/GetImage.ashx?width=400&height=300&crop=0&Compression=75&DoNotUpscale=true&image=@productImage", 1877 "@siteURL/Admin/Public/GetImage.ashx?width=448&height=225&crop=0&Compression=75&DoNotUpscale=true&image=@productImage" 1878 ],</text> 1879 } 1880 "description": "@GetString("Ecom: Product.ShortDescription")", 1881 "mpn": "925872", 1882 @if (!string.IsNullOrEmpty(brand)) 1883 { 1884 <text>"brand": { 1885 "@@type": "Thing", 1886 "name": "@brand" 1887 },</text> 1888 } 1889 "offers": { 1890 "@@type": "Offer", 1891 "priceCurrency": "@GetString("Ecom:Product.Price.Currency.Code")", 1892 "price": "@GetString("Ecom:Product.Price.Price")", 1893 "availability": "@(GetInteger("Ecom:Product.Stock") > 0 ? "InStock" : "OutOfStock")" 1894 } 1895 } 1896 </script> 1897 <script> 1898 document.addEventListener("DOMContentLoaded", function () { 1899 if (document.getElementById("PriceAndActions")) { 1900 document.getElementById("PriceAndActions").addEventListener("contentLoaded", function (event) { 1901 if (document.querySelector(".js-variants") != null) { 1902 MatchVariants.Update(document.querySelector(".js-variants"), "DoNothing"); 1903 } 1904 }); 1905 } 1906 }); 1907 1908 //Custom dropdown 1909 var isOpen = false; 1910 1911 function toggleOptions(id) { 1912 1913 isOpen = !isOpen; 1914 if (isOpen) { 1915 document.getElementById(id).style.visibility = 'visible'; 1916 document.getElementById(id).classList.add("active"); 1917 document.getElementById(id).focus(); 1918 } else { 1919 document.getElementById(id).blur(); 1920 document.getElementById(id).classList.remove("active"); 1921 document.getElementById(id).style.visibility = 'hidden'; 1922 } 1923 1924 } 1925 1926 function selected(val, id, blurId) { 1927 document.getElementById(id).innerHTML = val; 1928 toggleOptions(blurId); 1929 var variantContainer = $(".js-variants"); 1930 variantContainer.find('.dropdown-container').each(function () { 1931 1932 var $this = $(this); 1933 var disabledItem = $this.find('.disabled'); 1934 if (disabledItem) { 1935 var displayValueItem = $this.find('.value-text'); 1936 1937 if (displayValueItem.html() == disabledItem.html()) { 1938 displayValueItem.html("@Translate("Select variant")"); 1939 } 1940 } 1941 1942 }); 1943 } 1944 </script>

Kontakt os

Har du spørgsmål til vores produkter, løsninger eller services? Eller søger du hjælp til beregninger og dimensioneringer? Vi står klar til at hjælpe. Udfyld formularen herunder, og vi kontakter dig hurtigst muligt.