Error executing template "Designs/Rapido/eCom/Product/Product.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<RenderStickers>b__14_0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 522
at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<RenderImage>b__15_0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 595
at RazorEngine.Templating.TemplateWriter.ToString()
at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue()
at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 204
at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 146
at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 226
at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 135
at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 226
at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 146
at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<RenderProductTop>b__56_0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 2875
at RazorEngine.Templating.TemplateWriter.ToString()
at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue()
at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 204
at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 118
at CompiledRazorTemplates.Dynamic.RazorEngine_e36c43d94e9048ff83135f059de8869d.Execute() in D:\Dynamicweb.net\Solutions\skabertrang\naturdrogeriet.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 2865
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.<RunCompile>b__0(TextWriter writer)
at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
@using System.Web
@using Dynamicweb.Extensibility
@using Dynamicweb.Content
@using System
@using System.IO
@using Dynamicweb.Core
@using System.Web
@using System.Globalization
@using System.Web.UI.HtmlControls
@using Dynamicweb.Rapido.Blocks
@using Dynamicweb.Ecommerce
@functions {
List<LoopItem> downloadDocuments = new List<LoopItem>();
//downloadDocuments variable, will be defined in Fields.cshtml and used in ProductAssets.cshtml
BlocksPage productsPage = BlocksPage.GetBlockPage("Product");
public static string ToPascalCase(string str) {
return CultureInfo.InvariantCulture.TextInfo
.ToTitleCase(str.ToLowerInvariant())
.Replace("-", "")
.Replace("_", "")
.Replace(" ", "");
}
}
@{
bool isB2BCustomer = Pageview.User != null && Pageview.User.GroupsIds.Contains(91);
if (isB2BCustomer && GetBoolean("Ecom:Product:Field.Hide_In_B2B")) {
var productsList = Dynamicweb.Services.Pages.GetPageByNavigationTag(Pageview.AreaID, "ProductsPage");
if (productsList != null) {
Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + productsList.ID);
} else {
Dynamicweb.Context.Current.Response.Redirect("/");
}
Dynamicweb.Context.Current.Response.End();
}
string productBlocksPosition = Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition").SelectedValue : "thumbs-image-info";
bool productInfoOnTheRight = productBlocksPosition.LastIndexOf("info") == productBlocksPosition.Length - 4;
Block productTop = new Block() {
Id = "Top",
SortId = 10,
SkipRenderBlocksList = true,
Template = RenderProductTop()
};
productsPage.Add(productTop);
Block productMainInfo = new Block() {
Id = "MainInformation",
SortId = productInfoOnTheRight ? 20 : 10,
Design = new Design {
Size = "auto",
RenderType = RenderType.Column
}
};
productsPage.Add("Top", productMainInfo);
//Optional mini tabs block
Block miniTabsBlock = new Block() {
Id = "MiniTabs",
SortId = 40,
Template = RenderProductMiniTabs(),
SkipRenderBlocksList = true
};
productsPage.Add("MainInformation", miniTabsBlock);
//-----
Block productTabsBlock = new Block() {
Id = "Tabs",
SortId = 30,
Template = RenderProductTabs(),
SkipRenderBlocksList = true
};
productsPage.Add(productTabsBlock);
Block productDetailsBlock = new Block() {
Id = "Section",
SortId = 30
};
productsPage.Add(productDetailsBlock);
Block productSnippetsBlock = new Block() {
Id = "Snippets",
SortId = 40
};
productsPage.Add(productSnippetsBlock);
}
@* Include the required Grid builder (Contains the methods @RenderBlockList and @RenderBlock) *@
@using System.Text.RegularExpressions
2 @using System.Collections.Generic
3 @using System.Reflection
4 @using System.Web.UI.HtmlControls
5 @using Dynamicweb.Rapido.Blocks.Components
6 @using Dynamicweb.Rapido.Blocks.Components.Articles
7 @using Dynamicweb.Rapido.Blocks.Components.Documentation
8 @using Dynamicweb.Rapido.Blocks
9
10
11 @*--- START: Base block renderers ---*@
12
13 @helper RenderBlockList(List<Block> blocks)
14 {
15 blocks = blocks.OrderBy(item => item.SortId).ToList();
16
17 foreach (Block item in blocks)
18 {
19 <!-- START: @item.Id -->
20
21 if (item.Design == null)
22 {
23 @RenderBlock(item)
24 }
25 else if (item.Design.RenderType == RenderType.None) {
26 string cssClass = item.Design.CssClass != null ? item.Design.CssClass : "";
27
28 <div class="@cssClass dw-mod">
29 @RenderBlock(item)
30 </div>
31 }
32 else if (item.Design.RenderType != RenderType.Hide)
33 {
34 string cssClass = item.Design.CssClass != null ? item.Design.CssClass : "";
35
36 if (!item.SkipRenderBlocksList) {
37 if (item.Design.RenderType == RenderType.Row)
38 {
39 <div class="grid grid--align-content-start @cssClass dw-mod" id="Block__@item.Id">
40 @RenderBlock(item)
41 </div>
42 }
43
44 if (item.Design.RenderType == RenderType.Column)
45 {
46 string hidePadding = item.Design.HidePadding ? "u-no-padding" : "";
47 string size = item.Design.Size ?? "12";
48 size = Regex.IsMatch(size, @"\d") ? "md-" + item.Design.Size : item.Design.Size;
49
50 <div class="grid__col-lg-@item.Design.Size grid__col-md-@item.Design.Size grid__col-sm-12 grid__col-xs-12 @hidePadding @cssClass dw-mod" id="Block__@item.Id">
51 @RenderBlock(item)
52 </div>
53 }
54
55 if (item.Design.RenderType == RenderType.Table)
56 {
57 <table class="table @cssClass dw-mod" id="Block__@item.Id">
58 @RenderBlock(item)
59 </table>
60 }
61
62 if (item.Design.RenderType == RenderType.TableRow)
63 {
64 <tr class="@cssClass dw-mod" id="Block__@item.Id">
65 @RenderBlock(item)
66 </tr>
67 }
68
69 if (item.Design.RenderType == RenderType.TableColumn)
70 {
71 <td class="@cssClass dw-mod" id="Block__@item.Id">
72 @RenderBlock(item)
73 </td>
74 }
75
76 if (item.Design.RenderType == RenderType.CardHeader)
77 {
78 <div class="card-header @cssClass dw-mod">
79 @RenderBlock(item)
80 </div>
81 }
82
83 if (item.Design.RenderType == RenderType.CardBody)
84 {
85 <div class="card @cssClass dw-mod">
86 @RenderBlock(item)
87 </div>
88 }
89
90 if (item.Design.RenderType == RenderType.CardFooter)
91 {
92 <div class="card-footer @cssClass dw-mod">
93 @RenderBlock(item)
94 </div>
95 }
96 }
97 else
98 {
99 @RenderBlock(item)
100 }
101 }
102
103 <!-- END: @item.Id -->
104 }
105 }
106
107 @helper RenderBlock(Block item)
108 {
109 if (item.Template != null)
110 {
111 @BlocksPage.RenderTemplate(item.Template)
112 }
113
114 if (item.Component != null)
115 {
116 string methodName = item.Component.HelperName;
117 dynamic[] methodParameters = new dynamic[1];
118 methodParameters[0] = item.Component;
119 Type methodType = this.GetType();
120 MethodInfo generalMethod = methodType.GetMethod(methodName);
121
122 if (generalMethod != null) {
123 @generalMethod.Invoke(this, methodParameters).ToString();
124 } else {
125 throw new Exception(item.Component.GetType().Name + " method '" + methodName +"' could not be invoked");
126 }
127 }
128
129 if (item.BlocksList.Count > 0 && !item.SkipRenderBlocksList)
130 {
131 @RenderBlockList(item.BlocksList)
132 }
133 }
134
135 @*--- END: Base block renderers ---*@
136
@* Include the Blocks for the page *@
@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
137 @using Dynamicweb.Core
138 @using System
139 @using System.Web
140 @using System.Collections.Generic
141 @using Dynamicweb.Rapido.Blocks
142
143 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
144 @using System.Linq;
145
146 @functions{
147 public class Sticker {
148 public string className { get; set; }
149 public string text { get; set; }
150 public string groupColor { get; set; }
151 public string image { get; set; }
152 public string imageSrc { get; set; }
153 }
154
155 public class StickersContainer {
156 public string position { get; set; }
157 public List<Sticker> Stickers { get; set; }
158 }
159
160 public void AddSticker(List<StickersContainer> list, Sticker sticker, string stickerPosition) {
161 StickersContainer stickersContainerTemp;
162 if (string.IsNullOrEmpty(stickerPosition)) {
163 stickerPosition = "top-left";
164 }
165 stickersContainerTemp = list.FirstOrDefault(stickersContainer => stickersContainer.position == stickerPosition);
166 if (stickersContainerTemp == null) {
167 stickersContainerTemp = new StickersContainer() {
168 position = stickerPosition,
169 Stickers = new List<Sticker>()
170 };
171 list.Add(stickersContainerTemp);
172 }
173 stickersContainerTemp.Stickers.Add(sticker);
174 }
175
176 public List<StickersContainer> GetStickersContainersList(List<LoopItem> discountsLoop, double discountPrice, double price, DateTime createdDate, string customStickerValue, string groupName, string newGroupColor) {
177 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly");
178 bool isSaleStickersEnabled = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetBoolean("Enable");
179 bool isNewsStickersEnabled = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetBoolean("Enable");
180 bool isCustomStickersEnabled = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetBoolean("Enable");
181 bool b2cUser = false;
182 if (Pageview.User == null || Pageview.User != null && Pageview.User.HasGroup(7913)) {
183 b2cUser = true;
184 }
185
186 List<StickersContainer> resultList = new List<StickersContainer>();
187
188 if (!pointShopOnly && isSaleStickersEnabled && b2cUser) {
189 string contentType = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetString("ContentType");
190 contentType = !string.IsNullOrEmpty(contentType) ? contentType : "Name";
191 var currency = Dynamicweb.Ecommerce.Services.Currencies.GetDefaultCurrency();
192 Sticker saleSticker = new Sticker();
193 saleSticker.className = "stickers-container__tag--sale";
194
195 switch (contentType) {
196 case "Name":
197 foreach (LoopItem discount in discountsLoop) {
198 saleSticker.text = discount.GetString("Ecom:Product.Discount.Name");
199 saleSticker.image = discount.GetString("Ecom:Product.Discount.CampaignImage");
200 if (!string.IsNullOrEmpty(saleSticker.image)) {
201 int startPath = saleSticker.image.IndexOf("src=\"")+5;
202 saleSticker.imageSrc = saleSticker.image.Substring(startPath, saleSticker.image.IndexOf("\" ") - startPath);
203 }
204 saleSticker.groupColor = discount.GetString("Ecom:Product.Discount.CampaignColor");
205 }
206 break;
207 case "Amount":
208 if (discountsLoop.Count > 0) {
209 saleSticker.text = Dynamicweb.Ecommerce.Services.Currencies.Format(currency, discountPrice - price);
210 }
211 break;
212 case "Percents":
213 double percents = 0;
214 foreach (LoopItem discount in discountsLoop) {
215 percents += discount.GetDouble("Ecom:Product.Discount.PercentWithoutVAT");
216 }
217 if (percents > 0) {
218 saleSticker.text = Math.Round(percents, 0) + "%";
219 }
220 break;
221 case "Amount+and+percents":
222 double amount = 0;
223 double percent = 0;
224 foreach (LoopItem discount in discountsLoop) {
225 if (discount.GetString("Ecom:Product.Discount.Type") == "PERCENT") {
226 percent += discount.GetDouble("Ecom:Product.Discount.PercentWithoutVAT");
227 } else if (discount.GetString("Ecom:Product.Discount.Type") == "AMOUNT") {
228 amount += discount.GetDouble("Ecom:Product.Discount.AmountWithVAT");
229 }
230 }
231
232 if (percent > 0) {
233 saleSticker.text = percent + "%";
234 } else if (amount > 0) {
235 saleSticker.text = "-" + Dynamicweb.Ecommerce.Services.Currencies.Format(currency, amount);
236 }
237 break;
238 default:
239 if (discountsLoop.Count > 0) {
240 saleSticker.text = Translate("Sale!");
241 }
242 break;
243 }
244
245 string saleStickerPosition = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetList("Position") != null ?
246 Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetList("Position").SelectedValue : "topLeft";
247 if (!string.IsNullOrEmpty(saleSticker.text)) {
248 AddSticker(resultList, saleSticker, saleStickerPosition);
249 }
250 }
251
252 if (!pointShopOnly && isNewsStickersEnabled && createdDate.AddDays(Converter.ToDouble(Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetString("Expiration"))) > DateTime.Now) {
253 Sticker newSticker = new Sticker();
254 newSticker.className = "stickers-container__tag--new";
255 newSticker.text = Translate("New!");
256 string newStickerPosition = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetList("Position") != null ?
257 Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetList("Position").SelectedValue : "topLeft";
258 AddSticker(resultList, newSticker, newStickerPosition);
259 }
260
261 if (!pointShopOnly && isCustomStickersEnabled && !string.IsNullOrEmpty(customStickerValue)) {
262 Sticker customSticker = new Sticker();
263 customSticker.className = "stickers-container__tag--custom";
264 customSticker.text = customStickerValue;
265 string customStickerPosition = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetList("Position") != null ?
266 Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetList("Position").SelectedValue : "topLeft";
267 AddSticker(resultList, customSticker, customStickerPosition);
268 }
269 if (!string.IsNullOrWhiteSpace(groupName)) {
270 Sticker groupSticker = new Sticker();
271 groupSticker.className = "stickers-container__tag--group";
272 groupSticker.text = groupName;
273 if (!string.IsNullOrWhiteSpace(newGroupColor)) {
274 groupSticker.className += " " + newGroupColor;
275 }
276
277 //følger bare custom sticker pos. kan evt. udvides efter behov.
278 string groupStickerPosition = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetList("Position") != null ?
279 Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetList("Position").SelectedValue : "topLeft";
280 AddSticker(resultList, groupSticker, groupStickerPosition);
281
282 }
283
284 return resultList;
285 }
286 }
287 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
288
289
290 @*
291 This is a temporary fallback for the DefaultImage. The image pattern MUST be set up like this:
292
293 ImageSmall = /{ProductNumber}.jpg
294 ImageMedium = /{ProductNumber}{VariantOptionLevel1}.jpg
295 ImageLarge = /{ProductNumber}{VariantComboName}.jpg
296
297 In addition to the ImageDefault setting
298 *@
299
300 @functions {
301 public string GetProductImage(LoopItem productObject = null)
302 {
303 string theImage = "";
304
305 if (productObject == null) {
306 theImage = GetString("Ecom:Product.ImageDefault.Default.Clean");
307 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageLarge.Clean") : theImage;
308 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageMedium.Clean") : theImage;
309 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageSmall.Clean") : theImage;
310 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageLarge.Default.Clean") : theImage;
311 } else {
312 theImage = productObject.GetString("Ecom:Product.ImageDefault.Default.Clean");
313 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageLarge.Clean") : theImage;
314 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageMedium.Clean") : theImage;
315 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageSmall.Clean") : theImage;
316 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageLarge.Default.Clean") : theImage;
317 }
318
319 return theImage;
320 }
321 }
322
323 @functions {
324 BlocksPage mainImagePage = BlocksPage.GetBlockPage("Product");
325 bool showThumbs;
326 bool thumbsOnTheSide;
327 }
328
329 @{
330 string imageBlockWidth = Pageview.AreaSettings.GetItem("ProductPage").GetList("TopLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("TopLayout").SelectedValue : "6";
331 string blocksPosition = Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition").SelectedValue : "thumbs-image-info";
332 bool infoOnTheRight = blocksPosition.LastIndexOf("info") == blocksPosition.Length - 4;
333 showThumbs = blocksPosition.IndexOf("thumbs") != -1;
334 thumbsOnTheSide = showThumbs && blocksPosition.IndexOf("thumbsBottom") == -1;
335 bool thumbsOnTheLeft = blocksPosition.IndexOf("image") > blocksPosition.IndexOf("thumbs");
336 //imageBlockWidth = imageBlockPosition == "left-left" || imageBlockPosition == "left-right" ? Converter.ToString(12 - Converter.ToInt32(imageBlockWidth)) : imageBlockWidth;
337
338 Block mainImageBlock = new Block()
339 {
340 Id = "MainImage",
341 SortId = infoOnTheRight ? 10 : 20,
342 Design = new Design
343 {
344 Size = imageBlockWidth,
345 RenderType = RenderType.Column
346 },
347 BlocksList = new List<Block>
348 {
349 new Block {
350 Id = "MainImageRow",
351 SortId = 10,
352 Design = new Design
353 {
354 RenderType = RenderType.Row
355 },
356 BlocksList = new List<Block>
357 {
358 new Block
359 {
360 Id = "Carousel",
361 SortId = 10,
362 Template = RenderThumbnails(),
363 Design = new Design
364 {
365 Size = thumbsOnTheSide ? "2" : "12",
366 RenderType = RenderType.Column,
367 CssClass = thumbsOnTheSide ? "u-hidden-xxs" : ""
368 }
369 }
370 }
371 }
372 }
373 };
374 mainImagePage.Add("Top", mainImageBlock);
375
376 mainImagePage.Add("MainImageRow",
377 new Block()
378 {
379 Id = "ProductImageModal",
380 SortId = 0,
381 Template = RenderModal()
382 });
383
384 if (showThumbs)
385 {
386 mainImagePage.Add("MainImageRow",
387 new Block
388 {
389 Id = "Image",
390 SortId = thumbsOnTheLeft ? 20 : 0,
391 Template = RenderImage(),
392 Design = new Design
393 {
394 Size = thumbsOnTheSide ? "auto" : "12",
395 RenderType = RenderType.Column
396 }
397 });
398 }
399 }
400
401 @helper RenderModal()
402 {
403 <!-- Trigger for the gallery modal -->
404 <input type="checkbox" id="GalleryModalTrigger" class="modal-trigger" />
405
406 if (!string.IsNullOrEmpty(GetString("Ecom:Product.ImageLarge.Default.Clean")))
407 {
408 <!-- Gallery modal -->
409 <div class="modal-container">
410 <label for="GalleryModalTrigger" id="GalleryModalOverlay" class="modal-overlay"></label>
411 <div class="modal" id="GalleryModal">
412 <div class="modal__body modal__body--full">
413 @RenderCarousel("modalCarousel", 1, "horizontal", 3, true)
414 <label class="modal__close-btn dw-mod" for="GalleryModalTrigger"></label>
415 </div>
416 </div>
417 </div>
418 }
419 }
420
421 @helper RenderStickers()
422 {
423 var primaryProductGroup = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(GetString("Ecom:Product.PrimaryOrFirstGroupID"));
424 string groupColor = "" + primaryProductGroup.ProductGroupFieldValues.Where(x => x.ProductGroupField.SystemName == "StandardStickerColor").FirstOrDefault().Value;
425 bool isVariant = !string.IsNullOrWhiteSpace(GetString("Ecom:Product.VariantID"));
426
427 if (isVariant)
428 {
429 foreach (var i in Dynamicweb.Ecommerce.Products.Group.GetGroupsByProduct(Dynamicweb.Ecommerce.Products.Product.GetProductById(GetString("Ecom:Product.ID"))))
430 {
431 groupColor += i.ProductGroupFieldValues.Where(x => x.ProductGroupField.SystemName == "StandardStickerColor").FirstOrDefault().Value;
432 }
433 }
434 List<StickersContainer> StickersContainers = GetStickersContainersList(
435 GetLoop("ProductDiscounts"),
436 GetDouble("Ecom:Product.Discount.Price.Price"),
437 GetDouble("Ecom:Product.Price.Price"),
438 GetDate("Ecom:Product.Created"),
439 GetString("Ecom:Product:Field.CustomSticker.Value"),
440 GetString("Ecom:Group.Name"),
441 groupColor
442
443 );
444
445 @*foreach (StickersContainer stickersContainer in StickersContainers)
446 {
447 <div class="stickers-container stickers-container--@(stickersContainer.position) dw-mod">
448 @foreach (Sticker sticker in stickersContainer.Stickers)
449 {
450 <div class="stickers-container__tag @sticker.className dw-mod">@sticker.text</div>
451 }
452 </div>
453 }*@
454
455 foreach (StickersContainer stickersContainer in StickersContainers)
456 {
457 string isImageClass = "";
458
459 //if (!String.IsNullOrWhiteSpace(stickersContainer.Stickers(image)))
460 //{
461 // isImageClass = "withImage";
462 //}
463
464 bool anyWithImage = stickersContainer.Stickers.Any(x => String.IsNullOrWhiteSpace(x.image));
465 if (anyWithImage)
466 {
467 isImageClass = "withImage";
468 }
469
470 <div class="stickers-container stickers-container--@(stickersContainer.position) dw-mod @(isImageClass)">
471 @foreach (Sticker sticker in stickersContainer.Stickers.Where(x => String.IsNullOrWhiteSpace(x.image)))
472 {
473 <div class="stickers-container__tag @sticker.className dw-mod">
474 @sticker.text
475 </div>
476 }
477
478 @foreach (Sticker sticker in stickersContainer.Stickers.Where(x => !String.IsNullOrWhiteSpace(x.image)))
479 {
480 <div class="stickers-container__tag @sticker.className dw-mod sticker-with-image">
481 @sticker.image
482 </div>
483 }
484
485 </div>
486 }
487 }
488
489 @helper RenderImage()
490 {
491 string imagePrefix = "/Admin/Public/GetImage.ashx?width=800&height=800&crop=5&Format=jpg&FillCanvas=True&DoNotUpscale=true&Compression=75&image=";
492 string productId = GetString("Ecom:Product.ID");
493 string image = GetProductImage();
494
495 <label for="GalleryModalTrigger" class="product__image-container u-position-relative">
496 <img class="product__image-container__image dw-mod b-lazy" src="/Files/Images/placeholder.gif" data-src="@imagePrefix@image" alt="@GetString("Ecom:Product.Name")" id="Image_@productId" data-for="FullImage" data-number="0" onclick="modalCarousel.GoToSlide('modalCarousel', this.getAttribute('data-number'))" />
497 @RenderStickers()
498 </label>
499 }
500
501 @helper RenderThumbnails()
502 {
503 <div class="@(showThumbs ? "product__thumbs" : "") dw-mod">
504 @RenderCarousel(
505 "productCarousel",
506 !showThumbs ? 1 : 5,
507 thumbsOnTheSide ? "vertical" : "horizontal",
508 !showThumbs ? 3 : 2
509 )
510 @if (!showThumbs)
511 {
512 @RenderStickers()
513 }
514 </div>
515 }
516
517 @helper RenderCarousel(string id, int slidesInView, string direction, int preloaderSize, bool isModal = false)
518 {
519 <div class="carousel dw-mod" id="@id">
520 <div class="thumb-list carousel__container @(slidesInView != 1 ? "carousel__container--hidden" : "") js-carousel-slides dw-mod">
521 @*Main image thumb*@
522 @RenderProductImage(GetProductImage(), slidesInView == 1, isModal ? "modal--full__img" : "", true, isModal)
523
524 @foreach (LoopItem alternativeImage in GetLoop("Ecom:Product.AlternativeImages"))
525 {
526 if (!string.IsNullOrEmpty(alternativeImage.GetString("Ecom:Product.AlternativeImages.Image")))
527 {
528 @RenderProductImage(alternativeImage.GetString("Ecom:Product.AlternativeImages.Image"), slidesInView == 1, isModal ? "modal--full__img" : "", false, isModal)
529 }
530 }
531
532 @foreach (LoopItem detail in GetLoop("Details"))
533 {
534 if (!string.IsNullOrEmpty(detail.GetString("Ecom:Product:Detail.Image.Clean")))
535 {
536 string ext = Path.GetExtension(detail.GetString("Ecom:Product:Detail.Image.Clean")).ToLower();
537 if (ext == ".jpg" || ext == ".jpeg" || ext == ".gif" || ext == ".png")
538 {
539 @RenderProductImage(detail.GetString("Ecom:Product:Detail.Image.Clean"), slidesInView == 1, isModal ? "modal--full__img" : "", false, isModal)
540 }
541 }
542 }
543 </div>
544
545 <script>
546 document.addEventListener("DOMContentLoaded", function () {
547 @id = new CarouselModule('#@id', {
548 slidesInView: @slidesInView,
549 direction: "@direction",
550 preloaderSize: @preloaderSize,
551 showCounter: @isModal.ToString().ToLower()
552 });
553 });
554 </script>
555 </div>
556 }
557
558 @helper RenderProductImage(string image, bool isBig, string cssClass = "", bool isActive = false, bool isModal = false)
559 {
560 //Add product image to the og meta data
561 Pageview.Meta.AddTag("og:image", string.Format("{0}://{1}{2}", Dynamicweb.Context.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Host, GetProductImage()));
562
563 string productId = GetString("Ecom:Product.ID");
564 string thumbPrefix = "/Admin/Public/GetImage.ashx?width=200&height=200&crop=5&Format=jpg&FillCanvas=True&DoNotUpscale=true&Compression=75&image=";
565 string imagePrefix = "/Admin/Public/GetImage.ashx?width=800&height=800&crop=5&Format=jpg&FillCanvas=True&DoNotUpscale=true&Compression=75&image=";
566
567 <div class="carousel__slide dw-mod">
568 @if (isModal)
569 {
570 <img src="@imagePrefix@image" class="@cssClass" alt="@GetString("Ecom:Product.Name")">
571 }
572 else if (isBig)
573 {
574 <label for="GalleryModalTrigger">
575 <img src="@imagePrefix@image" alt="@GetString("Ecom:Product.Name")" class="js-gallery @cssClass" data-for="FullImage" data-image="@image" onclick="modalCarousel.GoToSlide('modalCarousel', this.closest('.carousel__slide').index());">
576 </label>
577 }
578 else
579 {
580 <div class="thumb-list__item dw-mod js-thumb js-gallery @(isActive ? "js-thumb--active thumb-list__item--active" : "")" data-for="Image_@productId" data-image="@imagePrefix@image" onmouseover="Gallery.openImage(this)">
581 <label for="GalleryModalTrigger">
582 <img src="@thumbPrefix@image" alt="@GetString("Ecom:Product.Name")" class="js-gallery @cssClass" data-for="FullImage" data-image="@imagePrefix@image" onclick="modalCarousel.GoToSlide('modalCarousel', this.closest('.carousel__slide').index());">
583 </label>
584 </div>
585 }
586 </div>
587 }
@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
588 @using Dynamicweb.Core
589 @using System
590 @using System.Web
591 @using System.Collections.Generic
592 @using Dynamicweb.Rapido.Blocks
593 @functions {
594 bool useFacebookPixel;
595 bool useGoogleTagManager;
596 BlocksPage mainInfoPage = BlocksPage.GetBlockPage("Product");
597 }
598
599 @{
600 //ck ændrede fra 1 til 10 for at omgå problem med at få vist pris. Kan muligvis have forårsaget andet visnings gejl.
601 bool mainInfoRenderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 10 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList");
602
603 useFacebookPixel = !string.IsNullOrWhiteSpace(Pageview.AreaSettings.GetItem("Settings").GetString("FacebookPixelID"));
604 useGoogleTagManager = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("GoogleTagManagerID"));
605 bool hidePrice = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HidePrice");
606 bool hideAddToCartButton = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("hideAddToCartButton");
607
608 Block mainInfoHeader = new Block()
609 {
610 Id = "MainInfoHeader",
611 SortId = 21,
612 Template = RenderMainInfoHeader()
613 };
614 mainInfoPage.Add("MainInformation", mainInfoHeader);
615
616 Block mainInfoDescription = new Block()
617 {
618 Id = "ShortDescription",
619 SortId = 30,
620 Template = RenderShortDescription()
621 };
622 mainInfoPage.Add("MainInformation", mainInfoDescription);
623
624 if (!mainInfoRenderVariantsAsProducts) {
625 Block mainInfoVariants = new Block()
626 {
627 Id = "Variants",
628 SortId = 50,
629 Template = RenderMainInfoVariants()
630 };
631 mainInfoPage.Add("MainInformation", mainInfoVariants);
632 }
633
634 Block mainInfoBOM = new Block()
635 {
636 Id = "BOM",
637 SortId = 60,
638 Template = RenderMainInfoBOM()
639 };
640 mainInfoPage.Add("MainInformation", mainInfoBOM);
641
642 if (!mainInfoRenderVariantsAsProducts) {
643 if (!hidePrice && !hideAddToCartButton) {
644 Block mainInfoBuy = new Block()
645 {
646 Id = "Buy",
647 SortId = 31,
648 Template = RenderMainInfoBuy()
649 };
650 mainInfoPage.Add("MainInformation", mainInfoBuy);
651 }
652
653 Block stockAndShipping = new Block()
654 {
655 Id = "StockAndShipping",
656 SortId = 90,
657 Template = RenderStockAndShipping()
658 };
659 mainInfoPage.Add("MainInformation", stockAndShipping);
660 }
661 }
662
663 @helper RenderMainInfoHeader()
664 {
665 bool renderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList");
666 string pageId = GetGlobalValue("Global:Page.ID").ToString();
667 string currentPrice = GetString("Ecom:Product.Discount.Price.PriceFormatted") == GetString("Ecom:Product.Price.PriceFormatted") ? GetString("Ecom:Product.Price.PriceFormatted") : GetString("Ecom:Product.Discount.Price.PriceFormatted");
668 // bool hideFavorites = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideFavoriteButton");
669 bool hideProductNumber = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideProductNumber");
670
671 bool useFontAwesomePro = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetBoolean("UseFontAwesomePro");
672 // var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star";
673 //string favoriteIcon = "fas fa-" + selectedFavoriteIcon;
674 // string favoriteOutlineIcon = "far fa-" + selectedFavoriteIcon;
675
676 //fix for displaying variant name - don't remove next line!
677 GetLoop("VariantCombinations");
678
679 string helsamLink = "http://www.helsam.dk/_cart.asp?action=add&ProductEAN=" + GetString("Ecom:Product.ID.UrlEncoded") + "&quantity=1";
680 string helsebixLink = "http://www.helsebixen.dk/shop/easyshopping/index/updatecart/?e_sku=" + GetString("Ecom:Product.ID.UrlEncoded") + "&e_qty=1";
681
682 bool b2cUser = false;
683 bool b2bUser = false;
684 if (Pageview.User != null) {
685 b2cUser = Pageview.User.GroupsIds.Contains(7913);
686 b2bUser = Pageview.User.GroupsIds.Contains(91);
687
688 } else {
689 b2cUser = true;
690 }
691
692 <div>
693 @if (!b2cUser) {
694 var findDealer = Dynamicweb.Services.Pages.GetPageByNavigationTag(Pageview.AreaID, "finddealer");
695
696 if (Pageview.User == null || !b2bUser) {
697 string discernibleHelsam = Translate("Køb") + " " + GetString("Ecom:Product.Name") + Translate("hos Helsam");
698 string discernibleHelsebixen = Translate("Køb") + " " + GetString("Ecom:Product.Name") + Translate("hos Helsebixen");
699 <div class="product_direct_sale">
700 @*<div class="find-shop-img">
701 <a href="@helsamLink" target="_blank" title="helsam - @Translate("Buy here")" class="" aria-label="@discernibleHelsam">
702 <img src="/Files/Images/Graphics/helsam.png" class="" alt="helsam" />
703 </a>
704 <a href="@helsebixLink" target="_blank" title="helsebixen.dk - @Translate("Buy here")" class="" aria-label="@discernibleHelsebixen">
705 <img src="/Files/Images/Graphics/helsebixen.png" class="" alt="helse bixen" />
706 </a>
707 </div>*@
708 @if (findDealer != null) {
709 string link = "/Default.aspx?ID=" + findDealer.ID;
710
711 <div class="find-shop-link">
712 <a href="@link" title="@Translate("Find shop")" class="btn btn--secondary dw-mod">
713 <i class="fal fa-map-signs"></i>
714 @Translate("Find shop")
715 </a>
716
717 </div>
718 }
719
720 </div>
721 }
722 }
723
724 <div class="u-pull--left product__title dw-mod">
725
726 <h1 class="u-no-margin">@GetString("Ecom:Product.Name") </h1>
727
728 <div class="item-number dw-mod">
729 <div class="item-number dw-mod">
730
731 @if (!hideProductNumber) {
732 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product.Number"))) {
733 <span class="item-number dw-mod">@Translate("Product number"): @GetString("Ecom:Product.Number")</span>
734 }
735
736 if (Pageview.User != null && Pageview.User.GroupsIds.Contains(91)) {
737
738 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.EAN"))) {
739 <span class="item-number item-ean-number dw-mod">| @Translate("EAN"): @GetString("Ecom:Product:Field.EAN")</span>
740 }
741 }
742 }
743 </div>
744
745 </div>
746 </div>
747
748 @{
749 bool hideFavorites = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideFavoriteButton");
750 // bool renderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList");
751
752 var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star";
753 string favoriteIcon = "fas fa-" + selectedFavoriteIcon;
754 string favoriteOutlineIcon = "far fa-" + selectedFavoriteIcon;
755 }
756 <div class="u-pull--right">
757 @*@if (!hideFavorites && Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")) && !renderVariantsAsProducts) {*@
758 @if (!hideFavorites && Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName"))) {
759
760 string favoriteId = "Favorite" + GetString("Ecom:Product.ID");
761 <div id="@favoriteId" class="favorites favorites--md u-pull--right js-favorite-btn dw-mod">
762 <div>
763 @{
764 string favorite = GetBoolean("Ecom:Product.IsProductInFavoriteList") ? favoriteIcon : favoriteOutlineIcon;
765 string AddToWishlist = "fbq('track', 'AddToWishlist', {" +
766 "content_name: '" + GetString("Ecom:Product.Name") + "'," +
767 "content_ids: ['" + GetString("Ecom:Product.Number") + "']," +
768 "value: " + GetDouble("Ecom:Product.Price.Price") + "," +
769 "currency: '" + GetString("Ecom:Product.Price.Currency.Code") + "'" +
770 "});";
771 }
772 <label for="FavoriteTrigger"><i class="@favorite fa-1_5x"></i></label>
773 </div>
774 <input type="checkbox" id="FavoriteTrigger" class="dropdown-trigger" />
775
776 <div class="dropdown">
777 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod">
778 <ul class="list list--clean dw-mod">
779 @if (GetLoop("CustomerCenter.ListTypes").Count > 0) {
780 foreach (LoopItem listType in GetLoop("CustomerCenter.ListTypes")) {
781 foreach (LoopItem list in listType.GetLoop("CustomerCenter.ProductLists")) {
782 string favLinkType = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? list.GetString("Ecom:Product.RemoveFromThisList") : list.GetString("Ecom:Product.AddToThisListAction");
783 string isInListIcon = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? favoriteIcon : favoriteOutlineIcon;
784 string listElementName = list.GetString("Ecom:CustomerCenter.List.Name") == "My favorites" ? Translate("My favorites") : list.GetString("Ecom:CustomerCenter.List.Name");
785 <li>
786 <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(list.GetString("Ecom:Product.List.IsProductInThisList") != "True" && useFacebookPixel ? AddToWishlist : "")"><i class="@isInListIcon"></i> @listElementName</a>
787 </li>
788 }
789 }
790 } else {
791 string favLinkType = GetString("Ecom:Product.AddToFavorites") + "&CCListType=0&CCCreateNewList=" + Translate("My favorites");
792 string isInListIcon = favoriteOutlineIcon;
793 <li>
794 <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(useFacebookPixel ? AddToWishlist : "")"><i class="@isInListIcon"></i> @Translate("My favorites")</a>
795 </li>
796 }
797 </ul>
798 </div>
799 <label class="dropdown-trigger-off" for="FavoriteTrigger"></label>
800 </div>
801 </div>
802 }
803 </div>
804 </div>
805 }
806
807 @helper RenderStockAndShipping()
808 {
809 bool hideStockState = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideStockState");
810 bool hideDelivery = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideShipping");
811 bool onlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null;
812
813 if (!onlyPreview && (!string.IsNullOrEmpty(GetString("Ecom:Product:Stock.Text")) || !string.IsNullOrEmpty(GetString("Ecom:Product:Stock.DeliveryText")))) {
814 string stockIcon = GetInteger("Ecom:Product.Stock") > 0 ? "stock-icon--in" : "stock-icon--not";
815
816 <div class="product__stock-delivery dw-mod">
817 @if (!hideStockState) {
818 @GetString("Ecom:Product:Stock.Text") <div class="stock-icon @stockIcon"></div>
819 }
820
821 @if (!String.IsNullOrEmpty(GetString("Ecom:Product:Stock.DeliveryText")) && !hideDelivery) {
822 <span>@Translate("Shipping")</span> <span>@GetString("Ecom:Product:Stock.DeliveryText")</span> <span>@GetString("Ecom:Product:Stock.DeliveryUnit")</span>
823 }
824 </div>
825 }
826 }
827
828 @helper RenderShortDescription()
829 {
830 var livsstilOptions = GetLoop("Livsstil.Options").Where(x => x.GetBoolean("Livsstil.Option.IsSelected"));
831
832 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product.ShortDescription"))) {
833 Pageview.Meta.AddTag("og:description", GetString("Ecom:Product.ShortDescription").Replace("<p>", "").Replace("</p>", "").Trim());
834 <div class="introduction-text">
835 @GetString("Ecom:Product.ShortDescription")
836 </div>
837 }
838 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Salgsfeatures"))) {
839 <p>@GetString("Ecom:Product:Field.Salgsfeatures")</p>
840 }
841 if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Anvendelse"))) {
842
843 <p class="mb-1"><strong>@Translate(GetString("Ecom:Product:Field.Anvendelse.Name")):. </strong> @GetString("Ecom:Product:Field.Anvendelse")</p>
844 }
845
846 if (livsstilOptions.Any()) {
847 <ul class="lifestyle-icons">
848 @foreach (var i in livsstilOptions) {
849 string iconSrc = "/Files/Images/Graphics/Icons/Lifestyle/" + i.GetString("Livsstil.Option.Value") + ".png";
850 string iconName = Translate(i.GetString("Livsstil.Option.Name"));
851 <li>
852 <img src="@iconSrc" title="@iconName" alt="@iconName" class="" />
853 </li>
854 }
855 </ul>
856 }
857
858 }
859
860 @helper RenderMainInfoVariants()
861 {
862 string pageId = GetGlobalValue("Global:Page.ID").ToString();
863 string productId = GetString("Ecom:Product.ID");
864 string variantSelection = !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("variantId")) ? HttpContext.Current.Request.QueryString.Get("variantId").Replace(".", ",") : "";
865 string hideHelpText = "";
866
867 foreach (LoopItem variantgroup in GetLoop("VariantGroups")) {
868 foreach (LoopItem variantoption in variantgroup.GetLoop("VariantAvailableOptions")) {
869 if (variantoption.GetBoolean("Ecom:VariantOption.Selected")) {
870 hideHelpText = "u-hidden";
871 }
872 }
873 }
874
875 if (GetLoop("VariantGroups").Count > 0) {
876 var variantCombinationsObject = new List<Array>();
877 foreach (LoopItem variantcomb in GetLoop("VariantStockCombinations")) {
878 string[] combinations = variantcomb.GetString("Ecom:VariantStockCombination.VariantID").Split('.');
879 variantCombinationsObject.Add(combinations);
880 }
881
882 string combinationsJson = Newtonsoft.Json.JsonConvert.SerializeObject(variantCombinationsObject).Replace("\"", "\'");
883
884 var variantGroupsObject = new List<List<String>>();
885 foreach (LoopItem variantGroup in GetLoop("VariantGroups")) {
886 var variantsObject = new List<String>();
887 foreach (LoopItem variantOption in variantGroup.GetLoop("VariantAvailableOptions")) {
888 variantsObject.Add(variantOption.GetString("Ecom:VariantOption.ID"));
889 }
890 variantGroupsObject.Add(variantsObject);
891 }
892 string variantsJson = Newtonsoft.Json.JsonConvert.SerializeObject(variantGroupsObject).Replace("\"", "\'");
893 string productGroupId = HttpContext.Current.Request["GroupId"];
894 <div>
895 <div class="js-variants" data-total-variant-groups="@GetLoop("VariantGroups").Count" data-combinations="@combinationsJson" data-variants="@variantsJson" data-variant-selections="@variantSelection" data-selection-complete="UpdatePage" data-page-id="@pageId" data-product-id="@productId" data-group-id="@productGroupId">
896 @foreach (LoopItem variantGroup in GetLoop("VariantGroups")) {
897 string groupId = variantGroup.GetString("Ecom:VariantGroup.ID");
898
899 <div>
900 <div class="product__variant-group-name u-bold dw-mod">@variantGroup.GetString("Ecom:VariantGroup.Name")</div>
901 <div class="u-margin-top">
902 @foreach (LoopItem variantOption in variantGroup.GetLoop("VariantAvailableOptions")) {
903 string selected = variantOption.GetBoolean("Ecom:VariantOption.Selected") ? "checked" : "";
904 string color = !String.IsNullOrEmpty(variantOption.GetString("Ecom:VariantOption.Colorcode")) ? variantOption.GetString("Ecom:VariantOption.Colorcode") : null;
905 color = color == null && !String.IsNullOrEmpty(variantOption.GetString("Ecom:VariantOption.Color")) ? variantOption.GetString("Ecom:VariantOption.Color") : color;
906
907 if (!string.IsNullOrEmpty(variantOption.GetString("Ecom:VariantOption.ImgSmall.Clean"))) {
908 string variantImage = "/Admin/Public/GetImage.ashx?width=100&height=50&crop=5&Compression=75&image=/Images/" + variantOption.GetString("Ecom: VariantOption.ImgSmall.Clean");
909 <img data-variant-id="@variantOption.GetString("Ecom:VariantOption.ID")" data-variant-group="@groupId" src="@variantImage" onclick="MatchVariants.SelectThis(event)" alt="@variantOption.GetString("Ecom:VariantOption.Name")" title="@variantOption.GetString("Ecom:VariantOption.Name")" class="btn btn--tag @selected js-variant-option" data-check="@selected" />
910 } else if (!String.IsNullOrEmpty(color)) {
911 <button type="button" data-variant-id="@variantOption.GetString("Ecom:VariantOption.ID")" data-variant-group="@groupId" onclick="MatchVariants.SelectThis(event)" class="btn btn--colorbox u-margin-right @selected js-variant-option" data-check="@selected" style="background-color: @color"></button>
912 } else {
913 <button type="button" data-variant-id="@variantOption.GetString("Ecom:VariantOption.ID")" data-variant-group="@groupId" onclick="MatchVariants.SelectThis(event)" class="btn btn--tag @selected js-variant-option" data-check="@selected">@variantOption.GetString("Ecom:VariantOption.Name")</button>
914 }
915 }
916 </div>
917 </div>
918 }
919 </div>
920 <small class="js-help-text help-text @hideHelpText">@Translate("Please select variant!")</small>
921 </div>
922 }
923 }
924
925 @helper RenderMainInfoBOM()
926 {
927 if (GetLoop("BOMProducts").Count > 0) {
928 <h2 class="section-title">@Translate("Including products")</h2>
929 foreach (LoopItem BOMProductItem in GetLoop("BOMProducts")) {
930 string link = "/" + BOMProductItem.GetString("Ecom:Product.LinkGroup.Clean") + (!String.IsNullOrEmpty(BOMProductItem.GetString("Ecom:Product.VariantID")) ? "&VariantID=" + BOMProductItem.GetString("Ecom:Product.VariantID") : "");
931 <div class="grid__col--border grid">
932 <div class="grid__cell grid__cell--align-middle-left">
933 <a href="@link" class="u-pull--left u-margin-right">
934 <img class="b-lazy" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=50&image=@GetProductImage(BOMProductItem)&Compression=99" alt="@BOMProductItem.GetString("Ecom:Product.Name")" />
935 </a>
936 <a href="@link">@BOMProductItem.GetString("Ecom:Product.Name")</a>
937 </div>
938 </div>
939 }
940 }
941 }
942
943 @helper RenderMainInfoBuy()
944 {
945 string pageId = GetGlobalValue("Global:Page.ID").ToString();
946 string variantId = HttpContext.Current.Request.QueryString.Get("variantId");
947 string productId = GetString("Ecom:Product.ID");
948 string feedId = pageId + "&ProductID=" + productId + "&VariantID=" + variantId + "&Feed=True&redirect=false";
949
950 //string productIndicativePrice = GetString("Ecom:Product:Field.Vejledendepris");
951
952
953 <div class="product__price-actions js-handlebars-root dw-mod" id="PriceAndActions" data-template="PricesAndActionsTemplate" data-json-feed="/Default.aspx?ID=@feedId" data-preloader="minimal"></div>
954 <input type="hidden" value="@GetString("Ecom:Product.VariantID.Extented")" name="Variant" id="Variant_@GetString("Ecom:Product.ID")" />
955 @RenderMainInfoBuyScripts()
956 }
957
958 @helper RenderMainInfoBuyScripts()
959 {
960
961
962 /* Custom user level start*/
963 int userRank = 99;
964 bool b2cUser = false;
965 bool b2bUser = false;
966 if (Pageview.User != null) {
967 b2cUser = Pageview.User.GroupsIds.Contains(7913);
968 b2bUser = Pageview.User.GroupsIds.Contains(91);
969 for (int i = 1; i <= 3; i++) {
970 if (Pageview.User.HasGroup(Pageview.AreaSettings.GetItem("Custom").GetItem("CustomSettings").GetInt32("EcomCustomerRank" + i))) {
971 userRank = i;
972 break;
973 }
974 }
975 }
976 /* Custom user level end*/
977 bool hidePrice = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HidePrice");
978 //Hiding cart options for lower user ranks
979 bool hideAddToCartButton = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("hideAddTshowVATPriceoCartButton") || userRank > 2;
980 bool onlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null || userRank > 2;
981 string b2cSoldoutDisable = "";
982
983 if (!b2bUser) {
984 hideAddToCartButton = false;
985
986 if (GetBoolean("Ecom:Product:Field.B2cCurrentlySoldout")) {
987 b2cSoldoutDisable = "disabled";
988 }
989 }
990
991 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly");
992 string variantId = HttpContext.Current.Request.QueryString.Get("variantId") ?? "";
993 string feedId = GetGlobalValue("Global:Page.ID").ToString() + "&ProductID=" + GetString("Ecom:Product.ID") + "&VariantID=" + variantId + "&Feed=True&redirect=false";
994 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart";
995 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("ShowBothPricesWithWithoutVAT");
996 bool isPricesWithVATEnabled = Converter.ToBoolean(Pageview.Area.EcomPricesWithVat);
997
998 @* Handlebars templates *@
999 <script id="PricesAndActionsTemplate" type="text/x-template">
1000 {{#.}}
1001 @if (!onlyPreview || !b2bUser) {
1002 if (!hidePrice) {
1003
1004 <div class="product__price-actions__price dw-mod u-margin-top--lg">
1005 @if (pointShopOnly) {
1006 <text>
1007 {{#if havePointPrice}}
1008 <div class="price price--product-page dw-mod">{{points}} @Translate("points")</div>
1009 {{else}}
1010 @Translate("Not available")
1011 {{/if}}
1012 </text>
1013 } else {
1014
1015 if (b2bUser) {
1016 <div class="u-flex grid--wrap">
1017 <div class="grid__col-md-6"></div>
1018 <div class="price price--product-page dw-mod">@Translate("Normal pris pr. stk.")</div>
1019 <div class="price price--product-page dw-mod" style="margin-left: auto">{{vejledendePris}}</div>
1020 </div>
1021 <div class="u-flex grid--wrap">
1022 <div class="grid__col-md-6"></div>
1023 <div class="price price--product-page dw-mod" style="font-size: 16px">@Translate("Din pris pr. stk.")</div>
1024 <div class="price price--product-page dw-mod" style="margin-left: auto; font-size: 16px">{{livePriceFormatted}}</div>
1025 </div>
1026 } else {
1027 <div class="before-price {{onSale}} dw-mod">{{discount}}</div>
1028 <div class="u-flex grid--wrap">
1029 <div class="grid__col-md-6"></div>
1030 @*<div class="price price--product-page dw-mod">Pris pr. stk.</div>*@
1031 @*<div class="price price--product-page dw-mod" style="margin-left: auto">{{priceWithVAT}} @GetString("Ecom:Product.Currency.Code")</div>*@
1032 <div class="price price--product-page dw-mod" style="margin-left: auto">{{priceWithVAT}}</div>
1033 </div>
1034 }
1035
1036 if (showVATPrice && false) {
1037
1038 <small class="vat-price vat-price--product-page u-margin-top dw-mod">
1039 @if (isPricesWithVATEnabled) {
1040 @Translate("excl. VAT") <text>({{priceWithoutVAT}})</text>
1041 } else {
1042 @Translate("incl. VAT") <text>({{priceWithVAT}})</text>
1043 }
1044 </small>
1045 }
1046 }
1047 </div>
1048
1049 <h5 class="color-primary fw-500 text-right u-margin-bottom u-margin-top">@Translate("Delivery costs may be added")</h5>
1050
1051 }
1052 if (!hideAddToCartButton) {
1053 <div class="buttons-collection buttons-collection--right product__price-actions__actions dw-mod u-margin-top--lg">
1054
1055 <input type="checkbox" id="UnitOptions_{{id}}" class="dropdown-trigger" />
1056 <div class="dropdown u-w150px u-w80px--xs use-btn-primary-height dw-mod {{hasUnits}}">
1057 <label class="dropdown__header dropdown__btn dw-mod" for="UnitOptions_{{id}}">{{unitName}}</label>
1058 <div id="unitOptions" class="dropdown__content dw-mod">
1059 {{#unitOptions}}
1060 {{>UnitOption}}
1061 {{/unitOptions}}
1062 </div>
1063 <label class="dropdown-trigger-off" for="UnitOptions_{{id}}"></label>
1064 </div>
1065
1066 @*<span class="package-size">
1067 @Translate("Kollistørrelse"): @GetString("Ecom:Product:Field.Kollistoerrelse")
1068 </span>*@
1069
1070 <input type="hidden" value="{{unitId}}" name="Unit" id="Unit_{{id}}" />
1071 @if (pointShopOnly) {
1072 <button type="button" id="CartButton_{{id}}" class="btn btn--primary btn--condensed u-no-margin dw-mod js-cart-btn {{disabledBuyButton}} {{#unless canBePurchasedWithPoints}}js-stay-disabled{{/unless}}" name="CartCmd" value="addWithPoints"
1073 onclick="Cart.AddToCart(event, {
1074 id: '{{productId}}',
1075 variantId: '{{variantid}}',
1076 unitId: '{{unitId}}',
1077 quantity: 1,
1078 buyForPoints: true,
1079 productInfo: {{productInfo}}
1080 }); {{facebookPixelAction}}">
1081 <i class="@cartIcon"></i><span class="u-hidden-xs u-hidden-xxs"> @Translate("Buy with points")</span>
1082 </button>
1083 <text>
1084 {{#unless canBePurchasedWithPoints}}
1085 {{#if havePointPrice}}
1086 <small class="help-text u-no-margin u-margin-top">@Translate("Not enough points to buy this")</small>
1087 {{/if}}
1088 {{/unless}}
1089 </text>
1090 } else {
1091
1092 <div class="u-flex grid--wrap u-margin-bottom" style="margin-right: 0">
1093 <div class="grid__col-md-6"></div>
1094 @if (b2bUser) {
1095 <div class="price price--product-page grid--align-self-center dw-mod" style="font-size: 16px">
1096 {{#if packageSize}}
1097 @Translate("Kollistørrelse"): {{packageSize}}
1098 {{/if}}
1099 </div>
1100 }
1101
1102 <div style="margin-left: auto">
1103
1104
1105 @if (!string.IsNullOrWhiteSpace(b2cSoldoutDisable)) {
1106 <button style="opacity:1 !important" disabled type="button" id="" class="btn btn--primary btn--condensed u-no-margin dw-mod js-cart-btn" name="submit">
1107 <span>@Translate("Currently soldout")</span>
1108 @*<span class="u-hidden-xs u-hidden-xxs"> @Translate("Currently soldout")</span>*@
1109 </button>
1110 } else {
1111 <input type="number" class="product__quantity-selector u-w70px use-btn-primary-height dw-mod" id="Quantity_{{id}}" name="Quantity" value="{{quantity}}" min="1" onchange="HandlebarsBolt.UpdateContent('PriceAndActions', '/Default.aspx?ID=@feedId&quantity=' + (+(this.value) <= 0 ? 1 : +(this.value)))" style="margin-bottom: 0">
1112 <button type="button" id="CartButton_{{id}}" class="btn btn--secondary btn--condensed u-no-margin dw-mod js-cart-btn" name="submit"
1113 onclick="Cart.AddToCart(event, {
1114 id: '{{productId}}',
1115 variantId: '{{variantid}}',
1116 unitId: '{{unitId}}',
1117 quantity: document.getElementById('Quantity_{{id}}').value,
1118 productInfo: {{productInfo}}
1119 }); {{facebookPixelAction}}">
1120 <i class="d-sm-block @cartIcon"></i>
1121 <span class="u-hidden-xs u-hidden-xxs"> @Translate("Add to cart")</span>
1122 </button>
1123 }
1124 </div>
1125 </div>
1126 if (b2bUser) {
1127 <div class="u-flex grid--wrap u-margin-bottom" style="margin-right: 0">
1128 <div class="grid__col-md-6"></div>
1129 <div class="price price--product-page dw-mod" style="font-size: 16px">@Translate("Total")</div>
1130 <div class="price price--product-page dw-mod" style="margin-left: auto; font-size: 16px">{{livePriceTotalFormatted}}</div>
1131 </div>
1132 }
1133
1134
1135 @*bool hideFavorites = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideFavoriteButton");
1136 bool renderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList");
1137
1138 var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star";
1139 string favoriteIcon = "fas fa-" + selectedFavoriteIcon;
1140 string favoriteOutlineIcon = "far fa-" + selectedFavoriteIcon;
1141
1142 <div class="">
1143 @if (!hideFavorites && Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")) && !renderVariantsAsProducts) {
1144 string favoriteId = "Favorite" + GetString("Ecom:Product.ID");
1145 <div id="@favoriteId" class="favorites favorites--md u-pull--right js-favorite-btn dw-mod">
1146 <div>
1147 @{
1148 string favorite = GetBoolean("Ecom:Product.IsProductInFavoriteList") ? favoriteIcon : favoriteOutlineIcon;
1149 string AddToWishlist = "fbq('track', 'AddToWishlist', {" +
1150 "content_name: '" + GetString("Ecom:Product.Name") + "'," +
1151 "content_ids: ['" + GetString("Ecom:Product.Number") + "']," +
1152 "value: " + GetDouble("Ecom:Product.Price.Price") + "," +
1153 "currency: '" + GetString("Ecom:Product.Price.Currency.Code") + "'" +
1154 "});";
1155 }
1156 <label for="FavoriteTrigger"><i class="@favorite"></i> @Translate("Add to favorites")</label>
1157 </div>
1158 <input type="checkbox" id="FavoriteTrigger" class="dropdown-trigger" />
1159
1160 <div class="dropdown">
1161 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod">
1162 <ul class="list list--clean dw-mod">
1163 @if (GetLoop("CustomerCenter.ListTypes").Count > 0) {
1164 foreach (LoopItem listType in GetLoop("CustomerCenter.ListTypes")) {
1165 foreach (LoopItem list in listType.GetLoop("CustomerCenter.ProductLists")) {
1166 string favLinkType = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? list.GetString("Ecom:Product.RemoveFromThisList") : list.GetString("Ecom:Product.AddToThisListAction");
1167 string isInListIcon = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? favoriteIcon : favoriteOutlineIcon;
1168 <li>
1169 <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(list.GetString("Ecom:Product.List.IsProductInThisList") != "True" && useFacebookPixel ? AddToWishlist : "")"><i class="@isInListIcon"></i> @list.GetValue("Ecom:CustomerCenter.List.Name")</a>
1170 </li>
1171 }
1172 }
1173 } else {
1174 string favLinkType = GetString("Ecom:Product.AddToFavorites") + "&CCListType=0&CCCreateNewList=" + Translate("My favorites");
1175 string isInListIcon = favoriteOutlineIcon;
1176 <li>
1177 <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(useFacebookPixel ? AddToWishlist : "")"><i class="@isInListIcon"></i> @Translate("My favorites")</a>
1178 </li>
1179 }
1180 </ul>
1181 </div>
1182 <label class="dropdown-trigger-off" for="FavoriteTrigger"></label>
1183 </div>
1184 </div>
1185 }
1186 </div>*@
1187 }
1188 </div>
1189 if (Pageview.User != null && !pointShopOnly && Dynamicweb.Security.Licensing.LicenseManager.LicenseHasFeature("LoyaltyPoints")) {
1190 <text>
1191 {{#if canBePurchasedWithPoints}}
1192 <form method="post" role="form" class="u-no-margin u-margin-top">
1193 <input type="hidden" name="ProductID" value="{{id}}" />
1194 <button type="submit" class="btn btn--loyalty-points u-no-margin dw-mod pull-right u-no-margin js-cart-btn {{disabledBuyButton}}" name="CartCmd" value="addWithPoints">@Translate("Buy for") {{points}} @Translate("points")</button>
1195 </form>
1196 {{/if}}
1197 </text>
1198 }
1199 } else {
1200 <button type="button" id="CartButton_{{id}}" class="u-hidden"></button>
1201 }
1202 } else {
1203 <div class="product__price-actions__price dw-mod u-margin-bottom--lg">
1204 @if (pointShopOnly) {
1205 // something.
1206 } else {
1207 @*<div class="before-price {{onSale}} dw-mod">{{discount}}</div>*@
1208
1209 <div class="price price--product-page dw-mod">
1210 {{#ifCond vejledendePrisDouble '>' 0}}
1211 @Translate("Vejl. pris"): @Translate("DKK") {{vejledendePris}}
1212 {{/ifCond}}
1213 </div>
1214 @*if(showVATPrice) {
1215 <small class="vat-price vat-price--product-page u-margin-top dw-mod">
1216 @if(isPricesWithVATEnabled) {
1217 @Translate("excl. VAT") <text>({{priceWithoutVAT}})</text>
1218 } else {
1219 @Translate("incl. VAT") <text>({{priceWithVAT}})</text>
1220 }
1221 </small>
1222 }*@
1223 }
1224 </div>
1225 }
1226 {{/.}}
1227 </script>
1228
1229 <script id="Units" type="text/x-template">
1230 <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent('PriceAndActions', '/Default.aspx?ID=@feedId&UnitID={{value}}')">{{{name}}}</div>
1231 </script>
1232
1233 <script id="UnitOption" type="text/x-template">
1234 <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent('PriceAndActions', '{{link}}&feed=true&UnitID={{value}}&rid={{id}}')">{{{name}}}</div>
1235 </script>
1236
1237
1238 <script>
1239 document.addEventListener("DOMContentLoaded", function () {
1240 if (document.getElementById("PriceAndActions")) {
1241 document.getElementById("PriceAndActions").addEventListener("contentLoaded", function (event) {
1242 if (document.querySelector(".js-variants") != null) {
1243 MatchVariants.Update(document.querySelector(".js-variants"), "DoNothing");
1244 }
1245 });
1246 }
1247 });
1248 </script>
1249 }
1250
1251 @if (useGoogleTagManager) {
1252 var groupObject = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(GetString("Ecom:Product.PrimaryOrFirstGroupID"));
1253 //var gtmPrice = (GetDouble("Ecom:Product.Discount.Price.Price") != GetDouble("Ecom:Product.Price.Price") ? GetDouble("Ecom:Product.Discount.Price.Price") : GetDouble("Ecom:Product.Price.Price"));
1254 var gtmPrice = GetDouble("Ecom:Product:Field.Vejledendepris.Value.Raw");
1255 <script>
1256 // Measure a view of product details. This example assumes the detail view occurs on pageload,
1257 // and also tracks a standard pageview of the details page.
1258
1259 dataLayer.push({
1260 "ecommerce": {
1261 "detail": {
1262 "actionField": {}, // 'detail' actions have an optional list property.
1263 "products": [{
1264 "name": "@GetString("Ecom:Product.Name")", // Name or ID is required.
1265 "id": "@GetString("Ecom:Product.ID")",
1266 "price": "@gtmPrice",
1267 "brand": "@GetString("Ecom:Product:Field.brand.Value")",
1268 "category": "@(groupObject != null ? groupObject.Name : "")",
1269 "variant": "@(!string.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) ? GetString("Ecom:Product.VariantID") : GetString("Ecom:Product.VariantID.Extented"))"
1270 }]
1271 }
1272 }
1273 });
1274 </script>
1275 }
@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
1276 @using Dynamicweb.Core
1277 @using System
1278 @using System.Web
1279 @using System.Collections.Generic
1280 @using Dynamicweb.Rapido.Blocks
1281 @functions {
1282 BlocksPage productAssetsPage = BlocksPage.GetBlockPage("Product");
1283 }
1284
1285 @{
1286 string productAssetsLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("ProductAssetsLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductAssetsLayout").SelectedValue : "Section";
1287 productAssetsLayout = productAssetsLayout == "Ribbon" ? "Section" : productAssetsLayout;
1288
1289 if (productAssetsLayout != "hide")
1290 {
1291 Block productAssetsBlock = new Block()
1292 {
1293 Name = productAssetsLayout != "MainInformation" ? Translate("Product assets") : "",
1294 Id = "ProductAssets",
1295 SortId = 10,
1296 @*downloadDocuments variable, declared in Product.cshtml and defined in Fields.cshtml*@
1297 Template = RenderProductAssets(productAssetsLayout, downloadDocuments),
1298 Design = new Design
1299 {
1300 Size = "12",
1301 RenderType = RenderType.Column,
1302 HidePadding = true
1303 }
1304 };
1305 productAssetsPage.Add(productAssetsLayout, productAssetsBlock);
1306 }
1307 }
1308
1309 @helper RenderProductAssets(string layout, List<LoopItem> documents)
1310 {
1311 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductAssetsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
1312 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductAssetsLayout").SelectedValue == "Ribbon" ? "u-padding--lg" : "";
1313 string exportPageId = GetPageIdByNavigationTag("ProductExportFeed").ToString();
1314
1315 //images
1316
1317 HashSet<string> images = new HashSet<string>();
1318
1319 images.Add(GetProductImage());
1320
1321 foreach (LoopItem alternativeImage in GetLoop("Ecom:Product.AlternativeImages"))
1322 {
1323 string alt_image = alternativeImage.GetString("Ecom:Product.AlternativeImages.Image");
1324
1325 if (!string.IsNullOrEmpty(alt_image))
1326 {
1327 images.Add(alt_image);
1328 }
1329 }
1330
1331 foreach (LoopItem detail in GetLoop("Details"))
1332 {
1333 string detail_image = detail.GetString("Ecom:Product:Detail.Image.Clean");
1334
1335 if (!string.IsNullOrEmpty(detail_image))
1336 {
1337 images.Add(detail_image);
1338 }
1339 }
1340
1341 <div class="product__section @ribbonClasses dw-mod">
1342 <div class="product__description center-container @ribbonSubClasses dw-mod">
1343 @if (layout == "Section")
1344 {
1345 <h2>@Translate("Product assets")</h2>
1346 }
1347
1348 <form action="/Default.aspx?ID=@exportPageId&ProductID=@System.Web.HttpContext.Current.Request.QueryString.Get("ProductID")&VariantID=@System.Web.HttpContext.Current.Request.QueryString.Get("VariantID")" method="post" class="u-flex grid--direction-column u-no-margin">
1349 <div class="grid">
1350 @if (images.Count > 0)
1351 {
1352 <div class="grid__col-md-4">
1353 <div class="u-margin-bottom">
1354 <input type="checkbox" class="u-no-margin form__control" id="allImages" onchange="selectAll(this)" />
1355 <label for="allImages" class="u-bold u-inline-block">@Translate("Images") (@(images.Count))</label>
1356 </div>
1357
1358 <ul class="panel-list">
1359 @foreach (string image in images)
1360 {
1361 @RenderPanelListItem(image)
1362 }
1363 </ul>
1364 </div>
1365 }
1366
1367 @if (documents.Count > 0)
1368 {
1369 <div class="grid__col-md-4">
1370 <div class="u-margin-bottom">
1371 <input type="checkbox" class="u-no-margin form__control" id="allDocuments" onchange="selectAll(this)" />
1372 <label for="allDocuments" class="u-bold u-inline-block">@Translate("Documents") (@documents.Count)</label>
1373 </div>
1374
1375 <ul class="panel-list">
1376 @foreach (LoopItem document in documents)
1377 {
1378 string fieldValue;
1379 if (!string.IsNullOrEmpty(document.GetString("Document.FullPath")))
1380 {
1381 fieldValue = document.GetString("Product.CustomField.Value.Clean");
1382 @RenderDocument(fieldValue)
1383 }
1384 if (document.GetString("Ecom:Product.CategoryField.TypeID") == "9")
1385 {
1386 fieldValue = document.GetString("Ecom:Product.CategoryField.Value");
1387 @RenderDocument(fieldValue)
1388 }
1389 }
1390 </ul>
1391 </div>
1392 }
1393 <div class="grid__col-md-4">
1394 <input id="ID" name="ID" type="hidden" value="532" />
1395 <input id="download" name="download" type="hidden" value="true" />
1396 <input name="siteUrl" type="hidden" value="@string.Format("{0}://{1}", GetGlobalValue("Global:Request.Scheme"), GetGlobalValue("Global:Request.Host"))" />
1397
1398 <div class="u-bold u-margin-bottom">@Translate("Export")</div>
1399
1400 <label for="exportLanguage">@Translate("Language")</label>
1401 <select id="exportLanguage" name="RequestLanguageId" class="u-full-width">
1402 @foreach (var lang in Services.Languages.GetLanguages().OrderBy(l => l.Name))
1403 {
1404 var selected = lang.IsDefault ? "selected" : "";
1405 <option value="@lang.LanguageId" @selected>@lang.Name</option>
1406 }
1407 </select>
1408
1409 <label for="purpose">@Translate("Image purpose")</label>
1410 <select id="purpose" name="purpose" class="u-full-width">
1411 <option value="Office">@Translate("Office")</option>
1412 <option value="Original">@Translate("Original")</option>
1413 <option value="Print">@Translate("Print")</option>
1414 <option value="Web">@Translate("Web")</option>
1415 </select>
1416
1417 <label for="exportFormat">@Translate("Export format")</label>
1418 <select id="exportFormat" name="format" class="u-full-width">
1419 <option value="csv">Csv</option>
1420 <option value="json">Json</option>
1421 <option value="xml">Xml</option>
1422 </select>
1423
1424 <input type="submit" value="@Translate("Download")" class="btn btn--full btn--primary u-no-margin dw-mod" title="@Translate("Download")" />
1425 </div>
1426 </div>
1427 </form>
1428 </div>
1429 </div>
1430 <script>
1431 function selectAll(checkbox) {
1432 Array.prototype.slice.call(checkbox.parentElement.nextElementSibling.getElementsByTagName('input')).forEach(function (input) {
1433 input.checked = checkbox.checked;
1434 });
1435 }
1436 </script>
1437 }
1438
1439 @helper RenderPanelListItem(string imageName)
1440 {
1441 <li class="panel-list__item">
1442 <div class="panel-list__item-check">
1443 <input type="checkbox" name="Image_@imageName" class="u-no-margin form__control" id="Image_@imageName" />
1444 <label for="Image_@imageName"></label>
1445 </div>
1446 <div class="panel-list__item-image">
1447 <label for="Image_@imageName">
1448 <img class="b-lazy flex-img" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=55&height=55&crop=5&FillCanvas=True&Compression=75&image=@imageName" alt="@Path.GetFileName(imageName)">
1449 </label>
1450 </div>
1451 <div class="panel-list__item-name">
1452 <label for="Image_@imageName" class="u-truncate-text u-w170px">
1453 @Path.GetFileName(imageName)
1454 </label>
1455 </div>
1456 </li>
1457 }
1458
1459 @helper RenderDocument(string fieldValue)
1460 {
1461 <li class="panel-list__item">
1462 <div class="panel-list__item-check">
1463 <input type="checkbox" name="Document_@fieldValue" class="u-no-margin form__control" id="Document_@fieldValue" />
1464 <label for="Document_@fieldValue"></label>
1465 </div>
1466 <div class="panel-list__item-name">
1467 <label for="Document_@fieldValue" class="u-truncate-text u-max-w220px">
1468 @Path.GetFileName(fieldValue)
1469 </label>
1470 </div>
1471 </li>
1472 }
@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
1473 @using Dynamicweb.Core
1474 @using System
1475 @using System.Web
1476 @using System.Collections.Generic
1477 @using Dynamicweb.Rapido.Blocks
1478
1479 @functions {
1480 BlocksPage productGeneratePDFPage = BlocksPage.GetBlockPage("Product");
1481 }
1482
1483 @{
1484 string generatePDFLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("GeneratePDFLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("GeneratePDFLayout").SelectedValue : "Section";
1485 generatePDFLayout = generatePDFLayout == "Ribbon" ? "Section" : generatePDFLayout;
1486
1487 if (GetPageIdByNavigationTag("PdfFolder") > 0 && generatePDFLayout != "hide")
1488 {
1489 Block generatePDFBlock = new Block()
1490 {
1491 Name = generatePDFLayout != "MainInformation" ? Translate("Generate PDF") : "",
1492 Id = "GeneratePDF",
1493 SortId = 10,
1494 Template = RenderGeneratePDFSection(generatePDFLayout),
1495 Design = new Design
1496 {
1497 Size = "12",
1498 RenderType = RenderType.Column,
1499 HidePadding = true
1500 }
1501 };
1502
1503 productGeneratePDFPage.Add(generatePDFLayout, generatePDFBlock);
1504 }
1505 }
1506
1507 @helper RenderGeneratePDFSection(string layout)
1508 {
1509 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("GeneratePDFLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
1510 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses;
1511 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("GeneratePDFLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : "";
1512 string exportPageId = GetPageIdByNavigationTag("ProductExportFeed").ToString();
1513 int pdfFolderId = GetPageIdByNavigationTag("PdfFolder");
1514
1515 <div class="product__section @ribbonClasses grid dw-mod">
1516 <div class="dw-mod grid__col-md-4 @ribbonSubClasses">
1517 @if (layout == "Section") {
1518 <h2>@Translate("Generate PDF")</h2>
1519 }
1520
1521 <form action="/Default.aspx?ID=@exportPageId&ProductID=@System.Web.HttpContext.Current.Request.QueryString.Get("ProductID")&VariantID=@System.Web.HttpContext.Current.Request.QueryString.Get("VariantID")&GeneratePdf=true" method="post" class="u-no-margin">
1522 <input name="siteUrl" type="hidden" value="@string.Format("{0}://{1}", GetGlobalValue("Global:Request.Scheme"), GetGlobalValue("Global:Request.Host"))" />
1523
1524 <label for="PdfLanguageId">@Translate("Language")</label>
1525 <select id="PdfLanguageId" name="PdfLanguageId" class="u-full-width">
1526 @foreach (var lang in Services.Languages.GetLanguages().OrderBy(l => l.Name))
1527 {
1528 var selected = lang.IsDefault ? "selected" : "";
1529 <option value="@lang.LanguageId" @selected>@lang.Name</option>
1530 }
1531 </select>
1532 <label for="PdfPageId">@Translate("Generate PDF")</label>
1533 <select id="PdfPageId" name="PdfPageId" class="u-full-width">
1534 <option value="" selected>@Translate("Select type")</option>
1535 @foreach (Dynamicweb.Content.Page page in ServiceLocator.Current.GetPageService().GetPagesByParentID(pdfFolderId))
1536 {
1537 <option value="@page.ID">@page.MenuText</option>
1538 }
1539 </select>
1540
1541 <input type="submit" value="@Translate("Generate PDF")" class="btn btn--full btn--primary u-no-margin dw-mod" title="@Translate("Generate PDF")" />
1542 </form>
1543 </div>
1544 </div>
1545 }
@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
1546 @using Dynamicweb.Core
1547 @using System
1548 @using System.Web
1549 @using System.Collections.Generic
1550 @using Dynamicweb.Rapido.Blocks
1551
1552 @functions {
1553 BlocksPage productDescriptionPage = BlocksPage.GetBlockPage("Product");
1554 }
1555
1556 @{
1557 string fullDesctiptionLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("FullDescriptionLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue : "Section";
1558 fullDesctiptionLayout = fullDesctiptionLayout == "Ribbon" ? "Section" : fullDesctiptionLayout;
1559
1560 if (!string.IsNullOrEmpty(GetString("Ecom:Product.LongDescription")) && fullDesctiptionLayout != "hide") {
1561 Block detailsDescription = new Block() {
1562 Name = fullDesctiptionLayout != "MainInformation" ? Translate("Detailed description") : "",
1563 Id = "FullDescription",
1564 SortId = 10,
1565 Template = RenderProductDescription(fullDesctiptionLayout),
1566 Design = new Design {
1567 Size = "12",
1568 RenderType = RenderType.Column,
1569 HidePadding = true
1570 }
1571 };
1572 productDescriptionPage.Add(fullDesctiptionLayout, detailsDescription);
1573 }
1574
1575 }
1576
1577 @helper RenderProductDescription(string layout) {
1578 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
1579 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses;
1580 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : "";
1581
1582 bool b2cUser = false;
1583 if (Pageview.User != null) {
1584 b2cUser = Pageview.User.GroupsIds.Contains(7913);
1585
1586 } else {
1587 b2cUser = true;
1588 }
1589
1590 <div class="product__section @ribbonClasses dw-mod">
1591 <div class="product__description center-container @ribbonSubClasses dw-mod">
1592 @if (layout == "Section") {
1593 <h2>@Translate("Description")</h2>
1594 }
1595 @GetString("Ecom:Product.LongDescription")
1596 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Kollistoerrelse")) && !b2cUser) {
1597 <p class="color-gray">@Translate(GetString("Ecom:Product:Field.Kollistoerrelse.Name")): @GetString("Ecom:Product:Field.Kollistoerrelse")</p>
1598 }
1599
1600 </div>
1601 </div>
1602 }
@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
1603 @using Dynamicweb.Core
1604 @using System
1605 @using System.Web
1606 @using System.Globalization;
1607 @using System.Collections.Generic
1608 @using Dynamicweb.Rapido.Blocks
1609
1610 @functions {
1611 BlocksPage productFieldsPage = BlocksPage.GetBlockPage("Product");
1612
1613 static string ConvertBytes(long bytes)
1614 {
1615 double size = bytes / 1024; //KB
1616 if (size > 1024)
1617 {
1618 size = (bytes / 1024f) / 1024f; //MB
1619 return string.Format("{0:n1} MB", size);
1620 }
1621 else
1622 {
1623 return string.Format("{0:n0} KB", size);
1624 }
1625 }
1626
1627 static bool isImage(string path)
1628 {
1629 return new List<string> { ".jpg", ".jpeg", ".gif", ".png", ".svg" }.Contains(Path.GetExtension(path).ToLower());
1630 }
1631
1632 string getIconForFile(string fileName)
1633 {
1634 string ext = Path.GetExtension(fileName);
1635 string icon = "";
1636 switch (ext.ToLower())
1637 {
1638 case ".xls":
1639 case ".xlsx":
1640 icon = "fa-file-excel";
1641 break;
1642 case ".ppt":
1643 case ".pptx":
1644 icon = "fa-file-powerpoint";
1645 break;
1646 case ".doc":
1647 case ".docx":
1648 icon = "fa-file-word";
1649 break;
1650 case ".jpg":
1651 case ".jpeg":
1652 case ".png":
1653 case ".gif":
1654 case ".pdf":
1655 return "<img class='product__document-img' alt='" + fileName + "' src='/Admin/Public/GetImage.ashx?crop=5&height=70&width=120&Compression=75&DoNotUpscale=true&image=" + fileName + "' />";
1656 default:
1657 icon = "fa-file";
1658 break;
1659 }
1660 return "<i class='product__document-icon far " + icon + "'></i> ";
1661 }
1662 }
1663
1664 @*downloadDocuments variable, declared in Product.cshtml - this variable also will be used in ProductAssets.cshtml*@
1665
1666 @{
1667 foreach (LoopItem customField in GetLoop("CustomFieldValues"))
1668 {
1669 if (!string.IsNullOrEmpty(customField.GetString("Product.CustomField.Name")) && !string.IsNullOrEmpty(customField.GetString("Product.CustomField.Value.Clean")) && customField.GetString("Product.CustomField.Name") != "Custom sticker")
1670 {
1671 if (!string.IsNullOrEmpty(customField.GetString("Document.FullPath")))
1672 {
1673 downloadDocuments.Add(customField);
1674 }
1675 }
1676 }
1677
1678 foreach (LoopItem customField in GetLoop("ProductCategories"))
1679 {
1680 foreach (LoopItem field in customField.GetLoop("ProductCategoryFields"))
1681 {
1682 if (!string.IsNullOrEmpty(field.GetString("Ecom:Product.CategoryField.Label")) && !string.IsNullOrEmpty(field.GetString("Ecom:Product.CategoryField.Value")))
1683 {
1684 if (field.GetString("Ecom:Product.CategoryField.TypeID") == "9")
1685 {
1686 downloadDocuments.Add(field);
1687 }
1688 }
1689 }
1690 }
1691
1692 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true;
1693 string detailFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout").SelectedValue : "Section";
1694 detailFieldsLayout = detailFieldsLayout == "Ribbon" || string.IsNullOrEmpty(detailFieldsLayout) ? "Section" : detailFieldsLayout;
1695 string categoryFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout").SelectedValue : "Section";
1696 categoryFieldsLayout = categoryFieldsLayout == "Ribbon" || string.IsNullOrEmpty(categoryFieldsLayout) ? "Section" : categoryFieldsLayout;
1697 string downloadsFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout").SelectedValue : "Section";
1698 downloadsFieldsLayout = downloadsFieldsLayout == "Ribbon" || string.IsNullOrEmpty(downloadsFieldsLayout) ? "Section" : downloadsFieldsLayout;
1699
1700 string detailFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsView").SelectedValue : "grid";
1701 string categoryFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsView").SelectedValue : "grid";
1702 string downloadsFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsFieldsView").SelectedValue : "grid";
1703
1704 //Fjern && false for at få vist detajle fanen
1705 if (GetLoop("CustomFieldValues").Count > 0 && detailFieldsLayout != "hide" && false)
1706 {
1707 Block detailsCustom = new Block()
1708 {
1709 Name = detailFieldsLayout != "MainInformation" ? Translate("Details") : "",
1710 Id = "CustomFields",
1711 SortId = 30,
1712 Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Information"), RenderCustomFields(GetLoop("CustomFieldValues"), detailFieldsView)),
1713 Design = new Design
1714 {
1715 Size = "12",
1716 RenderType = RenderType.Column,
1717 HidePadding = true
1718 }
1719 };
1720
1721 productFieldsPage.Add(detailFieldsLayout, detailsCustom);
1722 }
1723
1724 if (categoryFieldsLayout != "hide")
1725 {
1726 foreach (LoopItem categoryGroup in GetLoop("ProductCategories"))
1727 {
1728 bool hasFields = categoryGroup.GetLoop("ProductCategoryFields").FirstOrDefault(cf => !string.IsNullOrEmpty(cf.GetString("Ecom:Product.CategoryField.Value"))) != null;
1729
1730 if (collectAllDownloads) {
1731 int downloadableCount = 0;
1732 foreach (LoopItem field in categoryGroup.GetLoop("ProductCategoryFields"))
1733 {
1734 if (field.GetString("Ecom:Product.CategoryField.TypeID") == "9")
1735 {
1736 downloadableCount++;
1737 }
1738 }
1739
1740 if (downloadableCount == categoryGroup.GetLoop("ProductCategoryFields").Count) {
1741 hasFields = false;
1742 }
1743 }
1744
1745 if (hasFields)
1746 {
1747 Block detailsCategoryFields = new Block()
1748 {
1749 Name = categoryFieldsLayout != "MainInformation" ? categoryGroup.GetString("Ecom:Product.Category.Name") : "",
1750 Id = ToPascalCase(categoryGroup.GetString("Ecom:Product.Category.Name")),
1751 SortId = 40,
1752 Template = RenderProductSection(categoryFieldsLayout, categoryFieldsView, categoryGroup.GetString("Ecom:Product.Category.Name"), RenderProductCategoryFields(categoryGroup.GetLoop("ProductCategoryFields"), categoryFieldsView)),
1753 Design = new Design
1754 {
1755 Size = "12",
1756 RenderType = RenderType.Column,
1757 HidePadding = true
1758 }
1759 };
1760
1761 productFieldsPage.Add(categoryFieldsLayout, detailsCategoryFields);
1762 }
1763 }
1764 }
1765
1766 if (downloadDocuments.Count > 0 && downloadsFieldsLayout != "hide" && collectAllDownloads == true)
1767 {
1768 Block detailsDownloads = new Block()
1769 {
1770 Name = downloadsFieldsLayout != "MainInformation" ? Translate("Downloads") : "",
1771 Id = "StandardDownloads",
1772 SortId = 50,
1773 Template = RenderProductSection(downloadsFieldsLayout, downloadsFieldsView, Translate("Downloads"), RenderProductDownloadsFields(downloadDocuments, downloadsFieldsView)),
1774 Design = new Design
1775 {
1776 Size = "12",
1777 RenderType = RenderType.Column,
1778 HidePadding = true
1779 }
1780 };
1781
1782 productFieldsPage.Add(downloadsFieldsLayout, detailsDownloads);
1783 }
1784 }
1785
1786 @helper RenderCustomFields(List<LoopItem> fieldsLoop, string viewType)
1787 {
1788 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true;
1789
1790 foreach (LoopItem customField in fieldsLoop)
1791 {
1792 string customSystemField = customField.GetString("Product.CustomField.System");
1793 if( customSystemField == "Indholddagsdosis" ||
1794 customSystemField == "Kollistoerrelse" ||
1795 customSystemField == "Anprisninger" ||
1796 customSystemField == "Pligttekst" ||
1797 customSystemField == "Anvendelse" ||
1798 customSystemField == "Salgsfeatures" ||
1799 customSystemField == "Livsstil" ||
1800 customSystemField == "Ingredienser" ||
1801 customSystemField == "Naeringsindhold" ||
1802 customSystemField == "Indeholder" ||
1803 customSystemField == "EAN" ||
1804 customSystemField == "Vejledendepris") {
1805 continue;
1806 }
1807 string fieldValue = customField.GetString("Product.CustomField.Value.Clean");
1808 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue;
1809 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue;
1810
1811 if (customField.GetLoop("Product.CustomField.Options").Count > 0)
1812 {
1813 fieldValue = customField.GetString("Product.CustomField.Label");
1814 }
1815
1816 if (!string.IsNullOrEmpty(customField.GetString("Product.CustomField.Name")) && !string.IsNullOrEmpty(fieldValue) && customField.GetString("Product.CustomField.Name") != "Custom sticker")
1817 {
1818 if (string.IsNullOrEmpty(customField.GetString("Document.FullPath")) && collectAllDownloads == false)
1819 {
1820 @RenderFieldItem(customField.GetString("Product.CustomField.Name"), fieldValue, viewType);
1821 }
1822 else if (collectAllDownloads == false)
1823 {
1824 @RenderFieldItem(customField.GetString("Product.CustomField.Name"), fieldValue, viewType, "download");
1825 }
1826 }
1827 }
1828 }
1829
1830 @helper RenderProductSection(string layout, string viewType, string name, RazorEngine.Templating.TemplateWriter writer) {
1831 string ribbonClasses = layout == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
1832 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses;
1833 string ribbonSubClasses = layout == "Ribbon" ? "center-container--ribbon" : "";
1834
1835 <div class="product__section @ribbonClasses dw-mod">
1836 <div class="center-container @ribbonSubClasses dw-mod">
1837 @if (layout == "Section")
1838 {
1839 <h2>@name</h2>
1840 }
1841
1842 @if (viewType != "table")
1843 {
1844 <div class="grid grid--bleed u-margin-bottom--lg">
1845 @writer
1846 </div>
1847 }
1848 else
1849 {
1850 string tableWidth = layout != "MainInformation" ? "grid__col-md-6" : "grid__col-md-12";
1851
1852 <div class="grid grid--external-bleed-x u-margin-bottom--lg">
1853 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12">
1854 <table class="table--no-top-border">
1855 @writer
1856 </table>
1857 </div>
1858 </div>
1859 }
1860 </div>
1861 </div>
1862 }
1863
1864 @helper RenderProductCategoryFields(List<LoopItem> fieldsLoop, string viewType) {
1865 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true;
1866
1867 foreach (LoopItem categoryField in fieldsLoop)
1868 {
1869 string fieldValue = categoryField.GetString("Ecom:Product.CategoryField.Value");
1870 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue;
1871 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue;
1872
1873 if (!string.IsNullOrEmpty(categoryField.GetString("Ecom:Product.CategoryField.Label")) && !string.IsNullOrEmpty(fieldValue))
1874 {
1875 if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") != "9" || collectAllDownloads == false)
1876 {
1877 if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "15")
1878 {
1879 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), categoryField.GetString("Ecom:Product.CategoryField.OptionLabel"), viewType);
1880 }
1881 else if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "8")
1882 {
1883 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType, "link");
1884 }
1885 else if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "9")
1886 {
1887 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType, "download");
1888 }
1889 else
1890 {
1891 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType);
1892 }
1893 }
1894 }
1895 }
1896 }
1897
1898 @helper RenderProductDownloadsFields(List<LoopItem> fieldsLoop, string viewType) {
1899 foreach (LoopItem document in fieldsLoop)
1900 {
1901 string fieldValue;
1902 if (!string.IsNullOrEmpty(document.GetString("Document.FullPath")))
1903 {
1904 fieldValue = document.GetString("Product.CustomField.Value.Clean");
1905 @RenderFieldItem(fieldValue, document.GetString("Document.FullPath"), viewType, "download")
1906 }
1907
1908 if (document.GetString("Ecom:Product.CategoryField.TypeID") == "9")
1909 {
1910 fieldValue = document.GetString("Ecom:Product.CategoryField.Value");
1911 @RenderFieldItem(fieldValue, fieldValue, viewType, "download")
1912 }
1913 }
1914 }
1915
1916 @helper RenderFieldItem(string name, string value, string viewType, string fieldType = "clean")
1917 {
1918 if (viewType != "table")
1919 {
1920 string fieldColumns = viewType == "list" ? "12" : "4";
1921 <div class="grid__col-md-@fieldColumns grid__col-sm-12 u-margin-bottom">
1922 <div class="u-bold">
1923 @name
1924 </div>
1925 <div>
1926 @RenderFieldItemContent(name, value, fieldType)
1927 </div>
1928 </div>
1929 }
1930 else
1931 {
1932 <tr>
1933 <th>@name</th>
1934 <td>
1935 @RenderFieldItemContent(name, value, fieldType)
1936 </td>
1937 </tr>
1938 }
1939 }
1940
1941 @helper RenderFieldItemContent(string name, string value, string fieldType = "clean")
1942 {
1943 if (fieldType == "link")
1944 {
1945 <a target="_blank" rel="noopener" href="@value">
1946 @if (isImage(value))
1947 {
1948 @getIconForFile(value)
1949 }
1950 else
1951 {
1952 @value
1953 }
1954 </a>
1955 }
1956 else if (fieldType == "download")
1957 {
1958 FileInfo info = new FileInfo(Dynamicweb.Core.SystemInformation.MapPath(value));
1959
1960 if (info.Exists)
1961 {
1962 <div class="grid grid--no-wrap">
1963 <a href="@value" download title="@Translate("Download")" class="product__document u-min-w120px u-ta-center dw-mod">@getIconForFile(value)</a>
1964 <div class="product__document-info dw-mod">
1965 <a href="@value" download title="@Translate("Download")" class="product__document dw-mod">@Path.GetFileName(value)</a>
1966 <small class="u-block u-margin-top">@ConvertBytes(info.Length)</small>
1967 </div>
1968 </div>
1969 }
1970 }
1971 else
1972 {
1973 @value
1974 }
1975 }
1976
@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
1977 @using Dynamicweb.Core
1978 @using System
1979 @using System.Web
1980 @using System.Collections.Generic
1981 @using Dynamicweb.Rapido.Blocks
1982
1983 @functions{
1984 BlocksPage productVideoPage = BlocksPage.GetBlockPage("Product");
1985 }
1986
1987 @{
1988 string videosLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue : "Section";
1989 videosLayout = videosLayout == "Ribbon" || string.IsNullOrEmpty(videosLayout) ? "Section" : videosLayout;
1990
1991 int videosCount = 0;
1992
1993 foreach (LoopItem detailField in GetLoop("Details"))
1994 {
1995 if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("youtube.com/embed") != -1)
1996 {
1997 videosCount++;
1998 }
1999 if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("vimeo.com") != -1)
2000 {
2001 videosCount++;
2002 }
2003 }
2004
2005 if (videosCount > 0 && videosLayout != "hide")
2006 {
2007 Block detailsVideos = new Block()
2008 {
2009 Name = videosLayout != "MainInformation" ? Translate("Videos") : "",
2010 Id = "Videos",
2011 SortId = 60,
2012 Template = ProductVideos(videosCount, videosLayout),
2013 Design = new Design
2014 {
2015 Size = "12",
2016 RenderType = RenderType.Column
2017 }
2018 };
2019 productVideoPage.Add(videosLayout, detailsVideos);
2020 }
2021 }
2022
2023 @helper ProductVideos(int videosCount, string layout) {
2024 string videoColumn = "12";
2025 videoColumn = videosCount == 2 ? "6" : videoColumn;
2026 videoColumn = videosCount > 2 ? "4" : videoColumn;
2027 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
2028 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses;
2029 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : "";
2030
2031 <div class="product__section @ribbonClasses dw-mod">
2032 <div class="center-container @ribbonSubClasses dw-mod">
2033 @if (layout == "Section") {
2034 <h2>@Translate("Videos")</h2>
2035 }
2036
2037 <div class="grid grid--external-bleed-x u-margin-bottom--lg">
2038 @foreach (LoopItem detailField in GetLoop("Details"))
2039 {
2040 if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("youtube.com/embed") != -1 || detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("vimeo.com") != -1)
2041 {
2042 <div class="grid__col-md-@videoColumn grid__col-lg-@videoColumn">
2043 <div class="video-wrapper">
2044 @detailField.GetString("Ecom:Product:Detail.Text")
2045 </div>
2046 </div>
2047 }
2048 }
2049 </div>
2050 </div>
2051 </div>
2052 }
@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
2053 @using Dynamicweb.Core
2054 @using System
2055 @using System.Web
2056 @using System.Collections.Generic
2057 @using Dynamicweb.Rapido.Blocks
2058
2059 @functions{
2060 BlocksPage productRelatedPage = BlocksPage.GetBlockPage("Product");
2061 }
2062
2063 @{
2064 string relatedProductsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue : "Section";
2065 relatedProductsLayout = relatedProductsLayout == "Ribbon" || string.IsNullOrEmpty(relatedProductsLayout) ? "Section" : relatedProductsLayout;
2066 bool relatedOnlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null;
2067 bool relatedShowStock = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowStockAndShipping");
2068 bool showAddToDownloadButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToDownloadButton");
2069 bool relatedShowPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice");
2070 bool relatedShowFavoriteButton = !Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("HideFavoriteButton") && Pageview.User != null;
2071 bool relatedPointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly");
2072 bool relatedShowCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToCartButton");
2073 bool relatedShowViewButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowViewButton");
2074 string relatedCartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart";
2075 string relatedMoreText = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText")) ? Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText") : "View";
2076 bool relatedShowNumber = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowProductNumber");
2077
2078 // int relatedProductsPageSize = 4;
2079 int relatedProductsPageSize = 16;
2080 int relatedProductsColumnWidth = 3;
2081
2082 if (Pageview.Device.ToString() == "Mobile") {
2083 relatedProductsPageSize = 1;
2084 relatedProductsColumnWidth = 12;
2085 }
2086
2087 if (Pageview.Device.ToString() == "Tablet") {
2088 relatedProductsPageSize = 3;
2089 relatedProductsColumnWidth = 4;
2090 }
2091
2092 if (relatedProductsLayout != "hide") {
2093 if (GetLoop("eCom:Related.CustomersWhoSawThisAlsoSaw").Any()) {
2094
2095 string[] customersWhoSawThisAlsoSawProductIds = GetLoop("eCom:Related.CustomersWhoSawThisAlsoSaw").Select(x => x.GetString("Ecom:Product.ID")).ToArray();
2096 string relatedGroupId = "OtherSeenProducts";
2097 string baseFeedPageUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + 4 + "&ProdID=" + GetString("Ecom:Product.ID") + "&feed=true";
2098 string relatedFeed = baseFeedPageUrl + "&" + relatedGroupId + "=" + string.Join(",", customersWhoSawThisAlsoSawProductIds);
2099 string relatedGroupName = "otherSeenProducts";
2100 Block detailsRelated = new Block()
2101 {
2102 Name = relatedGroupName,
2103 Id = relatedGroupId,
2104 SortId = 70,
2105 Template = RenderRelatedProducts(relatedGroupName, relatedGroupId, relatedFeed, relatedProductsLayout, Translate("CustomersWhoSawThisAlsoSaw")),
2106 Design = new Design
2107 {
2108 Size = "12",
2109 RenderType = RenderType.Column,
2110 HidePadding = true
2111 }
2112 };
2113
2114 productRelatedPage.Add(relatedProductsLayout, detailsRelated);
2115 }
2116 foreach (LoopItem relatedGroup in GetLoop("ProductRelatedGroups")) {
2117 string relatedGroupId = ToPascalCase(relatedGroup.GetString("Ecom:Product:RelatedGroup.Name"));
2118 string baseFeedPageUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + relatedProductsPageSize + "&ProdID=" + GetString("Ecom:Product.ID") + "&feed=true";
2119 string relatedFeed = baseFeedPageUrl + "&" + relatedGroupId + "=" + GetString("Ecom:Product.ID") + "&GroupName=" + relatedGroupId;
2120 string relatedGroupName = relatedProductsLayout != "maininformation" ? relatedGroup.GetString("Ecom:Product:RelatedGroup.Name") : "";
2121 Block detailsRelated = new Block()
2122 {
2123 Name = relatedGroupName,
2124 Id = relatedGroupId,
2125 SortId = 80,
2126 Template = RenderRelatedProducts(relatedGroupName, relatedGroupId, relatedFeed, relatedProductsLayout, Translate("Relaterede varer")),
2127 Design = new Design
2128 {
2129 Size = "12",
2130 RenderType = RenderType.Column,
2131 HidePadding = true
2132 }
2133 };
2134
2135 productRelatedPage.Add(relatedProductsLayout, detailsRelated);
2136 }
2137
2138 //CustomersWhoSawThisAlsoSaw
2139
2140
2141 }
2142 }
2143
2144 @helper RenderRelatedProducts(string name, string groupId, string relatedFeedUrl, string layout, string header = "")
2145 {
2146 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
2147 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses;
2148 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : "";
2149
2150 <div class="product__section @ribbonClasses dw-mod">
2151 <div class="center-container @ribbonSubClasses dw-mod">
2152 <h2>@header</h2>
2153 @if (layout == "Section") {
2154 @*<h2>@name</h2>*@
2155
2156 }
2157 <div class="js-handlebars-root" id="ProductList_@groupId" data-template="ProductContainer" data-pre-render-template="ProductPreRenderContainer" data-json-feed="@relatedFeedUrl" data-preloader="minimal"></div>
2158 </div>
2159 </div>
2160 }
2161
2162 @* Script templates for related products *@
2163 <script id="ProductPreRenderContainer" type="text/x-template">
2164 <div class="u-h600px u-full-width">
2165 <div class="grid">
2166 <div class="grid__col-12">
2167 <div class="pre-render-element pre-render-element--md"></div>
2168 </div>
2169 </div>
2170 </div>
2171 </script>
2172
2173 <script id="ProductContainer" type="text/x-template">
2174 {{#.}}
2175 @*<h2>@Translate("Relaterede varer")</h2>*@
2176 <div class="u-min-h400px u-full-width">
2177 <div class="grid">
2178 @*<div class="grid__col-45px grid__col--bleed-x"><div class="grid__cell grid__cell--align-middle-left"><button class="btn btn--condensed btn--clean {{prevdisabled}} dw-mod" onclick="HandlebarsBolt.UpdateContent('ProductList_{{groupName}}', '{{prevPage}}')" {{prevdisabled}}><i class="fas fa-chevron-left fa-2x"></i></button></div></div>*@
2179 <div class="grid__col-auto grid__col--bleed-x">
2180 <div id="ProductsContainer" data-template="ProductGridItemContainer" class="grid product-list dw-mod" data-save-cookie="true">
2181 {{#ProductsContainer}}
2182 <div id="Product{{productId}}" class="grid__col-@relatedProductsColumnWidth product-list__grid-item dw-mod">
2183 {{#Product}}
2184 @if (useGoogleTagManager) {
2185 <text>{{{googleEnchantImpression 'Related products' currency googleImpression}}}</text>
2186 }
2187 <div class="grid__cell product-list__grid-item__image dw-mod {{noImage}}">
2188 <a href="{{link}}" onclick="Scroll.SavePosition(event)" class="u-block u-position-relative">
2189 <img class="grid__cell-img grid__cell-img--centered b-lazy" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=300&height=300&crop=5&Format=jpg&Compression=75&image={{image}}" alt="{{{name}}}" />
2190
2191 </a>
2192 @if (relatedShowFavoriteButton) {
2193 <div class="favorites favorites--for-grid-view u-pull--right {{hasVariants}} dw-mod" {{hasVariants}}>
2194 {{#Favorite}}
2195 {{>FavoriteTemplate}}
2196 {{/Favorite}}
2197 </div>
2198 }
2199 </div>
2200
2201 <div class="grid__cell product-list__grid-item__price-info {{shortGridInfo}} dw-mod">
2202
2203 {{#StickersContainers}}
2204 {{>StickersContainer}}
2205 {{/StickersContainers}}
2206
2207 <a href="{{link}}" onclick="Scroll.SavePosition(event)" title="{{{name}}}">
2208 <h6 class="u-condensed-text">
2209 {{{name}}}
2210 </h6>
2211 </a>
2212
2213 @if (relatedShowNumber) {
2214 <div class="item-number dw-mod">@Translate("Product number"): {{number}}</div>
2215 }
2216
2217 @if (relatedShowPrice && !relatedOnlyPreview) {
2218 if (relatedPointShopOnly) {
2219 <text>
2220 {{#if havePointPrice}}
2221 <div>{{points}} @Translate("points")</div>
2222 {{else}}
2223 @Translate("Not available")
2224 {{/if}}
2225 </text>
2226 } else {
2227 <div class="price price--product-list dw-mod">{{livePriceFormatted}}</div>
2228 <div class="before-price {{onSale}} dw-mod">{{discount}}</div>
2229 }
2230 }
2231 </div>
2232
2233 <div class="product-list__grid-item__footer dw-mod">
2234 @if (relatedShowCartButton && !relatedOnlyPreview) {
2235 <div class="u-ta-center u-inline-block">
2236 <div class="buttons-collection {{hideBuyOptions}}">
2237 @if (relatedPointShopOnly) {
2238 <button type="button" id="CartButton_{{id}}" class="btn btn--primary btn--condensed u-no-margin dw-mod js-cart-btn {{disabledBuyButton}} {{#unless canBePurchasedWithPoints}}js-stay-disabled{{/unless}}" name="CartCmd" value="addWithPoints"
2239 onclick="Cart.AddToCart(event, {
2240 id: {{productId}}',
2241 variantId: '{{variantid}}',
2242 unitId: '{{unitId}}',
2243 quantity: 1,
2244 buyForPoints: true,
2245 productInfo: {{productInfo}}
2246 }); {{facebookPixelAction}}" {{disabledBuyButton}}>
2247 <i class="@relatedCartIcon"></i><span class="u-hidden-xs u-hidden-xxs"> @Translate("Buy with points")</span>
2248 </button>
2249 } else {
2250 <button type="button" id="CartButton_{{id}}" class="js-cart-btn btn btn--primary btn--condensed u-no-margin u-pull--right dw-mod {{disabledBuyButton}}" name="submit"
2251 onclick="Cart.AddToCart(event, {
2252 id: '{{productId}}',
2253 variantId: '{{variantid}}',
2254 unitId: '{{unitId}}',
2255 quantity: document.getElementById('Quantity_{{id}}').value,
2256 productInfo: {{productInfo}}
2257 }); {{facebookPixelAction}}" {{disabledBuyButton}}>
2258 <i class="@relatedCartIcon"></i><span class="u-hidden-xs u-hidden-xxs"> @Translate("Add to cart")</span>
2259 </button>
2260 <input type="number" class="u-w80px u-pull--right" id="Quantity_{{id}}" name="Quantity{{id}}" value="1" min="1">
2261 }
2262 </div>
2263 </div>
2264
2265 if (relatedShowViewButton) {
2266 <div class="u-ta-center {{hideViewMore}}">
2267 <a href="{{link}}" id="CartButton_{{id}}" class="btn btn--secondary u-no-margin dw-mod" onclick="Scroll.SavePosition(event); {{googleImpressionClick}}" title="@Translate(relatedMoreText)">@Translate(relatedMoreText)</a>
2268 </div>
2269 }
2270
2271 } else if (relatedShowViewButton) {
2272 <div class="u-ta-center">
2273 <a href="{{link}}" id="CartButton_{{id}}" class="btn btn--secondary u-no-margin dw-mod" onclick="Scroll.SavePosition(event); {{googleImpressionClick}}" title="@Translate(relatedMoreText)">@Translate(relatedMoreText)</a>
2274 </div>
2275 }
2276
2277 @if (!relatedOnlyPreview && relatedShowStock) {
2278 <div class="u-margin-top">
2279 <div><span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span> {{stockText}}</div>
2280 <div>
2281 {{#if deliveryText}}
2282 {{deliveryText}}
2283 {{else}}
2284 -
2285 {{/if}}
2286 </div>
2287 </div>
2288 }
2289
2290 @if (showAddToDownloadButton && Pageview.User != null) {
2291 <button type="button" class="btn btn--primary u-no-margin u-margin-top btn--condensed dw-mod js-add-to-downloads" title="@Translate("Add")" data-product-id="{{productId}}">
2292 <i class="fas fa-plus js-button-icon"></i>
2293 <span class="js-button-text">@Translate("Add")</span>
2294 </button>
2295 }
2296 </div>
2297 {{/Product}}
2298 </div>
2299 {{/ProductsContainer}}
2300 </div>
2301 </div>
2302 @*<div class="grid__col-45px grid__col--bleed-x"><div class="grid__cell grid__cell--align-middle-right"><button class="btn btn--condensed btn--clean {{nextdisabled}} dw-mod" onclick="HandlebarsBolt.UpdateContent('ProductList_{{groupName}}', '{{nextPage}}')" {{nextdisabled}}><i class="fas fa-chevron-right fa-2x"></i></button></div></div>*@
2303 </div>
2304 </div>
2305 {{/.}}
2306 </script>
2307
2308 @* Favorites templates *@
2309
2310 <script id="FavoriteTemplate" type="text/x-template">
2311 <div class="favorites-list u-ta-left">
2312 <label for="FavoriteTrigger_{{id}}" class="u-no-margin"><i class="{{favoriteIcon}} fa-1_5x"></i></label>
2313 <input type="checkbox" id="FavoriteTrigger_{{id}}" class="dropdown-trigger" />
2314 <div class="dropdown dropdown--absolute-position">
2315 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod">
2316 <ul class="list list--clean dw-mod">
2317 {{#FavoriteLists}}
2318 {{>FavoriteListItem}}
2319 {{/FavoriteLists}}
2320 </ul>
2321 </div>
2322 <label class="dropdown-trigger-off" for="FavoriteTrigger_{{id}}"></label>
2323 </div>
2324 </div>
2325 </script>
2326
2327 <script id="StickersContainer" type="text/x-template">
2328 <div class="stickers-container stickers-container--{{position}} dw-mod">
2329 {{#Stickers}}
2330 {{>Sticker}}
2331 {{/Stickers}}
2332 </div>
2333 </script>
2334
2335 @*<script id="Sticker" type="text/x-template">
2336 <div class="stickers-container__tag {{className}} dw-mod">{{text}}</div>
2337 </script>*@
2338
2339 <script id="Sticker" type="text/x-template">
2340 {{#if groupColor}}
2341 <div class="stickers-container__tag {{className}} dw-mod" style="background-color:{{groupColor}};">{{text}}</div>
2342 {{else}}
2343 <div class="stickers-container__tag {{className}} dw-mod">{{text}}</div>
2344 {{/if}}
2345 </script>
2346
2347 <script id="FavoriteListItem" type="text/x-template">
2348 <li>
2349 <a href="{{link}}" class="list__link u-no-underline dw-mod" onclick="{{facebookPixelAction}}"><i class="{{favoriteIcon}}"></i> {{{name}}}</a>
2350 </li>
2351 </script>
@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
2352 @using Dynamicweb.Core
2353 @using System
2354 @using System.Web
2355 @using System.Collections.Generic
2356 @using Dynamicweb.Rapido.Blocks
2357
2358 @functions {
2359 BlocksPage productVariantsPage = BlocksPage.GetBlockPage("Product");
2360 }
2361
2362 @{
2363 bool renderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList");
2364 bool variantsOnlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null;
2365 bool showProductNumberForVariants = !Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideProductNumbers");
2366 bool showImageForEachVariant = !Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideImageForEachVariant");
2367 bool variantsPointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly");
2368 string variantsListPageSize = HttpContext.Current.Request.QueryString.Get("PageSize") ?? "30";
2369 string variantsFeedUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + variantsListPageSize + "&MainProductID=" + GetString("Ecom:Product.ID") + "&OnlyShowVariants=true&feed=true";
2370 string variantsCartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart";
2371 string variantsListLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue : "Section";
2372 variantsListLayout = variantsListLayout == "Ribbon" ? "Section" : variantsListLayout;
2373
2374 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("ShowBothPricesWithWithoutVAT");
2375 bool isPricesWithVATEnabled = Converter.ToBoolean(Pageview.Area.EcomPricesWithVat);
2376
2377 if (renderVariantsAsProducts && variantsListLayout != "hide")
2378 {
2379 Block detailsVariantsList = new Block()
2380 {
2381 Name = variantsListLayout != "MainInformation" ? Translate("Variants list") : "",
2382 Id = "VariantsList",
2383 SortId = 20,
2384 Template = RenderVariantsProductList(variantsListLayout),
2385 Design = new Design
2386 {
2387 Size = "12",
2388 RenderType = RenderType.Column,
2389 HidePadding = true
2390 }
2391 };
2392 productVariantsPage.Add(variantsListLayout, detailsVariantsList);
2393 }
2394 }
2395
2396 @helper RenderVariantsProductList(string layout)
2397 {
2398 string variantsListPageSize = HttpContext.Current.Request.QueryString.Get("PageSize") ?? "30";
2399 string variantsFeedUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + variantsListPageSize + "&MainProductID=" + GetString("Ecom:Product.ID") + "&OnlyShowVariants=true&feed=true";
2400 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
2401 ribbonClasses = layout == "Tabs" ? "u-no-padding" : ribbonClasses;
2402 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : "";
2403
2404 <div class="product__section @ribbonClasses dw-mod">
2405 <div class="center-container @ribbonSubClasses dw-mod">
2406 @if (layout == "Section") {
2407 <h2>@Translate("Variants")</h2>
2408 }
2409
2410 <div class="js-handlebars-root" id="VariantsListRoot" data-template="VariantProductsContainer" data-json-feed="@variantsFeedUrl" data-preloader="minimal"></div>
2411 </div>
2412 </div>
2413 }
2414
2415
2416 @* Script templates for variant products *@
2417
2418 <script id="VariantProductsContainer" type="text/x-template">
2419 {{#.}}
2420 <div class="">
2421 <table id="VariantsProductsContainer" class="table u-position-relative dw-mod">
2422 <thead>
2423 <tr>
2424 @if (showImageForEachVariant)
2425 {
2426 <td width="75"> </td>
2427 }
2428 <td>@Translate("Product")</td>
2429 {{#AvailableCustomFields}}
2430 {{>TableFieldNameTemplate}}
2431 {{/AvailableCustomFields}}
2432 @if (Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantGroupsInTable")) {
2433 foreach (LoopItem variantgroup in GetLoop("VariantGroups"))
2434 {
2435 <td>@variantgroup.GetString("Ecom:VariantGroup.Name")</td>
2436 }
2437 }
2438 <td width="360"> </td>
2439 </tr>
2440 </thead>
2441
2442 <tbody id="VariantProductListContainer" data-template="VariantProductItemContainer" data-save-cookie="true">
2443 {{#ProductsContainer}}
2444 {{>VariantProductItemContainer}}
2445 {{/ProductsContainer}}
2446 </tbody>
2447 </table>
2448 </div>
2449
2450 <div class="grid">
2451 <div class="grid__col-12 grid__col--bleed-y">
2452 <button type="button" id="LoadMoreButton" class="btn btn--primary {{nextdisabled}} dw-mod" data-current="{{currentPage}}" data-page-size="{{pageSize}}" data-total="{{totalPages}}" data-container="VariantProductListContainer" data-feed-url="@variantsFeedUrl{{loadMoreFeedParams}}" onclick="LoadMore.Next(this)" {{nextdisabled}}>@Translate("Load") @Translate("more")</button>
2453 </div>
2454 </div>
2455 {{/.}}
2456 </script>
2457
2458 <script id="VariantProductItemContainer" type="text/x-template">
2459 {{#.}}
2460 <tr id="VariantProduct{{id}}" data-template="VariantProductItem" data-preloader="overlay" style="z-index: {{zIndex}}">
2461 {{#Product}}
2462 {{>VariantProductItem}}
2463 {{/Product}}
2464 </tr>
2465 {{/.}}
2466 </script>
2467
2468 <script id="VariantProductItem" type="text/x-template">
2469 {{#.}}
2470 @if (showImageForEachVariant)
2471 {
2472 <td width="75">
2473 <div class="lightbox u-hidden-xxs">
2474 <a href="{{link}}" onclick="Scroll.SavePosition(event)">
2475 <img class="lightbox__image {{noImage}}" src="/Admin/Public/GetImage.ashx?width=220&height=220&crop=5&Compression=75&image={{image}}" alt="{{{name}}}" />
2476 <div class="u-margin-right {{noImage}}">
2477 <img src="/Admin/Public/GetImage.ashx?width=75&height=55&crop=5&FillCanvas=true&Compression=75&image={{image}}" alt="{{{name}}}" />
2478 </div>
2479 </a>
2480 </div>
2481 </td>
2482 }
2483
2484 <td class="u-va-middle">
2485 <a href="{{link}}" onclick="Scroll.SavePosition(event)" title="{{{name}}}"><h6 class="u-no-margin">{{{name}}}</h6></a>
2486 <div class="item-number item-number--compressed dw-mod">
2487 @if (showProductNumberForVariants)
2488 {
2489 <div class="u-margin-bottom">@Translate("Product number"): {{number}}</div>
2490 }
2491 @*@if (!variantsOnlyPreview)
2492 {
2493 <div>
2494 <span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span> {{stockText}} {{deliveryText}}
2495 </div>
2496 }*@
2497 else
2498 {
2499 <div class="grid__cell-footer stickers-container stickers-container--block dw-mod">
2500 {{#Stickers}}
2501 {{>MiniSticker}}
2502 {{/Stickers}}
2503 </div>
2504 }
2505 </div>
2506 </td>
2507 {{#CustomFields}}
2508 {{>TableFieldValueTemplate}}
2509 {{/CustomFields}}
2510 @if (Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantGroupsInTable"))
2511 {
2512 <text>
2513 {{#VariantSelectionNames}}
2514 {{>TableFieldNameTemplate}}
2515 {{/VariantSelectionNames}}
2516 </text>
2517 }
2518 <td width="365" class="u-va-middle">
2519 @if (variantsOnlyPreview)
2520 {
2521 <div class="u-hidden-sm">
2522 <div class="u-full-width u-ta-right u-padding-right">
2523 <div class="before-price {{onSale}} before-price--micro dw-mod">{{discount}}</div>
2524 <div class="price price--product-list price--micro dw-mod">{{livePriceFormatted}}</div>
2525 </div>
2526 </div>
2527 }
2528 else
2529 {
2530 <div class="grid grid--align-center grid--justify-end">
2531
2532 <div class="u-margin-right">
2533 <input type="checkbox" id="UnitOptions_{{id}}" class="dropdown-trigger" />
2534 <div class="dropdown u-w120px {{hasUnits}} dw-mod">
2535 <label class="dropdown__header dropdown__btn dw-mod" for="UnitOptions_{{id}}">{{unitName}}</label>
2536 <div id="unitOptions" class="dropdown__content dw-mod">
2537 {{#unitOptions}}
2538 {{>UnitOption}}
2539 {{/unitOptions}}
2540 </div>
2541 <label class="dropdown-trigger-off" for="UnitOptions_{{id}}"></label>
2542 </div>
2543 <input type="hidden" value="{{unitId}}" name="Unit{{id}}" id="Unit_{{id}}" />
2544 <input type="hidden" value="{{variantid}}" name="VariantID{{id}}" id="Variant_{{id}}" />
2545 </div>
2546 <div class="u-margin-right u-hidden-xs u-hidden-xxs">
2547 @if (variantsPointShopOnly) {
2548 <text>
2549 {{#if canBePurchasedWithPoints}}
2550 <div class="price price--product-list price--micro dw-mod">{{points}} @Translate("points")</div>
2551 {{else}}
2552 {{#if havePointPrice}}
2553 <small class="help-text u-no-margin u-margin-top">@Translate("Not enough points to buy this")</small>
2554 {{else}}
2555 <small class="help-text u-no-margin u-margin-top">@Translate("Not available")</small>
2556 {{/if}}
2557 {{/if}}
2558 </text>
2559 } else {
2560 <div class="before-price before-price--micro {{onSale}} dw-mod">{{discount}}</div>
2561 <div class="price price--condensed price--product-list dw-mod">
2562 {{price}}
2563 @if (showVATPrice) {
2564 <small class="vat-price vat-price--product-page u-margin-top dw-mod">
2565 @if (isPricesWithVATEnabled) {
2566 @Translate("excl. VAT") <text>({{priceWithoutVAT}})</text>
2567 } else {
2568 @Translate("incl. VAT") <text>({{priceWithVAT}})</text>
2569 }
2570 </small>
2571 }
2572 </div>
2573 }
2574 </div>
2575 @if (variantsPointShopOnly) {
2576 <div>
2577 <button {{#unless canBePurchasedWithPoints}} disabled{{/unless}} type="button"
2578 id="CartButton_{{id}}"
2579 class="btn btn--primary btn--condensed u-no-margin dw-mod js-cart-btn {{#unless canBePurchasedWithPoints}}disabled js-stay-disabled{{/unless}}"
2580 name="CartCmd"
2581 value="addWithPoints"
2582 onclick="Cart.AddToCart(event, {
2583 id: '{{productId}}',
2584 variantId: '{{variantid}}',
2585 unitId: '{{unitId}}',
2586 quantity: 1,
2587 buyForPoints: true,
2588 productInfo: {{productInfo}}
2589 })">
2590 <i class="@variantsCartIcon"></i>
2591 </button>
2592 </div>
2593 } else {
2594 <div>
2595 <input type="number" class="u-w80px u-no-margin u-margin-right" id="Quantity_{{id}}" name="Quantity{{id}}" value="1" min="1">
2596 </div>
2597 <div>
2598 <button type="button" id="CartButton_{{id}}" class="btn btn--primary btn--condensed u-no-margin dw-mod" name="submit"
2599 onclick="Cart.AddToCart(event, {
2600 id: '{{productId}}',
2601 variantId: '{{variantid}}',
2602 unitId: '{{unitId}}',
2603 quantity: document.getElementById('Quantity_{{id}}').value,
2604 productInfo: {{productInfo}}
2605 });">
2606 <i class="@variantsCartIcon"></i>
2607 </button>
2608 </div>
2609 }
2610 <div class="favorites u-margin-left {{hasVariants}} dw-mod" {{hasVariants}}>
2611 {{#Favorite}}
2612 {{>FavoriteTemplate}}
2613 {{/Favorite}}
2614 </div>
2615 </div>
2616 }
2617 </td>
2618 {{/.}}
2619 </script>
2620
2621 <script id="TableFieldNameTemplate" type="text/x-template">
2622 <td class="u-va-middle">{{{name}}}</td>
2623 </script>
2624
2625 <script id="TableFieldValueTemplate" type="text/x-template">
2626 <td class="u-va-middle">{{value}}</td>
2627 </script>
2628
2629 <script id="MiniSticker" type="text/x-template">
2630 <div class="stickers-container__tag stickers-container__tag--micro {{className}} dw-mod">{{text}}</div>
2631 </script>
@if(File.Exists(HttpContext.Current.Server.MapPath("/Files/Templates/Designs/Rapido/eCom/Product/Blocks/Custom__Blocks.cshtml"))) {
<text>@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
2632 @using Dynamicweb.Core
2633 @using System
2634 @using System.Web
2635 @using System.Collections.Generic
2636 @using Dynamicweb.Rapido.Blocks
2637
2638 @{
2639 BlocksPage customProductBlocks = BlocksPage.GetBlockPage("Product");
2640
2641 //detailFieldsLayout skulle gerne være Tabs
2642
2643
2644
2645 if(detailFieldsLayout != "hide" && (GetLoop("Indeholder.Options").Where(x => x.GetBoolean("Indeholder.Option.IsSelected")).Any() || !string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Naeringsindhold")) || !string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Ingredienser")))) {
2646 Block contentsBlock = new Block {
2647 Id = "Contents",
2648 Name = Translate("Indhold"),
2649 SortId = 102,
2650 Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Indhold"), RenderContents()),
2651 Design = new Design {
2652 Size = "12",
2653 RenderType = RenderType.Column,
2654 HidePadding = true
2655 }
2656 };
2657 customProductBlocks.Add(detailFieldsLayout, contentsBlock);
2658 }
2659
2660
2661 if(detailFieldsLayout != "hide" && !string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Pligttekst"))) {
2662 Block dutyTextBlock = new Block {
2663 Id = "DutyText",
2664 Name = Translate("Pligttekst"),
2665 SortId = 105,
2666 Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Pligttekst"), RenderDutyText()),
2667 Design = new Design {
2668 Size = "12",
2669 RenderType = RenderType.Column,
2670 HidePadding = true
2671 }
2672 };
2673 customProductBlocks.Add(detailFieldsLayout, dutyTextBlock);
2674 }
2675 if(detailFieldsLayout != "hide" && !string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Anprisninger"))) {
2676 Block excellenceBlock = new Block {
2677 Id = "Excellence",
2678 Name = Translate("Anprisninger"),
2679 SortId = 110,
2680 Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Anprisninger"), RenderExcellence()),
2681 Design = new Design {
2682 Size = "12",
2683 RenderType = RenderType.Column,
2684 HidePadding = true
2685 }
2686 };
2687 customProductBlocks.Add(detailFieldsLayout, excellenceBlock);
2688 }
2689
2690 }
2691
2692 @helper RenderExcellence() {
2693 <div class="grid grid--external-bleed-x u-margin-bottom--lg">
2694 <div class="grid__col-md-12 grid__col-sm-12 grid__col-xs-12">
2695 <ul>
2696 @foreach(var i in GetLoop("Anprisninger.Options").Where(x => x.GetBoolean("Anprisninger.Option.IsSelected"))) {
2697 var excellencePage = Dynamicweb.Services.Pages.GetPageByNavigationTag(Pageview.AreaID, i.GetString("Anprisninger.Option.Value"));
2698 if(excellencePage != null) {
2699 <li>
2700 <a href="/Default.aspx?ID=@excellencePage.ID">@excellencePage.MenuText</a>
2701 </li>
2702 }
2703 }
2704 </ul>
2705 </div>
2706 </div>
2707 }
2708
2709
2710 @helper RenderContents() {
2711
2712 var indeholderLoop = GetLoop("Indeholder.Options").Where(x => x.GetBoolean("Indeholder.Option.IsSelected"));
2713 <div class="grid grid--external-bleed-x u-margin-bottom--lg">
2714 <div class="grid__col-md-12 grid__col-sm-12 grid__col-xs-12">
2715 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Ingredienser"))) {
2716 <div class="u-bold">@Translate("Ingredienser")</div>
2717 <p>@GetString("Ecom:Product:Field.Ingredienser")</p>
2718 }
2719 @if (indeholderLoop.Any()) {
2720 <div class="u-bold">@Translate("Dette produkt indeholder"):</div>
2721 <ul>
2722 @foreach (var i in indeholderLoop) {
2723 <li>@i.GetString("Indeholder.Option.Name")</li>
2724 }
2725 </ul>
2726
2727 }
2728 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Naeringsindhold"))) {
2729 <div class="u-bold">@Translate("Næringsindhold")</div>
2730 <p>@GetString("Ecom:Product:Field.Naeringsindhold")</p>
2731 }
2732
2733
2734 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Indholddagsdosis"))) {
2735 <div class="u-bold">@Translate("Indhold pr. dagsdosis")</div>
2736 <p>@GetString("Ecom:Product:Field.Indholddagsdosis")</p>
2737 }
2738
2739 </div>
2740 </div>
2741 }
2742 @helper RenderDutyText() {
2743 <div class="grid grid--external-bleed-x u-margin-bottom--lg">
2744 <div class="grid__col-md-12 grid__col-sm-12 grid__col-xs-12">
2745 <p>
2746 @GetString("Ecom:Product:Field.Pligttekst")
2747 </p>
2748 </div>
2749 </div>
2750 }</text>
}
<div class="product__info dw-mod u-margin-bottom--lg js-product">
<div class="grid grid--align-content-start">
@* The @RenderBlockList base helper is included in Components/GridBuilder.cshtml *@
@RenderBlockList(productsPage.BlocksRoot.BlocksList)
</div>
</div>
@helper RenderProductTop() {
List<Block> subBlocks = productsPage.GetBlockListById("Top").OrderBy(item => item.SortId).ToList();
<div class="product__top paragraph-container paragraph-container--full-width dw-mod">
<div class="center-container u-padding dw-mod">
<div class="grid">
@RenderBlockList(subBlocks)
</div>
</div>
</div>
}
@helper RenderProductMiniTabs() {
List<Block> subBlocks = productsPage.GetBlockListById("MiniTabs").OrderBy(item => item.SortId).ToList();
if(subBlocks.Count > 0) {
<div class="grid__col-12 product__info tabs u-no-padding u-margin-bottom--lg dw-mod">
@{
bool firstTab = true;
foreach(Block item in subBlocks) {
string isChecked = firstTab ? "checked" : "";
firstTab = false;
<input type="radio" class="tabs__trigger" name="productMiniTabs" id="@item.Id" onchange="bLazy.revalidate()" @isChecked />
}
}
<div class="tabs__list dw-mod">
@foreach(Block item in subBlocks) {
<label for="@item.Id" class="tabs__label dw-mod">@item.Name</label>
}
</div>
<div class="tabs__blocks dw-mod">
@foreach(Block item in subBlocks) {
string hidePadding = item.Design.HidePadding ? "u-no-padding" : "";
if(item.Design.RenderType != RenderType.Hide) {
<div class="tabs__block u-border dw-mod" id="Block__@item.Id">
<block class="product__block paragraph-container product__block--bordered dw-mod">
<div class="center-container u-padding--lg dw-mod">
@RenderBlock(item)
</div>
</block>
</div>
}
}
</div>
</div>
}
}
@helper RenderProductTabs() {
List<Block> subBlocks = productsPage.GetBlockListById("Tabs").OrderBy(item => item.SortId).ToList();
<div class="grid__col-12 product__info product__info--tabs tabs dw-mod">
@{
bool firstTab = true;
foreach(Block item in subBlocks) {
string isChecked = firstTab ? "checked" : "";
firstTab = false;
<input type="radio" class="tabs__trigger" name="productTabs" id="@item.Id" onchange="bLazy.revalidate()" @isChecked />
}
}
<div class="tabs__list dw-mod">
@foreach(Block item in subBlocks) {
<label for="@item.Id" class="tabs__label dw-mod">@item.Name</label>
}
</div>
<div class="tabs__blocks dw-mod">
@foreach(Block item in subBlocks) {
string hidePadding = item.Design.HidePadding ? "u-no-padding" : "";
if(item.Design.RenderType != RenderType.Hide) {
<div class="tabs__block dw-mod" id="Block__@item.Id">
<section class="product__section paragraph-container paragraph-container--full-width product__section--bordered dw-mod">
<div class="center-container u-padding--lg dw-mod">
@RenderBlock(item)
</div>
</section>
</div>
}
}
</div>
</div>
}