Error executing template "Designs/Mobler2018/eCom/Product/Product.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at CompiledRazorTemplates.Dynamic.RazorEngine_360c5cf4e3564bbd80472fe37137d828.Execute() in D:\dynamicweb.net\Solutions\mobler.LIVE\Files\Templates\Designs\Mobler2018\eCom\Product\Product.cshtml:line 943
at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
at RazorEngine.Templating.RazorEngineService.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 Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @using System.Web
2 @using Mobler.Website.CustomModules.MoblerHelpers
3 @using System.Text.RegularExpressions
4 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
5
6 @{
7 string shopname = MoblerHelpers.GetShopName();
8 string SelectPlaceholder = Translate("ShopSelectPlaceholder", "Indtast by, postnummer eller adresse");
9 var shopInfo = MoblerHelpers.ShopInfo();
10 int ShopPageId = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetInt("ShopPageId");
11 var AllShops = Firstweb.Custom.CustomCode.Frontend.Helpers.Shops.GetAllShops(ShopPageId);
12 int AjaxCartPageId = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetInt("AjaxCartPageId");
13 int CustomersAlsoSawPageId = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetInt("CustomersAlsoSawPageId");
14 string CartPage = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("CartPage");
15 string VariantsEndpoint = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("VariantsUrl");
16 string VariantDetailsEndpoint = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("VariantDetailsUrl");
17 string BlackFridayTheme = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("BlackFridayTheme");
18 string ProductID = GetString("Ecom:Product.ID");
19 string GroupID = GetString("Ecom:Product.PrimaryOrFirstGroupID");
20 string DefaultVariantID = GetString("Ecom:Product.DefaultVariantComboID");
21 string ProductImage = MoblerHelpers.GetProductListImage(ProductID, DefaultVariantID);
22 string ProductName = GetString("Ecom:Product.Name");
23 string ProductNumber = GetString("Ecom:Product.Number");
24 string ProductCatalogLink = !String.IsNullOrEmpty(GetString("Ecom:Product:Field.ProductCatelog.Value.Clean")) ? GetString("Ecom:Product:Field.ProductCatelog.Value.Clean") : "";
25 string VariantId = GetString("Ecom:Product.VariantID");
26 string ShortDescription = GetString("Ecom:Product.ShortDescription");
27 string LongDescription = GetString("Ecom:Product.LongDescription").Replace("||", "<br/>");
28 string CurrentVariantName = GetString("Ecom:Product.SelectedVariantComboName");
29 var FaqQuestions = MoblerHelpers.GetProductFAQs(ProductID, GroupID);
30
31 string MetaDescription = GetString("Ecom:Product.MetaDescription");
32
33 if (string.IsNullOrEmpty(MetaDescription))
34 {
35 MetaDescription = Mobler.Website.CustomCode.Frontend.Helpers.Text.GetFirstLine(LongDescription.Replace("<br/>", " "));
36 }
37 else
38 {
39 MetaDescription = ""; //Meta data description bliver sat af DW, hvis dette felt er udfyldt, så vi skal ikke opsætte noget.
40 }
41
42
43 var RelatedBlogs = Firstweb.Custom.CustomCode.Frontend.Helpers.Blogs.GetBlogsRelatedToProduct(ProductID);
44 bool NewItem = GetBoolean("Ecom:Product:Field.NewItem");
45 bool LowPrice = GetBoolean("Ecom:Product:Field.Splash3");
46
47
48 Mobler.Website.CustomCode.Frontend.ProductsDisplayVariant productsDisplayVariant = Mobler.Website.CustomCode.Frontend.ProductsDisplayVariant.Instance();
49
50 bool ForSale = !GetBoolean("Ecom:Product:Field.NotForSaleOnline");
51
52 var MainProdNr = string.Empty;
53 var VariantNr = string.Empty;
54 string FirstImage = "";
55 if (!string.IsNullOrWhiteSpace(ProductNumber))
56 {
57 string[] MainProdSplit = ProductNumber.Split('_');
58
59 if (MainProdSplit.Length > 1)
60 {
61 MainProdNr = MainProdSplit[0];
62 VariantNr = MainProdSplit[1];
63 }
64 else
65 {
66 MainProdNr = ProductNumber;
67 }
68 }
69 var Images = MoblerHelpers.GetProductImages(GetString("Ecom:Product.ID"), VariantNr);
70 bool First = true;
71 bool FirstIndicator = true;
72 int IndicatorIncrementer = 0;
73 string PriceSaving = GetString("Ecom:Product:Field.Spar.Value");
74 string ProductLink = GetString("Ecom:Product.Link.Clean");
75 double DiscountedPrice = GetDouble("Ecom:Product.Discount.Price.Price");
76 double ActualPrice = GetDouble("Ecom:Product.Price.Price");
77 var TotalDiscount = GetDouble("Ecom:Product.Discount.TotalAmount.Price");
78 double spar = 0;
79 double price = 0;
80 if (!GetBoolean("Ecom:Product:Field.Splash3.Value") && !GetBoolean("Ecom:Product:Field.Offer.Value"))
81 {
82 if (DiscountedPrice < ActualPrice)
83 {
84 spar = TotalDiscount;
85 price = DiscountedPrice;
86 }
87 else
88 {
89 price = ActualPrice;
90 }
91 }
92 else
93 {
94 spar = GetDouble("Ecom:Product:Field.Spar.Value.Clean");
95 price = GetDouble("Ecom:Product.Price.Price");
96 }
97 double OriginalPrice = spar + price;
98 string DataLayerPrice = ActualPrice.ToString().Replace(".", "").Replace(",", ".");
99 System.Web.HttpContext.Current.Items["OverrideOgTags"] = true;
100 string OgImage = "https://mobler.dk" + Images.FirstOrDefault();
101
102 string TrimmedTeaser = Firstweb.Custom.CustomCode.Frontend.Helpers.JSFormatting.TrimLinebreaks(ShortDescription);
103 string TrimmedName = Firstweb.Custom.CustomCode.Frontend.Helpers.JSFormatting.TrimLinebreaks(ProductName);
104
105 var ParentGroups = Firstweb.Custom.CustomCode.Frontend.Helpers.EcomGroups.getBreadCrumbGroupList(GroupID, true);
106 string ShowOnPageUrl = "";
107 string GetCartEndpoint = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("GetCartJson");
108
109 string QuickDeliveryColor = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("QuickDeliveryColor");
110 string QuickDeliveryDescription = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("QuickDeliveryDescription");
111 string NormalDeliveryDescription = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("NormalDeliveryDescription");
112 string BrandName = GetString("Ecom:Product:Field.Maerkevarer.Value.Clean");
113 string DeliveryTime = Translate("DeliveryTime." + BrandName, "Gns. leveringstid 3-12 dage");
114 bool HideDelivery = DeliveryTime == "Skjul";
115 string DeliveryColor = "#00AB5D";
116 bool QuickDelivery = GetBoolean("Ecom:Product:Field.QuickDelivery.Value.Clean");
117 string CustomDelivery = GetString("Ecom:Product:Field.CustomDeliveryTime.Value.Clean");
118 if (QuickDelivery)
119 {
120 DeliveryColor = QuickDeliveryColor;
121 DeliveryTime = Translate("DeliveryTime.QuickDelivery", "Ekstra hurtig levering");
122 }
123 else if (!String.IsNullOrEmpty(CustomDelivery))
124 {
125 DeliveryTime = CustomDelivery;
126 }
127 string DeliveryFontWeightModifier = QuickDelivery ? "font-weight-bold" : "";
128 bool DisplayAverageDeliveryTime = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetBoolean("DisplayAverageDeliveryTime");
129
130 double CostPrice = GetDouble("Ecom:Product:Field.FirstwebCostPrice.Value.Raw");
131 string DailyPriceBackgroundColor = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("AktuelDagsprisBackgroundColor");
132 string DailyPriceTextColor = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("AktuelDagsprisTextColor");
133 string EAN = GetString("Ecom:Product:Field.FirstEan.Value");
134
135 string productionDescription = GetString("Ecom:Product:Field.FirstwebProductionDescription");
136 }
137
138
139 @SnippetStart("ProductDetailsMeta")
140 @if (!string.IsNullOrEmpty(MetaDescription))
141 {
142 <meta name="description" content="@MetaDescription" />
143 }
144 @SnippetEnd("ProductDetailsMeta")
145
146 @SnippetStart("OgTags")
147 <meta property="og:type" content="product" />
148 <meta property="og:description" content="@Regex.Replace(ShortDescription, "<.*?>", String.Empty)" />
149 <meta property="og:image" content="@OgImage" />
150 @SnippetEnd("OgTags")
151
152 @using Mobler.Website.CustomModules.MoblerHelpers
153 @using Dynamicweb.Ecommerce.Products
154 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
155
156 @helper RenderProduct(LoopItem product)
157 {
158 string BlackFridayTheme = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("BlackFridayTheme");
159 string CTAbg = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("SeProdukt_CTABaggrundsfarve");
160 string CTAtextcolor = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("SeProdukt_CTATekstfarve");
161 string ProductID = product.GetString("Ecom:Product.ID");
162 string ProductNumber = product.GetString("Ecom:Product.Number");
163 string DefaultVariantID = product.GetString("Ecom:Product.DefaultVariantComboID");
164 string ProductImage = MoblerHelpers.GetProductListImageWithMainImage(ProductID, ProductNumber);
165 string ProductName = product.GetString("Ecom:Product.Name");
166 string VariantId = product.GetString("Ecom:Product.VariantID");
167 if (String.IsNullOrEmpty(VariantId)) {
168 VariantId = DefaultVariantID;
169 }
170 bool NewItem = product.GetBoolean("Ecom:Product:Field.NewItem");
171 bool LowPrice = product.GetBoolean("Ecom:Product:Field.Splash3");
172 double CostPrice = product.GetDouble("Ecom:Product:Field.FirstwebCostPrice.Value.Raw");
173 string ShortDescription = product.GetString("Ecom:Product.ShortDescription");
174 string PriceSaving = product.GetString("Ecom:Product:Field.Spar.Value");
175 string ProductLink = product.GetString("Ecom:Product.Link.Clean");
176 if (!String.IsNullOrEmpty(VariantId)) {
177 ProductLink = ProductLink + "&variantid=" + VariantId;
178 }
179 double DiscountedPrice = product.GetDouble("Ecom:Product.Discount.Price.Price");
180 double ActualPrice = product.GetDouble("Ecom:Product.Price.Price");
181 var TotalDiscount = product.GetDouble("Ecom:Product.Discount.TotalAmount.Price");
182 double spar = 0;
183 double price = 0;
184 if (!product.GetBoolean("Ecom:Product:Field.Splash3.Value") && !product.GetBoolean("Ecom:Product:Field.Offer.Value"))
185 {
186 if (DiscountedPrice < ActualPrice)
187 {
188 spar = TotalDiscount;
189 price = DiscountedPrice;
190 }
191 else
192 {
193 price = ActualPrice;
194 }
195 }
196 else
197 {
198 spar = product.GetDouble("Ecom:Product:Field.Spar.Value.Clean");
199 price = product.GetDouble("Ecom:Product.Price.Price");
200 }
201 double OriginalPrice = spar + price;
202
203
204 var languageId = product.GetString("Ecom:Product.LanguageID");
205 var dwProduct = Dynamicweb.Ecommerce.Services.Products.GetProductById(ProductID, VariantId, languageId);
206 var VariantCombinations = dwProduct.VariantCombinations.ToList().Where(v => v.GetProduct(languageId).Number != VariantId);
207 bool ManyVariants = VariantCombinations.Count() > 3;
208 if (ManyVariants)
209 {
210 VariantCombinations = VariantCombinations.Take(3).ToList();
211 }
212
213 string BrandName = product.GetString("Ecom:Product:Field.Maerkevarer.Value.Clean");
214 bool QuickDelivery = product.GetBoolean("Ecom:Product:Field.QuickDelivery.Value.Clean");
215 string DeliveryTime = Translate("DeliveryTime." + BrandName, "Gns. leveringstid 3-12 dage");
216 string DeliveryColor = "#00AB5D";
217 if (QuickDelivery) {
218 DeliveryTime = Translate("DeliveryTime.QuickDelivery", "Ekstra hurtig levering");
219 DeliveryColor = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("QuickDeliveryColor");
220 }
221
222 <div class="col-11 col-sm-6 col-lg-3 mt-3 mx-auto mx-sm-0 mb-3">
223 <a href="@ProductLink" class="product-list-product box-shadow px-3 pt-3 pb-5 h-100 d-flex flex-column align-items-center mb-3 overflow-hidden">
224 <div class="d-flex flex-column align-items-center">
225 <div class="img-container">
226 <img class="js-product-image-@ProductID" src="@ProductImage" alt="@ProductName" />
227 </div>
228 </div>
229 <h3 class="mt-2 mb-0 fs2 text-center mw-100 font-weight-bold">@ProductName</h3>
230 <div class="fs0 color-subtle text-center mw-100 mb-0 product-description">@ShortDescription</div>
231 <div class="d-flex flex-wrap justify-content-center w-100 align-content-end flex-fill">
232 <p class="color-subtle m-0 fs0 w-100 text-center">
233 @if (!string.IsNullOrWhiteSpace(product.GetString("Ecom:Product:Field.dybdeint.Value.Clean")))
234 {
235 if (product.GetString("Ecom:Product:Field.dybdeint.Value.Clean") != "0")
236 {
237 <span>D/L: @product.GetValue("Ecom:Product:Field.dybdeint.Value.Clean")</span>
238 }
239 }
240 @if (!string.IsNullOrWhiteSpace(product.GetString("Ecom:Product:Field.hoejdeint.Value.Clean")))
241 {
242 if (product.GetString("Ecom:Product:Field.hoejdeint.Value.Clean") != "0")
243 {
244 <span>H: @product.GetValue("Ecom:Product:Field.hoejdeint.Value.Clean")</span>
245 }
246 }
247 @if (!string.IsNullOrWhiteSpace(product.GetString("Ecom:Product:Field.breddeint.Value.Clean")))
248 {
249 if (product.GetString("Ecom:Product:Field.breddeint.Value.Clean") != "0")
250 {
251 <span>B: @product.GetValue("Ecom:Product:Field.breddeint.Value.Clean")</span>
252 }
253 }
254 </p>
255 @if (QuickDelivery)
256 {
257 <div class="delivery-information my-2 w-100 justify-content-center">
258 <svg class="delivery-icon mr-2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" fill="@DeliveryColor" x="0px" y="0px" width="20px" height="20px" viewBox="0 0 612 612" style="enable-background:new 0 0 612 612;" xml:space="preserve">
259 <g>
260 <g>
261 <path d="M226.764,375.35c-28.249,0-51.078,22.91-51.078,51.16c0,28.166,22.829,51.078,51.078,51.078s51.078-22.912,51.078-51.078 C277.841,398.26,255.013,375.35,226.764,375.35z M226.764,452.049c-14.125,0-25.54-11.498-25.54-25.541 c0-14.123,11.415-25.539,25.54-25.539c14.124,0,25.539,11.416,25.539,25.539C252.302,440.551,240.888,452.049,226.764,452.049z M612,337.561v54.541c0,13.605-11.029,24.635-24.636,24.635h-26.36c-4.763-32.684-32.929-57.812-66.927-57.812 c-33.914,0-62.082,25.129-66.845,57.812H293.625c-4.763-32.684-32.93-57.812-66.845-57.812c-33.915,0-62.082,25.129-66.844,57.812 h-33.012c-13.606,0-24.635-11.029-24.635-24.635v-54.541H612L612,337.561z M494.143,375.35c-28.249,0-51.16,22.91-51.16,51.16 c0,28.166,22.912,51.078,51.16,51.078c28.166,0,51.077-22.912,51.077-51.078C545.22,398.26,522.309,375.35,494.143,375.35z M494.143,452.049c-14.125,0-25.539-11.498-25.539-25.541c0-14.123,11.414-25.539,25.539-25.539 c14.042,0,25.539,11.416,25.539,25.539C519.682,440.551,508.185,452.049,494.143,452.049z M602.293,282.637l-96.817-95.751 c-6.159-6.077-14.453-9.526-23.076-9.526h-48.86v-18.313c0-13.631-11.004-24.635-24.635-24.635H126.907 c-13.55,0-24.635,11.005-24.635,24.635v3.86L2.3,174.429l177.146,23.068L0,215.323l178.814,25.423L0,256.25l102.278,19.29 l-0.007,48.403h509.712v-17.985C611.983,297.171,608.452,288.796,602.293,282.637z M560.084,285.839h-93.697 c-2.135,0-3.86-1.724-3.86-3.859v-72.347c0-2.135,1.725-3.86,3.86-3.86h17.82c0.985,0,1.971,0.411,2.71,1.068l75.796,72.347 C565.257,281.569,563.532,285.839,560.084,285.839z" />
262
263 </g>
264 </g>
265 </svg>
266 <p class="delivery-text font-weight-bold">@DeliveryTime - <span class="text-underline cursor-pointer" data-bind="click: ToggleQuickDeliveryInfo" style="color: @DeliveryColor">@Translate("Product.DeliveryInfo.ReadmoreText", "Læs mere")</span></p>
267 </div>
268 }
269 <p class="fs5 my-0 d-flex align-items-center font-weight-bold">
270 @if (VariantCombinations.Count() > 0)
271 {
272 <span class="font-weight-semibold fs0 mr-2">@Translate("ProductPrice.From", "Fra")</span>
273 }
274 @MoblerHelpers.formatPrice(price)
275 </p>
276 @if (CostPrice > 0)
277 {
278 string DailyPriceBackgroundColor = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("AktuelDagsprisBackgroundColor");
279 string DailyPriceTextColor = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("AktuelDagsprisTextColor");
280 string EAN = product.GetString("Ecom:Product:Field.FirstEan.Value");
281 var PriceShapePrices = Firstweb.Custom.CustomCode.Frontend.Helpers.PriceShapeHelpers.GetProductPrice(ProductNumber, EAN);
282
283 <div class="discount-splash price-shape" style="background-color: @DailyPriceBackgroundColor"><p class="m-0" style="color: @DailyPriceTextColor;">@Translate("ProductDailyPriceSplash", "Dagspris")</p></div>
284 if (PriceShapePrices != null)
285 {
286 if (price < PriceShapePrices.MoblerPrice)
287 {
288 <div class="d-flex w-100 mb-2">
289 @if (VariantCombinations.Count() > 0)
290 {
291 <p class="color-black-w-opacity fs0 m-0 text-uppercase">@Translate("PriceRecommendPriceFrom", "Vejl. pris fra") @MoblerHelpers.formatPrice(PriceShapePrices.MoblerPrice)</p>
292 }
293 else
294 {
295 <p class="color-black-w-opacity fs0 m-0 text-uppercase">@Translate("PriceRecommendPrice", "Vejl. pris") @MoblerHelpers.formatPrice(PriceShapePrices.MoblerPrice)</p>
296 }
297 </div>
298 }
299 }
300
301 }
302 else if (spar > 0)
303 {
304 if (BlackFridayTheme == "True")
305 {
306 <div class="discount-splash bf-bg-black bf-color-white"><p class="m-0 font-weight-bold">@Translate("ProductOffer", "Tilbud")</p></div>
307 }
308 else
309 {
310 <div class="discount-splash"><p class="m-0 font-weight-bold">@Translate("ProductOffer", "Tilbud")</p></div>
311 }
312 <div class="d-flex justify-content-between w-100 mb-2">
313 <p class="color-black-w-opacity fs0 m-0 text-uppercase">@Translate("PriceBefore", "Før") @MoblerHelpers.formatPrice(OriginalPrice)</p>
314 <p class="bg-discount fs0 text-uppercase m-0 px-2 font-weight-bold">@Translate("PriceSaving", "Spar") @MoblerHelpers.formatPrice(spar)</p>
315 </div>
316 }
317 else if (NewItem)
318 {
319 <div class="discount-splash new-item"><p class="m-0 font-weight-bold">@Translate("ProductNew", "Nyhed")</p></div>
320 }
321 else if (LowPrice)
322 {
323 <div class="discount-splash low-price"><p class="m-0 font-weight-bold">@Translate("ProductLowPrice", "Fast lavpris")</p></div>
324 }
325 </div>
326 @if (VariantCombinations.Count() > 0)
327 {
328 <div class="w-100 row align-items-center justify-content-center">
329 @foreach (var Variant in VariantCombinations)
330 {
331 var currentproductLoop = Variant.GetProduct(languageId);
332 string VariantNumber = currentproductLoop.Number;
333 string VariantLink = product.GetString("Ecom:Product.Link.Clean") + "&variantid=" + currentproductLoop.VariantId;
334 string VariantVariantId = "";
335 if (VariantNumber.Split('_').Length > 1)
336 {
337 VariantVariantId = VariantNumber.Split('_')[1];
338 }
339 string imageProductDetails = string.Format("/Admin/Public/GetImage.ashx?Image={0}&Width=60&height=50&Format=png&Crop=5&resolution=50", MoblerHelpers.GetProductImages(ProductID, VariantVariantId).First());
340 string ImageLarge = imageProductDetails.Replace("&Width=60&height=50", "&Width=260&height=200");;
341 <div class="w-25 p-1 mb-2 d-block" data-bind="previewVariant: { variantImage: '@ImageLarge', currentImage: '.js-product-image-@ProductID', originalImage: '@ProductImage', link: '@VariantLink' }">
342 <img class="img-fluid" src="@imageProductDetails" />
343 </div>
344 }
345 @if (ManyVariants)
346 {
347 <div class="w-25 p-1 mb-2 d-flex justify-content-center align-items-center fs2">
348 <span class="see-more-dots">
349 <i class="fas fa-ellipsis-h"></i>
350 </span>
351 </div>
352 }
353 </div>
354 <div class="variant-price-disclaimer">@Translate("VariantPriceDisclaimer", "Prisen kan variere efter materialevalg")</div>
355 }
356 @if (BlackFridayTheme == "True")
357 {
358 <div class="bf-bg-black product-cta d-block text-center fs2 font-weight-bold">@Translate("GoToProduct", "Se produkt")</div>
359 } else {
360 <div class="bg-brand product-cta d-block text-center fs2 font-weight-bold" style="background-color: @CTAbg;color: @CTAtextcolor;">@Translate("GoToProduct", "Se produkt")</div>
361 }
362
363 </a>
364
365 </div>
366 }
367
368 @helper RenderWideOffer(LoopItem product)
369 {
370 string ProductID = product.GetString("Ecom:Product.ID");
371 string DefaultVariantID = product.GetString("Ecom:Product.DefaultVariantComboID");
372 string ProductImage = MoblerHelpers.GetProductListImage(ProductID, DefaultVariantID).Replace("Width=260&height=200", "Width=400&height=230");
373 string ProductName = product.GetString("Ecom:Product.Name");
374 string ShortDescription = product.GetString("Ecom:Product.ShortDescription");
375 string PriceSaving = product.GetString("Ecom:Product:Field.Spar.Value");
376 string ProductLink = product.GetString("Ecom:Product.Link.Clean");
377 double DiscountedPrice = product.GetDouble("Ecom:Product.Discount.Price.Price");
378 double ActualPrice = product.GetDouble("Ecom:Product.Price.Price");
379 var TotalDiscount = product.GetDouble("Ecom:Product.Discount.TotalAmount.Price");
380 double spar = 0;
381 double price = 0;
382 if (!product.GetBoolean("Ecom:Product:Field.Splash3.Value") && !product.GetBoolean("Ecom:Product:Field.Offer.Value"))
383 {
384 if (DiscountedPrice < ActualPrice)
385 {
386 spar = TotalDiscount;
387 price = DiscountedPrice;
388 }
389 else
390 {
391 price = ActualPrice;
392 }
393 }
394 else
395 {
396 spar = product.GetDouble("Ecom:Product:Field.Spar.Value.Clean");
397 price = product.GetDouble("Ecom:Product.Price.Price");
398 }
399 double OriginalPrice = spar + price;
400
401 <div class="col-12 bg-white box-shadow-grey border-radius-bottom-8px mt-5">
402 <div class="row">
403
404 <div class="col-12 col-md-4 d-flex align-items-center justify-content-center p-2">
405 @if (spar > 0)
406 {
407 <div class="discount-splash d-md-none">
408 <p class="m-0">
409 @Translate("ProductOffer", "Tilbud")
410 </p>
411 </div>
412 }
413 <a href="@ProductLink">
414 <img class="img-fluid" src="@ProductImage" alt="@ProductName" />
415 </a>
416 </div>
417 <div class="col-12 col-md-8 px-0 pt-4 pb-0 pb-sm-3 d-flex flex-column align-items-center
418 justify-content-end">
419 @if (spar > 0)
420 {
421 <div class="discount-splash d-none d-md-flex">
422 <p class="m-0">
423 @Translate("ProductOffer", "Tilbud")
424 </p>
425 </div>
426 }
427 <div class="px-2">
428 <h1 class="wide-offer--title mw-100 word-break mt-3 mt-sm-0 font-weight-bold text-uppercase text-center">@ProductName</h1>
429 <div class="wide-offer--subtitle word-break text-center color-dark-grey rte-content">
430 @ShortDescription
431 </div>
432 </div>
433 <div class="mt-2 fs5 font-weight-bold">
434 @MoblerHelpers.formatPrice(price)
435 </div>
436 <div class="d-flex flex-column justify-content-center align-items-center flex-sm-row w-100">
437
438 @if (spar > 0)
439 {
440 <div class="d-flex mb-2 mb-sm-0 justify-content-center">
441 <p class="color-black-w-opacity m-0 mr-5 p-1 text-uppercase">
442 @Translate("PriceBefore", "Før") @MoblerHelpers.formatPrice(OriginalPrice)
443 </p>
444 <p class="bg-discount font-weight-bold mb-0 mr-sm-5 px-2 p-1 text-uppercase">
445 @Translate("PriceSaving", "Spar") @MoblerHelpers.formatPrice(spar)
446 </p>
447 </div>
448 }
449 <a class="wide-offer--button btn btn-primary pl-3 pr-3" href="@ProductLink">
450 @Translate("GoToProduct", "Se produkt")
451 </a>
452 </div>
453 </div>
454
455 </div>
456 </div>
457
458 }
459
460 @helper Render2ColOffer(LoopItem product)
461 {
462 string ProductID = product.GetString("Ecom:Product.ID");
463 string DefaultVariantID = product.GetString("Ecom:Product.DefaultVariantComboID");
464 string ProductImage = MoblerHelpers.GetProductListImage(ProductID, DefaultVariantID).Replace("Width=260", "Width=450").Replace("height=200", "Height=400");
465 string ProductName = product.GetString("Ecom:Product.Name");
466 string ShortDescription = product.GetString("Ecom:Product.ShortDescription");
467 string PriceSaving = product.GetString("Ecom:Product:Field.Spar.Value");
468 string ProductLink = product.GetString("Ecom:Product.Link.Clean");
469 double DiscountedPrice = product.GetDouble("Ecom:Product.Discount.Price.Price");
470 double ActualPrice = product.GetDouble("Ecom:Product.Price.Price");
471 var TotalDiscount = product.GetDouble("Ecom:Product.Discount.TotalAmount.Price");
472 double spar = 0;
473 double price = 0;
474 if (!product.GetBoolean("Ecom:Product:Field.Splash3.Value") && !product.GetBoolean("Ecom:Product:Field.Offer.Value"))
475 {
476 if (DiscountedPrice < ActualPrice)
477 {
478 spar = TotalDiscount;
479 price = DiscountedPrice;
480 }
481 else
482 {
483 price = ActualPrice;
484 }
485 }
486 else
487 {
488 spar = product.GetDouble("Ecom:Product:Field.Spar.Value.Clean");
489 price = product.GetDouble("Ecom:Product.Price.Price");
490 }
491 double OriginalPrice = spar + price;
492
493
494 <div class="col-12 col-md-6 mt-5">
495 <a href="@ProductLink" class="offer-2col box-shadow-large border-radius-bottom-10px w-100 h-100 d-flex flex-column color-black">
496 <div class="d-flex align-items-center justify-content-center offer-2col--img-container">
497 <img class="img-fluid" src="@ProductImage" alt="@ProductName">
498 @if (spar > 0)
499 {
500 <div class="discount-splash">
501 <p class="m-0">
502 @Translate("ProductOffer", "Tilbud")
503 </p>
504 </div>
505 }
506 </div>
507 <div>
508 <h1 class="offer-2col--title pl-3 pr-3 mb-3 text-center color-black text-uppercase">
509 @ProductName
510 </h1>
511 <div class="offer-2col--subtitle color-dark-grey pl-3 pr-3 my-3 my-md-5 text-center">
512 @ShortDescription
513 </div>
514 </div>
515 <div class="d-flex flex-wrap flex-fill justify-content-center align-items-end">
516 <div class="d-flex flex-wrap flex-fill justify-content-center align-items-end">
517 <p class="offer-2col--price mb-3 text-center font-weight-bold color-black w-100">
518 @MoblerHelpers.formatPrice(price)
519 </p>
520 @if (spar > 0)
521 {
522 <div class="d-flex justify-content-center mb-3">
523 <span class="offer-2col--pricebefore color-black-w-opacity mr-5 p-1 text-uppercase">
524 @Translate("PriceBefore", "Før") @MoblerHelpers.formatPrice(OriginalPrice)
525 </span>
526 <span class="offer-2col--pricesave color-black bg-discount font-weight-bold p-1 text-uppercase">
527 @Translate("PriceSaving", "Spar") @MoblerHelpers.formatPrice(spar)
528 </span>
529 </div>
530 }
531
532 <div class="w-100">
533 <div class="offer-2col--button btn btn-primary p-3 border-radius-bottom-10px w-100 mb-sm-0 font-weight-bold">
534 @Translate("GoToProduct", "Se produkt")
535 </div>
536 </div>
537 </div>
538 </div>
539 </a>
540 </div>
541 }
542
543 @using Mobler.Website.CustomModules.MoblerHelpers
544 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
545
546 @helper RenderBlogTeaser(Firstweb.Custom.CustomCode.Frontend.Helpers.Blog Blog)
547 {
548 string CleanLink = Blog.Link.Replace("default.aspx?id", "Default.aspx?Id");
549 <div class="col-12 col-md-4 px-0 px-md-3 mb-4">
550 <a href="@CleanLink" class="blog d-block">
551 <div class="image" style="background-image:url('@Blog.Image')">
552 <img class="d-none" src="@Blog.Image" alt="Alternate Text" />
553 </div>
554 <div class="text">
555 <div class="positioning">
556 <h4 class="col-10 col-md-9 px-2 pt-3 bg-white font-weight-bold text-center mx-auto">@Blog.Header</h4>
557 <p class="text-center color-subtle">@Blog.Date</p>
558 <p class="text-center font-weight-bold m-0 color-primary">@Translate("BlogReadMore", "Læs mere her")</p>
559 </div>
560 </div>
561 </a>
562 </div>
563 }
564
565 @helper RenderLargeBlogTeaser(Firstweb.Custom.CustomCode.Frontend.Helpers.Blog Blog, string ImagePosition)
566 {
567 string ImageClass = ImagePosition == "Left" ? "" : "offset-md-4";
568 string TextClass = ImagePosition == "Left" ? "" : "left";
569 string Image = "/Admin/Public/GetImage.ashx?Image=" + Blog.Image + "&Height=400&Format=png&Crop=0";
570 string CleanLink = Blog.Link.Replace("default.aspx?id", "Default.aspx?Id");
571 <div class="col-12 blog">
572 <div class="row">
573 <div class="col-12 col-md-8 px-0 px-md-3 @ImageClass">
574 <div class="image-container" style="background-image:url('@Image')">
575 <img class="img-fluid" src="@Image" alt="@Blog.Header" />
576 </div>
577 </div>
578 <div class="col-12 col-md-6 text-container mb-5 mb-md-0 @TextClass">
579 <div class="text bg-white p-3">
580 <div>
581 <h4>@Blog.Header</h4>
582 @Blog.Teaser
583 </div>
584 <a class="font-weight-bold" href="@CleanLink">@Translate("BlogReadMore", "Læs mere her")</a>
585 </div>
586 </div>
587 </div>
588 </div>
589 }
590
591 @helper RenderLatestBlogsTeasers()
592 {
593 var LatestBlogs = Firstweb.Custom.CustomCode.Frontend.Helpers.Blogs.GetLatestBlogs();
594 foreach (var Blog in LatestBlogs)
595 {
596 @RenderBlogTeaser(Blog)
597 }
598 }
599
600
601 <div class="container pt-3 d-none d-md-block">
602
603 <div class="bread">
604 <p class="color-subtle">@Translate("Breadcrumb.CurrentPage", "Her er du:")</p>
605 <p class="bread-item color-subtle">
606 <a href="/">
607 @Translate("Breadcrumb.Frontpage", "Forside")
608 </a>
609 </p>
610 @foreach (var Group in ParentGroups)
611 {
612 <p class="bread-item color-subtle">
613 @if (Group == ParentGroups.First())
614 {
615 @Group.Name
616 ShowOnPageUrl = Group.ProductGroupFieldValues.GetProductGroupFieldValue("FirstwebGroupPrimaryPage").Value.ToString();
617 }
618 else
619 {
620 <a href="/@ShowOnPageUrl&GroupId=@Group.Id">
621 @Group.Name
622 </a>
623 }
624 </p>
625 }
626
627 <p class="active color-subtle">@ProductName</p>
628 </div>
629
630 </div>
631
632 <div class="container mt-3 mb-5 product-details position-relative" data-bind="viewModel: 'ProductViewModel'">
633
634 <div class="d-none" data-bind="setInitValue: { observable: CartPageId, value: '@AjaxCartPageId' }"></div>
635 <div class="d-none" data-bind="setInitValue: { observable: MiniCart, value: '.js-mini-cart-lines' }"></div>
636 <div class="d-none" data-bind="setInitValue: { observable: CartCount, value: '.js-cart-count' }"></div>
637 <div class="d-none" data-bind="setInitValue: { observable: CustomersAlsoSawLines, value: '.js-customers-also-saw-lines' }"></div>
638 <div class="d-none" data-bind="setInitValue: { observable: CustomersAlsoSawPage, value: '@CustomersAlsoSawPageId' }"></div>
639 <div class="d-none" data-bind="setInitValue: { observable: MainProductId, value: '@MainProdNr' }"></div>
640 <div class="d-none" data-bind="setInitValue: { observable: VariantsEndpoint, value: '@VariantsEndpoint' }"></div>
641 <div class="d-none" data-bind="setInitValue: { observable: VariantDetailsEndpoint, value: '@VariantDetailsEndpoint' }"></div>
642 <div class="d-none" data-bind="setInitValue: { observable: TeaserText, value: '@TrimmedTeaser' }"></div>
643 <div class="d-none" data-bind="setInitValue: { observable: ProductName, value: '@TrimmedName' }"></div>
644 <div class="d-none" data-bind="setInitValue: { observable: ProductNumber, value: '@ProductNumber' }"></div>
645 <div class="d-none" data-bind="setInitValue: { observable: VariantId, value: '@VariantId' }"></div>
646 <div class="d-none" data-bind="setInitValue: { observable: Price, value: '@MoblerHelpers.formatPrice(price)' }"></div>
647 <div class="d-none js-update-cart" data-bind="setInitValue: { observable: CartEndpoint, value: '@GetCartEndpoint' }, click: GetCart"></div>
648
649 <div id="blueimp-gallery" class="blueimp-gallery">
650 <div class="slides"></div>
651 <h3 class="title"></h3>
652 <a class="prev">‹</a>
653 <a class="next">›</a>
654 <a class="close">×</a>
655 <a class="play-pause"></a>
656 <ol class="indicator"></ol>
657 </div>
658
659 <div class="modal fade video-modal" id="videoModal" tabindex="-1" role="dialog" aria-labelledby="video-modal" aria-hidden="true">
660 <div class="modal-dialog modal-dialog-centered" role="document">
661 <div class="modal-content">
662 <div class="modal-body">
663 <div id="player"></div>
664 </div>
665 </div>
666 </div>
667 </div>
668
669 <div class="add-to-cart-overlay" data-bind="css: { 'd-block': ProcessingAjax }">
670 <p class="fs4 m-0 color-white">@Translate("ProductAjaxAddingToCart", "Tilføjer til kurv") <i class="fa fa-spinner fa-spin ml-3 fs5"></i></p>
671 </div>
672
673 <div class="add-to-cart-overlay" data-bind="css: { 'd-block': ProcessingVariantDetailsAjax }">
674 <p class="fs4 m-0 color-white">@Translate("ProductAjaxGettingVariant", "Henter variant") <i class="fa fa-spinner fa-spin ml-3 fs5"></i></p>
675 </div>
676
677 <div class="delivery-information-popup" data-bind="css: { 'd-flex': DeliveryInfoOpen }, click: ToggleDeliveryInfo">
678 <div class="description-content bg-white px-3 py-4 px-lg-4 position-relative" data-bind="click: OpenDeliveryInfo, clickBubble: false">
679 <div class="modal-closer-custom" data-bind="click: ToggleDeliveryInfo, clickBubble: false">
680 <img src="/Files/Templates/Designs/Mobler2018/assets/img/icons/close.svg" />
681 </div>
682 @if (QuickDelivery)
683 {
684 <div>
685 @QuickDeliveryDescription
686 </div>
687 }
688 else if (DisplayAverageDeliveryTime)
689 {
690 <div>
691 @NormalDeliveryDescription
692 </div>
693 }
694 </div>
695 </div>
696
697 @if (CostPrice > 0)
698 {
699 string PriceDescription = Firstweb.Custom.CustomCode.Frontend.Helpers.AreaItems.GetString("DagsprisDescription");
700 <div class="delivery-information-popup" data-bind="css: { 'd-flex': PriceInfoOpen }, click: TogglePriceInfo">
701 <div class="description-content bg-white px-3 py-4 px-lg-4 position-relative" data-bind="click: OpenPriceInfo, clickBubble: false">
702 <div class="modal-closer-custom" data-bind="click: TogglePriceInfo, clickBubble: false">
703 <img src="/Files/Templates/Designs/Mobler2018/assets/img/icons/close.svg" />
704 </div>
705 <div>
706 @PriceDescription
707 </div>
708 </div>
709 </div>
710 }
711
712
713 <h1 class="header mb-4" data-bind="text: ProductName">@ProductName</h1>
714
715 <div class="d-flex flex-wrap">
716
717 <div class="image-container position-relative overflow-hidden">
718
719 <div class="discount-splash unimportant-hidden" data-bind="css: { 'd-flex': SplashType() == 1 }"><p class="m-0">@Translate("ProductOffer", "Tilbud")</p></div>
720 <div class="discount-splash unimportant-hidden new-item" data-bind="css: { 'd-flex': SplashType() == 2 }"><p class="m-0">@Translate("ProductNew", "Nyhed")</p></div>
721 <div class="discount-splash unimportant-hidden low-price" data-bind="css: { 'd-flex': SplashType() == 3 }"><p class="m-0">@Translate("ProductLowPrice", "Fast lavpris")</p></div>
722 <div class="discount-splash unimportant-hidden price-shape" data-bind="css: { 'd-flex': SplashType() == 4 }" style="background-color: @DailyPriceBackgroundColor;"><p class="m-0" style="color: @DailyPriceTextColor;">@Translate("ProductDailyPriceSplash", "Dagspris")</p></div>
723
724 <div id="imageSlider" class="carousel slide" data-ride="carousel">
725 <div class="carousel-inner align-items-center" data-bind="if: Images().length == 0">
726
727 @foreach (var Image in Images)
728 {
729 if (First)
730 {
731 <a href="/Admin/Public/GetImage.ashx?Image=@Image&width=2000" class="mb-3 mb-lg-0 carousel-item active" data-gallery>
732 <img class="product-image main-image" src="/Admin/Public/GetImage.ashx?Image=@Image&width=950&height=500&crop=5" alt="@ProductName" />
733 </a>
734 First = false;
735 FirstImage = "/Admin/Public/GetImage.ashx?Image=" + Image + "&width=950&height=500&crop=5";
736 }
737 else
738 {
739 <a href="/Admin/Public/GetImage.ashx?Image=@Image&width=2000" class="mb-3 mb-lg-0 carousel-item" data-gallery>
740 <img class="product-image main-image" src="/Admin/Public/GetImage.ashx?Image=@Image&width=950&height=500&crop=5" alt="@ProductName" />
741 </a>
742 }
743
744 }
745
746 </div>
747 <div class="carousel-inner align-items-center d-flex js-ko-carousel" data-bind="foreach: Images()">
748
749 <a data-bind="attr: { href: '/Admin/Public/GetImage.ashx?Image=' + $data + '&width=2000' }" class="mb-3 mb-lg-0 carousel-item active" data-gallery>
750 <img class="product-image main-image" data-bind="attr: { src: '/Admin/Public/GetImage.ashx?Image=' + $data + '&width=950&height=500&crop=5' }" />
751 </a>
752
753 </div>
754 </div>
755
756 @if (Images.Count > 1)
757 {
758 <div class="row small-gutter carousel-row" data-bind="css: { 'd-none': Images().length > 0 }">
759
760 @foreach (var Image in Images)
761 {
762 if (FirstIndicator)
763 {
764 <div data-target="#imageSlider" data-slide-to="@IndicatorIncrementer" class="col-4 mt-lg-3 cursor-pointer active">
765 <div class="secondary-image">
766 <img class="product-image" src="/Admin/Public/GetImage.ashx?Image=@Image&width=400&height=230&crop=5" alt="@ProductName" />
767 </div>
768 </div>
769 FirstIndicator = false;
770 }
771 else
772 {
773 <div data-target="#imageSlider" data-slide-to="@IndicatorIncrementer" class="col-4 mt-lg-3 cursor-pointer">
774 <div class="secondary-image">
775 <img class="product-image" src="/Admin/Public/GetImage.ashx?Image=@Image&width=400&height=230&crop=5" alt="@ProductName" />
776 </div>
777 </div>
778 }
779 IndicatorIncrementer++;
780 }
781
782 @if (!String.IsNullOrEmpty(GetString("Ecom:Product:Field.VideoKlip.Value")))
783 {
784 string BackgroundSize = !String.IsNullOrEmpty(GetString("Ecom:Product:Field.VideoBillede.Value.Clean")) ? "cover" : "contain";
785 string OverlayImage = !String.IsNullOrEmpty(GetString("Ecom:Product:Field.VideoBillede.Value.Clean")) ? GetString("Ecom:Product:Field.VideoBillede.Value.Clean") : FirstImage;
786 <div class="youtube-video-container mt-lg-3" data-bind="youtubeVideo: { videoId: '@GetString("Ecom:Product:Field.VideoKlip.Value")', overlayId: 'js-video-overlay', playerId: 'player' }">
787 <div id="js-video-overlay" class="video-overlay pointer" style="background-image:url('@OverlayImage');background-size: @BackgroundSize;">
788 <div class="visual-overlay d-flex flex-column justify-content-center align-items-center h-100 w-100">
789 <img src="/Files/Templates/Designs/Mobler2018/assets/img/icons/Play.svg" />
790 <p class="mt-3 mb-0 color-white">@Translate("Product.WatchVideo", "Se video")</p>
791 </div>
792 </div>
793 </div>
794 }
795
796 </div>
797
798 <div class="row small-gutter carousel-row unimportant-hidden" data-bind="css: { 'd-flex': Images().length > 0 }, foreach: Images()">
799
800 <!-- ko if: $index() == 0 -->
801 <div data-target="#imageSlider" class="col-4 mt-lg-3 cursor-pointer active" data-bind="click: $parent.ChangeSlide.bind($data, $index())">
802 <div class="secondary-image">
803 <img class="product-image" data-bind="attr: { src: '/Admin/Public/GetImage.ashx?Image=' + $data + '&width=400&height=230&crop=5' }" alt="@ProductName" />
804 </div>
805 </div>
806 <!-- /ko -->
807 <!-- ko if: $index() != 0 -->
808 <div data-target="#imageSlider" class="col-4 mt-lg-3 cursor-pointer" data-bind="click: $parent.ChangeSlide.bind($data, $index())">
809 <div class="secondary-image">
810 <img class="product-image" data-bind="attr: { src: '/Admin/Public/GetImage.ashx?Image=' + $data + '&width=400&height=230&crop=5' }" alt="@ProductName" />
811 </div>
812 </div>
813 <!-- /ko -->
814
815 </div>
816 }
817
818 </div>
819
820 <div class="pl-lg-4 description-container d-flex flex-wrap flex-column mt-3 mt-lg-0 position-relative">
821
822 <div class="mb-2">@ShortDescription</div>
823
824 <div class="w-100"><p class="color-primary pointer mb-2" data-bind="scrollToElement: { target: '#js-full-description' }">@Translate("ProductReadFullDescription", "Læs hele beskrivelsen")</p></div>
825
826 <div class="w-100">
827 <p class="color-subtle m-0">@Translate("ProductProductNumber", "Produktnummer:") <span data-bind="text: ProductNumber">@ProductNumber</span></p>
828 <p class="color-subtle m-0">
829 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.dybdeint.Value.Clean")))
830 {
831 if (GetString("Ecom:Product:Field.dybdeint.Value.Clean") != "0")
832 {
833 <span>D/L: @GetValue("Ecom:Product:Field.dybdeint.Value.Clean")</span>
834 }
835 }
836 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.hoejdeint.Value.Clean")))
837 {
838 if (GetString("Ecom:Product:Field.hoejdeint.Value.Clean") != "0")
839 {
840 <span>H: @GetValue("Ecom:Product:Field.hoejdeint.Value.Clean")</span>
841 }
842 }
843 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.breddeint.Value.Clean")))
844 {
845 if (GetString("Ecom:Product:Field.breddeint.Value.Clean") != "0")
846 {
847 <span>B: @GetValue("Ecom:Product:Field.breddeint.Value.Clean")</span>
848 }
849 }
850 </p>
851 </div>
852
853 @if ((QuickDelivery || DisplayAverageDeliveryTime) && !HideDelivery)
854 {
855 <div class="w-100 mt-3">
856
857 <div class="delivery-information">
858 <svg class="delivery-icon mr-2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" fill="@DeliveryColor" x="0px" y="0px" width="30px" height="30px" viewBox="0 0 612 612" style="enable-background:new 0 0 612 612;" xml:space="preserve">
859 <g>
860 <g>
861 <path d="M226.764,375.35c-28.249,0-51.078,22.91-51.078,51.16c0,28.166,22.829,51.078,51.078,51.078s51.078-22.912,51.078-51.078 C277.841,398.26,255.013,375.35,226.764,375.35z M226.764,452.049c-14.125,0-25.54-11.498-25.54-25.541 c0-14.123,11.415-25.539,25.54-25.539c14.124,0,25.539,11.416,25.539,25.539C252.302,440.551,240.888,452.049,226.764,452.049z M612,337.561v54.541c0,13.605-11.029,24.635-24.636,24.635h-26.36c-4.763-32.684-32.929-57.812-66.927-57.812 c-33.914,0-62.082,25.129-66.845,57.812H293.625c-4.763-32.684-32.93-57.812-66.845-57.812c-33.915,0-62.082,25.129-66.844,57.812 h-33.012c-13.606,0-24.635-11.029-24.635-24.635v-54.541H612L612,337.561z M494.143,375.35c-28.249,0-51.16,22.91-51.16,51.16 c0,28.166,22.912,51.078,51.16,51.078c28.166,0,51.077-22.912,51.077-51.078C545.22,398.26,522.309,375.35,494.143,375.35z M494.143,452.049c-14.125,0-25.539-11.498-25.539-25.541c0-14.123,11.414-25.539,25.539-25.539 c14.042,0,25.539,11.416,25.539,25.539C519.682,440.551,508.185,452.049,494.143,452.049z M602.293,282.637l-96.817-95.751 c-6.159-6.077-14.453-9.526-23.076-9.526h-48.86v-18.313c0-13.631-11.004-24.635-24.635-24.635H126.907 c-13.55,0-24.635,11.005-24.635,24.635v3.86L2.3,174.429l177.146,23.068L0,215.323l178.814,25.423L0,256.25l102.278,19.29 l-0.007,48.403h509.712v-17.985C611.983,297.171,608.452,288.796,602.293,282.637z M560.084,285.839h-93.697 c-2.135,0-3.86-1.724-3.86-3.859v-72.347c0-2.135,1.725-3.86,3.86-3.86h17.82c0.985,0,1.971,0.411,2.71,1.068l75.796,72.347 C565.257,281.569,563.532,285.839,560.084,285.839z" />
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877 </g>
878 </g>
879 </svg>
880 <p class="delivery-text @DeliveryFontWeightModifier">@DeliveryTime - <a href="#" class="text-underline" data-bind="click: ToggleDeliveryInfo" style="color: @DeliveryColor">@Translate("Product.DeliveryInfo.ReadmoreText", "Læs mere")</a></p>
881 </div>
882
883 </div>
884 }
885
886 @if (CostPrice > 0)
887 {
888 <div class="w-100 mt-3">
889
890 <div class="delivery-information">
891 <div class="live-price-animation"></div>
892 <p class="delivery-text">@Translate("Product.PriceInfo.RecommendedPriceInfo", "Aktuel dagspris - ")<a href="#" class="text-underline" data-bind="click: TogglePriceInfo">@Translate("Product.PriceInfo.RecommendedPriceLink", "Læs mere")</a></p>
893 </div>
894
895 </div>
896 }
897
898
899 <div class="w-100">
900 @if (GetBoolean("Ecom:Product:Field.Farvevarianter1.Value"))
901 {
902 <img class="img-fluid mb-3 mt-5" src="/Files/Images/Farver/farver1.png" />
903 <p class="mb-0">@Translate("ProductColor1Text", "Fås i flere forskellige varianter og moduler, besøg dit lokale Møblér bolighus og få vejledning til design af din sofa.")</p>
904 }
905 else if (GetBoolean("Ecom:Product:Field.Farvevarianter2.Value"))
906 {
907 <img class="img-fluid mb-3 mt-5" src="/Files/Images/Farver/farver2.png" />
908 <p class="mb-0">@Translate("ProductColor2Text", "Farve 2 hjælpetekst")</p>
909 }
910 else if (GetBoolean("Ecom:Product:Field.Farvevarianter3.Value"))
911 {
912 <img class="img-fluid mb-3 mt-5" src="/Files/Images/Farver/farver3.png" />
913 <p class="mb-0">@Translate("ProductColor3Text", "Farve 3 hjælpetekst")</p>
914 }
915 else if (GetBoolean("Ecom:Product:Field.Farvevarianter4.Value"))
916 {
917 <img class="img-fluid mb-3 mt-5" src="/Files/Images/Farver/farver4.png" />
918 <p class="mb-0">@Translate("ProductColor4Text", "Farve 4 hjælpetekst")</p>
919 }
920 else if (GetBoolean("Ecom:Product:Field.Farvevarianter5.Value"))
921 {
922 <img class="img-fluid mb-3 mt-5" src="/Files/Images/Farver/farver5.png" />
923 <p class="mb-0">@Translate("ProductColor5Text", "Farve 5 hjælpetekst")</p>
924 }
925 </div>
926
927 @if (GetLoop("VariantCombinations").Count > 0)
928 {
929 var VariantGroupsWithMultipleOptions = GetLoop("VariantGroups").Where(x => x.GetLoop("VariantAvailableOptions").Count > 1);
930 int VariantGroupCount = VariantGroupsWithMultipleOptions.Count();
931 int VariantCombinationsCount = GetLoop("VariantCombinations").Count;
932 int PossibleVariantCombinations = 1;
933 foreach (var VG in GetLoop("VariantGroups"))
934 {
935 PossibleVariantCombinations *= VG.GetLoop("VariantAvailableOptions").Count;
936 }
937 if (VariantGroupCount == 1)
938 {
939 var RelevantVariantGroup = VariantGroupsWithMultipleOptions.FirstOrDefault();
940 var SelectedVariant = RelevantVariantGroup.GetLoop("VariantAvailableOptions").Where(x => x.GetBoolean("Ecom:VariantOption.Selected")).FirstOrDefault();
941 <div class="position-relative">
942 <div class="variant-dropdown p-2 box-shadow mt-3 d-flex justify-content-between align-items-center pointer js-variant-dropdown">
943 <p class="m-0"><span class="font-weight-bold">@RelevantVariantGroup.GetString("Ecom:VariantGroup.Label")</span> - <span data-bind="text: SelectedVariantOption0">@SelectedVariant.GetString("Ecom:VariantOption.Name")</span></p>
944 <i class="fas fa-chevron-down"></i>
945 </div>
946 <div class="variant-options bg-white">
947 @foreach (var Variant in RelevantVariantGroup.GetLoop("VariantAvailableOptions"))
948 {
949 var VariantCombination = GetLoop("VariantCombinations").Where(x => x.GetString("Ecom:VariantCombination.VariantID").ToString().Contains(Variant.GetString("Ecom:VariantOption.ID"))).FirstOrDefault();
950 string VariantName = Variant.GetString("Ecom:VariantOption.Name");
951 string VariantIdentifier = Variant.GetString("Ecom:VariantOption.ID");
952 string VariantLink = VariantCombination.GetString("Ecom:VariantCombination.Link.Clean");
953 string VariantPreview = String.Empty;
954 var ObservableToSet = "SelectedVariantOption0";
955 var ObservableToSetId = "SelectedVariantOptionId0";
956 bool ShowPreview = RelevantVariantGroup.GetString("Ecom:VariantGroup.Name").ToString().ToLower().Contains("farve") || RelevantVariantGroup.GetString("Ecom:VariantGroup.Name").ToString().ToLower().Contains("materiale") ? true : false;
957 if (!String.IsNullOrEmpty(Variant.GetString("Ecom:VariantOption.ImgSmall.Clean")) && ShowPreview)
958 {
959 if (Variant.GetString("Ecom:VariantOption.ImgSmall.Clean").StartsWith("#"))
960 {
961 VariantPreview = "style= \"background-color: " + Variant.GetString("Ecom:VariantOption.ImgSmall.Clean") + ";\"";
962 }
963 else
964 {
965 VariantPreview = "style=\"background-image: url('" + Variant.GetString("Ecom:VariantOption.ImgSmall.Clean") + "');\"";
966 }
967 }
968 <div class="option pointer color-primary d-flex w-100 p-2 bg-grey" data-bind="click: UpdateVariantAndSetObservable.bind($data, '@VariantIdentifier', @ObservableToSet, '@VariantName', @ObservableToSetId)">
969 @if (!String.IsNullOrEmpty(VariantPreview))
970 {
971 <span class="option-preview mr-2" @VariantPreview></span>
972 }
973 <span>@VariantName</span>
974 </div>
975 <div class="d-none" data-bind="setInitValue: { observable: @ObservableToSet, value: '@SelectedVariant.GetString("Ecom:VariantOption.Name")' }"></div>
976 <div class="d-none" data-bind="setInitValue: { observable: @ObservableToSetId, value: '@SelectedVariant.GetString("Ecom:VariantOption.ID")' }"></div>
977 }
978 </div>
979 </div>
980 }
981 else if (PossibleVariantCombinations == VariantCombinationsCount)
982 {
983 Dictionary<string, string> CurrentlySelectedVariantOptions = new Dictionary<string, string>();
984 foreach (var VG in GetLoop("VariantGroups"))
985 {
986 foreach (var VO in VG.GetLoop("VariantAvailableOptions").Where(x => x.GetBoolean("Ecom:VariantOption.Selected")))
987 {
988 CurrentlySelectedVariantOptions.Add(VG.GetString("Ecom:VariantGroup.Name"), VO.GetString("Ecom:VariantOption.ID"));
989 }
990 }
991 int VGLoopCounter = 0;
992 foreach (var VG in GetLoop("VariantGroups"))
993 {
994 List<LoopItem> RelevantVariantCombinations = new List<LoopItem>();
995 var VariantCombinationLink = GetLoop("VariantCombinations");
996 var SelectedVariant = VG.GetLoop("VariantAvailableOptions").Where(x => x.GetBoolean("Ecom:VariantOption.Selected")).FirstOrDefault();
997 var ObservableToSet = "SelectedVariantOption" + VGLoopCounter.ToString();
998 var ObservableToSetId = "SelectedVariantOptionId" + VGLoopCounter.ToString();
999 VGLoopCounter++;
1000 foreach (var VC in VariantCombinationLink)
1001 {
1002 var Add = true;
1003 foreach (var KVP in CurrentlySelectedVariantOptions.Where(s => s.Key != VG.GetString("Ecom:VariantGroup.Name")))
1004 {
1005 if (!VC.GetString("Ecom:VariantCombination.VariantID").ToString().Contains(KVP.Value))
1006 {
1007 Add = false;
1008 }
1009 }
1010 if (Add)
1011 {
1012 RelevantVariantCombinations.Add(VC);
1013 }
1014 }
1015 <div class="d-none" data-bind="setInitValue: { observable: @ObservableToSet, value: '@SelectedVariant.GetString("Ecom:VariantOption.Name")' }"></div>
1016 <div class="d-none" data-bind="setInitValue: { observable: @ObservableToSetId, value: '@SelectedVariant.GetString("Ecom:VariantOption.ID")' }"></div>
1017 <div class="position-relative">
1018 <div class="variant-dropdown p-2 box-shadow mt-3 d-flex justify-content-between align-items-center pointer js-variant-dropdown">
1019 <p class="m-0"><span class="font-weight-bold">@VG.GetString("Ecom:VariantGroup.Label")</span> - <span data-bind="text: @ObservableToSet">@SelectedVariant.GetString("Ecom:VariantOption.Name")</span></p>
1020 <i class="fas fa-chevron-down"></i>
1021 </div>
1022 <div class="variant-options bg-white">
1023 @foreach (var VO in VG.GetLoop("VariantAvailableOptions"))
1024 {
1025 var VariantCombination = RelevantVariantCombinations.Where(vc => vc.GetString("Ecom:VariantCombination.VariantID").ToString().Contains(VO.GetString("Ecom:VariantOption.ID"))).FirstOrDefault();
1026 string VariantLink = VariantCombination.GetString("Ecom:VariantCombination.Link.Clean");
1027 string VariandOptionId = VariantCombination.GetString("Ecom:VariantCombination.VariantID");
1028 string VariantPreview = String.Empty;
1029 string VOName = VO.GetString("Ecom:VariantOption.Name");
1030 string VOId = VO.GetString("Ecom:VariantOption.ID");
1031 bool ShowPreview = VG.GetString("Ecom:VariantGroup.Name").ToString().ToLower().Contains("farve") || VG.GetString("Ecom:VariantGroup.Name").ToString().ToLower().Contains("materiale") ? true : false;
1032 if (!String.IsNullOrEmpty(VO.GetString("Ecom:VariantOption.ImgSmall.Clean")) && ShowPreview)
1033 {
1034 if (VO.GetString("Ecom:VariantOption.ImgSmall.Clean").StartsWith("#"))
1035 {
1036 VariantPreview = "style= \"background-color: " + VO.GetString("Ecom:VariantOption.ImgSmall.Clean") + ";\"";
1037 }
1038 else
1039 {
1040 VariantPreview = "style=\"background-image: url('" + VO.GetString("Ecom:VariantOption.ImgSmall.Clean") + "');\"";
1041 }
1042 }
1043 <div class="option d-flex w-100 p-2 bg-grey color-primary pointer" data-bind="click: UpdateVariantAndSetObservable.bind($data, '@VOId', @ObservableToSet, '@VOName', @ObservableToSetId)">
1044 @if (!String.IsNullOrEmpty(VariantPreview))
1045 {
1046 <span class="option-preview mr-2" @VariantPreview></span>
1047 }
1048 @VOName
1049 </div>
1050 }
1051 </div>
1052 </div>
1053 }
1054 }
1055 else if (GetLoop("VariantGroups").Where(x => x.GetString("Ecom:VariantGroup.Name").ToString().ToLower().Contains("farve")).Count() > 0 && GetLoop("VariantGroups").Where(x => x.GetString("Ecom:VariantGroup.Name").ToString().ToLower().Contains("materiale")).Count() > 0)
1056 {
1057 <div class="mt-3">
1058 <p class="mb-1">@Translate("CurrentDesignName", "Valgte design: ")</p>
1059 <p class="font-weight-bold">@CurrentVariantName</p>
1060 </div>
1061 <div class="d-flex">
1062 <div class="btn btn-primary" data-bind="click: ToggleVariantPicker">@Translate("ChooseNewDesign", "Vælg design")</div>
1063 </div>
1064 }
1065 else
1066 {
1067 var SelectedVariant = GetLoop("VariantCombinations").Where(x => x.GetBoolean("Ecom:VariantCombination.Selected")).FirstOrDefault();
1068 var SelectedVariantName = SelectedVariant.GetString("Ecom:VariantCombination.VariantText");
1069 var SelectedVariantId = SelectedVariant.GetString("Ecom:VariantOption.ID");
1070 <div class="d-none" data-bind="setInitValue: { observable: SelectedVariantOption0, value: '@SelectedVariantName' }"></div>
1071 <div class="d-none" data-bind="setInitValue: { observable: SelectedVariantOptionId0, value: '@SelectedVariantId' }"></div>
1072 <div class="position-relative">
1073 <div class="variant-dropdown p-2 box-shadow mt-3 d-flex justify-content-between align-items-center pointer js-variant-dropdown">
1074 <p class="m-0"><span class="font-weight-bold">@Translate("FallbackVariantsText", "VARIANTER")</span> - <span data-bind="text: SelectedVariantOption0">@SelectedVariantName</span></p>
1075 <i class="fas fa-chevron-down"></i>
1076 </div>
1077 <div class="variant-options bg-white">
1078 @foreach (var Variant in GetLoop("VariantCombinations"))
1079 {
1080 string VariantName = Variant.GetString("Ecom:VariantCombination.VariantText");
1081 string VariantLink = Variant.GetString("Ecom:VariantCombination.Link.Clean");
1082 string VCId = Variant.GetString("Ecom:Product.VariantID");
1083 <div class="option color-primary pointer d-block p-2 bg-grey" data-bind="click: UpdateVariantAndSetObservable.bind($data, '@VCId', SelectedVariantOption0, '@VariantName', SelectedVariantOptionId0)">@VariantName</div>
1084 }
1085 </div>
1086 </div>
1087 }
1088
1089 }
1090
1091 <div class="row align-items-end f-grow-1">
1092 <div class="col-10 offset-1 col-sm-12 offset-sm-0 d-flex justify-content-center justify-content-lg-start">
1093 <div class="mt-5 d-flex flex-wrap flex-column justify-content-end">
1094 @if (CostPrice > 0)
1095 {
1096 var PriceShapePrices = Firstweb.Custom.CustomCode.Frontend.Helpers.PriceShapeHelpers.GetProductPrice(ProductNumber, EAN);
1097 <div class="d-none" data-bind="setInitValue: { observable: SplashType, value: 4 }"></div>
1098 if (PriceShapePrices != null && price < PriceShapePrices.MoblerPrice)
1099 {
1100 <div class="d-none" data-bind="setInitValue: { observable: ShowSaving, value: true }"></div>
1101 <div class="d-none" data-bind="setInitValue: { observable: CostPrice, value: '@MoblerHelpers.formatPrice(PriceShapePrices.MoblerPrice)' }"></div>
1102 }
1103 }
1104 else if (spar > 0)
1105 {
1106 <div class="d-none" data-bind="setInitValue: { observable: SplashType, value: 1 }"></div>
1107 <div class="d-none" data-bind="setInitValue: { observable: BeforePrice, value: '@MoblerHelpers.formatPrice(OriginalPrice)' }"></div>
1108 <div class="d-none" data-bind="setInitValue: { observable: Saving, value: '@MoblerHelpers.formatPrice(spar)' }"></div>
1109 }
1110 else if (NewItem)
1111 {
1112 <div class="d-none" data-bind="setInitValue: { observable: SplashType, value: 2 }"></div>
1113 }
1114 else if (LowPrice)
1115 {
1116 <div class="d-none" data-bind="setInitValue: { observable: SplashType, value: 3 }"></div>
1117 }
1118
1119 <div class="w-100 unimportant-hidden" data-bind="css: { 'd-flex': SplashType() == 1 }">
1120 <p class="color-subtle fs0 m-0 text-uppercase mr-3">@Translate("PriceBefore", "Før") <span data-bind="text: BeforePrice"></span></p>
1121 <p class="bg-discount fs0 text-uppercase m-0 px-2 font-weight-bold">@Translate("PriceSaving", "Spar") <span data-bind="text: Saving"></span></p>
1122 </div>
1123 <div class="w-100 unimportant-hidden" data-bind="css: { 'd-flex': SplashType() == 4 && ShowSaving }">
1124 @if (GetLoop("VariantCombinations").Count > 0)
1125 {
1126 <p class="color-subtle fs0 m-0 text-uppercase mr-3">@Translate("PriceRecommendPriceFrom", "Vejl. pris fra") <span data-bind="text: CostPrice"></span></p>
1127 }
1128 else
1129 {
1130 <p class="color-subtle fs0 m-0 text-uppercase mr-3">@Translate("PriceRecommendPrice", "Vejl. pris") <span data-bind="text: CostPrice"></span></p>
1131 }
1132 </div>
1133 <p class="price font-weight-bold m-0">
1134 <span class="unimportant-hidden" data-bind="css: { 'd-inline': SplashType() == 1 }">@Translate("ProductNow", "NU") </span>
1135 <span data-bind="text: Price"></span>
1136 </p>
1137
1138 <div class="payever-finance-express payever-button" data-code="@GetString("Ecom:Product.Number")" data-name="@GetString("Ecom:Product.Name")" data-price="@GetString("Ecom:Product.Price.Price").Replace(".", string.Empty).Replace(",", ".")" data-currency="DKK"></div>
1139 <script>(function (p, a, y, e, v, r, f) { p[v] = p[v] || []; p[v][r] = p[v][r] || []; if (!p[v][r][y]) { p[v][r][y] = f = a.createElement(y); f.async = 1; f.src = e; a.head.appendChild(f) } })(window, document, 'script', 'https://mein.payever.de/finances/business/mobler/finance-express/91203/scripts/finance_express.embed.min.js', 'Payever', 'FinanceExpress');</script>
1140
1141 @if (ForSale)
1142 {
1143 <div class="d-flex align-items-center mt-3">
1144 <p class="m-0 font-weight-bold fs1 mr-2">@Translate("Product.Quantity", "Antal")</p>
1145 <div class="d-flex">
1146 <div class="quantity-controls d-flex align-items-center mr-3">
1147 <div class="control minus" data-bind="click: DecreaseQuantity">
1148 -
1149 </div>
1150 <input type="text" name="Quantity" value="1" data-bind="value: Quantity" />
1151 <div class="control plus" data-bind="click: IncrementQuantity">
1152 +
1153 </div>
1154 </div>
1155 @if (BlackFridayTheme == "True")
1156 {
1157 <p class="btn btn-black-friday bf-bg-black add-to-cart m-0 d-flex align-items-center px-4" data-bind="click: AddToCart.bind($data, '@DataLayerPrice')">
1158 @Translate("ProductAddToCart", "Læg i kurv")
1159 </p>
1160 }
1161 else
1162 {
1163 <p class="btn btn-primary add-to-cart m-0 d-flex align-items-center px-4" data-bind="click: AddToCart.bind($data, '@DataLayerPrice')">
1164 @Translate("ProductAddToCart", "Læg i kurv")
1165 </p>
1166 }
1167 </div>
1168 </div>
1169 }
1170 else
1171 {
1172 <p>@Translate("Ecom:Product.NotForSaleMessage", "Produktet kan ikke købes.")</p>
1173 }
1174 </div>
1175 </div>
1176 </div>
1177
1178 </div>
1179
1180 </div>
1181
1182 <div class="d-flex flex-wrap justify-content-center external-ctas">
1183
1184 @if (!String.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.ProviderLink.Value.Clean")))
1185 {
1186 <a href="@GetString("Ecom:Product:Field.ProviderLink.Value.Clean")" target="_blank" class="bg-brand font-weight-bold d-flex align-items-center justify-content-center no-underline p-3 color-white">
1187 <span>@Translate("Product.DesignSelf", "Design selv")</span>
1188 <img src="/Files/Templates/Designs/Mobler2018/assets/img/icons/Pencil1.svg" />
1189 </a>
1190 }
1191
1192 @if (!String.IsNullOrEmpty(ProductCatalogLink))
1193 {
1194 <a class="btn btn-secondary rounded-0 d-flex justify-content-center align-items-center p-3 color-white font-weight-bold" href="@ProductCatalogLink" target="_blank">
1195 <span>@Translate("ProductProductCatalogLink", "Se inspirationsbrochure")</span>
1196 <img src="/Files/Templates/Designs/Mobler2018/assets/img/icons/Brochure.svg" />
1197 </a>
1198 }
1199
1200 </div>
1201
1202 <div class="d-flex flex-wrap mt-5">
1203
1204 <div id="js-full-description">
1205 <p class="fs3 mb-2 font-weight-bold">@Translate("ProductDescriptionHeader", "Beskrivelse")</p>
1206 <div class="unimportant-hidden" data-bind="html: FullDescription, css: { 'd-block': FullDescription().length > 0 }">
1207 </div>
1208 <div data-bind="css: { 'd-none': FullDescription().length > 0 }">
1209 @LongDescription
1210
1211 @if (!string.IsNullOrEmpty(productionDescription))
1212 {
1213 <br/><br />
1214 <h4>@Translate("Product.ProductionDescription.Headline", "Produktionsbeskrivelse")</h4>
1215 @:@productionDescription
1216 }
1217 </div>
1218 </div>
1219
1220 </div>
1221
1222 <div class="d-flex flex-wrap my-5">
1223
1224 <div class="description-container mt-5 mt-lg-0">
1225 <div class="bg-brand color-white box-shadow p-3 pb-5 questions">
1226 <img class="staff-img" src="/Files/Templates/Designs/Mobler2018/assets/img/sovnmand.png" />
1227
1228 @if (!String.IsNullOrWhiteSpace(shopInfo.ShopName) && shopInfo.ShopName != "Møblér")
1229 {
1230 <div class="shop-info">
1231 <h4 class="fs45">@Translate("ProductQuestionsHeader", "Har du spørsmål?")</h4>
1232 <p class="mb-1">@shopInfo.Address, @shopInfo.PostalAndCity</p>
1233 <p class="mb-1">@shopInfo.Phone</p>
1234 @if (!String.IsNullOrEmpty(shopInfo.Email))
1235 {
1236 <p class="mb-1"><a class="color-white" href="mailto:@shopInfo.Email">@shopInfo.Email</a></p>
1237 }
1238 @if (!String.IsNullOrEmpty(shopInfo.ShopName1))
1239 {
1240 <p class="mb-1 mt-2">@shopInfo.Address1, @shopInfo.PostalAndCity1</p>
1241 <p class="mb-2">@shopInfo.Phone1</p>
1242 }
1243 @if (!String.IsNullOrEmpty(shopInfo.ShopName2))
1244 {
1245 <p class="mb-1 mt-2">@shopInfo.Address2, @shopInfo.PostalAndCity2</p>
1246 <p class="mb-2">@shopInfo.Phone2</p>
1247 }
1248 @shopInfo.OpeningHours
1249 </div>
1250 }
1251 else
1252 {
1253 <h4 class="fs45">@Translate("ProductQuestionsHeader", "Har du spørsmål?")</h4>
1254 <p class="fs2 text">@Translate("ProductSelectNearestShop", "Vælg nærmeste Møbler bolighus")</p>
1255 <select style="width: 280px;" data-bind="select2SelectShop: { overlay: 'find-dealer-overlay', placeholder: '@SelectPlaceholder' }">
1256 @if (shopname == "Møblér")
1257 {
1258 <option selected disabled>@Translate("HeaderFindShop", "Find forhandler")</option>
1259 }
1260 else
1261 {
1262 foreach (var Shop in AllShops.Where(x => x.MenuText == shopname))
1263 {
1264 <option selected disabled value="@HttpUtility.UrlEncode(Shop.MenuText)">@Shop.ShopName</option>
1265 }
1266 }
1267 @foreach (var Shop in AllShops)
1268 {
1269 if (Shop.MenuText != "Møblér" && Shop.MenuText != shopname)
1270 {
1271 var Address = "<div>" + Shop.Address + "</div><div>" + Shop.PostalAndCity + "</div>";
1272 <option title="@Address" value="@HttpUtility.UrlEncode(Shop.MenuText)">@Shop.ShopName {{@Shop.PostalAndCity @Shop.SearchKeyWords}}</option>
1273 }
1274 }
1275 </select>
1276 }
1277 </div>
1278 </div>
1279
1280 </div>
1281
1282 @if (GetInteger("Ecom:Product.RelatedCount") > 0)
1283 {
1284 foreach (var Group in GetLoop("ProductRelatedGroups").Where(g => g.GetLoop("Products").Count > 0))
1285 {
1286 <div class="py-3 mt-5" data-bind="viewModel: 'ProductListViewModel'">
1287
1288 <div class="delivery-information-popup" data-bind="css: { 'd-flex': QuickDeliveryInfoOpen }, click: ToggleQuickDeliveryInfo">
1289 <div class="description-content bg-white px-3 py-4 px-lg-4 position-relative" data-bind="click: OpenQuickDeliveryInfo, clickBubble: false">
1290 <div class="modal-closer-custom" data-bind="click: ToggleQuickDeliveryInfo, clickBubble: false">
1291 <img src="/Files/Templates/Designs/Mobler2018/assets/img/icons/close.svg" />
1292 </div>
1293 <div>
1294 @QuickDeliveryDescription
1295 </div>
1296 </div>
1297 </div>
1298 <div class="delivery-information-popup" data-bind="css: { 'd-flex': NormalDeliveryInfoOpen }, click: ToggleNormalDeliveryInfo">
1299 <div class="description-content bg-white px-3 py-4 px-lg-4 position-relative" data-bind="click: OpenNormalDeliveryInfo, clickBubble: false">
1300 <div class="modal-closer-custom" data-bind="click: ToggleNormalDeliveryInfo, clickBubble: false">
1301 <img src="/Files/Templates/Designs/Mobler2018/assets/img/icons/close.svg" />
1302 </div>
1303 <div>
1304 @NormalDeliveryDescription
1305 </div>
1306 </div>
1307 </div>
1308
1309 <div class="line-through-header mb-3">
1310 <h4>@Group.GetString("Ecom:Product:RelatedGroup.Name")</h4>
1311 </div>
1312
1313 <div class="row">
1314
1315 @foreach (var Product in Group.GetLoop("Products"))
1316 {
1317 var productToRender = Product;
1318 string productId = Product.GetString("Ecom:Product.ID");
1319 string variantIdLoop = productsDisplayVariant.GetDisplayVariantId(productId);
1320
1321 if (Product.GetLoop("VariantCombinations").Count > 0 && Product.GetLoop("VariantCombinations").Any(x => x.GetString("Ecom:Product.VariantID").Equals(variantIdLoop)))
1322 {
1323 productToRender = Product.GetLoop("VariantCombinations").FirstOrDefault(x => x.GetString("Ecom:Product.VariantID").Equals(variantIdLoop));
1324 }
1325
1326 @RenderProduct(productToRender)
1327 }
1328 </div>
1329 </div>
1330 }
1331 }
1332
1333 @if (RelatedBlogs.Count > 0)
1334 {
1335 string ImagePosition = "Left";
1336 <div class="feature-blogs my-5">
1337
1338 <div class="row">
1339
1340 @foreach (var Blog in RelatedBlogs)
1341 {
1342 @RenderLargeBlogTeaser(Blog, ImagePosition)
1343 if (ImagePosition == "Left")
1344 {
1345 ImagePosition = "Right";
1346 }
1347 else
1348 {
1349 ImagePosition = "Left";
1350 }
1351 }
1352
1353 </div>
1354
1355 </div>
1356 }
1357
1358
1359 <div class="after-add-to-cart bg-white box-shadow" data-bind="css: { 'd-block': ProductAddedToCart }">
1360 <div class="closer fs3 pointer" data-bind="click: ProductAddedToCart(false)">
1361 <i class="fas fa-times-circle color-primary"></i>
1362 </div>
1363 <div class="p-3">
1364 <p class="font-weight-bold fs4 text-uppercase m-0">
1365 <i class="fas fa-check-circle color-primary"></i>
1366 @Translate("ProductProductAddedToCart", "Varen er lagt i indkøbskurven")
1367 </p>
1368 </div>
1369 <div class="mini-cart large-cart power-step">
1370
1371 <div class="position-relative">
1372 <div class="cart-command-loader unimportant-hidden justify-content-center align-items-center" data-bind="css: { 'd-flex': Loading }">
1373 <div class="d-flex align-items-center">
1374 <p class="m-0 mr-2">@Translate("Cart.UpdatingCart", "Opdaterer kurv")</p>
1375 <i class="fas fa-spinner fa-spin"></i>
1376 </div>
1377 </div>
1378
1379 <div class="lines" data-bind="foreach: Orderlines">
1380 <div class="cartline d-flex justify-content-between align-items-center px-3 py-2 position-relative bg-grey">
1381 <span class="delete-orderline color-subtle cursor-pointer mr-2" data-bind="click: $parent.DeleteOrderline.bind($data, OrderlineId)">
1382 <i class="fas fa-times"></i>
1383 </span>
1384 <div class="product-image w-10">
1385 <img class="img-fluid" data-bind="attr: { src: ImagePath }" />
1386 </div>
1387 <div class="flex-fill px-3 w-75">
1388 <p class="font-weight-bold m-0" data-bind="text: ProductName"></p>
1389 <p class="m-0 color-subtle small-quantity-indicator"><span data-bind="text: Quantity"></span> stk. a <span data-bind="text: QuantityPrice"></span></p>
1390 <div class="variant-dimensions" data-bind="foreach: VariantDimensions">
1391 <p class="m-0 color-subtle color-dark-grey font-weight-bold">
1392 <span data-bind="text: Label"></span>
1393 <span class="font-weight-normal" data-bind="text: Value"></span>
1394 </p>
1395 </div>
1396 </div>
1397 <div class="qty-counter w-10">
1398 <div class="d-flex">
1399 <div class="quantity-controls d-flex align-items-center mr-3">
1400 <div class="control minus" data-bind="click: $parent.QuantityControl.bind($data, -1, OrderlineId)">
1401 -
1402 </div>
1403 <input disabled type="text" name="Quantity" value="1" data-bind="value: Quantity, attr: { 'data-id': 'js-input-' + OrderlineId }" />
1404 <div class="control plus" data-bind="click: $parent.QuantityControl.bind($data, 1, OrderlineId)">
1405 +
1406 </div>
1407 </div>
1408 </div>
1409 </div>
1410
1411 <p class="fs0 m-0 orderline-price" data-bind="text: OrderlinePrice"></p>
1412 </div>
1413 </div>
1414 @if (BlackFridayTheme == "True")
1415 {
1416 <div class="bf-bg-black p-3 d-flex justify-content-between align-items-center price-summary">
1417 <p class="m-0 color-white fs-12px font-weight-semibold">@Translate("MiniCartTotal", "Din kurv i alt (ex. fragt)")</p>
1418 <p class="m-0 color-white fs1 font-weight-bold" data-bind="text: CartTotalNoFees"></p>
1419 </div>
1420 }
1421 else
1422 {
1423 <div class="bg-brand p-3 d-flex justify-content-between align-items-center price-summary">
1424 <p class="m-0 color-white fs-12px font-weight-semibold">@Translate("MiniCartTotal", "Din kurv i alt (ex. fragt)")</p>
1425 <p class="m-0 color-white fs1 font-extra-bold" data-bind="text: CartTotalNoFees"></p>
1426 </div>
1427 }
1428 </div>
1429
1430 </div>
1431 <div class="p-3 d-flex justify-content-between">
1432 <p class="pointer py-2 px-3 bg-dark-grey color-white rounded m-0" data-bind="click: ProductAddedToCart(false)">@Translate("MiniCartContinueShopping", "Handel videre")</p>
1433
1434 @if (BlackFridayTheme == "True")
1435 {
1436 <a href="@CartPage" class="pointer py-2 px-3 bf-bg-black color-white rounded d-block no-underline">@Translate("MiniCartGoToCheckout", "Gå til kassen")</a>
1437 }
1438 else
1439 {
1440 <a href="@CartPage" class="pointer py-2 px-3 bg-brand color-white rounded d-block no-underline">@Translate("MiniCartGoToCheckout", "Gå til kassen")</a>
1441 }
1442
1443 </div>
1444 <div class="js-customers-also-saw-lines"></div>
1445
1446 </div>
1447 <div class="variant-picker" data-bind="css: { 'open': VariantPickerOpen }">
1448 <div class="closer color-primary fs5 pointer" data-bind="click: ToggleVariantPicker">
1449 <i class="fas fa-times-circle"></i>
1450 </div>
1451 <div class="container py-5 position-relative">
1452 <h3 class="fs4 text-center">Design din @ProductName</h3>
1453 @{
1454 var ColorDimensions = GetLoop("VariantGroups").Where(g => g.GetString("Ecom:VariantGroup.Name").ToLower().Contains("farve"));
1455 var NonColorDimensions = GetLoop("VariantGroups").Where(g => !g.GetString("Ecom:VariantGroup.Name").ToLower().Contains("farve"));
1456 int FilterCounter = 0;
1457 string RowClass = NonColorDimensions.Any() && ColorDimensions.Any() ? "flex-row-reverse" : "";
1458 }
1459 <div class="row mt-5 @RowClass">
1460 @if (ColorDimensions.Any())
1461 {
1462 <div class="col-12 col-md-8">
1463 @foreach (var VariantDimension in ColorDimensions)
1464 {
1465 string DimensionName = VariantDimension.GetString("Ecom:VariantGroup.Name");
1466 string FilterName = "filter-" + FilterCounter;
1467 FilterCounter++;
1468 <div class="mb-5 mb-md-0">
1469 <p class="font-weight-bold fs2 mb-2">@DimensionName</p>
1470 <div class="row custom-row">
1471 @foreach (var VariantOption in VariantDimension.GetLoop("VariantAvailableOptions").OrderBy(v => v.GetString("Ecom:VariantOption.Name")))
1472 {
1473 string VariantOptionName = VariantOption.GetString("Ecom:VariantOption.Name");
1474 string VariantOptionId = VariantOption.GetString("Ecom:VariantOption.ID");
1475 string Preview = VariantOption.GetString("Ecom:VariantOption.ImgSmall.Clean");
1476 string PreviewCss = "";
1477 if (!String.IsNullOrEmpty(Preview))
1478 {
1479 if (Preview.StartsWith("#"))
1480 {
1481 PreviewCss = "style= \"background-color: " + Preview + ";\"";
1482 }
1483 else
1484 {
1485 PreviewCss = "style=\"background-image: url('" + Preview + "');\"";
1486 }
1487 }
1488 <div class="col-2 col-sm-3 col-md-2 mb-3 d-flex flex-column justify-content-end pointer color-variant" data-bind="click: AddToFilter.bind($data, $element, '@FilterName', '@VariantOptionId')">
1489 <p class="mb-0 color-variant-name d-none d-sm-block">@VariantOptionName</p>
1490 <div class="variant-preview position-relative d-flex" @PreviewCss></div>
1491 </div>
1492 }
1493 </div>
1494 </div>
1495 }
1496 </div>
1497 }
1498 @if (NonColorDimensions.Any())
1499 {
1500 <div class="col-12 col-sm-6 col-md-4">
1501 @foreach (var VariantDimension in NonColorDimensions)
1502 {
1503 string DimensionName = VariantDimension.GetString("Ecom:VariantGroup.Name");
1504 string FilterName = "filter-" + FilterCounter;
1505 FilterCounter++;
1506 <div class="mb-5">
1507 <p class="font-weight-bold fs2 mb-2">@DimensionName</p>
1508 <div class="row custom-row">
1509 @foreach (var VariantOption in VariantDimension.GetLoop("VariantAvailableOptions").OrderBy(v => v.GetString("Ecom:VariantOption.Name")))
1510 {
1511 string VariantOptionName = VariantOption.GetString("Ecom:VariantOption.Name");
1512 string VariantOptionId = VariantOption.GetString("Ecom:VariantOption.ID");
1513 string Preview = VariantOption.GetString("Ecom:VariantOption.ImgSmall.Clean");
1514 string PreviewCss = "";
1515 if (!String.IsNullOrEmpty(Preview))
1516 {
1517 if (Preview.StartsWith("#"))
1518 {
1519 PreviewCss = "style= \"background-color: " + Preview + ";\"";
1520 }
1521 else
1522 {
1523 PreviewCss = "style=\"background-image: url('/Files" + Preview + "');\"";
1524 }
1525 }
1526 if (DimensionName == "STØRRELSE")
1527 {
1528 <div class="col-6 col-sm-4 mb-3 d-flex flex-column justify-content-end pointer size-variant" data-bind="click: AddToFilter.bind($data, $element, '@FilterName', '@VariantOptionId')">
1529 <div class="variant-preview position-relative d-flex justify-content-center align-items-center" @PreviewCss>
1530 <p class="mb-0 color-variant-name font-weight-bold">@VariantOptionName</p>
1531 </div>
1532 </div>
1533 }
1534 else
1535 {
1536 <div class="col-6 col-sm-4 mb-3 d-flex flex-column justify-content-end pointer" data-bind="click: AddToFilter.bind($data, $element, '@FilterName', '@VariantOptionId')">
1537 <p class="mb-0 color-variant-name">@VariantOptionName</p>
1538 <div class="variant-preview position-relative d-flex" @PreviewCss></div>
1539 </div>
1540 }
1541 }
1542 </div>
1543 </div>
1544 }
1545 </div>
1546 }
1547
1548 <div class="col-12 d-flex justify-content-end">
1549 <p class="color-primary pointer my-3" data-bind="click: ResetFilters">Nulstil</p>
1550 </div>
1551 </div>
1552 <p class="font-weight-bold fs2 mt-5">
1553 @Translate("ChooseProduct", "Vælg produkt")
1554 </p>
1555 <div class="row align-items-end" data-bind="foreach: FilteredVariants">
1556 <div class="col-12 col-sm-6 col-md-3 mb-3">
1557 <a class="color-black no-underline" data-bind="attr: { href: Link }">
1558 <p class="fs0 font-weight-bold m-0" data-bind="text: Name"></p>
1559 <img class="img-fluid box-shadow my-1" data-bind="attr: { src: Image }" />
1560 <div class="d-flex justify-content-center mt-2">
1561 <div class="btn btn-primary">@Translate("VariantChooseProduct", "Vælg")</div>
1562 </div>
1563 </a>
1564 </div>
1565 </div>
1566 <div data-bind="visible: FilteredVariants().length == 0">
1567 <p class="font-weight-bold mt-3 fs3">@Translate("VariantsNoResults", "Filtreringen gav ingen resultater")</p>
1568 </div>
1569 </div>
1570 </div>
1571 </div>
1572
1573 @SnippetStart("DataLayerOverwrites")
1574 <script>
1575 ecomm_pagetype = "Product";
1576 ecomm_totalvalue = @GetString("Ecom:Product.Price.Price").Replace(".","").Replace(",",".");
1577 ecomm_prodid = "@GetString("Ecom:Product.ID")";
1578 </script>
1579 @SnippetEnd("DataLayerOverwrites")
1580