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