Error executing template "Designs/Rapido/eCom/Product/ProductCustom.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at Denform.Website.CustomModules.Application.GroupHelper.GetParentsRecursively(Group group, List`1 groupNames)
at CompiledRazorTemplates.Dynamic.RazorEngine_8378baef20af40da83ebe0da83e1ffcd.Execute() in D:\web\denform.dk\Files\Templates\Designs\Rapido\eCom\Product\ProductCustom.cshtml:line 3487
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>>
2
3 @using System.Web
4 @using Dynamicweb.Extensibility
5 @using Dynamicweb.Content
6 @using System
7 @using System.IO
8 @using Dynamicweb.Core
9 @using System.Web
10 @using System.Globalization
11 @using System.Web.UI.HtmlControls
12 @using Dynamicweb.Rapido.Blocks
13 @using Dynamicweb.Ecommerce
14
15 @functions {
16 List<LoopItem> downloadDocuments = new List<LoopItem>();
17 //downloadDocuments variable, will be defined in Fields.cshtml and used in ProductAssets.cshtml
18
19 BlocksPage productsPage = BlocksPage.GetBlockPage("Product");
20
21 public static string ToPascalCase(string str)
22 {
23 return CultureInfo.InvariantCulture.TextInfo
24 .ToTitleCase(str.ToLowerInvariant())
25 .Replace("-", "")
26 .Replace("_", "")
27 .Replace(" ", "");
28 }
29 }
30
31 @{
32 string productBlocksPosition = Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition").SelectedValue : "thumbs-image-info";
33 bool productInfoOnTheRight = productBlocksPosition.LastIndexOf("info") == productBlocksPosition.Length - 4;
34
35 Block productTop = new Block()
36 {
37 Id = "Top",
38 SortId = 10,
39 SkipRenderBlocksList = true,
40 Template = RenderProductTop()
41 };
42 productsPage.Add(productTop);
43
44 Block productMainInfo = new Block()
45 {
46 Id = "MainInformation",
47 SortId = productInfoOnTheRight ? 20 : 10,
48 Design = new Design
49 {
50 Size = "auto",
51 RenderType = RenderType.Column
52 }
53 };
54 productsPage.Add("Top", productMainInfo);
55
56 //Optional mini tabs block
57 Block miniTabsBlock = new Block()
58 {
59 Id = "MiniTabs",
60 SortId = 40,
61 Template = RenderProductMiniTabs(),
62 SkipRenderBlocksList = true
63 };
64 productsPage.Add("MainInformation", miniTabsBlock);
65 //-----
66
67 Block productTabsBlock = new Block()
68 {
69 Id = "Tabs",
70 SortId = 20,
71 Template = RenderProductTabs(),
72 SkipRenderBlocksList = true
73 };
74 productsPage.Add(productTabsBlock);
75
76 Block productDetailsBlock = new Block()
77 {
78 Id = "Section",
79 SortId = 30
80 };
81 productsPage.Add(productDetailsBlock);
82
83 Block productSnippetsBlock = new Block()
84 {
85 Id = "Snippets",
86 SortId = 40
87 };
88 productsPage.Add(productSnippetsBlock);
89 }
90
91 @* Include the required Grid builder (Contains the methods @RenderBlockList and @RenderBlock) *@
92 @using System.Text.RegularExpressions
93 @using System.Collections.Generic
94 @using System.Reflection
95 @using System.Web
96 @using System.Web.UI.HtmlControls
97 @using Dynamicweb.Rapido.Blocks.Components
98 @using Dynamicweb.Rapido.Blocks.Components.Articles
99 @using Dynamicweb.Rapido.Blocks.Components.Documentation
100 @using Dynamicweb.Rapido.Blocks
101
102
103 @*--- START: Base block renderers ---*@
104
105 @helper RenderBlockList(List<Block> blocks)
106 {
107 bool debug = !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("debug")) ? Convert.ToBoolean(HttpContext.Current.Request.QueryString.Get("debug")) : false;
108 blocks = blocks.OrderBy(item => item.SortId).ToList();
109
110 foreach (Block item in blocks)
111 {
112 if (debug) {
113 <!-- Block START: @item.Id -->
114 }
115
116 if (item.Design == null)
117 {
118 @RenderBlock(item)
119 }
120 else if (item.Design.RenderType == RenderType.None) {
121 string cssClass = item.Design.CssClass != null ? item.Design.CssClass : "";
122
123 <div class="@cssClass dw-mod">
124 @RenderBlock(item)
125 </div>
126 }
127 else if (item.Design.RenderType != RenderType.Hide)
128 {
129 string cssClass = item.Design.CssClass != null ? item.Design.CssClass : "";
130
131 if (!item.SkipRenderBlocksList) {
132 if (item.Design.RenderType == RenderType.Row)
133 {
134 <div class="grid grid--align-content-start @cssClass dw-mod" id="Block__@item.Id">
135 @RenderBlock(item)
136 </div>
137 }
138
139 if (item.Design.RenderType == RenderType.Column)
140 {
141 string hidePadding = item.Design.HidePadding ? "u-no-padding" : "";
142 string size = item.Design.Size ?? "12";
143 size = Regex.IsMatch(size, @"\d") ? "md-" + item.Design.Size : item.Design.Size;
144
145 <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">
146 @RenderBlock(item)
147 </div>
148 }
149
150 if (item.Design.RenderType == RenderType.Table)
151 {
152 <table class="table @cssClass dw-mod" id="Block__@item.Id">
153 @RenderBlock(item)
154 </table>
155 }
156
157 if (item.Design.RenderType == RenderType.TableRow)
158 {
159 <tr class="@cssClass dw-mod" id="Block__@item.Id">
160 @RenderBlock(item)
161 </tr>
162 }
163
164 if (item.Design.RenderType == RenderType.TableColumn)
165 {
166 <td class="@cssClass dw-mod" id="Block__@item.Id">
167 @RenderBlock(item)
168 </td>
169 }
170
171 if (item.Design.RenderType == RenderType.CardHeader)
172 {
173 <div class="card-header @cssClass dw-mod">
174 @RenderBlock(item)
175 </div>
176 }
177
178 if (item.Design.RenderType == RenderType.CardBody)
179 {
180 <div class="card @cssClass dw-mod">
181 @RenderBlock(item)
182 </div>
183 }
184
185 if (item.Design.RenderType == RenderType.CardFooter)
186 {
187 <div class="card-footer @cssClass dw-mod">
188 @RenderBlock(item)
189 </div>
190 }
191 }
192 else
193 {
194 @RenderBlock(item)
195 }
196 }
197
198 if (debug) {
199 <!-- Block END: @item.Id -->
200 }
201 }
202 }
203
204 @helper RenderBlock(Block item)
205 {
206 bool debug = !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("debug")) ? Convert.ToBoolean(HttpContext.Current.Request.QueryString.Get("debug")) : false;
207
208 if (item.Template != null)
209 {
210 @BlocksPage.RenderTemplate(item.Template)
211 }
212
213 if (item.Component != null)
214 {
215 string customSufix = "Custom";
216 string methodName = item.Component.HelperName;
217
218 ComponentBase[] methodParameters = new ComponentBase[1];
219 methodParameters[0] = item.Component;
220 Type methodType = this.GetType();
221
222 MethodInfo customMethod = methodType.GetMethod(methodName + customSufix);
223
224 try {
225 if (debug) {
226 <!-- Component: @methodName.Replace("Render", "") -->
227 }
228 if(customMethod != null) {
229 @customMethod.Invoke(this, methodParameters).ToString();
230 } else {
231 MethodInfo generalMethod = methodType.GetMethod(methodName);
232 @generalMethod.Invoke(this, methodParameters).ToString();
233 }
234 } catch {
235 try {
236 MethodInfo generalMethod = methodType.GetMethod(methodName);
237 @generalMethod.Invoke(this, methodParameters).ToString();
238 } catch(Exception ex) {
239 throw new Exception(item.Component.GetType().Name + " method '" + methodName +"' could not be invoked", ex);
240 }
241 }
242 }
243
244 if (item.BlocksList.Count > 0 && !item.SkipRenderBlocksList)
245 {
246 @RenderBlockList(item.BlocksList)
247 }
248 }
249
250 @*--- END: Base block renderers ---*@
251
252 @using Dynamicweb.Rapido.Blocks.Components
253 @using Dynamicweb.Rapido.Blocks.Components.General
254 @using Dynamicweb.Rapido.Blocks
255 @using System.IO
256
257 @* Required *@
258 @using Dynamicweb.Rapido.Blocks.Components
259 @using Dynamicweb.Rapido.Blocks.Components.General
260 @using Dynamicweb.Rapido.Blocks
261
262
263 @helper Render(ComponentBase component)
264 {
265 if (component != null)
266 {
267 @component.Render(this)
268 }
269 }
270
271 @* Components *@
272 @using System.Reflection
273 @using Dynamicweb.Rapido.Blocks.Components.General
274
275
276 @* Component *@
277
278 @helper RenderIcon(Icon settings)
279 {
280 if (settings != null)
281 {
282 string color = settings.Color != null ? "style=\"color: " + settings.Color + "\"" : "";
283
284 if (settings.Name != null)
285 {
286 if (string.IsNullOrEmpty(settings.Label))
287 {
288 <i class="@settings.Prefix @settings.Name @settings.CssClass" @color></i>
289 }
290 else
291 {
292 if (settings.LabelPosition == IconLabelPosition.Before)
293 {
294 <div class="u-flex u-flex--align-items-center @settings.CssClass">@settings.Label <i class="@settings.Prefix @settings.Name u-margin-left" @color></i></div>
295 }
296 else
297 {
298 <div class="u-flex u-flex--align-items-center @settings.CssClass"><i class="@settings.Prefix @settings.Name u-margin-right--lg u-w20px" @color></i>@settings.Label</div>
299 }
300 }
301 }
302 else if (!string.IsNullOrEmpty(settings.Label))
303 {
304 @settings.Label
305 }
306 }
307 }
308 @using System.Reflection
309 @using Dynamicweb.Rapido.Blocks.Components.General
310 @using Dynamicweb.Rapido.Blocks.Components
311 @using Dynamicweb.Core
312
313 @* Component *@
314
315 @helper RenderButton(Button settings)
316 {
317 if (settings != null && (!string.IsNullOrEmpty(settings.Title) || settings.Icon != null))
318 {
319 Dictionary<string, string> attributes = new Dictionary<string, string>();
320 List<string> classList = settings.CssClass != null ? settings.CssClass.Split(' ').ToList() : new List<string>();
321 if (settings.Disabled) {
322 attributes.Add("disabled", "true");
323 classList.Add("disabled");
324 }
325
326 if (!string.IsNullOrEmpty(settings.ConfirmText) || !string.IsNullOrEmpty(settings.ConfirmTitle))
327 {
328 settings.Id = !string.IsNullOrEmpty(settings.Id) ? settings.Id : Guid.NewGuid().ToString("N");
329 @RenderConfirmDialog(settings);
330 settings.OnClick = "document.getElementById('" + settings.Id + "ModalTrigger').checked = true";
331 }
332
333 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); }
334 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); }
335 if (!string.IsNullOrEmpty(settings.AltText))
336 {
337 attributes.Add("title", settings.AltText);
338 }
339 else if (!string.IsNullOrEmpty(settings.Title))
340 {
341 string cleanTitle = Regex.Replace(settings.Title, "<.*?>", String.Empty);
342 cleanTitle = cleanTitle.Replace(" ", " ");
343 attributes.Add("title", cleanTitle);
344 }
345
346 var onClickEvents = new List<string>();
347 if (!string.IsNullOrEmpty(settings.OnClick))
348 {
349 onClickEvents.Add(settings.OnClick);
350 }
351 if (!string.IsNullOrEmpty(settings.Href))
352 {
353 onClickEvents.Add("location.href='" + settings.Href + "'");
354 }
355 if (onClickEvents.Count > 0)
356 {
357 attributes.Add("onClick", string.Join(";", onClickEvents));
358 }
359
360 if (settings.ButtonLayout != ButtonLayout.None)
361 {
362 classList.Add("btn");
363 string btnLayout = Enum.GetName(typeof(ButtonLayout), settings.ButtonLayout).ToLower();
364 if (btnLayout == "linkclean")
365 {
366 btnLayout = "link-clean"; //fix
367 }
368 classList.Add("btn--" + btnLayout);
369 }
370
371 if (settings.Icon == null)
372 {
373 settings.Icon = new Icon();
374 }
375
376 settings.Icon.CssClass += Enum.GetName(typeof(ButtonLayout), settings.ButtonLayout).ToLower() != "linkclean" ? " u-flex--align-center" : "";
377 settings.Icon.Label = settings.Title;
378
379 attributes.Add("type", Enum.GetName(typeof(ButtonType), settings.ButtonType).ToLower());
380
381 <button class="@string.Join(" ", classList) dw-mod" @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@Render(settings.Icon)</button>
382 }
383 }
384
385 @helper RenderConfirmDialog(Button settings)
386 {
387 Modal confirmDialog = new Modal {
388 Id = settings.Id,
389 Width = ModalWidth.Sm,
390 Heading = new Heading
391 {
392 Level = 2,
393 Title = settings.ConfirmTitle
394 },
395 BodyText = settings.ConfirmText
396 };
397
398 confirmDialog.AddAction(new Button { Title = Translate("Cancel"), ButtonLayout = ButtonLayout.Secondary, OnClick = "document.getElementById('" + settings.Id + "ModalTrigger').checked = false"});
399 confirmDialog.AddAction(new Button { Title = Translate("OK"), ButtonLayout = ButtonLayout.Primary, OnClick = "document.getElementById('" + settings.Id + "ModalTrigger').checked = false;" + settings.OnClick });
400
401 @Render(confirmDialog)
402 }
403 @using Dynamicweb.Rapido.Blocks.Components.General
404 @using Dynamicweb.Rapido.Blocks.Components
405 @using Dynamicweb.Core
406
407 @helper RenderDashboard(Dashboard settings)
408 {
409 var widgets = settings.GetWidgets();
410
411 if (!string.IsNullOrEmpty(settings.WidgetsBaseBackgroundColor))
412 {
413 //set bg color for them
414
415 System.Drawing.Color color = System.Drawing.ColorTranslator.FromHtml(settings.WidgetsBaseBackgroundColor);
416 int r = Convert.ToInt16(color.R);
417 int g = Convert.ToInt16(color.G);
418 int b = Convert.ToInt16(color.B);
419
420 var count = widgets.Length;
421 var max = Math.Max(r, Math.Max(g, b));
422 double step = 255.0 / (max * count);
423 var i = 0;
424 foreach (var widget in widgets)
425 {
426 i++;
427
428 var shade = "rgb(" + Converter.ToString(r * step * i).Replace(",", ".") + ", " + Converter.ToString(g * step * i).Replace(",", ".") + ", " + Converter.ToString(b * step * i).Replace(",", ".") + ")";
429 widget.BackgroundColor = shade;
430 }
431 }
432
433 <div class="dashboard @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)>
434 @foreach (var widget in widgets)
435 {
436 <div class="dashboard__widget">
437 @Render(widget)
438 </div>
439 }
440 </div>
441 }
442 @using Dynamicweb.Rapido.Blocks.Components.General
443 @using Dynamicweb.Rapido.Blocks.Components
444
445 @helper RenderDashboardWidgetLink(DashboardWidgetLink settings)
446 {
447 if (!string.IsNullOrEmpty(settings.Link))
448 {
449 var backgroundStyles = "";
450 if (!string.IsNullOrEmpty(settings.BackgroundColor))
451 {
452 backgroundStyles = "style=\"background-color:" + settings.BackgroundColor + "\"";
453 }
454
455 <a href="@settings.Link" class="widget widget--link @settings.CssClass dw-mod" @backgroundStyles title="@settings.Title" @ComponentMethods.AddAttributes(settings.ExtraAttributes)>
456 <div class="u-center-middle u-color-light">
457 @if (settings.Icon != null)
458 {
459 settings.Icon.CssClass += "widget__icon";
460 @Render(settings.Icon)
461 }
462 <div class="widget__title">@settings.Title</div>
463 </div>
464 </a>
465 }
466 }
467 @using Dynamicweb.Rapido.Blocks.Components.General
468 @using Dynamicweb.Rapido.Blocks.Components
469
470 @helper RenderDashboardWidgetCounter(DashboardWidgetCounter settings)
471 {
472 var backgroundStyles = "";
473 if (!string.IsNullOrEmpty(settings.BackgroundColor))
474 {
475 backgroundStyles = "style='background-color:" + settings.BackgroundColor + "'";
476 }
477
478 <div class="widget @settings.CssClass dw-mod" @backgroundStyles @ComponentMethods.AddAttributes(settings.ExtraAttributes)>
479 <div class="u-center-middle u-color-light">
480 @if (settings.Icon != null)
481 {
482 settings.Icon.CssClass += "widget__icon";
483 @Render(settings.Icon)
484 }
485 <div class="widget__counter">@settings.Count</div>
486 <div class="widget__title">@settings.Title</div>
487 </div>
488 </div>
489 }
490 @using System.Reflection
491 @using Dynamicweb.Rapido.Blocks.Components.General
492 @using Dynamicweb.Rapido.Blocks.Components
493 @using Dynamicweb.Core
494
495 @* Component *@
496
497 @helper RenderLink(Link settings)
498 {
499 if (settings != null && !string.IsNullOrEmpty(settings.Href) && (!string.IsNullOrEmpty(settings.Title) || settings.Icon != null))
500 {
501 Dictionary<string, string> attributes = new Dictionary<string, string>();
502 List<string> classList = settings.CssClass != null ? settings.CssClass.Split(' ').ToList() : new List<string>();
503 if (settings.Disabled)
504 {
505 attributes.Add("disabled", "true");
506 classList.Add("disabled");
507 }
508
509 if (!string.IsNullOrEmpty(settings.AltText))
510 {
511 attributes.Add("title", settings.AltText);
512 }
513 else if (!string.IsNullOrEmpty(settings.Title))
514 {
515 attributes.Add("title", settings.Title);
516 }
517
518 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); }
519 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); }
520 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onClick", settings.OnClick); }
521 attributes.Add("href", settings.Href);
522
523 if (settings.ButtonLayout != ButtonLayout.None)
524 {
525 classList.Add("btn");
526 string btnLayout = Enum.GetName(typeof(ButtonLayout), settings.ButtonLayout).ToLower();
527 if (btnLayout == "linkclean")
528 {
529 btnLayout = "link-clean"; //fix
530 }
531 classList.Add("btn--" + btnLayout);
532 }
533
534 if (settings.Icon == null)
535 {
536 settings.Icon = new Icon();
537 }
538 settings.Icon.Label = settings.Title;
539
540 if (settings.Target == LinkTargetType.Blank && settings.Rel == LinkRelType.None)
541 {
542 settings.Rel = LinkRelType.Noopener;
543 }
544 if (settings.Target != LinkTargetType.None)
545 {
546 attributes.Add("target", "_" + Enum.GetName(typeof(LinkTargetType), settings.Target).ToLower());
547 }
548 if (settings.Download)
549 {
550 attributes.Add("download", "true");
551 }
552 if (settings.Rel != LinkRelType.None)
553 {
554 attributes.Add("rel", Enum.GetName(typeof(LinkRelType), settings.Rel).ToLower());
555 }
556
557 <a class="@string.Join(" ", classList) dw-mod" @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@Render(settings.Icon)</a>
558 }
559 }
560 @using System.Reflection
561 @using Dynamicweb.Rapido.Blocks.Components
562 @using Dynamicweb.Rapido.Blocks.Components.General
563 @using Dynamicweb.Rapido.Blocks
564
565
566 @* Component *@
567
568 @helper RenderRating(Rating settings)
569 {
570 if (settings.Score > 0)
571 {
572 int rating = settings.Score;
573 string iconType = "fa-star";
574
575 switch (settings.Type.ToString()) {
576 case "Stars":
577 iconType = "fa-star";
578 break;
579 case "Hearts":
580 iconType = "fa-heart";
581 break;
582 case "Lemons":
583 iconType = "fa-lemon";
584 break;
585 case "Bombs":
586 iconType = "fa-bomb";
587 break;
588 }
589
590 <div class="u-ta-right">
591 @for (int i = 0; i < settings.OutOf; i++)
592 {
593 <i class="@(rating > i ? "fas" : "far") @iconType"></i>
594 }
595 </div>
596 }
597 }
598 @using System.Reflection
599 @using Dynamicweb.Rapido.Blocks.Components.General
600 @using Dynamicweb.Rapido.Blocks.Components
601
602
603 @* Component *@
604
605 @helper RenderSelectFieldOption(SelectFieldOption settings)
606 {
607 Dictionary<string, string> attributes = new Dictionary<string, string>();
608 if (settings.Checked) { attributes.Add("selected", "true"); }
609 if (settings.Disabled) { attributes.Add("disabled", "true"); }
610 if (settings.Value != null) { attributes.Add("value", settings.Value); }
611 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); }
612
613 <option @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@settings.Label</option>
614 }
615 @using System.Reflection
616 @using Dynamicweb.Rapido.Blocks.Components.General
617 @using Dynamicweb.Rapido.Blocks.Components
618
619
620 @* Component *@
621
622 @helper RenderNavigation(Navigation settings) {
623 @RenderNavigation(new
624 {
625 id = settings.Id,
626 cssclass = settings.CssClass,
627 startLevel = settings.StartLevel,
628 endlevel = settings.EndLevel,
629 expandmode = settings.Expandmode,
630 sitemapmode = settings.SitemapMode,
631 template = settings.Template
632 })
633 }
634 @using Dynamicweb.Rapido.Blocks.Components.General
635 @using Dynamicweb.Rapido.Blocks.Components
636
637
638 @* Component *@
639
640 @helper RenderBreadcrumbNavigation(BreadcrumbNavigation settings) {
641 settings.Id = String.IsNullOrEmpty(settings.Id) ? "breadcrumb" : settings.Id;
642 settings.Template = String.IsNullOrEmpty(settings.Template) ? "Breadcrumb.xslt" : settings.Template;
643 settings.StartLevel = settings.StartLevel == 0 ? 1 : settings.StartLevel;
644 settings.EndLevel = settings.EndLevel == 10 ? 1 : settings.EndLevel;
645 settings.Expandmode = String.IsNullOrEmpty(settings.Expandmode) ? "all" : settings.Expandmode;
646 settings.SitemapMode = false;
647
648 @RenderNavigation(settings)
649 }
650 @using Dynamicweb.Rapido.Blocks.Components.General
651 @using Dynamicweb.Rapido.Blocks.Components
652
653
654 @* Component *@
655
656 @helper RenderLeftNavigation(LeftNavigation settings) {
657 settings.Id = String.IsNullOrEmpty(settings.Id) ? "breadcrumb" : settings.Id;
658 settings.Template = String.IsNullOrEmpty(settings.Template) ? "Breadcrumb.xslt" : settings.Template;
659 settings.StartLevel = settings.StartLevel == 0 ? 1 : settings.StartLevel;
660 settings.EndLevel = settings.EndLevel == 10 ? 1 : settings.EndLevel;
661 settings.Expandmode = String.IsNullOrEmpty(settings.Expandmode) ? "all" : settings.Expandmode;
662
663 <div class="grid__cell">
664 @RenderNavigation(settings)
665 </div>
666 }
667 @using System.Reflection
668 @using Dynamicweb.Rapido.Blocks.Components.General
669 @using Dynamicweb.Core
670
671 @* Component *@
672
673 @helper RenderHeading(Heading settings)
674 {
675 if (settings != null && !string.IsNullOrEmpty(settings.Title))
676 {
677 string color = settings.Color != null ? "style=\"color: " + settings.Color + "\"" : "";
678 string tagName = settings.Level != 0 ? "h" + settings.Level.ToString() : "div";
679
680 @("<" + tagName + " class=\"" + settings.CssClass + " dw-mod\" " + color + ">")
681 if (!string.IsNullOrEmpty(settings.Link))
682 {
683 @Render(new Link { Href = settings.Link, Icon = settings.Icon, Title = settings.Title, ButtonLayout = ButtonLayout.None })
684 }
685 else
686 {
687 if (settings.Icon == null)
688 {
689 settings.Icon = new Icon();
690 }
691 settings.Icon.Label = settings.Title;
692 @Render(settings.Icon)
693 }
694 @("</" + tagName + ">");
695 }
696 }
697 @using Dynamicweb.Rapido.Blocks.Components
698 @using Dynamicweb.Rapido.Blocks.Components.General
699 @using Dynamicweb.Rapido.Blocks
700
701
702 @* Component *@
703
704 @helper RenderImage(Image settings)
705 {
706 if (settings.FilterPrimary != ImageFilter.None || settings.FilterSecondary != ImageFilter.None)
707 {
708 Dictionary<string, string> optionalAttributes = new Dictionary<string, string>();
709 if (!string.IsNullOrEmpty(settings.FilterColor)) { optionalAttributes.Add("style", "background-color: " + settings.FilterColor); }
710
711 if (settings.Caption != null)
712 {
713 @:<div>
714 }
715
716 var primaryFilterClass = settings.FilterPrimary.ToString().ToLower();
717 var secondaryFilterClass = settings.FilterSecondary.ToString().ToLower();
718
719 <div class="image-filter image-filter--@primaryFilterClass u-position-relative dw-mod" @ComponentMethods.AddAttributes(optionalAttributes)>
720 <div class="image-filter image-filter--@secondaryFilterClass dw-mod">
721 @if (settings.Link != null)
722 {
723 <a href="@settings.Link">
724 @RenderTheImage(settings)
725 </a>
726 }
727 else
728 {
729 @RenderTheImage(settings)
730 }
731 </div>
732 </div>
733
734 if (settings.Caption != null)
735 {
736 <span class="image-caption dw-mod">@settings.Caption</span>
737 @:</div>
738 }
739 }
740 else
741 {
742 if (settings.Caption != null)
743 {
744 @:<div>
745 }
746 if (!string.IsNullOrEmpty(settings.Link))
747 {
748 <a href="@settings.Link">
749 @RenderTheImage(settings)
750 </a>
751 }
752 else
753 {
754 @RenderTheImage(settings)
755 }
756
757 if (settings.Caption != null)
758 {
759 <span class="image-caption dw-mod">@settings.Caption</span>
760 @:</div>
761 }
762 }
763 }
764
765 @helper RenderTheImage(Image settings)
766 {
767 if (settings != null)
768 {
769 string alternativeImage = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("AlternativeImage")) ? Pageview.AreaSettings.GetItem("Settings").GetFile("AlternativeImage").PathUrlEncoded : "/Images/missing_image.jpg";
770 string placeholderImage = "/Files/Images/placeholder.gif";
771 string imageEngine = "/Admin/Public/GetImage.ashx?";
772
773 string imageStyle = "";
774
775 switch (settings.Style)
776 {
777 case ImageStyle.Ball:
778 imageStyle = "grid__cell-img--ball";
779 break;
780
781 case ImageStyle.Triangle:
782 imageStyle = "grid__cell-img--triangle";
783 break;
784 }
785
786 if (settings.Style == ImageStyle.Ball || settings.Style == ImageStyle.Circle || settings.Style == ImageStyle.Triangle)
787 {
788 settings.ImageDefault.Crop = settings.ImageDefault.Crop == 5 ? settings.ImageDefault.Crop = 0 : settings.ImageDefault.Crop;
789
790 if (settings.ImageDefault != null)
791 {
792 settings.ImageDefault.Height = settings.ImageDefault.Width;
793 }
794 if (settings.ImageMedium != null)
795 {
796 settings.ImageMedium.Height = settings.ImageMedium.Width;
797 }
798 if (settings.ImageSmall != null)
799 {
800 settings.ImageSmall.Height = settings.ImageSmall.Width;
801 }
802 }
803
804 string defaultImage = imageEngine;
805 string imageSmall = "";
806 string imageMedium = "";
807
808 if (settings.DisableImageEngine)
809 {
810 defaultImage = settings.Path;
811 }
812 else
813 {
814 if (settings.ImageDefault != null)
815 {
816 defaultImage += Dynamicweb.Rapido.Services.Images.GetImagePathFromSettings(settings.ImageDefault);
817
818 if (settings.Path.GetType() != typeof(string))
819 {
820 defaultImage += settings.Path != null ? "Image=" + settings.Path.PathUrlEncoded : "";
821 defaultImage += settings.Path != null ? "&" + settings.Path.GetFocalPointParameters() : "";
822 }
823 else
824 {
825 defaultImage += settings.Path != null ? "Image=" + settings.Path : "";
826 }
827
828 defaultImage += "&AlternativeImage=" + alternativeImage;
829 }
830
831 if (settings.ImageSmall != null)
832 {
833 imageSmall = "data-src-small=\"" + imageEngine;
834 imageSmall += Dynamicweb.Rapido.Services.Images.GetImagePathFromSettings(settings.ImageSmall);
835
836 if (settings.Path.GetType() != typeof(string))
837 {
838 imageSmall += settings.Path != null ? "Image=" + settings.Path.PathUrlEncoded : "";
839 imageSmall += settings.Path != null ? "&" + settings.Path.GetFocalPointParameters() : "";
840 }
841 else
842 {
843 imageSmall += settings.Path != null ? "Image=" + settings.Path : "";
844 }
845
846 imageSmall += "&alternativeImage=" + alternativeImage;
847
848 imageSmall += "\"";
849 }
850
851 if (settings.ImageMedium != null)
852 {
853 imageMedium = "data-src-medium=\"" + imageEngine;
854 imageMedium += Dynamicweb.Rapido.Services.Images.GetImagePathFromSettings(settings.ImageMedium);
855
856 if (settings.Path.GetType() != typeof(string))
857 {
858 imageMedium += settings.Path != null ? "Image=" + settings.Path.PathUrlEncoded : "";
859 imageMedium += settings.Path != null ? "&" + settings.Path.GetFocalPointParameters() : "";
860 }
861 else
862 {
863 imageMedium += settings.Path != null ? "Image=" + settings.Path : "";
864 }
865
866 imageMedium += "&alternativeImage=" + alternativeImage;
867
868 imageMedium += "\"";
869 }
870 }
871
872 Dictionary<string, string> optionalAttributes = new Dictionary<string, string>();
873 if (!string.IsNullOrEmpty(settings.OnClick)) { optionalAttributes.Add("onclick", settings.OnClick); }
874 if (!string.IsNullOrEmpty(settings.Title))
875 {
876 optionalAttributes.Add("alt", settings.Title);
877 optionalAttributes.Add("title", settings.Title);
878 }
879
880 if (settings.DisableLazyLoad)
881 {
882 <img id="@settings.Id" class="@imageStyle @settings.CssClass dw-mod" src="@defaultImage" @ComponentMethods.AddAttributes(optionalAttributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes) />
883 }
884 else
885 {
886 <img id="@settings.Id" class="b-lazy @imageStyle @settings.CssClass dw-mod" src="@placeholderImage" data-src="@defaultImage" @imageSmall @imageMedium @ComponentMethods.AddAttributes(optionalAttributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes) />
887 }
888 }
889 }
890 @using System.Reflection
891 @using Dynamicweb.Rapido.Blocks.Components.General
892 @using Dynamicweb.Rapido.Blocks.Components
893
894 @* Component *@
895
896 @helper RenderFileField(FileField settings)
897 {
898 var attributes = new Dictionary<string, string>();
899 if (string.IsNullOrEmpty(settings.Id))
900 {
901 settings.Id = Guid.NewGuid().ToString("N");
902 }
903
904 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); }
905 if (settings.Disabled) { attributes.Add("disabled", "true"); }
906 if (settings.Required) { attributes.Add("required", "true"); }
907 if (settings.Multiple) { attributes.Add("multiple", "true"); }
908 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); }
909 if (string.IsNullOrEmpty(settings.ChooseFileText))
910 {
911 settings.ChooseFileText = Translate("Choose file");
912 }
913 if (string.IsNullOrEmpty(settings.NoFilesChosenText))
914 {
915 settings.NoFilesChosenText = Translate("No files chosen...");
916 }
917 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); }
918
919 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; }
920
921 string setValueToFakeInput = "FileUpload.setValueToFakeInput(this)";
922 attributes.Add("onchange", setValueToFakeInput + (!string.IsNullOrEmpty(settings.OnChange) ? settings.OnChange : ""));
923
924 attributes.Add("type", "file");
925 if (settings.Value != null) { attributes.Add("value", settings.Value); }
926 settings.CssClass = "u-full-width " + settings.CssClass;
927
928 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value);
929
930 <div class="form__field-group u-full-width @settings.WrapperCssClass dw-mod">
931 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null )
932 {
933 <div class="u-full-width">
934 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> }
935 @if (settings.Link != null) {
936 <div class="u-pull--right">
937 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; }
938 @Render(settings.Link)
939 </div>
940 }
941 </div>
942
943 }
944
945 @if (!string.IsNullOrEmpty(settings.HelpText))
946 {
947 <small class="form__help-text">@settings.HelpText</small>
948 }
949
950 <div class="form__field-combi file-input u-no-margin dw-mod">
951 <input @ComponentMethods.AddAttributes(resultAttributes) class="file-input__real-input" data-no-files-text="@settings.NoFilesChosenText" data-many-files-text="@Translate("files")" />
952 <label for="@settings.Id" class="file-input__btn btn--secondary btn dw-mod">@settings.ChooseFileText</label>
953 <label for="@settings.Id" class="@settings.CssClass file-input__fake-input js-fake-input dw-mod">@settings.NoFilesChosenText</label>
954 @if (settings.UploadButton != null)
955 {
956 settings.UploadButton.CssClass += " btn--condensed u-no-margin";
957 @Render(settings.UploadButton)
958 }
959 </div>
960 @Render(new NotificationMessage { Message = settings.ErrorMessage })
961 </div>
962 }
963 @using System.Reflection
964 @using Dynamicweb.Rapido.Blocks.Components.General
965 @using Dynamicweb.Rapido.Blocks.Components
966 @using Dynamicweb.Core
967 @using System.Linq
968
969 @* Component *@
970
971 @helper RenderDateTimeField(DateTimeField settings)
972 {
973 if (string.IsNullOrEmpty(settings.Id))
974 {
975 settings.Id = Guid.NewGuid().ToString("N");
976 }
977
978 var textField = new TextField {
979 Name = settings.Name,
980 Id = settings.Id,
981 Label = settings.Label,
982 HelpText = settings.HelpText,
983 Value = settings.Value,
984 Disabled = settings.Disabled,
985 Required = settings.Required,
986 ErrorMessage = settings.ErrorMessage,
987 CssClass = settings.CssClass,
988 WrapperCssClass = settings.WrapperCssClass,
989 OnChange = settings.OnChange,
990 OnClick = settings.OnClick,
991 Link = settings.Link,
992 ExtraAttributes = settings.ExtraAttributes,
993 //
994 Placeholder = settings.Placeholder
995 };
996
997 @Render(textField)
998
999 List<string> jsAttributes = new List<string>();
1000
1001 jsAttributes.Add("mode: '" + Enum.GetName(typeof(DateTimeFieldMode), settings.Mode).ToLower() + "'");
1002
1003 if (!string.IsNullOrEmpty(settings.DateFormat))
1004 {
1005 jsAttributes.Add("dateFormat: '" + settings.DateFormat + "'");
1006 }
1007 if (!string.IsNullOrEmpty(settings.MinDate))
1008 {
1009 jsAttributes.Add("minDate: '" + settings.MinDate + "'");
1010 }
1011 if (!string.IsNullOrEmpty(settings.MaxDate))
1012 {
1013 jsAttributes.Add("maxDate: '" + settings.MaxDate + "'");
1014 }
1015 if (settings.IsInline)
1016 {
1017 jsAttributes.Add("inline: " + Converter.ToString(settings.IsInline).ToLower());
1018 }
1019 if (settings.EnableTime)
1020 {
1021 jsAttributes.Add("enableTime: " + Converter.ToString(settings.EnableTime).ToLower());
1022 }
1023 if (settings.EnableWeekNumbers)
1024 {
1025 jsAttributes.Add("weekNumbers: " + Converter.ToString(settings.EnableWeekNumbers).ToLower());
1026 }
1027
1028 jsAttributes.AddRange(settings.GetFlatPickrOptions().Select(x => x.Key + ": " + x.Value));
1029
1030 <script>
1031 document.addEventListener("DOMContentLoaded", function () {
1032 flatpickr("#@textField.Id", {
1033 @string.Join(",", jsAttributes)
1034 });
1035 });
1036 </script>
1037 }
1038 @using System.Reflection
1039 @using Dynamicweb.Rapido.Blocks.Components.General
1040 @using Dynamicweb.Rapido.Blocks.Components
1041
1042 @* Component *@
1043
1044 @helper RenderTextField(TextField settings)
1045 {
1046 var attributes = new Dictionary<string, string>();
1047 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id))
1048 {
1049 settings.Id = Guid.NewGuid().ToString("N");
1050 }
1051
1052 /*base settings*/
1053 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); }
1054 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); }
1055 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); }
1056 if (settings.Disabled) { attributes.Add("disabled", "true"); }
1057 if (settings.Required) { attributes.Add("required", "true"); }
1058 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); }
1059 /*end*/
1060
1061 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); }
1062 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); }
1063 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); }
1064 if (settings.ReadOnly) { attributes.Add("readonly", "true"); }
1065 if (settings.MaxLength != 0) { attributes.Add("maxlength", settings.MaxLength.ToString()); }
1066 if (!string.IsNullOrEmpty(settings.Placeholder)) { attributes.Add("placeholder", settings.Placeholder); }
1067 attributes.Add("type", Enum.GetName(typeof(TextFieldType), settings.Type).ToLower());
1068 if (settings.Type == TextFieldType.Password) { attributes.Add("autocomplete", "off"); };
1069 if (settings.Value != null) { attributes.Add("value", settings.Value); }
1070
1071 settings.CssClass = "u-full-width " + settings.CssClass;
1072
1073 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; }
1074
1075 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value);
1076
1077 string noMargin = "u-no-margin";
1078 if (!settings.ReadOnly) {
1079 noMargin = "";
1080 }
1081
1082 <div class="form__field-group u-full-width @noMargin @settings.WrapperCssClass dw-mod">
1083 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null )
1084 {
1085 <div class="u-full-width">
1086 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> }
1087 @if (settings.Link != null) {
1088 settings.Link.ButtonLayout = ButtonLayout.LinkClean;
1089
1090 <div class="u-pull--right">
1091 @Render(settings.Link)
1092 </div>
1093 }
1094 </div>
1095
1096 }
1097
1098 @if (!string.IsNullOrEmpty(settings.HelpText))
1099 {
1100 <small class="form__help-text">@settings.HelpText</small>
1101 }
1102
1103 @if (settings.ActionButton != null)
1104 {
1105 settings.ActionButton.CssClass += " btn--condensed u-no-margin";
1106 <div class="form__field-combi u-no-margin dw-mod">
1107 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" />
1108 @Render(settings.ActionButton)
1109 </div>
1110 }
1111 else
1112 {
1113 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" />
1114 }
1115
1116 @Render(new NotificationMessage { Message = settings.ErrorMessage })
1117 </div>
1118 }
1119 @using System.Reflection
1120 @using Dynamicweb.Rapido.Blocks.Components.General
1121 @using Dynamicweb.Rapido.Blocks.Components
1122
1123 @* Component *@
1124
1125 @helper RenderNumberField(NumberField settings)
1126 {
1127 var attributes = new Dictionary<string, string>();
1128 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id))
1129 {
1130 settings.Id = Guid.NewGuid().ToString("N");
1131 }
1132
1133 /*base settings*/
1134 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); }
1135 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); }
1136 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); }
1137 if (settings.Disabled) { attributes.Add("disabled", "true"); }
1138 if (settings.Required) { attributes.Add("required", "true"); }
1139 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); }
1140 /*end*/
1141
1142 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); }
1143 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); }
1144 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); }
1145 if (settings.ReadOnly) { attributes.Add("readonly", "true"); }
1146 if (settings.Max != null) { attributes.Add("max", settings.Max.ToString()); }
1147 if (settings.Min != null) { attributes.Add("min", settings.Min.ToString()); }
1148 if (settings.Step != 0) { attributes.Add("step", settings.Step.ToString()); }
1149 if (settings.Value != null && !string.IsNullOrEmpty(settings.Value.ToString())) { attributes.Add("value", settings.Value.ToString()); }
1150 attributes.Add("type", "number");
1151
1152 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value);
1153
1154 <div class="form__field-group u-full-width @settings.WrapperCssClass dw-mod">
1155 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null )
1156 {
1157 <div class="u-full-width">
1158 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> }
1159 @if (settings.Link != null) {
1160 <div class="u-pull--right">
1161 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; }
1162 @Render(settings.Link)
1163 </div>
1164 }
1165 </div>
1166
1167 }
1168
1169 @if (!string.IsNullOrEmpty(settings.HelpText))
1170 {
1171 <small class="form__help-text">@settings.HelpText</small>
1172 }
1173
1174 @if (settings.ActionButton != null)
1175 {
1176 settings.ActionButton.CssClass += " btn--condensed u-no-margin";
1177 <div class="form__field-combi u-no-margin dw-mod">
1178 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" />
1179 @Render(settings.ActionButton)
1180 </div>
1181 }
1182 else
1183 {
1184 <div class="form__field-combi u-no-margin dw-mod">
1185 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" />
1186 </div>
1187 }
1188
1189 @Render(new NotificationMessage { Message = settings.ErrorMessage })
1190 </div>
1191 }
1192 @using System.Reflection
1193 @using Dynamicweb.Rapido.Blocks.Components.General
1194 @using Dynamicweb.Rapido.Blocks.Components
1195
1196
1197 @* Component *@
1198
1199 @helper RenderTextareaField(TextareaField settings)
1200 {
1201 Dictionary<string, string> attributes = new Dictionary<string, string>();
1202 string id = settings.Id;
1203 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(id))
1204 {
1205 id = Guid.NewGuid().ToString("N");
1206 }
1207
1208 if (!string.IsNullOrEmpty(id)) { attributes.Add("id", id); }
1209 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); }
1210 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); }
1211 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); }
1212 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); }
1213 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); }
1214 if (!string.IsNullOrEmpty(settings.Placeholder)) { attributes.Add("placeholder", settings.Placeholder); }
1215 if (settings.Disabled) { attributes.Add("disabled", "true"); }
1216 if (settings.Required) { attributes.Add("required", "true"); }
1217 if (settings.ReadOnly) { attributes.Add("readonly", "true"); }
1218 if (settings.MaxLength != 0) { attributes.Add("maxlength", settings.MaxLength.ToString()); }
1219 if (settings.Rows != 0) { attributes.Add("rows", settings.Rows.ToString()); }
1220 attributes.Add("name", settings.Name);
1221
1222 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; }
1223
1224 <div class="form__field-group @settings.WrapperCssClass dw-mod">
1225 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null )
1226 {
1227 <div class="u-full-width">
1228 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> }
1229 @if (settings.Link != null) {
1230 <div class="u-pull--right">
1231 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; }
1232 @Render(settings.Link)
1233 </div>
1234 }
1235 </div>
1236 }
1237
1238 @if (!string.IsNullOrEmpty(settings.HelpText))
1239 {
1240 <small class="form__help-text">@settings.HelpText</small>
1241 }
1242
1243 <textarea class="u-full-width @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@settings.Value</textarea>
1244
1245 @Render(new NotificationMessage { Message = settings.ErrorMessage })
1246 </div>
1247 }
1248 @using System.Reflection
1249 @using Dynamicweb.Rapido.Blocks.Components.General
1250 @using Dynamicweb.Rapido.Blocks.Components
1251
1252
1253 @* Component *@
1254
1255 @helper RenderHiddenField(HiddenField settings) {
1256 var attributes = new Dictionary<string, string>();
1257 attributes.Add("type", "hidden");
1258 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); }
1259 if (settings.Value != null) { attributes.Add("value", settings.Value); }
1260 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); }
1261
1262 <input @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)/>
1263 }
1264 @using System.Reflection
1265 @using Dynamicweb.Rapido.Blocks.Components.General
1266 @using Dynamicweb.Rapido.Blocks.Components
1267
1268 @* Component *@
1269
1270 @helper RenderCheckboxField(CheckboxField settings)
1271 {
1272 var attributes = new Dictionary<string, string>();
1273 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id))
1274 {
1275 settings.Id = Guid.NewGuid().ToString("N");
1276 }
1277
1278 /*base settings*/
1279 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); }
1280 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); }
1281 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); }
1282 if (settings.Disabled) { attributes.Add("disabled", "true"); }
1283 if (settings.Required) { attributes.Add("required", "true"); }
1284 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); }
1285 /*end*/
1286
1287 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; }
1288
1289 attributes.Add("type", "checkbox");
1290 if (settings.Checked) { attributes.Add("checked", "true"); }
1291 settings.CssClass = "form__control " + settings.CssClass;
1292 if (settings.Value != null) { attributes.Add("value", settings.Value); }
1293
1294 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value);
1295
1296 <div class="form__field-group @settings.WrapperCssClass dw-mod">
1297 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" />
1298 @if (!string.IsNullOrEmpty(settings.Label))
1299 {
1300 <label for="@settings.Id" class="dw-mod">@settings.Label</label>
1301 }
1302
1303 @if (settings.Link != null) {
1304 <span>
1305 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; }
1306 @Render(settings.Link)
1307 </span>
1308 }
1309
1310 @if (!string.IsNullOrEmpty(settings.HelpText))
1311 {
1312 <small class="form__help-text checkbox-help dw-mod">@settings.HelpText</small>
1313 }
1314 @Render(new NotificationMessage { Message = settings.ErrorMessage })
1315 </div>
1316 }
1317 @using System.Reflection
1318 @using Dynamicweb.Rapido.Blocks.Components.General
1319 @using Dynamicweb.Rapido.Blocks.Components
1320
1321
1322 @* Component *@
1323
1324 @helper RenderCheckboxListField(CheckboxListField settings)
1325 {
1326 <div class="form__field-group @settings.WrapperCssClass u-margin-bottom dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)>
1327 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null )
1328 {
1329 <div class="u-full-width">
1330 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> }
1331 @if (settings.Link != null) {
1332 <div class="u-pull--right">
1333 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; }
1334 @Render(settings.Link)
1335 </div>
1336 }
1337 </div>
1338
1339 }
1340
1341 <div class="u-pull--left">
1342 @if (!string.IsNullOrEmpty(settings.HelpText))
1343 {
1344 <small class="form__help-text">@settings.HelpText</small>
1345 }
1346
1347 @foreach (var item in settings.Options)
1348 {
1349 if (settings.Required)
1350 {
1351 item.Required = true;
1352 }
1353 if (settings.Disabled)
1354 {
1355 item.Disabled = true;
1356 }
1357 if (!string.IsNullOrEmpty(settings.Name))
1358 {
1359 item.Name = settings.Name;
1360 }
1361 if (!string.IsNullOrEmpty(settings.CssClass))
1362 {
1363 item.CssClass += settings.CssClass;
1364 }
1365
1366 /* value is not supported */
1367
1368 if (!string.IsNullOrEmpty(settings.OnClick))
1369 {
1370 item.OnClick += settings.OnClick;
1371 }
1372 if (!string.IsNullOrEmpty(settings.OnChange))
1373 {
1374 item.OnChange += settings.OnChange;
1375 }
1376 @Render(item)
1377 }
1378
1379 @Render(new NotificationMessage { Message = settings.ErrorMessage })
1380 </div>
1381
1382 </div>
1383 }
1384 @using Dynamicweb.Rapido.Blocks.Components.General
1385
1386 @* Component *@
1387
1388 @helper RenderSearch(Search settings)
1389 {
1390 var searchValue = HttpContext.Current.Request.QueryString.Get(settings.SearchParameter) ?? "";
1391 var groupValue = HttpContext.Current.Request.QueryString.Get(settings.GroupsParameter) ?? "";
1392
1393 if (string.IsNullOrEmpty(settings.Id))
1394 {
1395 settings.Id = Guid.NewGuid().ToString("N");
1396 }
1397
1398 var resultAttributes = new Dictionary<string, string>();
1399
1400 if (settings.PageSize != 0)
1401 {
1402 resultAttributes.Add("data-page-size", settings.PageSize.ToString());
1403 }
1404 if (!string.IsNullOrEmpty(settings.GroupItemsFeedUrl))
1405 {
1406 resultAttributes.Add("data-groups-feed-url", settings.GroupItemsFeedUrl);
1407 if (!string.IsNullOrEmpty(groupValue))
1408 {
1409 resultAttributes.Add("data-selected-group", groupValue);
1410 }
1411 if (!string.IsNullOrEmpty(settings.GroupsParameter))
1412 {
1413 resultAttributes.Add("data-groups-parameter", settings.GroupsParameter);
1414 }
1415 }
1416 resultAttributes.Add("data-force-init", "true");
1417 if (settings.GoToFirstSearchResultOnEnter)
1418 {
1419 resultAttributes.Add("data-go-to-first-search-result-on-enter", settings.GoToFirstSearchResultOnEnter.ToString().ToLower());
1420 }
1421 if (!string.IsNullOrEmpty(settings.SearchParameter))
1422 {
1423 resultAttributes.Add("data-search-parameter", settings.SearchParameter);
1424 }
1425 resultAttributes.Add("data-search-feed-url", settings.SearchData.SearchFeedUrl);
1426 resultAttributes.Add("data-results-template-id", settings.SearchData.ResultsTemplateId);
1427
1428 if (settings.SecondSearchData != null)
1429 {
1430 resultAttributes.Add("data-second-search-feed-url", settings.SecondSearchData.SearchFeedUrl);
1431 resultAttributes.Add("data-second-results-template-id", settings.SecondSearchData.ResultsTemplateId);
1432 }
1433 if (!string.IsNullOrEmpty(settings.ResultsPageUrl))
1434 {
1435 resultAttributes.Add("data-results-page-url", settings.ResultsPageUrl);
1436 }
1437
1438 resultAttributes = resultAttributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value);
1439
1440 string searchFieldCss = (settings.SearchButton == null) ? "search--with-icon" : "";
1441
1442 <div class="search @settings.CssClass @searchFieldCss js-search-data-source dw-mod" id="@settings.Id" @ComponentMethods.AddAttributes(resultAttributes)>
1443 @if (!string.IsNullOrEmpty(settings.GroupItemsFeedUrl))
1444 {
1445 <button type="button" class="search__groups-btn dw-mod js-search-groups-btn">@Translate("All")</button>
1446 <ul class="dropdown dropdown--absolute-position dw-mod search__groups-results js-search-groups-list"></ul>
1447 }
1448
1449 <input type="text" class="search__field dw-mod js-search-field" placeholder="@settings.Placeholder" value="@searchValue">
1450
1451 <div class="dropdown dropdown--absolute-position search__results dw-mod js-search-results @(settings.SecondSearchData != null ? "search__results--combined" : "")">
1452 @if (settings.SecondSearchData != null)
1453 {
1454 <div class="search__column search__column--products dw-mod">
1455 <div class="search__column-header dw-mod">@Translate("Products")</div>
1456 <ul class="search__results-list dw-mod js-search-results-list" id="@(settings.Id)_ResultsList"></ul>
1457 @if (!string.IsNullOrEmpty(settings.SearchData.ResultsPageUrl))
1458 {
1459 @Render(new Link {
1460 Title = Translate("View all"),
1461 CssClass = "js-view-all-button u-margin",
1462 Href = settings.SearchData.ResultsPageUrl
1463 });
1464 }
1465 </div>
1466 <div class="search__column search__column--pages dw-mod">
1467 <div class="search__column-header">@Translate("Pages")</div>
1468 <ul class="search__results-list dw-mod js-search-results-second-list" id="@(settings.Id)_SecondResultsList"></ul>
1469 @if (!string.IsNullOrEmpty(settings.SecondSearchData.ResultsPageUrl))
1470 {
1471 @Render(new Link
1472 {
1473 Title = Translate("View all"),
1474 CssClass = "js-view-all-button u-margin",
1475 Href = settings.SecondSearchData.ResultsPageUrl
1476 });
1477 }
1478 </div>
1479 }
1480 else
1481 {
1482 <div class="search__column search__column--only dw-mod">
1483 <ul class="search__results-list dw-mod js-search-results-list" id="@(settings.Id)_ResultsList"></ul>
1484 @if (!string.IsNullOrEmpty(settings.SearchData.ResultsPageUrl))
1485 {
1486 @Render(new Link {
1487 Title = Translate("View all"),
1488 CssClass = "js-view-all-button u-margin",
1489 Href = settings.SearchData.ResultsPageUrl
1490 });
1491 }
1492 </div>
1493 }
1494 </div>
1495
1496 @if (settings.SearchButton != null)
1497 {
1498 settings.SearchButton.CssClass += " search__btn js-search-btn";
1499 if (settings.RenderDefaultSearchIcon)
1500 {
1501 settings.SearchButton.Icon = new Icon { Name = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SearchIcon").SelectedValue };
1502 }
1503 @Render(settings.SearchButton);
1504 }
1505 </div>
1506 }
1507 @using System.Reflection
1508 @using Dynamicweb.Rapido.Blocks.Components.General
1509 @using Dynamicweb.Rapido.Blocks.Components
1510
1511
1512 @* Component *@
1513
1514 @helper RenderSelectField(SelectField settings)
1515 {
1516 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id))
1517 {
1518 settings.Id = Guid.NewGuid().ToString("N");
1519 }
1520
1521 <div class="form__field-group u-full-width @settings.WrapperCssClass dw-mod">
1522 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null )
1523 {
1524 <div class="u-full-width">
1525 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> }
1526 @if (settings.Link != null) {
1527 <div class="u-pull--right">
1528 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; }
1529 @Render(settings.Link)
1530 </div>
1531 }
1532 </div>
1533 }
1534
1535 @if (!string.IsNullOrEmpty(settings.HelpText))
1536 {
1537 <small class="form__help-text">@settings.HelpText</small>
1538 }
1539
1540 @if (settings.ActionButton != null)
1541 {
1542 settings.ActionButton.CssClass += " btn--condensed u-no-margin";
1543 <div class="form__field-combi u-no-margin dw-mod">
1544 @RenderSelectBase(settings)
1545 @Render(settings.ActionButton)
1546 </div>
1547 }
1548 else
1549 {
1550 @RenderSelectBase(settings)
1551 }
1552
1553 @Render(new NotificationMessage { Message = settings.ErrorMessage })
1554 </div>
1555 }
1556
1557 @helper RenderSelectBase(SelectField settings)
1558 {
1559 var attributes = new Dictionary<string, string>();
1560
1561 /*base settings*/
1562 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); }
1563 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); }
1564 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); }
1565 if (settings.Disabled) { attributes.Add("disabled", "true"); }
1566 if (settings.Required) { attributes.Add("required", "true"); }
1567 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); }
1568 /*end*/
1569
1570 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value);
1571
1572 <select @ComponentMethods.AddAttributes(resultAttributes) class="u-full-width @settings.CssClass dw-mod">
1573 @if (settings.Default != null)
1574 {
1575 @Render(settings.Default)
1576 }
1577
1578 @foreach (var item in settings.Options)
1579 {
1580 if (settings.Value != null) {
1581 item.Checked = item.Value == settings.Value;
1582 }
1583 @Render(item)
1584 }
1585 </select>
1586 }
1587 @using System.Reflection
1588 @using Dynamicweb.Rapido.Blocks.Components.General
1589 @using Dynamicweb.Rapido.Blocks.Components
1590
1591 @* Component *@
1592
1593 @helper RenderRadioButtonField(RadioButtonField settings)
1594 {
1595 var attributes = new Dictionary<string, string>();
1596 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id))
1597 {
1598 settings.Id = Guid.NewGuid().ToString("N");
1599 }
1600
1601 /*base settings*/
1602 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); }
1603 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); }
1604 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); }
1605 if (settings.Disabled) { attributes.Add("disabled", "true"); }
1606 if (settings.Required) { attributes.Add("required", "true"); }
1607 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); }
1608 /*end*/
1609
1610 attributes.Add("type", "radio");
1611 if (settings.Checked) { attributes.Add("checked", "true"); }
1612 settings.CssClass = "form__control " + settings.CssClass;
1613 if (settings.Value != null) { attributes.Add("value", settings.Value); }
1614
1615 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value);
1616
1617 <div class="form__field-group @settings.WrapperCssClass dw-mod">
1618 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" />
1619 @if (!string.IsNullOrEmpty(settings.Label))
1620 {
1621 <label for="@settings.Id" class="dw-mod">@settings.Label</label>
1622 }
1623 @if (!string.IsNullOrEmpty(settings.HelpText))
1624 {
1625 <small class="form__help-text">@settings.HelpText</small>
1626 }
1627 @Render(new NotificationMessage { Message = settings.ErrorMessage })
1628 </div>
1629 }
1630 @using System.Reflection
1631 @using Dynamicweb.Rapido.Blocks.Components.General
1632 @using Dynamicweb.Rapido.Blocks.Components
1633
1634
1635 @* Component *@
1636
1637 @helper RenderRadioButtonListField(RadioButtonListField settings)
1638 {
1639 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; }
1640
1641 <div class="form__field-group @settings.WrapperCssClass u-margin-bottom dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)>
1642 @if (!string.IsNullOrEmpty(settings.Label))
1643 {
1644 <label>@settings.Label</label>
1645 }
1646 @if (!string.IsNullOrEmpty(settings.HelpText))
1647 {
1648 <small class="form__help-text">@settings.HelpText</small>
1649 }
1650
1651 @foreach (var item in settings.Options)
1652 {
1653 if (settings.Required)
1654 {
1655 item.Required = true;
1656 }
1657 if (settings.Disabled)
1658 {
1659 item.Disabled = true;
1660 }
1661 if (!string.IsNullOrEmpty(settings.Name))
1662 {
1663 item.Name = settings.Name;
1664 }
1665 if (settings.Value != null && settings.Value == item.Value)
1666 {
1667 item.Checked = true;
1668 }
1669 if (!string.IsNullOrEmpty(settings.OnClick))
1670 {
1671 item.OnClick += settings.OnClick;
1672 }
1673 if (!string.IsNullOrEmpty(settings.OnChange))
1674 {
1675 item.OnChange += settings.OnChange;
1676 }
1677 if (!string.IsNullOrEmpty(settings.CssClass))
1678 {
1679 item.CssClass += settings.CssClass;
1680 }
1681 @Render(item)
1682 }
1683
1684 @Render(new NotificationMessage { Message = settings.ErrorMessage })
1685 </div>
1686 }
1687 @using System.Reflection
1688 @using Dynamicweb.Rapido.Blocks.Components.General
1689 @using Dynamicweb.Rapido.Blocks.Components
1690
1691
1692 @* Component *@
1693
1694 @helper RenderNotificationMessage(NotificationMessage settings)
1695 {
1696 if (!string.IsNullOrEmpty(settings.Message))
1697 {
1698 var attributes = new Dictionary<string, string>();
1699 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); }
1700
1701 string messageTypeClass = Enum.GetName(typeof(NotificationMessageType), settings.MessageType).ToLower();
1702 string messageLayoutClass = Enum.GetName(typeof(NotificationMessageLayout), settings.MessageLayout).ToLower();
1703 string minHeightClass = settings.Icon != null ? "u-min-h70px" : "";
1704
1705 <div class="notification-message-@messageTypeClass notification-message-@messageLayoutClass @messageLayoutClass @minHeightClass @settings.CssClass u-full-width dw-mod" @ComponentMethods.AddAttributes(attributes)>
1706 @if (settings.Icon != null) {
1707 settings.Icon.Label = !string.IsNullOrEmpty(settings.Icon.Label) ? settings.Message + settings.Icon.Label : settings.Message;
1708 @Render(settings.Icon)
1709 } else {
1710 @settings.Message
1711 }
1712 </div>
1713 }
1714 }
1715 @using Dynamicweb.Rapido.Blocks.Components.General
1716
1717
1718 @* Component *@
1719
1720 @helper RenderHandlebarsRoot(HandlebarsRoot settings) {
1721 string preRender = !String.IsNullOrEmpty(settings.PreRenderScriptTemplate) ? "data-pre-render-template=\"" + settings.PreRenderScriptTemplate + "\"" : "";
1722
1723 <div class="@settings.CssClass dw-mod js-handlebars-root" id="@settings.Id" data-template="@settings.ScriptTemplate" data-json-feed="@settings.FeedUrl" data-init-onload="@settings.InitOnLoad.ToString()" data-preloader="@settings.Preloader" @preRender>
1724 @if (settings.SubBlocks != null) {
1725 @RenderBlockList(settings.SubBlocks)
1726 }
1727 </div>
1728 }
1729 @using System.Reflection
1730 @using Dynamicweb.Rapido.Blocks.Components.General
1731 @using Dynamicweb.Rapido.Blocks.Components
1732 @using System.Text.RegularExpressions
1733
1734
1735 @* Component *@
1736
1737 @helper RenderSticker(Sticker settings) {
1738 if (!String.IsNullOrEmpty(settings.Title)) {
1739 string size = settings.Size.ToString() != "None" ? "" + "stickers-container__tag--" + settings.Size.ToString().ToLower() : "";
1740 string style = settings.Style.ToString() != "None" ? "" + "stickers-container__tag--" + settings.Style.ToString().ToLower() : "";
1741
1742 Dictionary<String, String> optionalAttributes = new Dictionary<string, string>();
1743 if (!String.IsNullOrEmpty(settings.Color) || !String.IsNullOrEmpty(settings.BackgroundColor)) {
1744 string styleTag = !String.IsNullOrEmpty(settings.Color) ? "color: " + settings.Color + "; " : "";
1745 styleTag += !String.IsNullOrEmpty(settings.BackgroundColor) ? "background-color: " + settings.BackgroundColor + "; " : "";
1746 optionalAttributes.Add("style", styleTag);
1747 }
1748
1749 <div class="stickers-container__tag @size @style @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(optionalAttributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@settings.Title</div>
1750 }
1751 }
1752
1753 @using System.Reflection
1754 @using Dynamicweb.Rapido.Blocks.Components.General
1755 @using Dynamicweb.Rapido.Blocks.Components
1756
1757
1758 @* Component *@
1759
1760 @helper RenderStickersCollection(StickersCollection settings)
1761 {
1762 if (settings.Stickers.Count > 0)
1763 {
1764 string position = "stickers-container--" + Regex.Replace(settings.Position.ToString(), "([a-z])([A-Z])", "$1-$2").ToLower();
1765
1766 <div class="stickers-container @position @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)>
1767 @foreach (Sticker sticker in settings.Stickers)
1768 {
1769 @Render(sticker)
1770 }
1771 </div>
1772 }
1773 }
1774
1775 @using Dynamicweb.Rapido.Blocks.Components.General
1776
1777
1778 @* Component *@
1779
1780 @helper RenderForm(Form settings) {
1781 if (settings != null)
1782 {
1783 Dictionary<string, string> optionalAttributes = new Dictionary<string, string>();
1784 if (!string.IsNullOrEmpty(settings.Action)) { optionalAttributes.Add("action", settings.Action); };
1785 if (!string.IsNullOrEmpty(settings.Name)) { optionalAttributes.Add("name", settings.Name); };
1786 if (!string.IsNullOrEmpty(settings.OnSubmit)) { optionalAttributes.Add("onsubmit", settings.OnSubmit); };
1787 var enctypes = new Dictionary<string, string>
1788 {
1789 { "multipart", "multipart/form-data" },
1790 { "text", "text/plain" },
1791 { "application", "application/x-www-form-urlencoded" }
1792 };
1793 if (settings.Enctype != FormEnctype.none) { optionalAttributes.Add("enctype", enctypes[Enum.GetName(typeof(FormEnctype), settings.Enctype).ToLower()]); };
1794 optionalAttributes.Add("method", settings.Method.ToString());
1795
1796 if (!string.IsNullOrEmpty(settings.FormStartMarkup))
1797 {
1798 @settings.FormStartMarkup
1799 }
1800 else
1801 {
1802 @:<form class="@settings.CssClass u-no-margin dw-mod" @ComponentMethods.AddAttributes(optionalAttributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>
1803 }
1804
1805 foreach (var field in settings.GetFields())
1806 {
1807 @Render(field)
1808 }
1809
1810 @:</form>
1811 }
1812 }
1813 @using System.Reflection
1814 @using Dynamicweb.Rapido.Blocks.Components.General
1815 @using Dynamicweb.Rapido.Blocks.Components
1816
1817
1818 @* Component *@
1819
1820 @helper RenderText(Text settings)
1821 {
1822 @settings.Content
1823 }
1824 @using System.Reflection
1825 @using Dynamicweb.Rapido.Blocks.Components.General
1826 @using Dynamicweb.Rapido.Blocks.Components
1827
1828
1829 @* Component *@
1830
1831 @helper RenderContentModule(ContentModule settings) {
1832 if (!string.IsNullOrEmpty(settings.Content))
1833 {
1834 @settings.Content
1835 }
1836 }
1837 @using System.Reflection
1838 @using Dynamicweb.Rapido.Blocks.Components.General
1839 @using Dynamicweb.Rapido.Blocks.Components
1840
1841
1842 @* Component *@
1843
1844 @helper RenderModal(Modal settings) {
1845 if (settings != null)
1846 {
1847 string modalId = !string.IsNullOrEmpty(settings.Id) ? settings.Id : Guid.NewGuid().ToString("N");
1848
1849 string onchange = !string.IsNullOrEmpty(settings.OnClose) ? "onchange=\"if(!this.checked){" + settings.OnClose + "}\"" : "";
1850
1851 <input type="checkbox" id="@(modalId)ModalTrigger" class="modal-trigger" @onchange />
1852
1853 <div class="modal-container">
1854 @if (!settings.DisableDarkOverlay)
1855 {
1856 <label for="@(modalId)ModalTrigger" id="@(modalId)ModalOverlay" class="modal-overlay"></label>
1857 }
1858 <div class="modal modal--@settings.Width.ToString().ToLower() modal-height--@settings.Height.ToString().ToLower()" id="@(modalId)Modal">
1859 @if (settings.Heading != null)
1860 {
1861 if (!string.IsNullOrEmpty(settings.Heading.Title))
1862 {
1863 <div class="modal__header">
1864 @Render(settings.Heading)
1865 </div>
1866 }
1867 }
1868 <div class="modal__body @(settings.Width.ToString().ToLower() == "full" ? "modal__body--full" : "")">
1869 @if (!string.IsNullOrEmpty(settings.BodyText))
1870 {
1871 @settings.BodyText
1872 }
1873 @if (settings.BodyTemplate != null)
1874 {
1875 @settings.BodyTemplate
1876 }
1877 @{
1878 var actions = settings.GetActions();
1879 }
1880 </div>
1881 @if (actions.Length > 0)
1882 {
1883 <div class="modal__footer">
1884 @foreach (var action in actions)
1885 {
1886 if (Pageview.Device.ToString() != "Mobile") {
1887 action.CssClass += " u-no-margin";
1888 } else {
1889 action.CssClass += " u-full-width u-margin-bottom";
1890 }
1891
1892 @Render(action)
1893 }
1894 </div>
1895 }
1896 <label class="modal__close-btn" for="@(modalId)ModalTrigger"></label>
1897 </div>
1898 </div>
1899 }
1900 }
1901 @using Dynamicweb.Rapido.Blocks.Components.General
1902
1903 @* Component *@
1904
1905 @helper RenderMediaListItem(MediaListItem settings)
1906 {
1907 <div class="media-list-item @settings.CssClass dw-mod" @(!string.IsNullOrEmpty(settings.Id) ? "id=\"" + settings.Id + "\"" : "")>
1908 @if (!string.IsNullOrEmpty(settings.Label))
1909 {
1910 if (!string.IsNullOrEmpty(settings.Link))
1911 {
1912 @Render(new Link
1913 {
1914 Href = settings.Link,
1915 CssClass = "media-list-item__sticker dw-mod",
1916 ButtonLayout = ButtonLayout.None,
1917 Title = settings.Label,
1918 OnClick = !string.IsNullOrEmpty(settings.OnClick) ? settings.OnClick : ""
1919 })
1920 }
1921 else if (!string.IsNullOrEmpty(settings.OnClick))
1922 {
1923 <span class="media-list-item__sticker dw-mod" onclick="@(settings.OnClick)">
1924 <span class="u-uppercase">@settings.Label</span>
1925 </span>
1926 }
1927 else
1928 {
1929 <span class="media-list-item__sticker media-list-item__sticker--no-link dw-mod">
1930 <span class="u-uppercase">@settings.Label</span>
1931 </span>
1932 }
1933 }
1934 <div class="media-list-item__wrap">
1935 <div class="media-list-item__info dw-mod">
1936 <div class="media-list-item__header dw-mod">
1937 @if (!string.IsNullOrEmpty(settings.Title))
1938 {
1939 if (!string.IsNullOrEmpty(settings.Link))
1940 {
1941 @Render(new Link
1942 {
1943 Href = settings.Link,
1944 CssClass = "media-list-item__name dw-mod",
1945 ButtonLayout = ButtonLayout.None,
1946 Title = settings.Title,
1947 OnClick = !string.IsNullOrEmpty(settings.OnClick) ? settings.OnClick : ""
1948 })
1949 }
1950 else if (!string.IsNullOrEmpty(settings.OnClick))
1951 {
1952 <span class="media-list-item__name dw-mod" onclick="@(settings.OnClick)">@settings.Title</span>
1953 }
1954 else
1955 {
1956 <span class="media-list-item__name media-list-item__name--no-link dw-mod">@settings.Title</span>
1957 }
1958 }
1959
1960 @if (!string.IsNullOrEmpty(settings.Status))
1961 {
1962 <div class="media-list-item__state dw-mod">@settings.Status</div>
1963 }
1964 </div>
1965 @{
1966 settings.InfoTable.CssClass += " media-list-item__parameters-table";
1967 }
1968
1969 @Render(settings.InfoTable)
1970 </div>
1971 <div class="media-list-item__actions dw-mod">
1972 <div class="media-list-item__actions-list dw-mod">
1973 @{
1974 var actions = settings.GetActions();
1975
1976 foreach (ButtonBase action in actions)
1977 {
1978 action.ButtonLayout = ButtonLayout.None;
1979 action.CssClass += " media-list-item__action link";
1980
1981 @Render(action)
1982 }
1983 }
1984 </div>
1985
1986 @if (settings.SelectButton != null && !string.IsNullOrEmpty(settings.SelectButton.Title))
1987 {
1988 settings.SelectButton.CssClass += " u-no-margin";
1989
1990 <div class="media-list-item__action-button">
1991 @Render(settings.SelectButton)
1992 </div>
1993 }
1994 </div>
1995 </div>
1996 </div>
1997 }
1998 @using Dynamicweb.Rapido.Blocks.Components.General
1999 @using Dynamicweb.Rapido.Blocks.Components
2000
2001 @helper RenderTable(Table settings)
2002 {
2003 Dictionary<string, string> attributes = new Dictionary<string, string>();
2004 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); }
2005
2006 var enumToClasses = new Dictionary<TableDesign, string>
2007 {
2008 { TableDesign.Clean, "table--clean" },
2009 { TableDesign.Bordered, "table--bordered" },
2010 { TableDesign.Striped, "table--striped" },
2011 { TableDesign.Hover, "table--hover" },
2012 { TableDesign.Compact, "table--compact" },
2013 { TableDesign.Condensed, "table--condensed" },
2014 { TableDesign.NoTopBorder, "table--no-top-border" }
2015 };
2016 string tableDesignClass = "";
2017 if (settings.Design != TableDesign.None)
2018 {
2019 tableDesignClass = enumToClasses[settings.Design];
2020 }
2021
2022 if (!string.IsNullOrEmpty(settings.CssClass) || settings.Design != TableDesign.None) { attributes.Add("class", "table " + tableDesignClass + " " + settings.CssClass + " dw-mod"); }
2023
2024 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.Last().Value);
2025
2026 <table @ComponentMethods.AddAttributes(resultAttributes)>
2027 @if (settings.Header != null)
2028 {
2029 <thead>
2030 @Render(settings.Header)
2031 </thead>
2032 }
2033 <tbody>
2034 @foreach (var row in settings.Rows)
2035 {
2036 @Render(row)
2037 }
2038 </tbody>
2039 @if (settings.Footer != null)
2040 {
2041 <tfoot>
2042 @Render(settings.Footer)
2043 </tfoot>
2044 }
2045 </table>
2046 }
2047 @using Dynamicweb.Rapido.Blocks.Components.General
2048 @using Dynamicweb.Rapido.Blocks.Components
2049
2050 @helper RenderTableRow(TableRow settings)
2051 {
2052 Dictionary<string, string> attributes = new Dictionary<string, string>();
2053 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); }
2054
2055 var enumToClasses = new Dictionary<TableRowDesign, string>
2056 {
2057 { TableRowDesign.NoBorder, "table__row--no-border" },
2058 { TableRowDesign.Border, "table__row--border" },
2059 { TableRowDesign.TopBorder, "table__row--top-line" },
2060 { TableRowDesign.BottomBorder, "table__row--bottom-line" },
2061 { TableRowDesign.Solid, "table__row--solid" }
2062 };
2063
2064 string tableRowDesignClass = "";
2065 if (settings.Design != TableRowDesign.None)
2066 {
2067 tableRowDesignClass = enumToClasses[settings.Design];
2068 }
2069
2070 if (!string.IsNullOrEmpty(settings.CssClass) || settings.Design != TableRowDesign.None) { attributes.Add("class", "table__row " + tableRowDesignClass + " " + settings.CssClass + " dw-mod"); }
2071
2072 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.Last().Value);
2073
2074 <tr @ComponentMethods.AddAttributes(resultAttributes)>
2075 @foreach (var cell in settings.Cells)
2076 {
2077 if (settings.IsHeaderRow)
2078 {
2079 cell.IsHeader = true;
2080 }
2081 @Render(cell)
2082 }
2083 </tr>
2084 }
2085 @using Dynamicweb.Rapido.Blocks.Components.General
2086 @using Dynamicweb.Rapido.Blocks.Components
2087 @using Dynamicweb.Core
2088
2089 @helper RenderTableCell(TableCell settings)
2090 {
2091 Dictionary<string, string> attributes = new Dictionary<string, string>();
2092 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); }
2093 if (settings.Colspan != 0) { attributes.Add("colspan", Converter.ToString(settings.Colspan)); }
2094 if (settings.Rowspan != 0) { attributes.Add("rowspan", Converter.ToString(settings.Rowspan)); }
2095 if (!string.IsNullOrEmpty(settings.CssClass)) { attributes.Add("class", settings.CssClass + " dw-mod"); }
2096
2097 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.Last().Value);
2098
2099 string tagName = settings.IsHeader ? "th" : "td";
2100
2101 @("<" + tagName + " " + ComponentMethods.AddAttributes(resultAttributes) + ">")
2102 @settings.Content
2103 @("</" + tagName + ">");
2104 }
2105 @using System.Linq
2106 @using Dynamicweb.Rapido.Blocks.Components.General
2107
2108 @* Component *@
2109
2110 @helper RenderPagination(Dynamicweb.Rapido.Blocks.Components.General.Pagination settings)
2111 {
2112 var pageNumberQueryStringName = Dynamicweb.Rapido.Services.Pagination.GetPageNumberQueryStringName(settings); // Get the proper 'page number' query string parameter
2113 var queryParameters = Dynamicweb.Rapido.Services.Url.GetQueryParameters(pageNumberQueryStringName); // Get the NameValueCollection from the querystring
2114
2115 if (settings.NumberOfPages > 1)
2116 {
2117 string url = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + "/Default.aspx";
2118 string ariaLabel = !string.IsNullOrWhiteSpace(settings.AriaLabel) ? settings.AriaLabel : Translate("Page navigation");
2119 Dictionary<string, int> startAndEndPageNumber = Dynamicweb.Rapido.Services.Pagination.GetStartAndEndPageNumber(settings);
2120
2121 <div class="pager u-margin-top dw-mod @settings.CssClass" aria-label="@ariaLabel">
2122 @if (settings.ShowPagingInfo)
2123 {
2124 <div class="pager__info dw-mod">
2125 @Translate("Page") @settings.CurrentPageNumber @Translate("of") @settings.NumberOfPages
2126 </div>
2127 }
2128 <ul class="pager__list dw-mod">
2129 @if (!string.IsNullOrWhiteSpace(settings.FirstPageUrl) && settings.ShowFirstAndLastControls)
2130 {
2131 @Render(new PaginationItem { Link = settings.FirstPageUrl, Icon = settings.FirstIcon })
2132 }
2133 @if (!string.IsNullOrWhiteSpace(settings.PreviousPageUrl) && settings.ShowNextAndPrevControls)
2134 {
2135 @Render(new PaginationItem { Link = settings.PreviousPageUrl, Icon = settings.PrevIcon })
2136 }
2137 @if (settings.GetPages().Any())
2138 {
2139 foreach (var page in settings.GetPages())
2140 {
2141 @Render(page)
2142 }
2143 }
2144 else
2145 {
2146 for (var page = startAndEndPageNumber["StartPage"]; page <= startAndEndPageNumber["EndPage"]; page++)
2147 {
2148 queryParameters = Dynamicweb.Rapido.Services.Url.UpdateQueryStringParameter(queryParameters, pageNumberQueryStringName, page.ToString());
2149 @Render(new PaginationItem { Label = page.ToString(), Link = Dynamicweb.Rapido.Services.Url.BuildUri(url, queryParameters).PathAndQuery, IsActive = (settings.CurrentPageNumber == page) });
2150 }
2151 }
2152 @if (!string.IsNullOrWhiteSpace(settings.NextPageUrl) && settings.ShowNextAndPrevControls)
2153 {
2154 @Render(new PaginationItem { Link = settings.NextPageUrl, Icon = settings.NextIcon })
2155 }
2156 @if (!string.IsNullOrWhiteSpace(settings.LastPageUrl) && settings.ShowFirstAndLastControls)
2157 {
2158 @Render(new PaginationItem { Link = settings.LastPageUrl, Icon = settings.LastIcon })
2159 }
2160 </ul>
2161 </div>
2162 }
2163 }
2164
2165 @helper RenderPaginationItem(PaginationItem settings)
2166 {
2167 if (settings.Icon == null)
2168 {
2169 settings.Icon = new Icon();
2170 }
2171
2172 settings.Icon.Label = settings.Label;
2173 <li class="pager__btn dw-mod">
2174 @if (settings.IsActive)
2175 {
2176 <span class="pager__num pager__num--current dw-mod">
2177 @Render(settings.Icon)
2178 </span>
2179 }
2180 else
2181 {
2182 <a href="@settings.Link" class="pager__num dw-mod">
2183 @Render(settings.Icon)
2184 </a>
2185 }
2186 </li>
2187 }
2188
2189
2190 @using Dynamicweb.Rapido.Blocks.Components.General
2191 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce
2192
2193
2194 @using Dynamicweb.Rapido.Blocks.Components
2195 @using Dynamicweb.Rapido.Blocks.Components.General
2196 @using Dynamicweb.Rapido.Blocks
2197 @using System.IO
2198
2199
2200 @using Dynamicweb.Rapido.Blocks.Components.General
2201 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce
2202
2203
2204 @* Component *@
2205
2206 @helper RenderVariantMatrix(VariantMatrix settings) {
2207 if (settings != null)
2208 {
2209 int productLoopCounter = 0;
2210 int groupCount = 0;
2211 List<VariantOption> firstDimension = new List<VariantOption>();
2212 List<VariantOption> secondDimension = new List<VariantOption>();
2213 List<VariantOption> thirdDimension = new List<VariantOption>();
2214
2215 foreach (VariantGroup variantGroup in settings.GetVariantGroups())
2216 {
2217 foreach (VariantOption variantOptions in variantGroup.GetVariantOptions())
2218 {
2219 if (groupCount == 0) {
2220 firstDimension.Add(variantOptions);
2221 }
2222 if (groupCount == 1)
2223 {
2224 secondDimension.Add(variantOptions);
2225 }
2226 if (groupCount == 2)
2227 {
2228 thirdDimension.Add(variantOptions);
2229 }
2230 }
2231 groupCount++;
2232 }
2233
2234 int rowCount = 0;
2235 int columnCount = 0;
2236
2237 <script>
2238 var variantsCollection = [];
2239 </script>
2240
2241 <table class="table table--compact js-variants-matrix dw-mod" id="VariantMatrixTable_@settings.ProductId">
2242 @if (groupCount == 1)
2243 {
2244 <tbody>
2245 @foreach (VariantOption firstVariantOption in firstDimension)
2246 {
2247 var variantId = firstVariantOption.Id;
2248 <tr>
2249 <td class="u-bold">
2250 @firstVariantOption.Name
2251 </td>
2252 <td>
2253 @RenderVariantMatrixQuantityField(variantId, settings, productLoopCounter, rowCount, columnCount)
2254 </td>
2255 </tr>
2256 productLoopCounter++;
2257 }
2258
2259 <tr>
2260 <td> </td>
2261 <td>
2262 <div class="qty-field js-total-qty-column-@columnCount dw-mod">0</div>
2263 </td>
2264 </tr>
2265 </tbody>
2266 }
2267 @if (groupCount == 2)
2268 {
2269 <thead>
2270 <tr>
2271 <td> </td>
2272 @foreach (VariantOption variant in secondDimension)
2273 {
2274 <td>@variant.Name</td>
2275 }
2276 </tr>
2277 </thead>
2278 <tbody>
2279 @foreach (VariantOption firstVariantOption in firstDimension)
2280 {
2281 string variantId = "";
2282 columnCount = 0;
2283
2284 <tr>
2285 <td class="u-min-w120px">@firstVariantOption.Name</td>
2286
2287 @foreach (VariantOption secondVariantOption in secondDimension)
2288 {
2289 variantId = firstVariantOption.Id + "." + secondVariantOption.Id;
2290 <td>
2291 @RenderVariantMatrixQuantityField(variantId, settings, productLoopCounter, rowCount, columnCount)
2292 </td>
2293
2294 columnCount++;
2295
2296 productLoopCounter++;
2297 }
2298
2299 <td>
2300 <div class="qty-field js-total-qty-row-@rowCount dw-mod">0</div>
2301 </td>
2302 </tr>
2303
2304 rowCount++;
2305 }
2306
2307 @{
2308 columnCount = 0;
2309 }
2310
2311 <tr>
2312 <td> </td>
2313 @foreach (VariantOption secondVariantOption in secondDimension)
2314 {
2315 <td>
2316 <div class="qty-field js-total-qty-column-@columnCount dw-mod">0</div>
2317 </td>
2318
2319 columnCount++;
2320 }
2321 <td> </td>
2322 </tr>
2323 </tbody>
2324 }
2325 @if (groupCount == 3)
2326 {
2327 <thead>
2328 <tr>
2329 <td> </td>
2330 @foreach (VariantOption thirdVariantOption in thirdDimension)
2331 {
2332 <td>@thirdVariantOption.Name</td>
2333 }
2334 </tr>
2335 </thead>
2336 <tbody>
2337 @foreach (VariantOption firstVariantOption in firstDimension)
2338 {
2339 int colspan = (thirdDimension.Count + 1);
2340
2341 <tr>
2342 <td colspan="@colspan" class="u-color-light-gray--bg u-bold">@firstVariantOption.Name</td>
2343 </tr>
2344
2345 foreach (VariantOption secondVariantOption in secondDimension)
2346 {
2347 string variantId = "";
2348 columnCount = 0;
2349
2350 <tr>
2351 <td class="u-min-w120px">@secondVariantOption.Name</td>
2352
2353 @foreach (VariantOption thirdVariantOption in thirdDimension)
2354 {
2355 variantId = firstVariantOption.Id + "." + secondVariantOption.Id + "." + thirdVariantOption.Id;
2356
2357 <td>
2358 @RenderVariantMatrixQuantityField(variantId, settings, productLoopCounter, rowCount, columnCount)
2359 </td>
2360
2361 columnCount++;
2362 productLoopCounter++;
2363 }
2364
2365 <td>
2366 <div class="qty-field js-total-qty-row-@rowCount dw-mod">0</div>
2367 </td>
2368 </tr>
2369 rowCount++;
2370 }
2371 }
2372
2373 @{
2374 columnCount = 0;
2375 }
2376
2377 <tr>
2378 <td> </td>
2379 @foreach (VariantOption thirdVariantOption in thirdDimension)
2380 {
2381 <td>
2382 <div class="qty-field js-total-qty-column-@columnCount dw-mod">0</div>
2383 </td>
2384
2385 columnCount++;
2386 }
2387 <td> </td>
2388 </tr>
2389 </tbody>
2390 }
2391 </table>
2392
2393 <script>
2394 document.addEventListener("DOMContentLoaded", function (event) {
2395 MatrixUpdateQuantity("@settings.ProductId");
2396 });
2397
2398 MatrixUpdateQuantity = function (productId) {
2399 var currentMatrix = document.getElementById("VariantMatrixTable_" + productId);
2400 var allQtyFields = currentMatrix.getElementsByClassName("js-qty");
2401
2402 var qtyRowArr = [];
2403 var qtyColumnArr = [];
2404
2405 var totalQty = 0;
2406
2407 for (var i = 0; i < allQtyFields.length; i++) {
2408 qtyRowArr[allQtyFields[i].getAttribute("data-qty-row-group")] = 0;
2409 qtyColumnArr[allQtyFields[i].getAttribute("data-qty-column-group")] = 0;
2410 }
2411
2412 for (var i = 0; i < allQtyFields.length; i++) {
2413 qtyRowArr[allQtyFields[i].getAttribute("data-qty-row-group")] += parseFloat(allQtyFields[i].value);
2414 qtyColumnArr[allQtyFields[i].getAttribute("data-qty-column-group")] += parseFloat(allQtyFields[i].value);
2415 totalQty += parseFloat(allQtyFields[i].value);
2416 }
2417
2418 //Update row counters
2419 for (var i = 0; i < qtyRowArr.length; i++) {
2420 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-row-" + i)[0];
2421
2422 if (qtyRowArr[i] != undefined && qtyCounter != null) {
2423 var currentCount = qtyCounter.innerHTML;
2424 qtyCounter.innerHTML = qtyRowArr[i];
2425
2426 if (currentCount != qtyCounter.innerHTML) {
2427 qtyCounter.classList.add("qty-field--active");
2428 }
2429 }
2430
2431 }
2432
2433 //Update column counters
2434 for (var i = 0; i < qtyColumnArr.length; i++) {
2435 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-column-" + i)[0];
2436
2437 if (qtyColumnArr[i] != undefined && qtyCounter != null) {
2438 var currentCount = qtyCounter.innerHTML;
2439 qtyCounter.innerHTML = qtyColumnArr[i];
2440
2441 if (currentCount != qtyCounter.innerHTML) {
2442 qtyCounter.classList.add("qty-field--active");
2443 }
2444 }
2445 }
2446
2447 if (document.getElementById("TotalQtyCount_" + productId)) {
2448 document.getElementById("TotalQtyCount_" + productId).innerHTML = totalQty;
2449 }
2450
2451 //Clean up animations
2452 setTimeout(function () {
2453 for (var i = 0; i < qtyRowArr.length; i++) {
2454 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-row-" + i)[0];
2455 if (qtyCounter != null) {
2456 qtyCounter.classList.remove("qty-field--active");
2457 }
2458 }
2459 for (var i = 0; i < qtyColumnArr.length; i++) {
2460 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-column-" + i)[0];
2461 if (qtyCounter != null) {
2462 qtyCounter.classList.remove("qty-field--active");
2463 }
2464 }
2465 }, 1000);
2466 }
2467 </script>
2468 }
2469 }
2470
2471 @helper RenderVariantMatrixQuantityField(string variantId, VariantMatrix settings, int productLoopCounter, int rowCount, int columnCount)
2472 {
2473 string loopCount = productLoopCounter.ToString();
2474
2475 bool combinationFound = false;
2476 double stock = 0;
2477 double quantityValue = 0;
2478 string note = "";
2479
2480 VariantProduct variantProduct = null;
2481
2482 if (settings.GetVariantProducts().TryGetValue(variantId, out variantProduct))
2483 {
2484 stock = variantProduct.Stock;
2485 quantityValue = variantProduct.Quantity;
2486 combinationFound = true;
2487 }
2488
2489 if (combinationFound)
2490 {
2491 <input type="hidden" name="ProductLoopCounter@(loopCount)" value="@loopCount" />
2492 <input type="hidden" name="ProductID@(loopCount)" value="@settings.ProductId" />
2493 <input type="hidden" name="VariantID@(loopCount)" value="@variantId" />
2494 <input type="hidden" name="CurrentNote@(loopCount)" id="CurrentNote_@(settings.ProductId)_@variantId" value="@note" />
2495 <input type="number" name="Quantity@(loopCount)" id="Quantity_@(settings.ProductId)_@variantId" value="@quantityValue" min="0" class="js-qty u-no-margin u-full-max-width" style="width: 100%; max-width: 100%" onkeyup="MatrixUpdateQuantity('@settings.ProductId')" onmouseup="MatrixUpdateQuantity('@settings.ProductId')" data-qty-row-group="@rowCount" data-qty-column-group="@columnCount">
2496
2497 if (stock != 0)
2498 {
2499 <small>@Translate("Stock") @stock</small>
2500 }
2501
2502 <script>
2503 var variants = '{ "ProductId" :' + '"@settings.ProductId"' + ', "VariantId": ' + '"@variantId"' +'}';
2504 variantsCollection.push(variants);
2505 document.getElementById("Quantity_@(settings.ProductId)_@variantId").closest(".js-variants-matrix").setAttribute("data-variants-collection", "[" + variantsCollection + "]" );
2506 </script>
2507 }
2508 else
2509 {
2510 <div class="use-btn-height" style="background-color: #a8a8a8"></div>
2511 }
2512 }
2513 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce
2514
2515 @* Component *@
2516
2517 @helper RenderAddToCart(AddToCart settings)
2518 {
2519 //set Id for quantity selector to get it's value from button
2520 if (settings.QuantitySelector != null)
2521 {
2522 if (string.IsNullOrEmpty(settings.QuantitySelector.Id))
2523 {
2524 settings.QuantitySelector.Id = Guid.NewGuid().ToString("N");
2525 }
2526
2527 settings.AddButton.QuantitySelectorId = settings.QuantitySelector.Id;
2528
2529 if (settings.Disabled)
2530 {
2531 settings.QuantitySelector.Disabled = true;
2532 }
2533
2534 if (string.IsNullOrEmpty(settings.QuantitySelector.Name))
2535 {
2536 settings.QuantitySelector.Name = settings.QuantitySelector.Id;
2537 }
2538 }
2539
2540 if (settings.Disabled)
2541 {
2542 settings.AddButton.Disabled = true;
2543 }
2544
2545 settings.AddButton.CssClass += " btn--condensed";
2546
2547 //unitsSelector
2548 if (settings.UnitSelector != null)
2549 {
2550 if (settings.Disabled)
2551 {
2552 settings.QuantitySelector.Disabled = true;
2553 }
2554 }
2555
2556 if (Pageview.Device.ToString() == "Mobile") {
2557 if (settings.UnitSelector != null)
2558 {
2559 <div class="margin-sm margin-position-bottom">
2560 @Render(settings.UnitSelector)
2561 </div>
2562 }
2563 }
2564
2565 <div class="buttons-collection @settings.WrapperCssClass" @ComponentMethods.AddAttributes(settings.ExtraAttributes)>
2566 @if (Pageview.Device.ToString() != "Mobile") {
2567 if (settings.UnitSelector != null)
2568 {
2569 @Render(settings.UnitSelector)
2570 }
2571 }
2572 @if (settings.QuantitySelector != null)
2573 {
2574 @Render(settings.QuantitySelector)
2575 }
2576 @Render(settings.AddButton)
2577 </div>
2578 }
2579 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce
2580
2581 @* Component *@
2582
2583 @helper RenderAddToCartButton(AddToCartButton settings)
2584 {
2585 if (!settings.HideTitle)
2586 {
2587 if (string.IsNullOrEmpty(settings.Title))
2588 {
2589 if (settings.BuyForPoints)
2590 {
2591 settings.Title = Translate("Buy with points");
2592 }
2593 else
2594 {
2595 settings.Title = Translate("Add to cart");
2596 }
2597 }
2598 }
2599 else
2600 {
2601 settings.Title = "";
2602 }
2603
2604 if (settings.Icon == null)
2605 {
2606 settings.Icon = new Icon();
2607 settings.Icon.LabelPosition = Dynamicweb.Rapido.Blocks.Components.General.IconLabelPosition.After;
2608 }
2609
2610 if (string.IsNullOrEmpty(settings.Icon.Name))
2611 {
2612 settings.Icon.Name = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue;
2613 }
2614
2615 settings.OnClick = "Cart.AddToCart(event, { " +
2616 "id: '" + settings.ProductId + "'," +
2617 (!string.IsNullOrEmpty(settings.VariantId) ? "variantId: '" + settings.VariantId + "'," : "") +
2618 (!string.IsNullOrEmpty(settings.UnitId) ? "unitId: '" + settings.UnitId + "'," : "") +
2619 (settings.BuyForPoints ? "buyForPoints: true," : "") +
2620 (!string.IsNullOrEmpty(settings.ProductInfo) ? "productInfo: " + settings.ProductInfo + "," : "") +
2621 "quantity: " + (string.IsNullOrEmpty(settings.QuantitySelectorId) ? "1" : "parseFloat(document.getElementById('" + settings.QuantitySelectorId + "').value)") +
2622 "});" + settings.OnClick;
2623
2624 @RenderButton(settings)
2625 }
2626 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce
2627
2628 @* Component *@
2629
2630 @helper RenderUnitSelector(UnitSelector settings)
2631 {
2632 if (string.IsNullOrEmpty(settings.Id))
2633 {
2634 settings.Id = Guid.NewGuid().ToString("N");
2635 }
2636 var disabledClass = settings.Disabled ? "disabled" : "";
2637
2638 <input type="checkbox" id="@settings.Id" class="dropdown-trigger" />
2639 <div class="dropdown unit-selector @settings.CssClass @disabledClass dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)>
2640 <label class="dropdown__header dropdown__btn dropdown__btn--unit-selector dw-mod" for="@settings.Id">@settings.SelectedOption</label>
2641 <div class="dropdown__content dw-mod">
2642 @settings.OptionsContent
2643 </div>
2644 <label class="dropdown-trigger-off" for="@settings.Id"></label>
2645 </div>
2646 }
2647 @using System.Reflection
2648 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce
2649
2650 @* Component *@
2651
2652 @helper RenderQuantitySelector(QuantitySelector settings)
2653 {
2654 var attributes = new Dictionary<string, string>();
2655
2656 /*base settings*/
2657 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); }
2658 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); }
2659 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); }
2660 if (settings.Disabled) { attributes.Add("disabled", "true"); }
2661 if (settings.Required) { attributes.Add("required", "true"); }
2662 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); }
2663 /*end*/
2664
2665 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); }
2666 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); }
2667 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); }
2668 if (settings.ReadOnly) { attributes.Add("readonly", "true"); }
2669 if (settings.Max != null) { attributes.Add("max", settings.Max.ToString()); }
2670 if (settings.Min == null) { settings.Min = 1; }
2671 attributes.Add("min", settings.Min.ToString());
2672 if (settings.Step != null && !string.IsNullOrEmpty(settings.Step.ToString())) { attributes.Add("step", settings.Step.ToString()); }
2673 if (settings.Value == null) { settings.Value = 1; }
2674 attributes.Add("value", settings.Value.ToString());
2675 attributes.Add("type", "number");
2676
2677 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value);
2678
2679 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" />
2680 }
2681 @using Dynamicweb.Rapido.Blocks.Components
2682
2683 @using Dynamicweb.Frontend
2684 @using Dynamicweb.Frontend.Devices
2685 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce
2686 @using Dynamicweb.Rapido.Blocks.Components.General
2687 @using System.Collections.Generic;
2688
2689 @* Component *@
2690
2691 @helper RenderCustomerCenterList(CustomerCenterList settings)
2692 {
2693 bool isTouchDevice = Pageview.Device.ToString() == "Mobile" || Pageview.Device.ToString() == "Tablet" ? true : false;
2694 string hideActions = isTouchDevice ? "u-block" : "";
2695
2696 <table class="table data-list dw-mod">
2697 @if (settings.GetHeaders().Length > 0) {
2698 <thead>
2699 <tr class="u-bold">
2700 @foreach (CustomerCenterListHeaderItem header in settings.GetHeaders())
2701 {
2702 var attributes = new Dictionary<string, string>();
2703 if (!string.IsNullOrEmpty(header.Id)) { attributes.Add("id", header.Id); }
2704 if (!string.IsNullOrEmpty(header.CssClass)) { attributes.Add("class", header.CssClass); }
2705 attributes.Add("align", header.Align.ToString());
2706 attributes = attributes.Concat(header.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value);
2707
2708 <td @ComponentMethods.AddAttributes(attributes)>@header.Title</td>
2709 }
2710 </tr>
2711 </thead>
2712 }
2713 @foreach (CustomerCenterListItem listItem in settings.GetItems())
2714 {
2715 int columnCount = 0;
2716 int totalColumns = listItem.GetInfoItems().Length;
2717 string rowHasActions = listItem.GetActions().Length > 0 ? "data-list__item--has-actions" : "";
2718 listItem.Id = !string.IsNullOrEmpty(listItem.Id) ? listItem.Id : Guid.NewGuid().ToString("N");
2719
2720 var attributes = new Dictionary<string, string>();
2721 if (!string.IsNullOrEmpty(listItem.Title)) { attributes.Add("title", listItem.Title); };
2722
2723 attributes = attributes.Concat(listItem.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value);
2724 <tbody class="data-list__item @rowHasActions @listItem.CssClass dw-mod" @ComponentMethods.AddAttributes(attributes)>
2725 <tr>
2726 @if (!string.IsNullOrEmpty(listItem.Title) || !string.IsNullOrEmpty(listItem.Description)) {
2727 string onClick = !string.IsNullOrEmpty(listItem.OnClick) ? "onclick=\"" + listItem.OnClick + "\"" : "";
2728
2729 <td rowspan="2" @onClick class="data-list__main-item dw-mod">
2730 @if (!string.IsNullOrEmpty(listItem.Title)) {
2731 <div class="u-bold">@listItem.Title</div>
2732 }
2733 @if (!string.IsNullOrEmpty(listItem.Description)) {
2734 <div>@listItem.Description</div>
2735 }
2736 </td>
2737 }
2738
2739 @foreach (CustomerCenterListInfoItem infoItem in listItem.GetInfoItems())
2740 {
2741 var infoAttributes = new Dictionary<string, string>();
2742 if (!string.IsNullOrEmpty(infoItem.Id)) { infoAttributes.Add("id", infoItem.Id); };
2743 if (!string.IsNullOrEmpty(infoItem.OnClick)) { infoAttributes.Add("onclick", infoItem.OnClick); };
2744 infoAttributes.Add("align", infoItem.Align.ToString());
2745
2746 infoAttributes = infoAttributes.Concat(infoItem.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value);
2747 string columnClick = columnCount < (totalColumns-1) && !string.IsNullOrEmpty(listItem.OnClick) ? "onclick=\"" + listItem.OnClick + "\"" : "";
2748
2749 <td @ComponentMethods.AddAttributes(infoAttributes) @columnClick class="data-list__info-item dw-mod">
2750 @if (!string.IsNullOrEmpty(infoItem.Title)) {
2751 <div>@infoItem.Title</div>
2752 }
2753 @if (!string.IsNullOrEmpty(infoItem.Subtitle)) {
2754 <div><small>@infoItem.Subtitle</small></div>
2755 }
2756 </td>
2757
2758 columnCount++;
2759 }
2760 </tr>
2761 <tr>
2762 <td colspan="7" align="right" class="u-va-bottom u-no-border">
2763 <div class="data-list__actions @hideActions dw-mod" id="ActionsMenu_@listItem.Id">
2764 @foreach (ButtonBase action in listItem.GetActions())
2765 {
2766 action.ButtonLayout = ButtonLayout.LinkClean;
2767 action.Icon.CssClass += " u-full-height";
2768 action.CssClass += " data-list__action-button link";
2769
2770 @Render(action)
2771 }
2772 </div>
2773 </td>
2774 </tr>
2775 </tbody>
2776 }
2777 </table>
2778 }
2779
2780 @* Include the Blocks for the page *@
2781 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
2782 @using Dynamicweb.Core
2783 @using System
2784 @using System.Web
2785 @using System.Collections.Generic
2786 @using Denform.Website.CustomModules.Application
2787 @using Dynamicweb.Content
2788 @using Dynamicweb.Ecommerce.Products
2789 @using Dynamicweb.Rapido.Services
2790 @using Dynamicweb.Rapido.Blocks
2791 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce
2792 @using Dynamicweb.Rapido.Blocks.Components.General
2793
2794 @functions {
2795 bool useFacebookPixel;
2796 BlocksPage mainInfoPage = BlocksPage.GetBlockPage("Product");
2797 }
2798 @{
2799 var mainInfoVariantsCount = GetInteger("Ecom:Product.VariantCount");
2800 useFacebookPixel = !string.IsNullOrWhiteSpace(Pageview.AreaSettings.GetItem("Settings").GetString("FacebookPixelID"));
2801 bool hideAddToCartButton = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("hideAddToCartButton");
2802
2803 //family members
2804 bool mainInfoIsFamilyMember = false;
2805 bool mainInfoIsFamilyMaster = false;
2806 var mainInfoVariantGroups = GetLoop("VariantGroups");
2807 var mainInfoVariantGroupCount = mainInfoVariantGroups.Count;
2808 if (mainInfoVariantGroupCount == 1)
2809 {
2810 var firstVariantGroup = Dynamicweb.Ecommerce.Services.VariantGroups.GetVariantGroup(Dynamicweb.Ecommerce.Common.Context.LanguageID, mainInfoVariantGroups[0]?.GetString("Ecom:VariantGroup.ID"));
2811 if (firstVariantGroup != null)
2812 {
2813 mainInfoIsFamilyMember = firstVariantGroup.Family;
2814 string variantId = !string.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) ? GetString("Ecom:Product.VariantID") : GetString("Ecom:Product.VariantID.Extented");
2815 mainInfoIsFamilyMaster = string.IsNullOrEmpty(variantId);
2816 }
2817 }
2818
2819 bool mainInfoRenderVariantsAsProducts = mainInfoVariantsCount > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList");
2820
2821 if (mainInfoIsFamilyMember)
2822 {
2823 mainInfoRenderVariantsAsProducts = mainInfoVariantsCount > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderFamilyVariantsAsProducts") && mainInfoIsFamilyMaster;
2824 }
2825
2826 if (Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsMatrixLayout") != null && mainInfoVariantsCount > 1)
2827 {
2828 mainInfoRenderVariantsAsProducts = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsMatrixLayout").SelectedValue != "hide" && Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("EnableVariantMatrix") ? true : mainInfoRenderVariantsAsProducts;
2829 }
2830
2831 Block mainInfoHeader = new Block()
2832 {
2833 Id = "MainInfoHeader",
2834 SortId = 10,
2835 Template = RenderMainInfoHeader()
2836 };
2837 mainInfoPage.Add("MainInformation", mainInfoHeader);
2838
2839 Block mainInfoDescription = new Block()
2840 {
2841 Id = "ShortDescription",
2842 SortId = 20,
2843 Template = RenderShortDescription()
2844 };
2845 mainInfoPage.Add("MainInformation", mainInfoDescription);
2846
2847 if (!mainInfoRenderVariantsAsProducts && !mainInfoIsFamilyMember)
2848 {
2849 Block mainInfoVariants = new Block()
2850 {
2851 Id = "Variants",
2852 SortId = 50,
2853 Template = RenderMainInfoVariants()
2854 };
2855 mainInfoPage.Add("MainInformation", mainInfoVariants);
2856 }
2857
2858 Block mainInfoBOM = new Block()
2859 {
2860 Id = "BOM",
2861 SortId = 60,
2862 Template = RenderMainInfoBOM()
2863 };
2864 mainInfoPage.Add("MainInformation", mainInfoBOM);
2865
2866 if (!mainInfoRenderVariantsAsProducts)
2867 {
2868 if (!hideAddToCartButton)
2869 {
2870 Block mainInfoBuy = new Block()
2871 {
2872 Id = "Buy",
2873 SortId = 80,
2874 Template = RenderMainInfoBuy()
2875 };
2876 mainInfoPage.Add("MainInformation", mainInfoBuy);
2877 }
2878 }
2879
2880 if (Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")) && User.IsBuyingAllowed() && GetPageIdByNavigationTag("OrderDraft") != 0)
2881 {
2882 Modal selectDraftModal = new Modal
2883 {
2884 Id = "OrderDraftSelect",
2885 Heading = new Heading { Title = Translate("Select draft cart"), Level = 2 },
2886 BodyTemplate = RenderOrderDraftSelectModalContent(),
2887 Width = ModalWidth.Md
2888 };
2889 selectDraftModal.AddAction(new Button { Title = Translate("Cancel"), OnClick = "document.getElementById('OrderDraftSelectModalTrigger').checked = false", ButtonLayout = ButtonLayout.Secondary });
2890 selectDraftModal.AddAction(new Button { Title = Translate("Add"), OnClick = "addToSelectedCart()" });
2891
2892 Block orderDraftSelect = new Block
2893 {
2894 Id = "OrderDraft",
2895 SortId = 90,
2896 Component = selectDraftModal
2897 };
2898 mainInfoPage.Add("MainInformation", orderDraftSelect);
2899
2900 Modal notificationDraftModal = new Modal
2901 {
2902 Id = "OrderDraftNotification",
2903 Heading = new Heading { Title = Translate("Added to cart"), Level = 2 },
2904 BodyText = Translate("The product has been added to the selected cart"),
2905 Width = ModalWidth.Md
2906 };
2907 notificationDraftModal.AddAction(new Button { Title = Translate("View draft"), OnClick = "goToSelectedCart()", ButtonLayout = ButtonLayout.Secondary });
2908 notificationDraftModal.AddAction(new Button { Title = Translate("Continue shopping"), OnClick = "document.getElementById('OrderDraftNotificationModalTrigger').checked = false" });
2909
2910 Block orderDraftComplete = new Block
2911 {
2912 Id = "OrderDraftComplete",
2913 SortId = 100,
2914 Component = notificationDraftModal
2915 };
2916 mainInfoPage.Add("MainInformation", orderDraftComplete);
2917
2918
2919 Block orderDraftScripts = new Block
2920 {
2921 Id = "OrderDraftScripts",
2922 SortId = 110,
2923 Template = RenderOrderDraftScripts()
2924 };
2925 mainInfoPage.Add("MainInformation", orderDraftScripts);
2926 }
2927
2928 //Block googleTagManagerScripts = new Block
2929 //{
2930 // Id = "GoogleTagManagerScripts",
2931 // SortId = 120,
2932 // Template = RenderGoogleTagManagerScripts()
2933 //};
2934 //mainInfoPage.Add("Snippets", googleTagManagerScripts);
2935 }
2936
2937 @helper RenderMainInfoHeader()
2938 {
2939 bool renderVariantsAsProducts = GetInteger("Ecom:Product.VariantCount") > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList");
2940 if (Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsMatrixLayout") != null && GetInteger("Ecom:Product.VariantCount") > 1)
2941 {
2942 renderVariantsAsProducts = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsMatrixLayout").SelectedValue != "hide" && Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("EnableVariantMatrix") ? true : renderVariantsAsProducts;
2943 }
2944
2945 string pageId = GetGlobalValue("Global:Page.ID").ToString();
2946 string currentPrice = GetString("Ecom:Product.Discount.Price.PriceFormatted") == GetString("Ecom:Product.Price.PriceFormatted") ? GetString("Ecom:Product.Price.PriceFormatted") : GetString("Ecom:Product.Discount.Price.PriceFormatted");
2947 bool hideFavorites = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideFavoriteButton");
2948 bool hideProductNumber = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideProductNumber");
2949
2950 bool useFontAwesomePro = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetBoolean("UseFontAwesomePro");
2951 var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star";
2952 string favoriteIcon = "fas fa-" + selectedFavoriteIcon;
2953 string favoriteOutlineIcon = "fal fa-" + selectedFavoriteIcon;
2954 bool hideStockState = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideStockState");
2955 bool hideDelivery = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideShipping");
2956
2957
2958 <div>
2959 <div class="nc-product__top-header">
2960 <h1 class="nc-product__product-title">@GetString("Ecom:Product.Name") </h1>
2961 @if (GetBoolean("Ecom:Product.HaveDiscount"))
2962 {
2963 <div class="nc-product__price nc-product__price--discounted">
2964 <h2 class="nc-product__valuta nc-product__price-content">
2965 @GetString("Ecom:Product.Price.Currency.Code")
2966 </h2>
2967 <h2 class="nc-product__discount-price nc-product__price-content">@String.Format("{0:0.0,00}", GetString("Ecom:Product.Discount.Price.Price"))</h2>
2968 <h2 class="nc-product__full-price nc-product__price-content">@String.Format("{0:0.0,00}", GetString("Ecom:Product.Price.Price")) </h2>
2969 </div>
2970 }
2971 else
2972 {
2973 <div class="nc-product__price">
2974 <h2 class="nc-product__full-price nc-product__price-content">@GetString("Ecom:Product.Price.Currency.Code") @String.Format("{0:0.0,00}", GetString("Ecom:Product.Price.Price")) </h2>
2975 </div>
2976 }
2977
2978 @if (User.IsStockInfoAllowed())
2979 {
2980 Dynamicweb.Ecommerce.Products.ProductService service = new Dynamicweb.Ecommerce.Products.ProductService();
2981 string ProductId = GetString("Ecom:Product.ID");
2982 string VariantId = GetString("Ecom:Product.VariantID");
2983 string defaultLanguage = Dynamicweb.Ecommerce.Common.Context.LanguageID;
2984
2985 //null checks for product and variant
2986 if (!string.IsNullOrEmpty(ProductId) && !string.IsNullOrEmpty(defaultLanguage) || !string.IsNullOrEmpty(ProductId) && !string.IsNullOrEmpty(VariantId) && !string.IsNullOrEmpty(defaultLanguage))
2987 {
2988 var currentProduct = service.GetProductById(ProductId, VariantId, defaultLanguage);
2989
2990 if (currentProduct != null)
2991 {
2992 bool neverOutOfStock = currentProduct.NeverOutOfStock;
2993
2994 <div class="nc-product__stock-delivery dw-mod">
2995
2996 @**If never out of stock is enabled on a product and 'hide stock state' is not enabled**@
2997 @if (neverOutOfStock && !hideStockState)
2998 {
2999 <span class="stock-icon stock-icon--in u-no-margin dw-mod" title="@Translate("På lager")"></span>
3000 <span class="nc-stock__stock-text">@Translate("På lager")</span>
3001 }
3002 @**If hide stock state is not enabled**@
3003 else if (!hideStockState)
3004 {
3005 // Check if HideStockState is not enabled, or if there is stock available
3006 int stockAmount = GetInteger("Ecom:Product.Stock");
3007 @**if stock amount is greater than 0, render in-stock-status markup**@
3008 if (stockAmount > 0)
3009 {
3010 <span class="stock-icon stock-icon--in u-no-margin dw-mod" title="@GetString("Ecom:Product:Stock.Text")"></span>
3011 <span class="nc-stock__stock-text">@GetString("Ecom:Product:Stock.Text")</span>
3012 }
3013 @**if stock amount is less or equal to 0, render in not-in-stock-status markup**@
3014 else
3015 {
3016 <span class="stock-icon stock-icon--not u-no-margin dw-mod" title="@Translate("Ikke på lager")"></span>
3017 <span class="nc-stock__stock-text">@Translate("Ikke på lager")</span>
3018 }
3019 }
3020 @**if hide stock state is enabled, render no stock status**@
3021 else
3022 {
3023 <span class="u-no-margin dw-mod"></span>
3024 <span class="nc-stock__stock-text"></span>
3025
3026 }
3027
3028 @if (!hideDelivery)
3029 {
3030 string delivery = @Translate("Delivery", "Levering") + " " + GetString("Ecom:Product:Stock.DeliveryText") + " " + GetString("Ecom:Product:Stock.DeliveryUnit");
3031
3032 <span class="nc-product__delivery-text">
3033 <img src="/Files/Templates/Designs/Rapido/css/icons/deliverytruck.svg" class="nc-product__delivery-icon"/>
3034 @delivery
3035 </span>
3036 }
3037 </div>
3038 }
3039 }
3040 }
3041 </div>
3042 <div class="u-pull--right">
3043 @if (!hideFavorites && Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")) && !renderVariantsAsProducts)
3044 {
3045 string favoriteId = "Favorite" + GetString("Ecom:Product.ID");
3046 <div id="@favoriteId" class="favorites favorites--md u-pull--right js-favorite-btn dw-mod">
3047 <div>
3048 @{
3049 string favorite = GetBoolean("Ecom:Product.IsProductInFavoriteList") ? favoriteIcon : favoriteOutlineIcon;
3050 string AddToWishlist = "fbq('track', 'AddToWishlist', {" +
3051 "content_name: '" + GetString("Ecom:Product.Name") + "'," +
3052 "content_ids: ['" + GetString("Ecom:Product.Number") + "']," +
3053 "value: " + GetDouble("Ecom:Product.Price.Price") + "," +
3054 "currency: '" + GetString("Ecom:Product.Price.Currency.Code") + "'" +
3055 "});";
3056 }
3057 <label for="FavoriteTrigger">
3058 <i class="@favorite fa-1_5x"></i>
3059 </label>
3060 </div>
3061 <input type="checkbox" id="FavoriteTrigger" class="dropdown-trigger"/>
3062
3063 <div class="dropdown">
3064 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod">
3065 <ul class="list list--clean dw-mod">
3066 @if (GetLoop("CustomerCenter.ListTypes").Count > 0)
3067 {
3068 foreach (LoopItem listType in GetLoop("CustomerCenter.ListTypes"))
3069 {
3070 foreach (LoopItem list in listType.GetLoop("CustomerCenter.ProductLists"))
3071 {
3072 string favLinkType = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? list.GetString("Ecom:Product.RemoveFromThisList") : list.GetString("Ecom:Product.AddToThisListAction");
3073 string isInListIcon = list.GetString("Ecom:Product.List.IsProductInThisList") == "True" ? favoriteIcon : favoriteOutlineIcon;
3074 <li>
3075 <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(list.GetString("Ecom:Product.List.IsProductInThisList") != "True" && useFacebookPixel ? AddToWishlist : "")">
3076 <i class="@isInListIcon u-margin-right--lg"></i> @list.GetValue("Ecom:CustomerCenter.List.Name")
3077 </a>
3078 </li>
3079 }
3080 }
3081 }
3082 else
3083 {
3084 string favLinkType = GetString("Ecom:Product.AddToFavorites") + "&CCListType=0&CCCreateNewList=" + Translate("My favorites");
3085 string isInListIcon = favoriteOutlineIcon;
3086 <li>
3087 <a href="@favLinkType" class="list__link u-no-underline dw-mod" onclick="@(useFacebookPixel ? AddToWishlist : "")">
3088 <i class="@isInListIcon u-margin-right--lg"></i> @Translate("My favorites")
3089 </a>
3090 </li>
3091 }
3092 </ul>
3093 </div>
3094 <label class="dropdown-trigger-off" for="FavoriteTrigger"></label>
3095 </div>
3096 </div>
3097 }
3098 </div>
3099 </div>
3100 }
3101
3102 @helper RenderStockAndShipping()
3103 {
3104 <div class="nc-product__item-number">@Translate("Product number"): @GetString("Ecom:Product.Number")</div>
3105 }
3106
3107 @helper RenderShortDescription()
3108 {
3109 string pageUrl = GetGlobalValue("Global:Pageview.Url.Raw");
3110 if (!String.IsNullOrEmpty(GetString("Ecom:Product.ShortDescription")))
3111 {
3112 Pageview.Meta.AddTag("og:description", GetString("Ecom:Product.ShortDescription"));
3113 <div class="introduction-text">
3114
3115
3116
3117
3118 @if(!String.IsNullOrEmpty((string)Pageview.Area.Item["TrustpilotImage"]))
3119 {
3120 <img alt="trustpilot" class="introduction-text__trustpilot" src="@Pageview.Area.Item["TrustpilotImage"]"/>
3121 }
3122
3123
3124
3125
3126
3127 @GetString("Ecom:Product.ShortDescription")
3128 @GetString("Ecom:Product:Field.USP")
3129 <div class="nc-product__anchor-links">
3130 <a href="#ProductDetails" rel="noopener" class="nc-product__link">
3131 @Translate("ProductDetails", "Detaljer om produktet")
3132 <img src="~/Files/Templates/Designs/Rapido/css/icons/arrow-right-papaya-orange.svg" class="nc-product__anchor-arrow"/>
3133 </a>
3134 <a href="#ProductSpecs" class="nc-product__link">
3135 @Translate("Specs", "Specifikationer")
3136 <img src="~/Files/Templates/Designs/Rapido/css/icons/arrow-right-papaya-orange.svg" class="nc-product__anchor-arrow"/>
3137 </a>
3138 </div>
3139 </div>
3140 }
3141 }
3142
3143 @helper RenderMainInfoVariants()
3144 {
3145 string pageId = GetGlobalValue("Global:Page.ID").ToString();
3146 string productId = GetString("Ecom:Product.ID");
3147 string variantSelection = !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("variantId")) ? HttpContext.Current.Request.QueryString.Get("variantId").Replace(".", ",") : "";
3148 string hideHelpText = "";
3149 string variantsLayout = Pageview.AreaSettings.GetItem("Ecommerce").GetString("VariantsLayout") != null ? Pageview.AreaSettings.GetItem("Ecommerce").GetList("VariantsLayout").SelectedValue : "buttons";
3150
3151 foreach (LoopItem variantgroup in GetLoop("VariantGroups"))
3152 {
3153 foreach (LoopItem variantoption in variantgroup.GetLoop("VariantAvailableOptions"))
3154 {
3155 if (variantoption.GetBoolean("Ecom:VariantOption.Selected"))
3156 {
3157 hideHelpText = "u-hidden";
3158 }
3159 }
3160 }
3161
3162 if (GetLoop("VariantGroups").Count > 0)
3163 {
3164 var variantCombinationsObject = new List<Array>();
3165 foreach (LoopItem variantcomb in GetLoop("VariantCombinations"))
3166 {
3167 string[] combinations = variantcomb.GetString("Ecom:VariantCombination.VariantID").Split('.');
3168 variantCombinationsObject.Add(combinations);
3169 }
3170
3171 string combinationsJson = Newtonsoft.Json.JsonConvert.SerializeObject(variantCombinationsObject).Replace("\"", "\'");
3172
3173 var variantGroupsObject = new List<List<String>>();
3174 foreach (LoopItem variantGroup in GetLoop("VariantGroups"))
3175 {
3176 var variantsObject = new List<String>();
3177 foreach (LoopItem variantOption in variantGroup.GetLoop("VariantAvailableOptions"))
3178 {
3179 variantsObject.Add(variantOption.GetString("Ecom:VariantOption.ID"));
3180 }
3181
3182 variantGroupsObject.Add(variantsObject);
3183 }
3184
3185 string variantsJson = Newtonsoft.Json.JsonConvert.SerializeObject(variantGroupsObject).Replace("\"", "\'");
3186 string productGroupId = HttpContext.Current.Request["GroupId"];
3187
3188 <div>
3189 <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">
3190 @foreach (LoopItem variantGroup in GetLoop("VariantGroups"))
3191 {
3192 string groupId = variantGroup.GetString("Ecom:VariantGroup.ID");
3193
3194 <div>
3195 <div class="product__variant-group-name u-bold dw-mod">@variantGroup.GetString("Ecom:VariantGroup.Name")</div>
3196 <div class="u-margin-top">
3197 @if (variantsLayout == "buttons")
3198 {
3199 foreach (LoopItem variantOption in variantGroup.GetLoop("VariantAvailableOptions"))
3200 {
3201 string selected = variantOption.GetBoolean("Ecom:VariantOption.Selected") ? "checked" : "";
3202 string color = !String.IsNullOrEmpty(variantOption.GetString("Ecom:VariantOption.Colorcode")) ? variantOption.GetString("Ecom:VariantOption.Colorcode") : null;
3203 color = color == null && !String.IsNullOrEmpty(variantOption.GetString("Ecom:VariantOption.Color")) ? variantOption.GetString("Ecom:VariantOption.Color") : color;
3204
3205 if (!String.IsNullOrEmpty(color))
3206 {
3207 <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>
3208 }
3209 else
3210 {
3211 <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>
3212 }
3213 }
3214 }
3215 else
3216 {
3217 <select id="VariantSelector_@groupId" class="u-full-width dw-mod" name="VariantSelector_@groupId" onchange="MatchVariants.SelectOnChange(event)">
3218 <option>@Translate("Choose")</option>
3219 @foreach (LoopItem variantOption in variantGroup.GetLoop("VariantAvailableOptions"))
3220 {
3221 string check = variantOption.GetBoolean("Ecom:VariantOption.Selected") ? "checked" : "";
3222 string selected = variantOption.GetBoolean("Ecom:VariantOption.Selected") ? "selected" : "";
3223 string color = !String.IsNullOrEmpty(variantOption.GetString("Ecom:VariantOption.Colorcode")) ? variantOption.GetString("Ecom:VariantOption.Colorcode") : null;
3224 color = color == null && !String.IsNullOrEmpty(variantOption.GetString("Ecom:VariantOption.Color")) ? variantOption.GetString("Ecom:VariantOption.Color") : color;
3225
3226 <option class="js-variant-option @selected" id="@(groupId)_@variantOption.GetString("Ecom:VariantOption.ID")" value="@(groupId)_@variantOption.GetString("Ecom:VariantOption.ID")" data-variant-id="@variantOption.GetString("Ecom:VariantOption.ID")" data-variant-group="@groupId" @selected data-check="@check">@variantOption.GetString("Ecom:VariantOption.Name")</option>
3227 }
3228 </select>
3229 }
3230 </div>
3231 </div>
3232 }
3233 </div>
3234 <small class="js-help-text help-text @hideHelpText">@Translate("Please select variant!")</small>
3235 </div>
3236 }
3237 }
3238
3239 @helper RenderMainInfoBOM()
3240 {
3241 if (GetLoop("BOMProducts").Count > 0)
3242 {
3243 <h2 class="section-title">@Translate("Including products")</h2>
3244 foreach (LoopItem BOMProductItem in GetLoop("BOMProducts"))
3245 {
3246 string link = "/" + BOMProductItem.GetString("Ecom:Product.LinkGroup.Clean") + (!String.IsNullOrEmpty(BOMProductItem.GetString("Ecom:Product.VariantID")) ? "&VariantID=" + BOMProductItem.GetString("Ecom:Product.VariantID") : "");
3247 <div class="grid__col--border grid">
3248 <div class="grid__cell grid__cell--align-middle-left">
3249 <a href="@link" class="u-pull--left u-margin-right">
3250 <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")"/>
3251 </a>
3252 <a href="@link">@BOMProductItem.GetString("Ecom:Product.Name")</a>
3253 </div>
3254 </div>
3255 }
3256 }
3257 }
3258
3259 @helper RenderMainInfoBuy()
3260 {
3261 string pageId = GetGlobalValue("Global:Page.ID").ToString();
3262 string variantId = HttpContext.Current.Request.QueryString.Get("variantId");
3263 string productId = GetString("Ecom:Product.ID");
3264 string feedId = pageId + "&ProductID=" + productId + "&VariantID=" + variantId + "&Feed=True&redirect=false";
3265
3266 <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>
3267 <input type="hidden" value="@GetString("Ecom:Product.VariantID.Extented")" name="Variant" id="Variant_@GetString("Ecom:Product.ID")"/>
3268 @RenderMainInfoBuyScripts()
3269 }
3270
3271 @helper RenderPriceInfo()
3272 {
3273 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly");
3274 bool showPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice");
3275 bool showCartButton = !Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideAddToCartButton");
3276 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductList").GetBoolean("ShowBothPricesWithWithoutVAT");
3277 bool isPricesWithVATEnabled = Converter.ToBoolean(Pageview.Area.EcomPricesWithVat);
3278
3279 <div class="price price--product-page dw-mod">{{ncPrice}}</div>
3280 }
3281
3282 @helper RenderMainInfoBuyScripts()
3283 {
3284 bool showPrice = !Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HidePrice");
3285 bool showCartButton = !Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideAddToCartButton");
3286 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly");
3287 string variantId = HttpContext.Current.Request.QueryString.Get("variantId") ?? "";
3288 string feedId = GetGlobalValue("Global:Page.ID").ToString() + "&ProductID=" + GetString("Ecom:Product.ID") + "&VariantID=" + variantId + "&Feed=True&redirect=false";
3289 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart";
3290 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("ShowBothPricesWithWithoutVAT");
3291 bool isPricesWithVATEnabled = Converter.ToBoolean(Pageview.Area.EcomPricesWithVat);
3292
3293 var customerId = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUserId();
3294 var shopId = Pageview.Area.EcomShopId;
3295 var orderType = Dynamicweb.Ecommerce.Orders.OrderType.Order;
3296 var cartsList = (List<Dynamicweb.Ecommerce.Orders.Order>)Dynamicweb.Ecommerce.Services.Orders.GetCustomerOrdersByType(customerId, shopId, orderType, 0, false, "", DateTime.MinValue, false, true);
3297 bool hidePrice = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HidePrice");
3298
3299 @* Handlebars templates *@
3300 <script id="PricesAndActionsTemplate" type="text/x-template">
3301 {{#.}}
3302 @if (Dynamicweb.Rapido.Services.User.IsPricesAllowed() && !hidePrice)
3303 {
3304 <div class="product__price-wrap dw-mod">
3305 @RenderPriceInfo()
3306 </div>
3307 }
3308
3309 @if (showCartButton && Dynamicweb.Rapido.Services.User.IsBuyingAllowed())
3310 {
3311 string klaviyoAddedToCartEvent = "";
3312 var addToCartBtn = new AddToCart
3313 {
3314 WrapperCssClass = "product__price-actions-flex-wrap buttons-collection--right dw-mod",
3315 AddButton = new AddToCartButton
3316 {
3317 ProductId = "{{productId}}",
3318 VariantId = "{{variantid}}",
3319 UnitId = "{{unitId}}",
3320 ProductInfo = "{{productInfo}}",
3321 BuyForPoints = pointShopOnly,
3322 OnClick = "trackAddedToCart({{klaviyoAction}});",
3323 ExtraAttributes = new Dictionary<string, string>
3324 {
3325 { "{{disabledBuyButton}}", "" }
3326 },
3327 CssClass = "nc-product__price-buy-button"
3328 },
3329 UnitSelector = new UnitSelector
3330 {
3331 OptionsContent = "{{#unitOptions}}{{>UnitOption}}{{/unitOptions}}",
3332 Id = "UnitOptions_{{id}}",
3333 SelectedOption = "{{unitName}}",
3334 CssClass = "{{#if hasOnlyOneUnit}}unit-selector--readonly{{/if}} {{hasUnits}}"
3335 }
3336 };
3337
3338 if (!pointShopOnly)
3339 {
3340 addToCartBtn.QuantitySelector = new QuantitySelector
3341 {
3342 Id = "Quantity_{{id}}"
3343 };
3344 }
3345
3346 <div class="nc-product__price-actions-wrap dw-mod">
3347 @Render(addToCartBtn)
3348
3349 @if (Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")) && User.IsBuyingAllowed() && cartsList.Count > 0 && GetPageIdByNavigationTag("OrderDraft") != 0)
3350 {
3351 var addToDraftCart = new Button
3352 {
3353 Id = "AddToDraftCart",
3354 Title = Translate("Add to draft"),
3355 ButtonLayout = ButtonLayout.Secondary,
3356 OnClick = "document.getElementById('OrderDraftSelectModalTrigger').checked = true",
3357 CssClass = "u-w220px u-margin-top"
3358 };
3359
3360 @Render(addToDraftCart)
3361 }
3362
3363 @if (Pageview.User != null && !pointShopOnly && Dynamicweb.Security.Licensing.LicenseManager.LicenseHasFeature("LoyaltyPoints"))
3364 {
3365 <text>
3366 {{#if canBePurchasedWithPoints}}
3367 <form method="post" role="form" class="u-no-margin u-margin-top">
3368 <input type="hidden" name="ProductID" value="{{id}}" />
3369 <button type="submit" class="btn btn--loyalty-points product__price-points-buy-button 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>
3370 </form>
3371 {{/if}}
3372 </text>
3373 }
3374
3375
3376 </div>
3377
3378 }
3379 else
3380 {
3381 <button type="button" id="CartButton_{{id}}" class="u-hidden"></button>
3382 }
3383 @RenderStockAndShipping()
3384 {{/.}}
3385 </script>
3386
3387 <script id="UnitOption" type="text/x-template">
3388 <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent('PriceAndActions', '{{link}}&feed=true&UnitID={{value}}')">{{name}}</div>
3389 </script>
3390
3391 <script>
3392 document.addEventListener("DOMContentLoaded", function () {
3393 if (document.getElementById("PriceAndActions")) {
3394 document.getElementById("PriceAndActions").addEventListener("contentLoaded", function (event) {
3395 if (document.querySelector(".js-variants") != null) {
3396 MatchVariants.Update(document.querySelector(".js-variants"), "DoNothing");
3397 }
3398 });
3399 }
3400 });
3401 </script>
3402 }
3403
3404 @helper RenderOrderDraftSelectModalContent()
3405 {
3406 var customerId = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUserId();
3407 var shopId = Pageview.Area.EcomShopId;
3408 var orderType = Dynamicweb.Ecommerce.Orders.OrderType.Order;
3409 var cartsList = (List<Dynamicweb.Ecommerce.Orders.Order>)Dynamicweb.Ecommerce.Services.Orders.GetCustomerOrdersByType(customerId, shopId, orderType, 0, false, "", DateTime.MinValue, false, true);
3410
3411 SelectField cartSelector = new SelectField
3412 {
3413 Id = "CartSelector",
3414 Label = Translate("I want to add this product to")
3415 };
3416
3417 foreach (Dynamicweb.Ecommerce.Orders.Order cart in cartsList)
3418 {
3419 string name = !string.IsNullOrEmpty(cart.DisplayName) ? cart.DisplayName : cart.Id;
3420 cartSelector.Options.Add(new SelectFieldOption { Label = name, Value = cart.Id });
3421 }
3422
3423 @Render(cartSelector)
3424 }
3425
3426 @helper RenderOrderDraftScripts()
3427 {
3428 string productId = GetString("Ecom:Product.ID");
3429 string variantId = !string.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) ? GetString("Ecom:Product.VariantID") : GetString("Ecom:Product.VariantID.Extented");
3430 string unitId = GetString("Ecom:Product.DefaultUnitID");
3431 var cartCmdUrl = "/Default.aspx?ID=" + Pageview.Page.ID;
3432 int orderDraftPageId = GetPageIdByNavigationTag("DraftDetails");
3433 int orderDraftParagraphId = Dynamicweb.Content.Services.Paragraphs.GetParagraphsByPageId(orderDraftPageId).ToList().First().ID;
3434
3435 foreach (LoopItem unitOption in GetLoop("Units"))
3436 {
3437 if (unitOption.GetString("Ecom:VariantOption.Selected") == "SELECTED")
3438 {
3439 unitId = unitOption.GetString("Ecom:VariantOption.ID");
3440 }
3441 }
3442
3443 <script>
3444 function addToSelectedCart() {
3445 var requestUrl = "@cartCmdUrl" + "&cartcmd=Add&Quantity=1" + "&CartId=" + document.getElementById("CartSelector").value + "&ProductId=@productId" + "&VariantId=@variantId" + "&UnitId=@unitId";
3446
3447 console.log(requestUrl)
3448
3449 document.getElementById('OrderDraftSelectModalTrigger').checked = false;
3450
3451 var overlayElement = document.createElement('div');
3452 overlayElement.className = "preloader-overlay";
3453 overlayElement.setAttribute('id', "CartOverlay");
3454 var overlayElementIcon = document.createElement('div');
3455 overlayElementIcon.className = "preloader-overlay__icon dw-mod";
3456 overlayElementIcon.style.top = window.pageYOffset + "px";
3457 overlayElement.appendChild(overlayElementIcon);
3458 document.getElementById('content').parentNode.insertBefore(overlayElement, document.getElementById('content'));
3459
3460 Request.Fetch().get(
3461 requestUrl,
3462 function () {
3463 var overlayNode = document.getElementById('CartOverlay');
3464 overlayNode.parentNode.removeChild(overlayNode);
3465 document.getElementById('OrderDraftNotificationModalTrigger').checked = true;
3466 },
3467 null,
3468 false
3469 );
3470 }
3471
3472 function goToSelectedCart() {
3473 window.location = "/Default.aspx?ID=" + "@orderDraftPageId" + "&CartID=" + document.getElementById('CartSelector').value + "&CartCmd=setcart" + "&redirect=false";
3474 }
3475 </script>
3476 }
3477
3478
3479 @{
3480 bool useGoogleTagManager = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("GoogleTagManagerID"));
3481
3482 var pageService = new PageService();
3483 GroupHelper gh = new GroupHelper();
3484 GroupService groupService = new GroupService();
3485
3486 var _group = groupService.GetGroup(GetString("Ecom:Product.PrimaryOrFirstGroupID"));
3487 var groupNames = gh.GetParentsRecursively(_group, new List<string>());
3488
3489 groupNames = gh.Format(groupNames, _group);
3490 var groups = gh.ListToString(groupNames);
3491
3492 if (useGoogleTagManager)
3493 {
3494 var groupObject = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(GetString("Ecom:Product.PrimaryOrFirstGroupID"));
3495 <script>
3496 price = @GetDouble("Ecom:Product.Price.PriceWithVAT.Value");
3497
3498 dataLayer.push({ecommerce:null});
3499 dataLayer.push({
3500 'event': 'view_item',
3501 "ecommerce":{
3502 "currency" : "@GetString("Ecom:Product.CurrencyCode")",
3503 "value" : price,
3504 "items":[
3505 {
3506 'item_id': '@GetString("Ecom:Product.ID")',
3507 "item_name": "@GetString("Ecom:Product.Name")",
3508 'price': price,
3509 "item_category": ("@groups".split("_")[0] != null ? "@groups".split("_")[0] : ""),
3510 "item_category2": ("@groups".split("_")[1] != null ? "@groups".split("_")[1] : ""),
3511 "item_category3": ("@groups".split("_")[2] != null ? "@groups".split("_")[2] : ""),
3512 "item_category4": ("@groups".split("_")[3] != null ? "@groups".split("_")[3] : ""),
3513 "item_category5": ("@groups".split("_")[4] != null ? "@groups".split("_")[4] : ""),
3514 "quantity": "1",
3515 }
3516 ]
3517 },
3518 });
3519
3520 // Measure a view of product details. This example assumes the detail view occurs on pageload,
3521 // and also tracks a standard pageview of the details page.
3522 dataLayer.push({
3523 'event': 'productDetails',
3524 "ecommerce": {
3525 "detail": {
3526 "currencyCode": "@GetString("Ecom:Product.Price.Currency.Code")",
3527 "actionField": {}, // 'detail' actions have an optional list property.
3528 "products": [{
3529 "name": "@GetString("Ecom:Product.Name")", // Name or ID is required.
3530 "id": "@GetString("Ecom:Product.ID")",
3531 "price": "@(GetDouble("Ecom:Product.Discount.Price.Price") != GetDouble("Ecom:Product.Price.Price") ? GetDouble("Ecom:Product.Discount.Price.Price") : GetDouble("Ecom:Product.Price.Price"))",
3532 "brand": "@GetString("Ecom:Product:Field.brand.Value")",
3533 "category": "@(groupObject != null ? groupObject.Name : "")",
3534 "variant": "@(!string.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) ? GetString("Ecom:Product.VariantID") : GetString("Ecom:Product.VariantID.Extented"))"
3535 }]
3536 }
3537 }
3538 });
3539 </script>
3540 }
3541 }
3542
3543
3544 <script type="text/javascript">
3545 function trackAddedToCart(data){
3546 data.AddedItemQuantity = parseFloat(document.getElementById('Quantity_@GetString("Ecom:Product.Number")').value)
3547 _learnq.push(["track", "Added to Cart", data]);
3548 }
3549 </script>
3550 <script>
3551
3552
3553 function AddToCartClicked(quantity){
3554
3555 var price = @GetDouble("Ecom:Product.Price.PriceWithVAT.Value");
3556
3557 dataLayer.push({ecommerce:null});
3558 dataLayer.push({
3559 'event': 'add_to_cart',
3560 "ecommerce":{
3561 "currency" : "@GetString("Ecom:Product.CurrencyCode")",
3562 "value" : quantity * price,
3563 "items":[
3564 {
3565 'item_id': "@GetString("Ecom:Product.ID")",
3566 "item_name": "@GetString("Ecom:Product.Name")",
3567 'price': price,
3568 "item_category": ("@groups".split("_")[0] != null ? "@groups".split("_")[0] : ""),
3569 "item_category2": ("@groups".split("_")[1] != null ? "@groups".split("_")[1] : ""),
3570 "item_category3": ("@groups".split("_")[2] != null ? "@groups".split("_")[2] : ""),
3571 "item_category4": ("@groups".split("_")[3] != null ? "@groups".split("_")[3] : ""),
3572 "item_category5": ("@groups".split("_")[4] != null ? "@groups".split("_")[4] : ""),
3573 "quantity": quantity,
3574 }
3575 ],
3576 },
3577 });
3578 }
3579 function delay() {
3580 setTimeout(function() {
3581
3582 var AddToCartButton = document.getElementsByClassName("nc-product__price-buy-button")[0];
3583
3584 AddToCartButton.addEventListener("click", function (item){
3585
3586 var q = "Quantity_";
3587 q += "@GetString("Ecom:Product.ID")";
3588 var quantity = document.getElementById(q).value;
3589 AddToCartClicked(quantity);
3590 })
3591
3592 }, 200);
3593 }
3594
3595 if (document.readyState == 'complete') {
3596 delay();
3597 } else {
3598 document.onreadystatechange = function () {
3599 if (document.readyState === "complete") {
3600 delay();
3601 }
3602 }
3603 }
3604 </script>
3605
3606 <script type="text/javascript">
3607 function trackAddedToCart(data){
3608 data.AddedItemQuantity = parseFloat(document.getElementById('Quantity_@GetString("Ecom:Product.Number")').value)
3609 _learnq.push(["track", "Added to Cart", data]);
3610 }
3611 </script>
3612 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
3613 @using Dynamicweb.Core
3614 @using System
3615 @using System.Web
3616 @using System.Collections.Generic
3617 @using Dynamicweb.Rapido.Blocks
3618 @using Dynamicweb.Rapido.Blocks.Components.General
3619
3620 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
3621 @using System.Linq;
3622 @using Dynamicweb.Rapido.Blocks.Components.General
3623 @using System.Collections.Generic
3624
3625 @functions{
3626 Dictionary<string, StickersListPosition> stickerPositions = new Dictionary<string, StickersListPosition>
3627 {
3628 { "top-left", StickersListPosition.TopLeft },
3629 { "top-right", StickersListPosition.TopRight },
3630 { "bottom-left", StickersListPosition.BottomLeft },
3631 { "bottom-right", StickersListPosition.BottomRight }
3632 };
3633
3634 public void AddSticker(List<StickersCollection> list, Sticker sticker, StickersListPosition stickerPosition)
3635 {
3636 StickersCollection stickersContainerTemp = list.FirstOrDefault(stickersContainer => stickersContainer.Position == stickerPosition);
3637 if (stickersContainerTemp == null)
3638 {
3639 stickersContainerTemp = new StickersCollection()
3640 {
3641 Position = stickerPosition,
3642 Stickers = new List<Sticker>()
3643 };
3644 list.Add(stickersContainerTemp);
3645 }
3646 stickersContainerTemp.Stickers.Add(sticker);
3647 }
3648
3649 public List<StickersCollection> GetStickersContainersList(List<LoopItem> discountsLoop, double discountPrice, double price, DateTime createdDate, string customStickerValue)
3650 {
3651 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly");
3652 bool isSaleStickersEnabled = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetBoolean("Enable");
3653 bool isNewsStickersEnabled = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetBoolean("Enable");
3654 bool isCustomStickersEnabled = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetBoolean("Enable");
3655
3656 List<StickersCollection> resultList = new List<StickersCollection>();
3657
3658 if (!pointShopOnly && isSaleStickersEnabled)
3659 {
3660 string contentType = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetString("ContentType");
3661 contentType = !string.IsNullOrEmpty(contentType) ? contentType : "Name";
3662 var currency = Dynamicweb.Ecommerce.Services.Currencies.GetDefaultCurrency();
3663 Sticker saleSticker = new Sticker();
3664 saleSticker.CssClass = "stickers-container__tag--sale";
3665
3666 switch (contentType)
3667 {
3668 case "Name":
3669 foreach (LoopItem discount in discountsLoop)
3670 {
3671 saleSticker.Title = discount.GetString("Ecom:Product.Discount.Name");
3672 }
3673 break;
3674 case "Amount":
3675 if (discountsLoop.Count > 0)
3676 {
3677 saleSticker.Title = Dynamicweb.Ecommerce.Services.Currencies.Format(currency, discountPrice - price);
3678 }
3679 break;
3680 case "Percents":
3681 double percents = 0;
3682 foreach (LoopItem discount in discountsLoop)
3683 {
3684 percents += discount.GetDouble("Ecom:Product.Discount.PercentWithoutVAT");
3685 }
3686 if (percents > 0)
3687 {
3688 saleSticker.Title = Math.Round(percents, 0) + "%";
3689 }
3690 break;
3691 case "Amount and percents":
3692 double amount = 0;
3693 double percent = 0;
3694 foreach (LoopItem discount in discountsLoop)
3695 {
3696 if (discount.GetString("Ecom:Product.Discount.Type") == "PERCENT")
3697 {
3698 percent += discount.GetDouble("Ecom:Product.Discount.PercentWithoutVAT");
3699 }
3700 else if (discount.GetString("Ecom:Product.Discount.Type") == "AMOUNT")
3701 {
3702 amount += discount.GetDouble("Ecom:Product.Discount.AmountWithVAT");
3703 }
3704 }
3705
3706 if (percent > 0)
3707 {
3708 saleSticker.Title = percent + "%";
3709 }
3710 else if (amount > 0)
3711 {
3712 saleSticker.Title = "-" + Dynamicweb.Ecommerce.Services.Currencies.Format(currency, amount);
3713 }
3714 break;
3715 default:
3716 if (discountsLoop.Count > 0)
3717 {
3718 saleSticker.Title = Translate("Sale!");
3719 }
3720 break;
3721 }
3722 StickersListPosition saleStickerPosition = StickersListPosition.TopLeft;
3723 if (Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetList("Position") != null)
3724 {
3725 string value = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("SaleSticker").GetList("Position").SelectedValue;
3726 saleStickerPosition = stickerPositions.ContainsKey(value) ? stickerPositions[value] : stickerPositions["top-left"];
3727 }
3728 if (!string.IsNullOrEmpty(saleSticker.Title))
3729 {
3730 AddSticker(resultList, saleSticker, saleStickerPosition);
3731 }
3732 }
3733
3734 if (!pointShopOnly && isNewsStickersEnabled && createdDate.AddDays(Converter.ToDouble(Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetString("Expiration"))) > DateTime.Now)
3735 {
3736 Sticker newSticker = new Sticker();
3737 newSticker.CssClass = "stickers-container__tag--new";
3738 newSticker.Title = Translate("New!");
3739
3740 StickersListPosition newStickerPosition = StickersListPosition.TopLeft;
3741 if (Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetList("Position") != null)
3742 {
3743 string value = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("NewSticker").GetList("Position").SelectedValue;
3744 newStickerPosition = stickerPositions.ContainsKey(value) ? stickerPositions[value] : stickerPositions["top-left"];
3745 }
3746 if (!string.IsNullOrEmpty(newSticker.Title))
3747 {
3748 AddSticker(resultList, newSticker, newStickerPosition);
3749 }
3750 }
3751
3752 if (!pointShopOnly && isCustomStickersEnabled && !string.IsNullOrEmpty(customStickerValue))
3753 {
3754 Sticker customSticker = new Sticker();
3755 customSticker.CssClass = "stickers-container__tag--custom";
3756 customSticker.Title = customStickerValue;
3757
3758 StickersListPosition customStickerPosition = StickersListPosition.TopLeft;
3759 if (Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetList("Position") != null)
3760 {
3761 string value = Pageview.AreaSettings.GetItem("Ecommerce").GetItem("CustomSticker").GetList("Position").SelectedValue;
3762 customStickerPosition = stickerPositions.ContainsKey(value) ? stickerPositions[value] : stickerPositions["top-left"];
3763 }
3764 if (!string.IsNullOrEmpty(customSticker.Title))
3765 {
3766 AddSticker(resultList, customSticker, customStickerPosition);
3767 }
3768 }
3769
3770 return resultList;
3771 }
3772 }
3773 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
3774
3775
3776 @*
3777 This is a temporary fallback for the DefaultImage. The image pattern MUST be set up like this:
3778
3779 ImageSmall = /{ProductNumber}.jpg
3780 ImageMedium = /{ProductNumber}{VariantOptionLevel1}.jpg
3781 ImageLarge = /{ProductNumber}{VariantComboName}.jpg
3782
3783 In addition to the ImageDefault setting
3784 *@
3785
3786 @functions {
3787 public string GetProductImage(LoopItem productObject = null)
3788 {
3789 string theImage = "";
3790
3791 if (productObject == null) {
3792 theImage = GetString("Ecom:Product.ImageDefault.Default.Clean");
3793 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageLarge.Clean") : theImage;
3794 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageMedium.Clean") : theImage;
3795 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageSmall.Clean") : theImage;
3796 theImage = String.IsNullOrEmpty(theImage) ? GetString("Ecom:Product.ImageLarge.Default.Clean") : theImage;
3797 } else {
3798 theImage = productObject.GetString("Ecom:Product.ImageDefault.Default.Clean");
3799 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageLarge.Clean") : theImage;
3800 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageMedium.Clean") : theImage;
3801 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageSmall.Clean") : theImage;
3802 theImage = String.IsNullOrEmpty(theImage) ? productObject.GetString("Ecom:Product.ImageLarge.Default.Clean") : theImage;
3803 }
3804
3805 return theImage;
3806 }
3807 }
3808
3809 @functions {
3810 BlocksPage mainImagePage = BlocksPage.GetBlockPage("Product");
3811 bool showThumbs;
3812 bool thumbsOnTheSide;
3813 }
3814
3815 @{
3816 int imageBlockWidth = Pageview.AreaSettings.GetItem("ProductPage").GetList("TopLayout") != null ? Converter.ToInt32(Pageview.AreaSettings.GetItem("ProductPage").GetList("TopLayout").SelectedValue) : 6;
3817 string blocksPosition = Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("ImageSectionPosition").SelectedValue : "thumbs-image-info";
3818 bool infoOnTheRight = blocksPosition.LastIndexOf("info") == blocksPosition.Length - 4;
3819 showThumbs = blocksPosition.IndexOf("thumbs") != -1;
3820 thumbsOnTheSide = showThumbs && blocksPosition.IndexOf("thumbsBottom") == -1;
3821 bool thumbsOnTheLeft = blocksPosition.IndexOf("image") > blocksPosition.IndexOf("thumbs");
3822 if (infoOnTheRight)
3823 {
3824 imageBlockWidth = 14 - imageBlockWidth;
3825 if (imageBlockWidth == 0)
3826 {
3827 imageBlockWidth = 14;
3828 }
3829 }
3830
3831 if (Pageview.Device.ToString() == "Mobile" || Pageview.Device.ToString() == "Tablet") {
3832 thumbsOnTheSide = false;
3833 }
3834
3835 Block mainImageBlock = new Block()
3836 {
3837 Id = "MainImage",
3838 SortId = infoOnTheRight ? 10 : 20,
3839 Design = new Design
3840 {
3841 Size = Converter.ToString(imageBlockWidth),
3842 RenderType = RenderType.Column
3843 },
3844 BlocksList = new List<Block>
3845 {
3846 new Block {
3847 Id = "MainImageRow",
3848 SortId = 10,
3849 Design = new Design
3850 {
3851 RenderType = RenderType.Row
3852 },
3853 BlocksList = new List<Block>
3854 {
3855 new Block
3856 {
3857 Id = "Carousel",
3858 SortId = 10,
3859 Template = RenderThumbnails(),
3860 Design = new Design
3861 {
3862 Size = thumbsOnTheSide ? "2" : "12",
3863 RenderType = RenderType.Column
3864 }
3865 }
3866 }
3867 }
3868 }
3869 };
3870 mainImagePage.Add("Top", mainImageBlock);
3871
3872 mainImagePage.Add("MainImageRow",
3873 new Block()
3874 {
3875 Id = "ProductImageModal",
3876 SortId = 0,
3877 Component = new Modal {
3878 Id = "Gallery",
3879 Width = ModalWidth.Lg,
3880 Height = ModalHeight.Full,
3881 BodyTemplate = RenderProductImagesCarousel("modalCarousel", 1, "horizontal", 3, true)
3882 }
3883 });
3884
3885 if (showThumbs)
3886 {
3887 mainImagePage.Add("MainImageRow",
3888 new Block
3889 {
3890 Id = "Image",
3891 SortId = thumbsOnTheLeft ? 20 : 0,
3892 Template = RenderProductImage(),
3893 Design = new Design
3894 {
3895 Size = thumbsOnTheSide ? "auto" : "12",
3896 RenderType = RenderType.Column
3897 }
3898 });
3899 }
3900 }
3901
3902 @helper RenderProductStickers()
3903 {
3904 List<StickersCollection> StickersContainers = GetStickersContainersList(
3905 GetLoop("ProductDiscounts"),
3906 GetDouble("Ecom:Product.Discount.Price.Price"),
3907 GetDouble("Ecom:Product.Price.Price"),
3908 GetDate("Ecom:Product.Created"),
3909 GetString("Ecom:Product:Field.CustomSticker.Value")
3910 );
3911
3912 foreach (StickersCollection stickersContainer in StickersContainers)
3913 {
3914 @Render(new StickersCollection { Stickers = stickersContainer.Stickers, Position = stickersContainer.Position })
3915 }
3916 }
3917
3918 @helper RenderProductImage()
3919 {
3920 //Add product image to the og meta data
3921 Pageview.Meta.AddTag("og:image", GetProductImage());
3922
3923 <label for="GalleryModalTrigger" class="nc-product__image-container u-position-relative">
3924 @{
3925 Image productImage = new Image
3926 {
3927 Path = GetProductImage(),
3928 Id = "Image_" + GetString("Ecom:Product.ID"),
3929 CssClass = "nc-product__image-container__image",
3930 Title = GetString("Ecom:Product.Name"),
3931 OnClick = "modalCarousel.GoToSlide('modalCarousel', this.getAttribute('data-number'))",
3932 ImageDefault = new ImageSettings
3933 {
3934 Width = 800,
3935 Height = 800,
3936 Crop = 7,
3937 FillCanvas = true
3938 }
3939 };
3940 productImage.ExtraAttributes.Add("data-number", "0");
3941 }
3942
3943 @Render(productImage)
3944
3945 @RenderProductStickers()
3946 </label>
3947 }
3948
3949 @helper RenderThumbnails()
3950 {
3951 <div class="dw-mod">
3952 @RenderProductImagesCarousel(
3953 "productCarousel",
3954 !showThumbs ? 1 : 5,
3955 thumbsOnTheSide ? "vertical" : "horizontal",
3956 !showThumbs ? 3 : 2
3957 )
3958 @if (!showThumbs)
3959 {
3960 @RenderProductStickers()
3961 }
3962 </div>
3963 }
3964
3965 @helper RenderProductImagesCarousel(string id, int slidesInView, string direction, int preloaderSize, bool isModal = false)
3966 {
3967 var selectedImageCategories = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductImagesInTopSection").SelectedValues;
3968 var imagesFromAssets = GetLoop("ImageCategories").Where(x => selectedImageCategories.Contains(x.GetString("Category.Id")));
3969
3970 HashSet<string> images = new HashSet<string>();
3971
3972 images.Add(GetProductImage());
3973
3974 foreach (LoopItem alternativeImage in GetLoop("Ecom:Product.AlternativeImages"))
3975 {
3976 string alt_image = alternativeImage.GetString("Ecom:Product.AlternativeImages.Image");
3977
3978 if (!string.IsNullOrEmpty(alt_image))
3979 {
3980 images.Add(alt_image);
3981 }
3982 }
3983
3984 int assetImagesCount = 0;
3985 foreach (LoopItem category in imagesFromAssets) {
3986 foreach (LoopItem asset in category.GetLoop("Category.Images")) {
3987 assetImagesCount++;
3988 }
3989 }
3990
3991 if (assetImagesCount > 0) {
3992 foreach (LoopItem category in imagesFromAssets) {
3993 foreach (LoopItem asset in category.GetLoop("Category.Images")) {
3994 images.Add(asset.GetString("Ecom:Product:Detail.Image.Clean"));
3995 }
3996 }
3997 } else {
3998 foreach (LoopItem detail in GetLoop("Details"))
3999 {
4000 string detail_image = detail.GetString("Ecom:Product:Detail.Image.Clean");
4001
4002 if (!string.IsNullOrEmpty(detail_image))
4003 {
4004 string ext = Path.GetExtension(detail_image).ToLower();
4005 if (ext == ".jpg" || ext == ".jpeg" || ext == ".gif" || ext == ".png")
4006 {
4007 images.Add(detail_image);
4008 }
4009 }
4010 }
4011 }
4012 <div class="carousel dw-mod" id="@id">
4013 <div class="thumb-list carousel__container @(slidesInView != 1 ? "carousel__container--hidden" : "") js-carousel-slides dw-mod">
4014 @{ var i = 0; }
4015 @foreach (var image in images)
4016 {
4017 @RenderProductImage(image, slidesInView == 1, isModal ? "modal--full__img" : "", i == 0, isModal)
4018 i++; //first is active
4019 }
4020 </div>
4021
4022 <script>
4023 document.addEventListener("DOMContentLoaded", function () {
4024 @id = new CarouselModule('#@id', {
4025 slidesInView: @slidesInView,
4026 direction: "@direction",
4027 preloaderSize: @preloaderSize,
4028 showCounter: @isModal.ToString().ToLower()
4029 });
4030 });
4031 </script>
4032 </div>
4033 }
4034
4035 @helper RenderProductImage(string image, bool isBig, string cssClass = "", bool isActive = false, bool isModal = false)
4036 {
4037 string productId = GetString("Ecom:Product.ID");
4038 string imagePrefix = "/Admin/Public/GetImage.ashx?width=800&height=800&crop=7&FillCanvas=True&DoNotUpscale=true&Compression=75&image=";
4039
4040 Image productImage = new Image {
4041 Path = image,
4042 Title = GetString("Ecom:Product.Name"),
4043 ImageDefault = new ImageSettings {
4044 Width = 800,
4045 Height = 800,
4046 Crop = 5,
4047 FillCanvas = false
4048 },
4049 CssClass = "u-middle " + cssClass,
4050 OnClick = "modalCarousel.GoToSlide('modalCarousel', this.closest('.carousel__slide').index());"
4051 };
4052 productImage.ExtraAttributes.Add("data-image", image);
4053
4054 <div class="carousel__slide dw-mod">
4055 @if (isModal)
4056 {
4057 @Render(new Image { Path = image, CssClass = cssClass, Title = GetString("Ecom:Product.Name"), DisableImageEngine = true });
4058 }
4059 else if (isBig)
4060 {
4061 <label for="GalleryModalTrigger" class="u-middle">
4062 @Render(productImage)
4063 </label>
4064 }
4065 else
4066 {
4067 Image productThumb = productImage;
4068 productThumb.ImageDefault = new ImageSettings
4069 {
4070 Width = 200,
4071 Height = 200,
4072 Crop = 7,
4073 FillCanvas = true
4074 };
4075 productImage.CssClass += " thumb-list__image";
4076 <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="@image" onmouseover="Gallery.openImage(this)">
4077 <label for="GalleryModalTrigger" class="thumb-list__image-label">
4078 @Render(productThumb)
4079 </label>
4080 </div>
4081 }
4082 </div>
4083 }
4084 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
4085 @using Dynamicweb.Core
4086 @using System
4087 @using System.Web
4088 @using System.Collections.Generic
4089 @using Dynamicweb.Rapido.Blocks
4090 @using Dynamicweb.Rapido.Blocks.Components.General
4091
4092 @functions {
4093 BlocksPage productAssetsPage = BlocksPage.GetBlockPage("Product");
4094 }
4095
4096 @{
4097 string productAssetsLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("ProductAssetsLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductAssetsLayout").SelectedValue : "Section";
4098 productAssetsLayout = productAssetsLayout == "Ribbon" ? "Section" : productAssetsLayout;
4099
4100 if (productAssetsLayout != "hide")
4101 {
4102 Block productAssetsBlock = new Block()
4103 {
4104 Name = productAssetsLayout != "MainInformation" ? Translate("Product assets") : "",
4105 Id = "ProductAssets",
4106 SortId = 10,
4107 Template = RenderProductAssets(productAssetsLayout, downloadDocuments), @*downloadDocuments variable, declared in Product.cshtml and defined in Fields.cshtml*@
4108 Design = new Design
4109 {
4110 Size = "12",
4111 RenderType = RenderType.Column,
4112 HidePadding = true
4113 }
4114 };
4115 productAssetsPage.Add(productAssetsLayout, productAssetsBlock);
4116 }
4117 }
4118
4119 @helper RenderProductAssets(string layout, List<LoopItem> documents)
4120 {
4121 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductAssetsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
4122 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductAssetsLayout").SelectedValue == "Ribbon" ? "u-padding--lg" : "";
4123 string exportPageId = GetPageIdByNavigationTag("ProductExportFeed").ToString();
4124
4125 //images
4126
4127 HashSet<string> images = new HashSet<string>();
4128
4129 images.Add(GetProductImage());
4130
4131 foreach (LoopItem alternativeImage in GetLoop("Ecom:Product.AlternativeImages"))
4132 {
4133 string alt_image = alternativeImage.GetString("Ecom:Product.AlternativeImages.Image");
4134
4135 if (!string.IsNullOrEmpty(alt_image))
4136 {
4137 images.Add(alt_image);
4138 }
4139 }
4140
4141 foreach (LoopItem detail in GetLoop("Details"))
4142 {
4143 string detail_image = detail.GetString("Ecom:Product:Detail.Image.Clean");
4144
4145 if (!string.IsNullOrEmpty(detail_image))
4146 {
4147 images.Add(detail_image);
4148 }
4149 }
4150
4151 <div class="product__section @ribbonClasses dw-mod">
4152 <div class="product__description center-container @ribbonSubClasses dw-mod">
4153 @if (layout == "Section")
4154 {
4155 @Render(new Heading { Title = Translate("Product assets"), Level = 2 })
4156 }
4157
4158 <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">
4159 <div class="grid">
4160 @if (images.Count > 0)
4161 {
4162 <div class="grid__col-md-4 js-checkboxes-list">
4163 @Render(new CheckboxField { Id = "allImages", OnChange = "selectAll(this)", Label = Translate("Images") + "(" + images.Count + ")" })
4164
4165 <ul class="panel-list">
4166 @foreach (string image in images)
4167 {
4168 @RenderProductPanelListItem(image)
4169 }
4170 </ul>
4171 </div>
4172 }
4173
4174 @if (documents.Count > 0)
4175 {
4176 <div class="grid__col-md-4 js-checkboxes-list">
4177 @Render(new CheckboxField { Id = "allDocuments", OnChange = "selectAll(this)", Label = Translate("Documents") + "(" + documents.Count + ")" })
4178
4179 <ul class="panel-list">
4180 @foreach (LoopItem document in documents)
4181 {
4182 string fieldValue;
4183 if (!string.IsNullOrEmpty(document.GetString("Document.FullPath")))
4184 {
4185 fieldValue = document.GetString("Product.CustomField.Value.Clean");
4186 @RenderDocument(fieldValue)
4187 }
4188 if (document.GetString("Ecom:Product.CategoryField.TypeID") == "9")
4189 {
4190 fieldValue = document.GetString("Ecom:Product.CategoryField.Value");
4191 @RenderDocument(fieldValue)
4192 }
4193 if (!string.IsNullOrEmpty(document.GetString("Ecom:Product:Detail.Image.Clean")))
4194 {
4195 fieldValue = document.GetString("Ecom:Product:Detail.Image.Clean");
4196 @RenderDocument(fieldValue)
4197 }
4198 }
4199 </ul>
4200 </div>
4201 }
4202 <div class="grid__col-md-4">
4203 @Render(new HiddenField { Id = "ID", Name = "ID", Value = "532" })
4204 @Render(new HiddenField { Id = "download", Name = "download", Value = "true" })
4205 @Render(new HiddenField { Id = "siteUrl", Name = "siteUrl", Value = string.Format("{0}://{1}", GetGlobalValue("Global:Request.Scheme"), GetGlobalValue("Global:Request.Host")) })
4206
4207 <div class="u-bold u-margin-bottom">@Translate("Export")</div>
4208
4209 @{
4210 SelectField languageSelect = new SelectField
4211 {
4212 Id = "exportLanguage",
4213 Label = Translate("Language"),
4214 Name = "RequestLanguageId",
4215 CssClass = "u-full-width"
4216 };
4217 foreach (var lang in Dynamicweb.Ecommerce.Services.Languages.GetLanguages().OrderBy(l => l.Name))
4218 {
4219 var selected = lang.IsDefault ? true : false;
4220 languageSelect.Options.Add(new SelectFieldOption { Label = lang.Name, Value = lang.LanguageId, Checked = selected });
4221 }
4222 @Render(languageSelect)
4223
4224 SelectField purposeSelect = new SelectField
4225 {
4226 Id = "purpose",
4227 Label = Translate("Image purpose"),
4228 Name = "purpose",
4229 CssClass = "u-full-width"
4230 };
4231 purposeSelect.Options.Add(new SelectFieldOption { Label = Translate("Office"), Value = "Office" });
4232 purposeSelect.Options.Add(new SelectFieldOption { Label = Translate("Original"), Value = "Original" });
4233 purposeSelect.Options.Add(new SelectFieldOption { Label = Translate("Print"), Value = "Print" });
4234 purposeSelect.Options.Add(new SelectFieldOption { Label = Translate("Web"), Value = "Web" });
4235 @Render(purposeSelect)
4236
4237 SelectField formatSelect = new SelectField
4238 {
4239 Id = "exportFormat",
4240 Label = Translate("Export format"),
4241 Name = "format",
4242 CssClass = "u-full-width"
4243 };
4244 formatSelect.Options.Add(new SelectFieldOption { Label = Translate("Csv"), Value = "csv" });
4245 formatSelect.Options.Add(new SelectFieldOption { Label = Translate("Json"), Value = "json" });
4246 formatSelect.Options.Add(new SelectFieldOption { Label = Translate("Xml"), Value = "xml" });
4247 @Render(formatSelect)
4248 }
4249
4250 @Render(new Button { ButtonType = ButtonType.Submit, ButtonLayout = ButtonLayout.Primary, CssClass = "btn--full u-no-margin", Title = Translate("Download") })
4251 </div>
4252 </div>
4253 </form>
4254 </div>
4255 </div>
4256 <script>
4257 function selectAll(checkbox) {
4258 checkbox.closest(".js-checkboxes-list").querySelectorAll(".js-checkbox").forEach(function (input) {
4259 input.checked = checkbox.checked;
4260 });
4261 }
4262 </script>
4263 }
4264
4265 @helper RenderProductPanelListItem(string imageName)
4266 {
4267 <li class="panel-list__item">
4268 <div class="panel-list__item-check">
4269 <input id="Image_@imageName" name="Image_@imageName" type="checkbox" class="form__control u-no-margin dw-mod js-checkbox" />
4270 <label for="Image_@imageName"></label>
4271 </div>
4272 <div class="panel-list__item-image">
4273 <label for="Image_@imageName" class="u-no-margin">
4274 @Render(new Image { Path = imageName, Title = Path.GetFileName(imageName), ImageDefault = new ImageSettings { Width = 55, Height = 55, Crop = 5, FillCanvas = true } })
4275 </label>
4276 </div>
4277 <div class="panel-list__item-name">
4278 <label for="Image_@imageName" class="u-truncate-text u-w170px" title="@Path.GetFileName(imageName)">
4279 @Path.GetFileName(imageName)
4280 </label>
4281 </div>
4282 </li>
4283 }
4284
4285 @helper RenderDocument(string fieldValue)
4286 {
4287 <li class="panel-list__item">
4288 <div class="panel-list__item-check">
4289 <input id="Document_@fieldValue" name="Document_@fieldValue" type="checkbox" class="form__control u-no-margin js-checkbox dw-mod">
4290 <label for="Document_@fieldValue"></label>
4291 </div>
4292 <div class="panel-list__item-name">
4293 <label for="Document_@fieldValue" class="u-truncate-text u-no-margin u-max-w220px" title="@Path.GetFileName(fieldValue)">
4294 @Path.GetFileName(fieldValue)
4295 </label>
4296 </div>
4297 </li>
4298 }
4299 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
4300 @using Dynamicweb.Core
4301 @using System
4302 @using System.Web
4303 @using System.Collections.Generic
4304 @using Dynamicweb.Rapido.Blocks
4305 @using Dynamicweb.Rapido.Blocks.Components.General
4306
4307 @functions {
4308 BlocksPage productGeneratePDFPage = BlocksPage.GetBlockPage("Product");
4309 }
4310
4311 @{
4312 string generatePDFLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("GeneratePDFLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("GeneratePDFLayout").SelectedValue : "Section";
4313 generatePDFLayout = generatePDFLayout == "Ribbon" ? "Section" : generatePDFLayout;
4314
4315 if (GetPageIdByNavigationTag("ProductPagePDFTemplates") > 0 && generatePDFLayout != "hide")
4316 {
4317 Block generatePDFBlock = new Block()
4318 {
4319 Name = generatePDFLayout != "MainInformation" ? Translate("Generate PDF") : "",
4320 Id = "GeneratePDF",
4321 SortId = 10,
4322 Template = RenderGeneratePDF(generatePDFLayout),
4323 Design = new Design
4324 {
4325 Size = "12",
4326 RenderType = RenderType.Column,
4327 HidePadding = true
4328 }
4329 };
4330
4331 productGeneratePDFPage.Add(generatePDFLayout, generatePDFBlock);
4332 }
4333 }
4334
4335 @helper RenderGeneratePDF(string layout)
4336 {
4337 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("GeneratePDFLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
4338 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses;
4339 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("GeneratePDFLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : "";
4340 string exportPageId = GetPageIdByNavigationTag("ProductExportFeed").ToString();
4341 int pdfFolderId = GetPageIdByNavigationTag("ProductPagePDFTemplates");
4342
4343 Form form = new Form { Action = "/Default.aspx?MainProductID=" + System.Web.HttpContext.Current.Request.QueryString.Get("ProductID") + "&VariantID=" + System.Web.HttpContext.Current.Request.QueryString.Get("VariantID") + "&Pdf=true", Method = FormMethod.Post, CssClass = "u-no-margin" };
4344 form.Add(new HiddenField { Name = "siteUrl", Value = string.Format("{0}://{1}", GetGlobalValue("Global:Request.Scheme"), GetGlobalValue("Global:Request.Host")) });
4345
4346 //Select languages
4347 SelectField languagesList = new SelectField
4348 {
4349 Id = "RequestLanguageID",
4350 Name = "RequestLanguageID",
4351 Label = Translate("Language"),
4352 CssClass = "u-full-width"
4353 };
4354
4355 foreach (var lang in Dynamicweb.Ecommerce.Services.Languages.GetLanguages().OrderBy(l => l.Name))
4356 {
4357 languagesList.Options.Add(new SelectFieldOption
4358 {
4359 Label = lang.Name,
4360 Value = lang.LanguageId,
4361 Checked = lang.IsDefault ? true : false
4362 });
4363 }
4364 form.Add(languagesList);
4365
4366 //Select pages
4367 SelectField pagesList = new SelectField
4368 {
4369 Id = "PDFTemplate",
4370 Name = "ID",
4371 Label = Translate("Generate PDF"),
4372 CssClass = "u-full-width"
4373 };
4374
4375 foreach (Dynamicweb.Content.Page page in ServiceLocator.Current.GetPageService().GetPagesByParentID(pdfFolderId))
4376 {
4377 pagesList.Options.Add(new SelectFieldOption
4378 {
4379 Label = page.MenuText,
4380 Value = Converter.ToString(page.ID)
4381 });
4382 }
4383 form.Add(pagesList);
4384
4385 form.Add(new Button { ButtonType = ButtonType.Submit, Title = Translate("Generate PDF"), CssClass = "btn--full u-no-margin" });
4386
4387 <div class="product__section @ribbonClasses grid dw-mod">
4388 <div class="dw-mod grid__col-md-4 @ribbonSubClasses">
4389 @if (layout == "Section")
4390 {
4391 @Render(new Heading { Title = Translate("Generate PDF"), Level = 2 })
4392 }
4393 @Render(form)
4394 </div>
4395 </div>
4396 }
4397
4398 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
4399 @using Dynamicweb.Core
4400 @using System
4401 @using System.Web
4402 @using System.Collections.Generic
4403 @using Dynamicweb.Rapido.Blocks
4404 @using Dynamicweb.Rapido.Blocks.Components.General
4405
4406 @functions {
4407 BlocksPage productDescriptionPage = BlocksPage.GetBlockPage("Product");
4408 }
4409
4410 @{
4411 string fullDesctiptionLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("FullDescriptionLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue : "Section";
4412 fullDesctiptionLayout = fullDesctiptionLayout == "Ribbon" ? "Section" : fullDesctiptionLayout;
4413
4414 if (!string.IsNullOrEmpty(GetString("Ecom:Product.LongDescription")) && fullDesctiptionLayout != "hide")
4415 {
4416 Block detailsDescription = new Block()
4417 {
4418 Name = fullDesctiptionLayout != "MainInformation" ? Translate("Description") : "",
4419 Id = "FullDescription",
4420 SortId = 30,
4421 Template = RenderProductDescription(fullDesctiptionLayout),
4422 Design = new Design
4423 {
4424 Size = "12",
4425 RenderType = RenderType.Column,
4426 HidePadding = true
4427 }
4428 };
4429 productDescriptionPage.Add(fullDesctiptionLayout, detailsDescription);
4430 }
4431 }
4432
4433 @helper RenderProductDescription(string layout)
4434 {
4435 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
4436 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses;
4437 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : "";
4438
4439 <div class="product__section @ribbonClasses dw-mod">
4440 <div class="product__description center-container @ribbonSubClasses dw-mod">
4441 @if (layout == "Section") {
4442 @Render(new Heading { Title = Translate("Description"), Level = 2 })
4443 }
4444 @Render(new Text { Content = GetString("Ecom:Product.LongDescription") })
4445 </div>
4446 </div>
4447 }
4448 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
4449 @using Dynamicweb.Core
4450 @using System
4451 @using System.Web
4452 @using System.Globalization;
4453 @using System.Collections.Generic
4454 @using Dynamicweb.Ecommerce.Products.Categories
4455 @using Dynamicweb.Ecommerce.Products.FieldDisplayGroups
4456 @using Dynamicweb.Ecommerce.Synchronization
4457 @using Dynamicweb.Rapido.Blocks
4458
4459
4460
4461 @functions {
4462 BlocksPage productFieldsPage = BlocksPage.GetBlockPage("Product");
4463
4464
4465 static string ConvertBytes(long bytes)
4466 {
4467 double size = bytes / 1024; //KB
4468 if (size > 1024)
4469 {
4470 size = (bytes / 1024f) / 1024f; //MB
4471 return string.Format("{0:n1} MB", size);
4472 }
4473 else
4474 {
4475 return string.Format("{0:n0} KB", size);
4476 }
4477 }
4478
4479 static bool isImage(string path)
4480 {
4481 return new List<string> { ".jpg", ".jpeg", ".gif", ".png", ".svg" }.Contains(Path.GetExtension(path).ToLower());
4482 }
4483
4484 string getIconForFile(string fileName)
4485 {
4486 string ext = Path.GetExtension(fileName);
4487 string icon = "";
4488 switch (ext.ToLower())
4489 {
4490 case ".xls":
4491 case ".xlsx":
4492 icon = "fa-file-excel";
4493 break;
4494 case ".ppt":
4495 case ".pptx":
4496 icon = "fa-file-powerpoint";
4497 break;
4498 case ".doc":
4499 case ".docx":
4500 icon = "fa-file-word";
4501 break;
4502 case ".jpg":
4503 case ".jpeg":
4504 case ".png":
4505 case ".gif":
4506 case ".pdf":
4507 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 + "' />";
4508 default:
4509 icon = "fa-file";
4510 break;
4511 }
4512 return "<i class='product__document-icon far " + icon + "'></i> ";
4513 }
4514
4515 }
4516
4517 @*downloadDocuments variable, declared in Product.cshtml - this variable also will be used in ProductAssets.cshtml*@
4518
4519
4520
4521 @{
4522
4523
4524
4525 var selectedDownloadCategories = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadAssets").SelectedValues;
4526 var downloadsFromAssets = GetLoop("ImageCategories").Where(x => selectedDownloadCategories.Contains(x.GetString("Category.Id")));
4527
4528 if (string.IsNullOrEmpty(selectedDownloadCategories.ToString()))
4529 {
4530 foreach (LoopItem customField in GetLoop("CustomFieldValues"))
4531 {
4532 if (!string.IsNullOrEmpty(customField.GetString("Product.CustomField.Name")) && !string.IsNullOrEmpty(customField.GetString("Product.CustomField.Value.Clean")) && customField.GetString("Product.CustomField.Name") != "Custom sticker" && customField.GetString("Product.CustomField.Name") != "RRP")
4533 {
4534 if (!string.IsNullOrEmpty(customField.GetString("Document.FullPath")))
4535 {
4536 downloadDocuments.Add(customField);
4537 }
4538 }
4539 }
4540
4541 foreach (LoopItem customField in GetLoop("ProductCategories"))
4542 {
4543 foreach (LoopItem field in customField.GetLoop("ProductCategoryFields"))
4544 {
4545 if (!string.IsNullOrEmpty(field.GetString("Ecom:Product.CategoryField.Label")) && !string.IsNullOrEmpty(field.GetString("Ecom:Product.CategoryField.Value")))
4546 {
4547 if (field.GetString("Ecom:Product.CategoryField.TypeID") == "9")
4548 {
4549 downloadDocuments.Add(field);
4550 }
4551 }
4552 }
4553 }
4554 }
4555 else
4556 {
4557 foreach (LoopItem category in downloadsFromAssets)
4558 {
4559 foreach (LoopItem asset in category.GetLoop("Category.Images"))
4560 {
4561 downloadDocuments.Add(asset);
4562 }
4563 }
4564 }
4565
4566 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true;
4567 string detailFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout").SelectedValue : "Section";
4568 detailFieldsLayout = detailFieldsLayout == "Ribbon" || string.IsNullOrEmpty(detailFieldsLayout) ? "Section" : detailFieldsLayout;
4569 string categoryFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout").SelectedValue : "Section";
4570 categoryFieldsLayout = categoryFieldsLayout == "Ribbon" || string.IsNullOrEmpty(categoryFieldsLayout) ? "Section" : categoryFieldsLayout;
4571 string displayGroupsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DisplayGroupsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DisplayGroupsLayout").SelectedValue : "Section";
4572 displayGroupsLayout = displayGroupsLayout == "Ribbon" || string.IsNullOrEmpty(displayGroupsLayout) ? "Section" : displayGroupsLayout;
4573 string downloadsFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout").SelectedValue : "Section";
4574 downloadsFieldsLayout = downloadsFieldsLayout == "Ribbon" || string.IsNullOrEmpty(downloadsFieldsLayout) ? "Section" : downloadsFieldsLayout;
4575
4576 string detailFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsView").SelectedValue : "grid";
4577 string categoryFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsView").SelectedValue : "grid";
4578 string downloadsFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsFieldsView").SelectedValue : "grid";
4579
4580 if (GetLoop("CustomFieldValues").Count > 0 && detailFieldsLayout != "hide")
4581 {
4582 if (string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("ProductDetailFields")))
4583 {
4584 Block detailsCustom = new Block()
4585 {
4586 Name = detailFieldsLayout != "MainInformation" ? Translate("Details") : "",
4587 Id = "CustomFields",
4588 SortId = 30,
4589 Design = new Design
4590 {
4591 Size = "12",
4592 RenderType = RenderType.Column,
4593 HidePadding = true
4594 }
4595 };
4596
4597 detailsCustom.Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Information"), RenderCustomFields(GetLoop("CustomFieldValues"), detailFieldsView));
4598 productFieldsPage.Add(detailFieldsLayout, detailsCustom);
4599 }
4600 else
4601 {
4602 var detailFieldsDisplayGroups = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductDetailFields").SelectedValues;
4603 var displayGroups = GetLoop("FieldDisplayGroups").Where(x => detailFieldsDisplayGroups.Contains(x.GetString("Ecom:FieldDisplayGroup.ID")));
4604
4605
4606 foreach (var group in displayGroups)
4607 {
4608 Block detailsCustom = new Block()
4609 {
4610 Name = detailFieldsLayout != "MainInformation" ? group.GetString("Ecom:FieldDisplayGroup.Name") : "",
4611 Id = "DetailFields_" + group.GetString("Ecom:FieldDisplayGroup.ID"),
4612 SortId = 30,
4613 Design = new Design
4614 {
4615 Size = "12",
4616 RenderType = RenderType.Column,
4617 HidePadding = true
4618 }
4619 };
4620
4621 detailsCustom.Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Information"), RenderDetailsFields(group.GetLoop("Fields"), detailFieldsView));
4622 productFieldsPage.Add(detailFieldsLayout, detailsCustom);
4623 }
4624 }
4625 }
4626
4627 if (categoryFieldsLayout != "hide")
4628 {
4629 foreach (LoopItem categoryGroup in GetLoop("ProductCategories"))
4630 {
4631 bool hasFields = categoryGroup.GetLoop("ProductCategoryFields").FirstOrDefault(cf => !string.IsNullOrEmpty(cf.GetString("Ecom:Product.CategoryField.Value"))) != null;
4632
4633
4634 if (collectAllDownloads)
4635 {
4636 int downloadableCount = 0;
4637 foreach (LoopItem field in categoryGroup.GetLoop("ProductCategoryFields"))
4638 {
4639 if (field.GetString("Ecom:Product.CategoryField.TypeID") == "9")
4640 {
4641 downloadableCount++;
4642 }
4643 }
4644
4645 if (downloadableCount == categoryGroup.GetLoop("ProductCategoryFields").Count)
4646 {
4647 hasFields = false;
4648 }
4649 }
4650
4651 //hasFields needs to be true, if not description will not be shown, even if it is not empty
4652 hasFields = true;
4653
4654 if (hasFields)
4655 {
4656 Block detailsCategoryFields = new Block()
4657 {
4658 Name = categoryFieldsLayout != "MainInformation" ? categoryGroup.GetString("Ecom:Product.Category.Name") : "",
4659 Id = ToPascalCase(categoryGroup.GetString("Ecom:Product.Category.Name")),
4660 SortId = 40,
4661 Template = RenderProductSection(categoryFieldsLayout, categoryFieldsView, categoryGroup.GetString("Ecom:Product.Category.Name"), RenderProductCategoryFields(categoryGroup.GetLoop("ProductCategoryFields"), categoryFieldsView)),
4662 Design = new Design
4663 {
4664 Size = "12",
4665 RenderType = RenderType.Column,
4666 HidePadding = true
4667 }
4668 };
4669
4670 productFieldsPage.Add(categoryFieldsLayout, detailsCategoryFields);
4671 }
4672 }
4673 }
4674
4675 if (displayGroupsLayout != "hide")
4676 {
4677 var detailFieldsDisplayGroups = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductDetailFields").SelectedValues;
4678 var displayGroups = GetLoop("FieldDisplayGroups").Where(x => !detailFieldsDisplayGroups.Contains(x.GetString("Ecom:FieldDisplayGroup.ID")));
4679
4680
4681 foreach (LoopItem group in displayGroups)
4682 {
4683 int fieldsCount = 0;
4684
4685 foreach (LoopItem field in group.GetLoop("Fields"))
4686 {
4687 if (!string.IsNullOrEmpty(field.GetString("Ecom:FieldDisplayGroup.Field.Name")) && !string.IsNullOrEmpty(field.GetString("Ecom:FieldDisplayGroup.Field.Value")))
4688 {
4689 fieldsCount++;
4690 }
4691 }
4692
4693 if (fieldsCount != 0)
4694 {
4695 Block displayGroup = new Block()
4696 {
4697 Name = displayGroupsLayout != "MainInformation" ? group.GetString("Ecom:FieldDisplayGroup.Name") : "",
4698 Id = "DisplayGroup_" + group.GetString("Ecom:FieldDisplayGroup.ID"),
4699 SortId = 40,
4700 Template = RenderProductSection(displayGroupsLayout, categoryFieldsView, group.GetString("Ecom:FieldDisplayGroup.Name"), RenderDetailsFields(group.GetLoop("Fields"), categoryFieldsView)),
4701 Design = new Design
4702 {
4703 Size = "12",
4704 RenderType = RenderType.Column,
4705 HidePadding = true
4706 }
4707 };
4708 productFieldsPage.Add(displayGroupsLayout, displayGroup);
4709 }
4710 else
4711 {
4712 Block displayGroup = new Block()
4713 {
4714 Name = displayGroupsLayout != "MainInformation" ? group.GetString("Ecom:FieldDisplayGroup.Name") : "",
4715 Id = "DisplayGroup_" + group.GetString("Ecom:FieldDisplayGroup.ID"),
4716 SortId = 40,
4717 Template = RenderProductDescription(displayGroupsLayout, categoryFieldsView, group.GetString("Ecom:FieldDisplayGroup.Name"), RenderDetailsFields(group.GetLoop("Fields"), categoryFieldsView)),
4718 Design = new Design
4719 {
4720 Size = "12",
4721 RenderType = RenderType.Column,
4722 HidePadding = true
4723 }
4724 };
4725 productFieldsPage.Add(displayGroupsLayout, displayGroup);
4726 }
4727 }
4728 }
4729
4730 if (downloadDocuments.Count > 0 && downloadsFieldsLayout != "hide" && collectAllDownloads == true)
4731 {
4732 Block detailsDownloads = new Block()
4733 {
4734 Name = downloadsFieldsLayout != "MainInformation" ? Translate("Downloads") : "",
4735 Id = "StandardDownloads",
4736 SortId = 50,
4737 Template = RenderProductSection(downloadsFieldsLayout, downloadsFieldsView, Translate("Downloads"), RenderProductDownloadsFields(downloadDocuments, downloadsFieldsView)),
4738 Design = new Design
4739 {
4740 Size = "12",
4741 RenderType = RenderType.Column,
4742 HidePadding = true
4743 }
4744 };
4745
4746 productFieldsPage.Add(downloadsFieldsLayout, detailsDownloads);
4747 }
4748 }
4749
4750 @helper RenderCustomFields(List<LoopItem> fieldsLoop, string viewType)
4751 {
4752 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true;
4753
4754 foreach (LoopItem customField in fieldsLoop)
4755 {
4756 string fieldValue = customField.GetString("Product.CustomField.Value.Clean");
4757 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue;
4758 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue;
4759
4760 if (customField.GetLoop("Product.CustomField.Options").Count > 0)
4761 {
4762 List<string> accumulatedValues = new List<string>();
4763
4764 foreach (var option in customField.GetLoop("Product.CustomField.Options"))
4765 {
4766 if (option.GetBoolean("Product.CustomField.Option.IsSelected"))
4767 {
4768 accumulatedValues.Add(option.GetString("Product.CustomField.Option.Name"));
4769 }
4770 }
4771 fieldValue = string.Join(", ", accumulatedValues);
4772 }
4773
4774 if (!string.IsNullOrEmpty(customField.GetString("Product.CustomField.Name")) && !string.IsNullOrEmpty(fieldValue) && customField.GetString("Product.CustomField.Name") != "Custom sticker" && customField.GetString("Product.CustomField.Name") != "RRP")
4775 {
4776 if (string.IsNullOrEmpty(customField.GetString("Document.FullPath")))
4777 {
4778 @RenderFieldItem(customField.GetString("Product.CustomField.Name"), fieldValue, viewType)
4779 ;
4780 }
4781 else if (collectAllDownloads == false)
4782 {
4783 @RenderFieldItem(customField.GetString("Product.CustomField.Name"), fieldValue, viewType, "download")
4784 ;
4785 }
4786 }
4787 }
4788 }
4789
4790 @helper RenderProductSection(string layout, string viewType, string name, RazorEngine.Templating.TemplateWriter writer)
4791 {
4792 string ribbonClasses = layout == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
4793 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses;
4794 string ribbonSubClasses = layout == "Ribbon" ? "center-container--ribbon" : "";
4795
4796
4797 <div class="product__section @ribbonClasses dw-mod js-product-detail-info">
4798
4799 <div class="center-container @ribbonSubClasses dw-mod">
4800 @if (viewType != "table")
4801 {
4802 <div class="grid grid--bleed u-margin-bottom--lg">
4803
4804 </div>
4805 }
4806 else
4807 {
4808 string tableWidth = layout != "MainInformation" ? "grid__col-md-6" : "grid__col-md-12";
4809
4810
4811 Dynamicweb.Ecommerce.Products.ProductService productService = new Dynamicweb.Ecommerce.Products.ProductService();
4812
4813 var product = productService.GetProductById(GetString("Ecom:Product.ID"), GetString("Ecom:Product.VariantID"), GetString("Ecom:Product.LanguageID"));
4814 var categoryService = new ProductCategoryService();
4815
4816
4817 List<string> labels = new List<string>();
4818 List<string> values = new List<string>();
4819
4820 if (categoryService.GetCategories(product, true) != null && categoryService.GetCategories(product, true).FirstOrDefault() != null)
4821 {
4822 var data = categoryService.GetCategories(product, true).FirstOrDefault().Fields.ToArray();
4823
4824
4825 if (data != null)
4826 {
4827 foreach (var field in data)
4828 {
4829 var lang = GetString("Ecom:Product.LanguageID");
4830
4831 if (categoryService.GetProductCategoryFieldValue(product, field).Value != null)
4832 {
4833 var fieldData = categoryService.GetProductCategoryFieldValue(product, field).Value.ToString();
4834 labels.Add(field.GetLabel(lang));
4835 values.Add((fieldData));
4836 }
4837 }
4838 }
4839 }
4840
4841
4842 if (name != "")
4843 {
4844 @* Details about the product card *@
4845 <div class="grid u-margin-bottom--lg nc-grid">
4846 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12 table__white extra-specs" id="ProductDetails">
4847 <table class="table--no-borders">
4848 <h3>@Translate("ProductDetails", "Detaljer om produktet")</h3>
4849 <div class="more-info">
4850 @GetString("Ecom:Product.LongDescription")
4851
4852 </div>
4853 <button class="expand-info--box accordion" data-info="@Translate("DataInfo", "Udvid info")" data-info-close="@Translate("DataInfoClose", "Fold info ind")">
4854 </button>
4855 </table>
4856
4857 </div>
4858 </div>
4859 if (labels.Count > 1)
4860 {
4861 @* Specifications for the product card *@
4862 <div class="grid u-margin-bottom--lg nc-grid">
4863 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12 table__white extra-specs" id="ProductSpecs">
4864 <table class="table--no-borders">
4865 <h3>@Translate("ProductSpecs", "Specifikationer")</h3>
4866 <tbody>
4867 @for (int i = 0; i < labels.Count; i++)
4868 {
4869 if (!string.IsNullOrEmpty(values[i]) && !string.IsNullOrEmpty(labels[i]))
4870 {
4871 <tr>
4872 <th style="padding: 0">@labels[i]</th>
4873 @if (values[i] == "True")
4874 {
4875 <td style="padding: 0">@Translate("Yes")</td>
4876 }
4877 else if (values[i] == "False")
4878 {
4879 <td style="padding: 0">@Translate("No")</td>
4880 }
4881 else
4882 {
4883 <td style="padding: 0">@values[i]</td>
4884 }
4885 </tr>
4886 }
4887 }
4888
4889 </tbody>
4890 <button class="expand-info--box accordion" data-info="@Translate("DataInfo", "Udvid info")" data-info-close="@Translate("DataInfoClose", "Fold info ind")">
4891 </button>
4892 </table>
4893 </div>
4894 </div>
4895 }
4896 }
4897 }
4898 </div>
4899 </div>
4900 }
4901
4902 @helper RenderProductDescription(string layout, string viewType, string name, RazorEngine.Templating.TemplateWriter writer, int fieldsCount = 0)
4903 {
4904 string ribbonClasses = layout == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
4905 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses;
4906 string ribbonSubClasses = layout == "Ribbon" ? "center-container--ribbon" : "";
4907
4908
4909 <div class="product__section @ribbonClasses dw-mod js-product-detail-info">
4910 <div class="center-container @ribbonSubClasses dw-mod">
4911 @if (viewType != "table")
4912 {
4913 <div class="grid grid--bleed u-margin-bottom--lg">
4914
4915 @writer
4916 </div>
4917 }
4918 else
4919 {
4920 string tableWidth = layout != "MainInformation" ? "grid__col-md-6" : "grid__col-md-12";
4921
4922 @* Details about the product card *@
4923 <div class="grid u-margin-bottom--lg nc-grid">
4924 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12 table__white extra-specs" id="ProductDetails">
4925 <table class="table--no-borders">
4926 <h3>@Translate("ProductDetails", "Detaljer om produktet")</h3>
4927 <div class="more-info">
4928 @GetString("Ecom:Product.LongDescription")
4929 </div>
4930 <button class="expand-info--box accordion" data-info="@Translate("DataInfo", "Udvid info")" data-info-close="@Translate("DataInfoClose", "Fold info ind")">
4931 </button>
4932 </table>
4933
4934 </div>
4935 </div>
4936 }
4937 </div>
4938 </div>
4939 }
4940
4941 @helper RenderProductCategoryFields(List<LoopItem> fieldsLoop, string viewType)
4942 {
4943 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true;
4944
4945 foreach (LoopItem categoryField in fieldsLoop)
4946 {
4947 string fieldValue = categoryField.GetString("Ecom:Product.CategoryField.Value");
4948 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue;
4949 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue;
4950
4951 if (!string.IsNullOrEmpty(categoryField.GetString("Ecom:Product.CategoryField.Label")) && !string.IsNullOrEmpty(fieldValue))
4952 {
4953 if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") != "9" || collectAllDownloads == false)
4954 {
4955 if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "15")
4956 {
4957 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), categoryField.GetString("Ecom:Product.CategoryField.OptionLabel"), viewType)
4958 ;
4959 }
4960 else if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "8")
4961 {
4962 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType, "link")
4963 ;
4964 }
4965 else if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "9")
4966 {
4967 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType, "download")
4968 ;
4969 }
4970 else
4971 {
4972 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType)
4973 ;
4974 }
4975 }
4976 }
4977 }
4978 }
4979
4980 @helper RenderDetailsFields(IEnumerable<LoopItem> fields, string viewType)
4981 {
4982 foreach (LoopItem field in fields)
4983 {
4984 string fieldValue = field.GetString("Ecom:FieldDisplayGroup.Field.Value");
4985 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue;
4986 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue;
4987
4988 if (!string.IsNullOrEmpty(field.GetString("Ecom:FieldDisplayGroup.Field.Name")) && !string.IsNullOrEmpty(fieldValue))
4989 {
4990 if (field.GetString("Ecom:FieldDisplayGroup.Field.TypeId") == "15")
4991 {
4992 @RenderFieldItem(field.GetString("Ecom:FieldDisplayGroup.Field.Name"), field.GetString("Ecom:FieldDisplayGroup.Field.OptionLabel"), viewType)
4993 ;
4994 }
4995 else if (field.GetString("Ecom:FieldDisplayGroup.Field.TypeId") == "8")
4996 {
4997 @RenderFieldItem(field.GetString("Ecom:Product.CategoryField.Name"), fieldValue, viewType, "link")
4998 ;
4999 }
5000 else if (field.GetString("Ecom:FieldDisplayGroup.Field.TypeId") == "9")
5001 {
5002 @RenderFieldItem(field.GetString("Ecom:FieldDisplayGroup.Field.Name"), fieldValue, viewType, "download")
5003 ;
5004 }
5005 else
5006 {
5007 @RenderFieldItem(field.GetString("Ecom:FieldDisplayGroup.Field.Name"), fieldValue, viewType)
5008 ;
5009 }
5010 }
5011 }
5012 }
5013
5014 @helper RenderProductDownloadsFields(List<LoopItem> fieldsLoop, string viewType)
5015 {
5016 foreach (LoopItem document in fieldsLoop)
5017 {
5018 string fieldValue;
5019 if (!string.IsNullOrEmpty(document.GetString("Document.FullPath")))
5020 {
5021 fieldValue = document.GetString("Product.CustomField.Value.Clean");
5022 @RenderFieldItem(fieldValue, document.GetString("Document.FullPath"), viewType, "download")
5023 }
5024
5025 if (document.GetString("Ecom:Product.CategoryField.TypeID") == "9")
5026 {
5027 fieldValue = document.GetString("Ecom:Product.CategoryField.Value");
5028 @RenderFieldItem(fieldValue, fieldValue, viewType, "download")
5029 }
5030 if (!string.IsNullOrEmpty(document.GetString("Ecom:Product:Detail.Image.Clean")))
5031 {
5032 fieldValue = document.GetString("Ecom:Product:Detail.Image.Clean");
5033 @RenderFieldItem("", fieldValue, viewType, "download")
5034 }
5035 }
5036 }
5037
5038 @helper RenderFieldItem(string name, string value, string viewType, string fieldType = "clean")
5039 {
5040 if (viewType != "table")
5041 {
5042 string fieldColumns = viewType == "list" ? "12" : "4";
5043 <div class="grid__col-md-@fieldColumns grid__col-sm-12 u-margin-bottom">
5044 <div class="u-bold">
5045 @name
5046 </div>
5047 <div>
5048 @RenderFieldItemContent(name, value, fieldType)
5049 </div>
5050 </div>
5051 }
5052 else
5053 {
5054 <tr>
5055 <th>@name</th>
5056 <td>
5057 @RenderFieldItemContent(name, value, fieldType)
5058 </td>
5059 </tr>
5060 }
5061 }
5062
5063 @helper RenderFieldItemContent(string name, string value, string fieldType = "clean")
5064 {
5065 if (fieldType == "link")
5066 {
5067 <a target="_blank" rel="noopener" href="@value">
5068 @if (isImage(value))
5069 {
5070 @getIconForFile(value)
5071 }
5072 else
5073 {
5074 @value
5075 }
5076 </a>
5077 }
5078 else if (fieldType == "download")
5079 {
5080 FileInfo info = new FileInfo(Dynamicweb.Core.SystemInformation.MapPath(value));
5081
5082 if (info.Exists)
5083 {
5084 <div class="grid grid--no-wrap">
5085 <a href="@value" download title="@Translate("Download")" class="product__document dw-mod">@getIconForFile(value)</a>
5086 <div class="product__document-info dw-mod">
5087 <a href="@value" download title="@Translate("Download")" class="product__document dw-mod">@Path.GetFileName(value)</a>
5088 <small class="u-block u-margin-top">@ConvertBytes(info.Length)</small>
5089 </div>
5090 </div>
5091 }
5092 }
5093 else
5094 {
5095 @value
5096 }
5097 }
5098 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
5099 @using Dynamicweb.Core
5100 @using System.Text.RegularExpressions
5101 @using System
5102 @using System.Web
5103 @using System.Collections.Generic
5104 @using Dynamicweb.Rapido.Blocks
5105 @using Dynamicweb.Rapido.Blocks.Components.General
5106
5107 @functions{
5108 BlocksPage productVideoPage = BlocksPage.GetBlockPage("Product");
5109 }
5110
5111 @{
5112 var selectedVideoCategories = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideoAssets").SelectedValues;
5113 var videosFromAssets = GetLoop("ImageCategories").Where(x => selectedVideoCategories.Contains(x.GetString("Category.Id")));
5114
5115 string videosLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue : "Section";
5116 videosLayout = videosLayout == "Ribbon" || string.IsNullOrEmpty(videosLayout) ? "Section" : videosLayout;
5117
5118 int videosCount = 0;
5119
5120 if (videosFromAssets != null)
5121 {
5122 foreach (LoopItem category in videosFromAssets) {
5123 foreach (LoopItem asset in category.GetLoop("Category.Images")) {
5124 videosCount++;
5125 }
5126 }
5127 } else {
5128 foreach (LoopItem detailField in GetLoop("Details"))
5129 {
5130 if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("youtube.com/embed") != -1)
5131 {
5132 videosCount++;
5133 }
5134 if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("vimeo.com") != -1)
5135 {
5136 videosCount++;
5137 }
5138 }
5139 }
5140
5141 if (videosCount > 0 && videosLayout != "hide")
5142 {
5143 Block detailsVideos = new Block()
5144 {
5145 Name = videosLayout != "MainInformation" ? Translate("Videos") : "",
5146 Id = "Videos",
5147 SortId = 60,
5148 Template = RenderProductVideos(videosCount, videosLayout),
5149 Design = new Design
5150 {
5151 Size = "12",
5152 RenderType = RenderType.Column,
5153 HidePadding = true
5154 }
5155 };
5156 productVideoPage.Add(videosLayout, detailsVideos);
5157 }
5158 }
5159
5160 @helper RenderProductVideos(int videosCount, string layout) {
5161 var selectedVideoCategories = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideoAssets").SelectedValues;
5162 var videosFromAssets = GetLoop("ImageCategories").Where(x => selectedVideoCategories.Contains(x.GetString("Category.Id")));
5163
5164 string videoColumn = "12";
5165 videoColumn = videosCount == 2 ? "6" : videoColumn;
5166 videoColumn = videosCount > 2 ? "4" : videoColumn;
5167 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
5168 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses;
5169 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : "";
5170
5171 <div class="product__section @ribbonClasses dw-mod">
5172 <div class="center-container @ribbonSubClasses dw-mod">
5173 @if (layout == "Section") {
5174 @Render(new Heading { Title = Translate("Videos"), Level = 2 })
5175 }
5176
5177 <div class="grid u-margin-bottom--lg">
5178 @if (videosFromAssets != null) {
5179 foreach (LoopItem category in videosFromAssets) {
5180 foreach (LoopItem asset in category.GetLoop("Category.Images")) {
5181 //getting video ID from youtube URL
5182 string videoCode = asset.GetString("Ecom:Product:Detail.Image.Clean");
5183 Regex regex = new Regex(@".be\/(.[^?]*)");
5184 Match match = regex.Match(videoCode);
5185 string videoId = "";
5186 if (match.Success)
5187 {
5188 videoId = match.Groups[1].Value;
5189 }
5190 else
5191 {
5192 regex = new Regex(@"v=([^&]+)");
5193 match = regex.Match(videoCode);
5194 if (match.Success)
5195 {
5196 videoId = match.Groups[1].Value;
5197 }
5198 }
5199
5200 <div class="grid__col-md-@videoColumn grid__col-lg-@videoColumn">
5201 <div class="video-wrapper">
5202 <div class="js-youtube-video" data-video="@videoId" id="ytPlayer@(Guid.NewGuid().ToString("N"))" data-auto-play="False" data-enable-controls="1"></div>
5203 </div>
5204 </div>
5205 }
5206 }
5207 } else {
5208 foreach (LoopItem detailField in GetLoop("Details"))
5209 {
5210 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)
5211 {
5212 <div class="grid__col-md-@videoColumn grid__col-lg-@videoColumn">
5213 <div class="video-wrapper">
5214 @detailField.GetString("Ecom:Product:Detail.Text")
5215 </div>
5216 </div>
5217 }
5218 }
5219 }
5220 </div>
5221 </div>
5222 </div>
5223 }
5224 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
5225 @using Dynamicweb.Core
5226 @using System
5227 @using System.Web
5228 @using System.Collections.Generic
5229 @using Denform.Website.CustomModules
5230 @using Dynamicweb.Rapido.Blocks
5231 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce
5232 @using Dynamicweb.Rapido.Blocks.Components.General
5233 @using Dynamicweb.Rapido.Services
5234
5235
5236 @functions{
5237 BlocksPage productRelatedPage = BlocksPage.GetBlockPage("Product");
5238 }
5239
5240 @{
5241 string relatedProductsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue : "Section";
5242 relatedProductsLayout = relatedProductsLayout == "Ribbon" || string.IsNullOrEmpty(relatedProductsLayout) ? "Section" : relatedProductsLayout;
5243 bool relatedShowStock = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowStockAndShipping");
5244 bool showAddToDownloadButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToDownloadButton");
5245 bool relatedShowPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice");
5246 bool relatedShowFavoriteButton = !Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("HideFavoriteButton") && Pageview.User != null;
5247 bool relatedPointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly");
5248 bool relatedShowCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToCartButton");
5249 bool relatedShowViewButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowViewButton");
5250 string relatedCartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart";
5251 string relatedMoreText = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText")) ? Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText") : "View";
5252 bool relatedShowNumber = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowProductNumber");
5253 //string relatedImageZoomOnHover = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("HoverImageZoom") ? "image-hover--zoom" : "";
5254
5255 int pageId = Pageview.Page.ID;
5256 string pageUrl = TemplateHelper.GetPageUrl(pageId);
5257
5258 string relatedGroupId = "";
5259
5260 int relatedProductsPageSize = 5;
5261
5262 if (Pageview.Device.ToString() == "Mobile")
5263 {
5264 relatedProductsPageSize = 2;
5265 }
5266
5267 if (Pageview.Device.ToString() == "Tablet")
5268 {
5269 relatedProductsPageSize = 4;
5270 }
5271
5272 int relatedProductsColumnWidth = 12 / relatedProductsPageSize;
5273
5274 if (relatedProductsLayout != "hide")
5275 {
5276 var i = 0;
5277 foreach (LoopItem relatedGroup in GetLoop("ProductRelatedGroups"))
5278 {
5279
5280 relatedGroupId = ToPascalCase(relatedGroup.GetString("Ecom:Product:RelatedGroup.Name"));
5281 string baseFeedPageUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + relatedProductsPageSize + "&ProdID=" + GetString("Ecom:Product.ID") + "&feed=true";
5282 string relatedFeed = baseFeedPageUrl + "&" + relatedGroupId + "=" + GetString("Ecom:Product.ID")+ GetString("Ecom:Product.VariantID") + "&GroupName=" + relatedGroupId;
5283 string relatedGroupName = relatedProductsLayout != "maininformation" ? relatedGroup.GetString("Ecom:Product:RelatedGroup.Name") : "";
5284
5285 i++;
5286
5287 Block detailsRelated = new Block()
5288 {
5289 Name = relatedGroupId,
5290 Id = relatedGroupId,
5291 SortId = 70 + i,
5292 Template = RenderRelatedProducts(Translate("Related_Products_heading", "Did you remember?"), relatedGroupId, relatedFeed, relatedProductsLayout),
5293 Design = new Design
5294 {
5295 Size = "12",
5296 RenderType = RenderType.Column,
5297 HidePadding = true
5298 }
5299 };
5300
5301 productRelatedPage.Add(relatedProductsLayout, detailsRelated);
5302 }
5303 }
5304 }
5305
5306 @helper RenderRelatedProducts(string name, string groupId, string relatedFeedUrl, string layout)
5307 {
5308 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
5309 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses;
5310 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : "";
5311
5312 <div class="nc-related-products @ribbonClasses ">
5313 <div class="center-container @ribbonSubClasses dw-mod">
5314 @if (layout == "Section") {
5315 <div style="text-align:center;" class="u-margin-bottom--xl">
5316 @Render(new Heading { Title = name, Level = 2 })
5317 </div>
5318 }
5319 <div class="js-handlebars-root" id="ProductList_@groupId" data-template="ProductContainer" data-pre-render-template="ProductPreRenderContainer" data-json-feed="@relatedFeedUrl" data-preloader="overlay"></div>
5320 </div>
5321 </div>
5322 }
5323 @* Script templates for related products *@
5324 <script id="ProductPreRenderContainer" type="text/x-template">
5325 <div class="u-h600px u-full-width">
5326 <div class="grid">
5327 <div class="grid__col-12">
5328 <div class="pre-render-element pre-render-element--md"></div>
5329 </div>
5330 </div>
5331 </div>
5332 </script>
5333
5334
5335 <script id="ProductContainer" type="text/x-template">
5336 {{#.}}
5337 {{log this}}
5338 <div class="nc-product-list__wrap dw-mod">
5339 <div id="ProductsContainer" data-template="ProductGridItemContainer" class="nc-product-list nc-product-list--small nc-product-list--loaded nc-product-list-related-products" data-save-cookie="true">
5340 {{#ProductsContainer}}
5341 <div id="Product{{productId}}" class="product-list-item dw-mod">
5342 {{#Product}}
5343 <div class="dw-mod {{noImage}}">
5344 <a href="{{link}}" class="product-list-item__link dw-mod">
5345 @Render(new Image { Path = "{{image}}", ImageDefault = new ImageSettings { Width = 600, Height = 600, Crop = 6, FillCanvas = true, Compression = 75, DoNotUpscale = true }, Title = "{{name}}", CssClass = "product-list-item__image" })
5346 {{#StickersContainers}}
5347 {{>StickersContainer}}
5348 {{/StickersContainers}}
5349 </a>
5350 </div>
5351 <div class="product-list-item__content-container">
5352 {{log this}}
5353 <div class="product-list-item__item-content">
5354 <div class="product-list-item__header">
5355 <a href="{{link}}" class="product-list-item__title-container" title="{{ name }}">
5356 <h4 class="product-list-item__title">
5357 {{ name }}
5358 </h4>
5359 @*{{#if description}}
5360 <h6 class="product-list-item__sub-title">
5361 {{ description }}
5362 </h6>
5363 {{/if}}*@
5364 </a>
5365 </div>
5366 <div class="product-list-price">
5367 <div class="product-list-price__container">
5368 <div class="product-list-price__valuta">
5369 {{currency}}
5370 </div>
5371 {{#if discount}}
5372 <div class="product-list-price__price">
5373 {{discount}}
5374 </div>
5375 {{/if}}
5376 @*{{#if price}}
5377 <div class="product-list-price__vat">
5378 {{price}}
5379 </div>
5380 {{/if}}*@
5381 </div>
5382 <div class="product-list-price__link-container">
5383 @{
5384 var addToCartBtn = new AddToCart
5385 {
5386 WrapperCssClass = "",
5387 AddButton = new AddToCartButton
5388 {
5389 ProductId = "{{productId}}",
5390 VariantId = "{{variantid}}",
5391 UnitId = "{{unitId}}", ProductInfo = "{{productInfo}}",
5392 OnClick = "{{facebookPixelAction}}",
5393 ButtonLayout = ButtonLayout.None,
5394 ExtraAttributes = new Dictionary<string, string>
5395 {
5396 { "{{disabledBuyButton}}", "" }
5397 },
5398 CssClass = "product-list-price__link product-list-price__button btn",
5399 Icon = new Icon {
5400 Prefix = "u-hidden",
5401 Label = Translate("Add to basket", "Læg i kurv"),
5402 CssClass = "u-full-width"
5403 }
5404 }
5405 };
5406 @Render(addToCartBtn)
5407 }
5408 </div>
5409 </div>
5410 </div>
5411 </div>
5412 {{/Product}}
5413 </div>
5414 {{/ProductsContainer}}
5415 </div>
5416 </div>
5417 <div style="display:flex; justify-content:center">
5418 <div class="grid__col-45px grid__col--bleed-x">
5419 <div class="grid__cell grid__cell--align-middle-left">
5420 <button type="button" class="btn--condensed btn btn--clean dw-mod {{prevdisabled}} u-position-relative" OnClick="HandlebarsBolt.UpdateContent('ProductList_@relatedGroupId', '{{prevPage}}')" {{prevdisabled}}>
5421 <i class="fas fa-chevron-left fa-2x u-flex--align-center arrow-prev-page"></i>
5422 </button>
5423 </div>
5424 </div>
5425 <div class="grid__col-45px grid__col--bleed-x">
5426 <div class="grid__cell grid__cell--align-middle-right">
5427 <h4>{{currentPage}}/{{totalPages}}</h4>
5428 </div>
5429 </div>
5430 <div class="grid__col-45px grid__col--bleed-x">
5431 <div class="grid__cell grid__cell--align-middle-right">
5432 <button type="button" class="btn--condensed btn btn--clean dw-mod {{nextdisabled}} u-position-relative" OnClick="HandlebarsBolt.UpdateContent('ProductList_@relatedGroupId', '{{nextPage}}')" {{nextdisabled}}>
5433 <i class="fas fa-chevron-right fa-2x u-flex--align-center arrow-next-page"></i>
5434 </button>
5435 </div>
5436 </div>
5437 </div>
5438 {{/.}}
5439 </script>
5440
5441 <script id="StickersContainer" type="text/x-template">
5442 <div class="stickers-container stickers-container--{{{convertStickerPositionToClassName Position}}} dw-mod">
5443 {{#Stickers}}
5444 {{>Sticker}}
5445 {{/Stickers}}
5446 </div>
5447 </script>
5448
5449 <script id="Sticker" type="text/x-template">
5450 @Render(new Sticker { Title = "{{Title}}", CssClass = "{{CssClass}}" })
5451 </script>
5452 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
5453 @using Dynamicweb.Core
5454 @using System
5455 @using System.Web
5456 @using System.Collections.Generic
5457 @using Dynamicweb.Rapido.Blocks
5458 @using Dynamicweb.Rapido.Blocks.Components.General
5459 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce
5460 @using Dynamicweb.Rapido.Services
5461
5462 @functions {
5463 BlocksPage productVariantsListPage = BlocksPage.GetBlockPage("Product");
5464 Dictionary<string, object> variantListSettings = new Dictionary<string, object> {
5465 { "RenderVariantsAsProducts", false },
5466 { "RenderVariantGroupsInTable", false },
5467 { "HideImage", false },
5468 { "HideProductNumbers", false }
5469 };
5470 }
5471
5472 @{
5473 var variantsCount = GetInteger("Ecom:Product.VariantCount");
5474 string variantsListLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue : "Section";
5475 variantsListLayout = variantsListLayout == "Ribbon" ? "Section" : variantsListLayout;
5476
5477 //family members
5478 bool isFamilyMember = false;
5479 var variantGroups = GetLoop("VariantGroups");
5480 var variantGroupCount = variantGroups.Count;
5481 if (variantGroupCount == 1)
5482 {
5483 var firstVariantGroup = Dynamicweb.Ecommerce.Services.VariantGroups.GetVariantGroup(Dynamicweb.Ecommerce.Common.Context.LanguageID, variantGroups[0]?.GetString("Ecom:VariantGroup.ID"));
5484 if (firstVariantGroup != null)
5485 {
5486 isFamilyMember = firstVariantGroup.Family;
5487 }
5488 }
5489 if (isFamilyMember)
5490 {
5491 variantListSettings["RenderVariantsAsProducts"] = variantsCount > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderFamilyVariantsAsProducts");
5492 variantListSettings["RenderVariantGroupsInTable"] = false;
5493 variantListSettings["HideImage"] = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideImageForEachFamilyVariant");
5494 variantListSettings["HideProductNumbers"] = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideFamilyProductNumbers");
5495 }
5496 else
5497 {
5498 variantListSettings["RenderVariantsAsProducts"] = variantsCount > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList");
5499 variantListSettings["RenderVariantGroupsInTable"] = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantGroupsInTable");
5500 variantListSettings["HideImage"] = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideImageForEachVariant");
5501 variantListSettings["HideProductNumbers"] = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideProductNumbers");
5502 }
5503
5504 if (Converter.ToBoolean(variantListSettings["RenderVariantsAsProducts"]) && variantsListLayout != "hide" && (isFamilyMember || !isFamilyMember))
5505 {
5506 productVariantsListPage.Add(variantsListLayout, new Block
5507 {
5508 Name = variantsListLayout != "MainInformation" ? Translate("Variants list") : "",
5509 Id = "VariantsList",
5510 SortId = 20,
5511 Template = RenderVariantsProductList(variantsListLayout),
5512 Design = new Design
5513 {
5514 Size = "12",
5515 RenderType = RenderType.Column,
5516 HidePadding = true
5517 }
5518 });
5519
5520 productVariantsListPage.Add("Section", new Block
5521 {
5522 Id = "VariantListScripts",
5523 SortId = 100,
5524 Template = RenderVariantListScripts(),
5525 Design = new Design {}
5526 });
5527 }
5528 }
5529
5530 @helper RenderVariantsProductList(string layout)
5531 {
5532 string variantsListPageSize = HttpContext.Current.Request.QueryString.Get("PageSize") ?? "30";
5533 string variantsFeedUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + variantsListPageSize + "&MainProductID=" + GetString("Ecom:Product.ID") + "&OnlyShowVariants=true&feed=true";
5534 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
5535 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses;
5536 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : "";
5537
5538 <div class="product__section @ribbonClasses dw-mod">
5539 <div class="center-container @ribbonSubClasses dw-mod">
5540 @if (layout == "Section")
5541 {
5542 @Render(new Heading { Title = Translate("Variants"), Level = 2 })
5543 }
5544 <div class="js-handlebars-root" id="VariantsListRoot" data-template="VariantProductsContainer" data-json-feed="@variantsFeedUrl" data-preloader="minimal"></div>
5545 </div>
5546 </div>
5547 }
5548
5549 @helper RenderVariantListScripts()
5550 {
5551 bool showProductNumberForVariants = !Converter.ToBoolean(variantListSettings["HideProductNumbers"]);
5552 bool showImageForEachVariant = !Converter.ToBoolean(variantListSettings["HideImage"]);
5553 bool variantsPointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly");
5554 string variantsListPageSize = HttpContext.Current.Request.QueryString.Get("PageSize") ?? "30";
5555 string variantsFeedUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + variantsListPageSize + "&MainProductID=" + GetString("Ecom:Product.ID") + "&OnlyShowVariants=true&feed=true";
5556 string variantsCartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart";
5557
5558 <script id="VariantProductsContainer" type="text/x-template">
5559 {{#.}}
5560 <div>
5561 <table id="VariantsProductsContainer" class="table u-position-relative dw-mod">
5562 <thead>
5563 <tr>
5564 @if (showImageForEachVariant)
5565 {
5566 <td width="75"> </td>
5567 }
5568 <td>@Translate("Product")</td>
5569 {{#AvailableCustomFields}}
5570 {{>TableFieldNameTemplate}}
5571 {{/AvailableCustomFields}}
5572 @if (Converter.ToBoolean(variantListSettings["RenderVariantGroupsInTable"])) {
5573 foreach (LoopItem variantgroup in GetLoop("VariantGroups"))
5574 {
5575 <td>@variantgroup.GetString("Ecom:VariantGroup.Name")</td>
5576 }
5577 }
5578 <td> </td>
5579 </tr>
5580 </thead>
5581
5582 <tbody id="VariantProductListContainer" data-template="VariantProductItemContainer" data-save-cookie="true">
5583 {{#ProductsContainer}}
5584 {{>VariantProductItemContainer}}
5585 {{/ProductsContainer}}
5586 </tbody>
5587 </table>
5588 </div>
5589
5590 <div class="grid">
5591 <div class="grid__col-12 grid__col--bleed-y">
5592 @{
5593 Button moreButton = new Button { Id = "LoadMoreButton", ButtonLayout = ButtonLayout.Primary, CssClass = "btn--full {{nextdisabled}}", Title = Translate("Load") + " " + Translate("more"), OnClick = "LoadMore.Next(this)" };
5594 moreButton.ExtraAttributes.Add("data-current", "{{currentPage}}");
5595 moreButton.ExtraAttributes.Add("data-page-size", "{{pageSize}}");
5596 moreButton.ExtraAttributes.Add("data-total", "{{totalPages}}");
5597 moreButton.ExtraAttributes.Add("data-container", "VariantProductListContainer");
5598 moreButton.ExtraAttributes.Add("data-feed-url", variantsFeedUrl + "{{loadMoreFeedParams}}");
5599 moreButton.ExtraAttributes.Add("", "{{nextdisabled}}");
5600 }
5601 @Render(moreButton)
5602 </div>
5603 </div>
5604 {{/.}}
5605 </script>
5606
5607 <script id="VariantProductItemContainer" type="text/x-template">
5608 {{#.}}
5609 <tr id="VariantProduct{{id}}" class="js-product" data-template="VariantProductItem" data-preloader="overlay" style="z-index: {{zIndex}}">
5610 {{#Product}}
5611 {{>VariantProductItem}}
5612 {{/Product}}
5613 </tr>
5614 {{/.}}
5615 </script>
5616
5617 <script id="VariantProductItem" type="text/x-template">
5618 {{#.}}
5619 @if (showImageForEachVariant)
5620 {
5621 <td width="75">
5622 <div class="lightbox u-hidden-xxs">
5623 <a href="{{link}}" onclick="Scroll.SavePosition(event)" title="{{name}}{{#if variantName}}, {{variantName}}{{/if}}">
5624 <img class="lightbox__image {{noImage}}" src="/Admin/Public/GetImage.ashx?width=220&height=220&crop=5&Compression=75&image={{image}}" alt="{{name}}{{#if variantName}}, {{variantName}}{{/if}}" />
5625 <div class="u-margin-right {{noImage}}">
5626 <img src="/Admin/Public/GetImage.ashx?width=75&height=55&crop=5&FillCanvas=true&Compression=75&image={{image}}" alt="{{name}}{{#if variantName}}, {{variantName}}{{/if}}" />
5627 </div>
5628 </a>
5629 </div>
5630 </td>
5631 }
5632
5633 <td class="u-va-middle">
5634 <a href="{{link}}" onclick="Scroll.SavePosition(event)" title="{{name}}{{#if variantName}}, {{variantName}}{{/if}}">
5635 <h6 class="u-no-margin">{{name}}{{#if variantName}}, {{variantName}}{{/if}}</h6>
5636 </a>
5637 @if (showProductNumberForVariants)
5638 {
5639 <div class="item-number item-number--compressed u-margin-bottom dw-mod">
5640 <div>{{number}}</div>
5641 </div>
5642 }
5643 @if (User.IsStockInfoAllowed())
5644 {
5645 <text>{{#if stockText}}</text>
5646 <div class="item-number item-number--compressed dw-mod">
5647 <span>
5648 <span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span>
5649 <span class="u-margin-right--lg"> {{stockText}}</span>
5650 {{deliveryText}}
5651 </span>
5652 </div>
5653 <text>{{/if}}</text>
5654 }
5655 else
5656 {
5657 <div class="grid__cell-footer stickers-container stickers-container--block dw-mod">
5658 {{#Stickers}}
5659 {{>MiniSticker}}
5660 {{/Stickers}}
5661 </div>
5662 }
5663 </td>
5664 {{#CustomFields}}
5665 {{>TableFieldValueTemplate}}
5666 {{/CustomFields}}
5667 @if (Converter.ToBoolean(variantListSettings["RenderVariantGroupsInTable"]))
5668 {
5669 <text>
5670 {{#VariantSelectionNames}}
5671 {{>TableFieldNameTemplate}}
5672 {{/VariantSelectionNames}}
5673 </text>
5674 }
5675 <td class="u-va-middle">
5676 @if (Dynamicweb.Rapido.Services.User.IsPricesAllowed() && !Dynamicweb.Rapido.Services.User.IsBuyingAllowed())
5677 {
5678 <div class="u-hidden-sm">
5679 <div class="u-full-width u-ta-right u-padding-right">
5680 <div class="before-price {{onSale}} before-price--micro dw-mod">{{discount}}</div>
5681 <div class="price price--product-list price--micro dw-mod">{{price}}</div>
5682 </div>
5683 </div>
5684 }
5685
5686 <div class="grid grid--align-center grid--justify-end">
5687 <div class="u-margin-right u-hidden-xs u-hidden-xxs">
5688 @if (variantsPointShopOnly)
5689 {
5690 <text>
5691 {{#if canBePurchasedWithPoints}}
5692 <div class="price price--product-list price--micro dw-mod">{{points}} @Translate("points")</div>
5693 {{else}}
5694 {{#if havePointPrice}}
5695 <small class="help-text u-no-margin u-margin-top">@Translate("Not enough points to buy this")</small>
5696 {{else}}
5697 <small class="help-text u-no-margin u-margin-top">@Translate("Not available")</small>
5698 {{/if}}
5699 {{/if}}
5700 </text>
5701 }
5702 else if (Dynamicweb.Rapido.Services.User.IsPricesAllowed())
5703 {
5704 <div class="before-price before-price--micro {{onSale}} dw-mod">{{discount}}</div>
5705 <div class="price price--condensed price--product-list dw-mod">{{price}}</div>
5706 }
5707 </div>
5708
5709 @if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed())
5710 {
5711 var addToCartBtn = new AddToCart
5712 {
5713 AddButton = new AddToCartButton
5714 {
5715 HideTitle = true,
5716 ProductId = "{{productId}}",
5717 VariantId = "{{variantid}}",
5718 UnitId = "{{unitId}}",
5719 ProductInfo = "{{productInfo}}",
5720 BuyForPoints = variantsPointShopOnly,
5721 OnClick = "{{facebookPixelAction}}"
5722 },
5723 UnitSelector = new UnitSelector
5724 {
5725 OptionsContent = "{{#unitOptions}}{{>VariantUnitOption}}{{/unitOptions}}",
5726 Id = "UnitOptions_{{id}}",
5727 SelectedOption = "{{unitName}}",
5728 CssClass = "{{hasUnits}}"
5729 }
5730 };
5731
5732 if (!variantsPointShopOnly)
5733 {
5734 addToCartBtn.QuantitySelector = new QuantitySelector
5735 {
5736 Id = "Quantity_{{id}}"
5737 };
5738 }
5739
5740 <div class="grid__cell u-flex-grow--0">
5741 @Render(addToCartBtn)
5742 </div>
5743 }
5744 <div class="favorites u-margin-left dw-mod">
5745 {{#Favorite}}
5746 {{>FavoriteTemplate}}
5747 {{/Favorite}}
5748 </div>
5749 </div>
5750 </td>
5751 {{/.}}
5752 </script>
5753
5754 <script id="TableFieldNameTemplate" type="text/x-template">
5755 <td class="u-va-middle">{{name}}</td>
5756 </script>
5757
5758 <script id="TableFieldValueTemplate" type="text/x-template">
5759 <td class="u-va-middle">{{value}}</td>
5760 </script>
5761
5762 <script id="MiniSticker" type="text/x-template">
5763 <div class="stickers-container__tag stickers-container__tag--micro {{CssClass}} dw-mod">{{Title}}</div>
5764 </script>
5765
5766 <script id="VariantUnitOption" type="text/x-template">
5767 <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent(this.closest('.js-product').id, '{{link}}&feed=true&UnitID={{value}}')">{{name}}</div>
5768 </script>
5769 }
5770
5771
5772 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
5773 @using Dynamicweb.Core
5774 @using System
5775 @using System.Web
5776 @using System.Collections.Generic
5777 @using Dynamicweb.Rapido.Blocks
5778 @using Dynamicweb.Rapido.Blocks.Components.General
5779 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce
5780
5781 @functions {
5782 BlocksPage productVariantsMatrixPage = BlocksPage.GetBlockPage("Product");
5783 }
5784
5785
5786 @{
5787 var matrixLayoutSetting = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsMatrixLayout");
5788 string variantsMatrixLayout = matrixLayoutSetting != null && !string.IsNullOrEmpty(matrixLayoutSetting.SelectedValue) ? matrixLayoutSetting.SelectedValue : "Section";
5789 variantsMatrixLayout = variantsMatrixLayout == "Ribbon" ? "Section" : variantsMatrixLayout;
5790 bool renderVariantsAsMatrix = GetInteger("Ecom:Product.VariantCount") > 1 && variantsMatrixLayout.ToLower() != "hide" && Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("EnableVariantMatrix");
5791
5792 if (renderVariantsAsMatrix)
5793 {
5794 Block variantsMatrix = new Block()
5795 {
5796 Name = Translate("Variants"),
5797 Id = "VariantsMatrix",
5798 SortId = 15,
5799 Template = RenderVariantsMatrixSection(variantsMatrixLayout),
5800 Design = new Design
5801 {
5802 Size = "12",
5803 RenderType = RenderType.Column,
5804 HidePadding = true
5805 }
5806 };
5807
5808 if (variantsMatrixLayout == "Section") {
5809 productVariantsMatrixPage.Add(variantsMatrix);
5810 } else {
5811 productVariantsMatrixPage.Add(variantsMatrixLayout, variantsMatrix);
5812 }
5813 }
5814 }
5815
5816 @helper RenderVariantsMatrixSection(string layout)
5817 {
5818 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart";
5819 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
5820 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses;
5821 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : "";
5822
5823 List<LoopItem> variantInfos = GetLoop("VariantInfos");
5824 string productId = GetString("Ecom:Product.ID");
5825 string pageId = Pageview.Page.ID.ToString();
5826
5827
5828 <div class="product__section u-no-padding @ribbonClasses dw-mod">
5829 <div class="center-container @ribbonSubClasses dw-mod">
5830 @RenderVariantInfoMatrix(variantInfos, productId, pageId, 0, "add")
5831 </div>
5832 </div>
5833 }
5834
5835 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
5836 @using Dynamicweb.Rendering
5837 @using Dynamicweb.Core
5838 @using System
5839 @using System.Web
5840 @using System.Collections.Generic
5841 @using Dynamicweb.Rapido.Blocks
5842 @using Dynamicweb.Rapido.Blocks.Components
5843 @using Dynamicweb.Rapido.Blocks.Components.General
5844
5845
5846 @* Component - Variant Info Matrix. This replaces the old Variant Matrix with a much cleaner approach *@
5847
5848 @helper RenderVariantInfoMatrix(List<LoopItem> variantInfos, string productId, string pageId, double totalPrice = 0, string actionType = "update") {
5849 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart";
5850 bool hideAddToCartButton = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("hideAddToCartButton");
5851
5852 string currencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code;
5853 string countryCode = Pageview.Area.CultureInfo != null ? Pageview.Area.CultureInfo.Name : "en-US";
5854
5855 int loopCount = 0;
5856 int dimensionsCount = 0;
5857 bool firstRun = true;
5858 List<string> headerLabels = new List<string>();
5859
5860 //Collect the missing data needed to render matrixes
5861 foreach (var variantInfoFirst in variantInfos)
5862 {
5863 dimensionsCount = 1;
5864
5865 foreach (var variantInfoSecond in variantInfoFirst.GetLoop("VariantInfos"))
5866 {
5867 dimensionsCount = 2;
5868
5869 if (firstRun) {
5870 headerLabels.Add(variantInfoSecond.GetString("OptionName"));
5871 }
5872
5873 foreach (var variantInfoThird in variantInfoSecond.GetLoop("VariantInfos"))
5874 {
5875 dimensionsCount = 3;
5876 }
5877 }
5878
5879 firstRun = false;
5880 }
5881
5882 @*One dimension*@
5883 if (dimensionsCount == 1)
5884 {
5885 int totalQuantity = 0;
5886
5887 <table cellspacing="0" class="table matrix js-matrix dw-mod">
5888 <thead class="matrix__head dw-mod">
5889 <tr>
5890 @foreach (var variantInfoFirst in variantInfos)
5891 {
5892 <td class="u-bold u-ta-center" width="80" >
5893 <div>@variantInfoFirst.GetString("OptionName")</div>
5894 <small>@variantInfoFirst.GetString("VariantId")</small>
5895 </td>
5896 }
5897 <td width="80px" align="right" class="matrix-label-field-right dw-mod">@Translate("Totals")</td>
5898 <td> </td>
5899 </tr>
5900 </thead>
5901 <tbody>
5902 <tr>
5903 @foreach (var variantInfoFirst in variantInfos)
5904 {
5905 double price = Dynamicweb.Ecommerce.Services.Products.GetProductById(productId, variantInfoFirst.GetString("VariantId"), Dynamicweb.Ecommerce.Common.Context.LanguageID).GetPrice(Dynamicweb.Ecommerce.Common.Context.Currency.Code, Dynamicweb.Ecommerce.Common.Context.Country.Code2).Price;
5906
5907 loopCount++;
5908 totalQuantity += variantInfoFirst.GetInteger("Quantity");
5909
5910 <td class="matrix__input-cell dw-mod">
5911 @if (variantInfoFirst.GetBoolean("IsProduct"))
5912 {
5913 <input type="hidden" name="ProductLoopCounter@(loopCount)" value="@(loopCount)" />
5914 <input type="hidden" name="ProductID@(loopCount)" value="@productId" />
5915 <input type="hidden" name="VariantID@(loopCount)" value="@variantInfoFirst.GetString("VariantId")" />
5916 <input type="number" name="Quantity@(loopCount)" value="@variantInfoFirst.GetString("Quantity")" data-price="@price" min="0" step="1" oninput="validity.valid||(value='');" class="matrix-input-field dw-mod" onchange="Matrix.UpdateQuantities(this)" data-row-id="ONE">
5917 } else {
5918 <div class="matrix__cell-disabled dw-mod"></div>
5919 }
5920 </td>
5921 }
5922 <td class="u-va-middle">
5923 <div class="u-bold u-ta-right matrix-label-field-right dw-mod" data-row-total="ONE">
5924 @totalQuantity
5925 </div>
5926 </td>
5927 <td class="u-bold u-va-middle u-ta-right matrix-label-field-right dw-mod">
5928 <div class="js-total-price" data-currency-code="@currencyCode" data-country-code="@countryCode"></div>
5929 </td>
5930 </tr>
5931 </tbody>
5932 <tfoot>
5933 <tr>
5934 <td colspan="@(variantInfos.Count + 2)"> </td>
5935 </tr>
5936 @if (!hideAddToCartButton)
5937 {
5938 <tr>
5939 <td colspan="@(variantInfos.Count + 2)" class="u-ta-right">
5940 <div class="u-padding--lg">
5941 @if (actionType == "update") {
5942 @Render(new Button { OnClick = "Matrix.UpdateCart(this, '" + pageId + "');", Title = Translate("Update"), ButtonLayout = ButtonLayout.Tertiary, Icon = new Icon { Prefix = "fal", Name = "fa-redo", LabelPosition = IconLabelPosition.After }, CssClass = "u-no-margin" })
5943 } else if (actionType == "justadd") {
5944 @Render(new Button { OnClick = "Matrix.AddToCart(this, '" + pageId + "');", Title = Translate("Add"), ButtonLayout = ButtonLayout.Tertiary, CssClass = "u-no-margin" })
5945 } else {
5946 @Render(new Button { OnClick = "Matrix.AddToCart(this, '" + pageId + "');", Title = Translate("Add to cart"), ButtonLayout = ButtonLayout.Tertiary, Icon = new Icon { Name = cartIcon, LabelPosition = IconLabelPosition.After }, CssClass = "u-no-margin" })
5947 }
5948 </div>
5949 </td>
5950 </tr>
5951 }
5952 </tfoot>
5953 </table>
5954 }
5955
5956 @*Two dimensions*@
5957 if (dimensionsCount == 2)
5958 {
5959 Dictionary<string, int> columnTotals = new Dictionary<string, int>();
5960 int counter = 0;
5961 int totalProducts = 0;
5962 int totalColumns = 0;
5963
5964 <table class="table matrix js-matrix dw-mod" cellspacing="0">
5965 <thead class="matrix__head dw-mod">
5966 <tr>
5967 <td width="160"> </td>
5968 @foreach (string label in headerLabels)
5969 {
5970 <td class="u-bold u-ta-center" width="80">@label</td>
5971 }
5972 <td align="right" width="80" class="matrix-label-field-right dw-mod">@Translate("Totals")</td>
5973 <td> </td>
5974 </tr>
5975 </thead>
5976 <tbody>
5977 @foreach (var variantInfoFirst in variantInfos)
5978 {
5979 int totalRowQuantity = 0;
5980 counter += variantInfoFirst.GetInteger("Quantity");
5981 totalColumns = variantInfoFirst.GetLoop("VariantInfos").Count;
5982
5983 <tr>
5984 <td class="matrix-label-field-left dw-mod">
5985 <div class="u-pull--left">
5986 <div>@variantInfoFirst.GetString("OptionName")</div>
5987 <small>@variantInfoFirst.GetString("VariantId")</small>
5988 </div>
5989
5990 @if (!string.IsNullOrEmpty(variantInfoFirst.GetString("Image"))) {
5991 <div class="matrix-option-image u-pull--right dw-mod" onclick="Matrix.ShowOptionImageModal(this)" data-img-src="/files/@variantInfoFirst.GetString("Image")">
5992 @Render(new Image {
5993 Path = variantInfoFirst.GetString("Image"),
5994 ImageDefault = new ImageSettings {
5995 Width = 28,
5996 Height = 28
5997 },
5998 ImageMedium = new ImageSettings {
5999 Width = 28,
6000 Height = 28
6001 },
6002 ImageSmall = new ImageSettings {
6003 Width = 28,
6004 Height = 28
6005 }
6006 })
6007 </div>
6008 }
6009 </td>
6010 @foreach (var variantInfoSecond in variantInfoFirst.GetLoop("VariantInfos"))
6011 {
6012 loopCount++;
6013 totalRowQuantity += variantInfoSecond.GetInteger("Quantity");
6014
6015 string optionName = variantInfoSecond.GetString("OptionName");
6016 int optionQuantity = variantInfoSecond.GetInteger("Quantity");
6017 if (columnTotals.ContainsKey(optionName)) {
6018 columnTotals[optionName] += optionQuantity;
6019 } else {
6020 columnTotals.Add(optionName, optionQuantity);
6021 }
6022
6023 <td class="matrix__input-cell dw-mod">
6024 @if (variantInfoSecond.GetBoolean("IsProduct")) {
6025 double price = Dynamicweb.Ecommerce.Services.Products.GetProductById(productId, variantInfoSecond.GetString("VariantId"), Dynamicweb.Ecommerce.Common.Context.LanguageID).GetPrice(Dynamicweb.Ecommerce.Common.Context.Currency.Code, Dynamicweb.Ecommerce.Common.Context.Country.Code2).Price;
6026
6027 <input type="hidden" name="ProductLoopCounter@(loopCount)" value="@(loopCount)" />
6028 <input type="hidden" name="ProductID@(loopCount)" value="@productId" />
6029 <input type="hidden" name="VariantID@(loopCount)" value="@variantInfoSecond.GetString("VariantId")" />
6030 <input type="number" name="Quantity@(loopCount)" value="@variantInfoSecond.GetString("Quantity")" data-price="@price" min="0" step="1" oninput="validity.valid||(value='');" class="matrix-input-field dw-mod" onchange="Matrix.UpdateQuantities(this)" data-row-id="@variantInfoFirst.GetString("OptionName")" data-column-id="@variantInfoSecond.GetString("OptionName")">
6031 } else {
6032 <div class="matrix__cell-disabled dw-mod"></div>
6033 }
6034 </td>
6035 }
6036 <td class="u-va-middle matrix-label-field-right dw-mod">
6037 <div class="u-bold u-ta-right" data-row-total="@variantInfoFirst.GetString("OptionName")">
6038 @totalRowQuantity
6039 </div>
6040 </td>
6041 <td> </td>
6042 </tr>
6043 }
6044 </tbody>
6045 <tfoot>
6046 <tr>
6047 <td class="u-bold u-va-middle matrix-label-field-left dw-mod">@Translate("Totals")</td>
6048 @foreach (var item in columnTotals)
6049 {
6050 totalProducts += item.Value;
6051
6052 <td>
6053 <div class="u-bold u-ta-center u-padding--lg" data-column-total="@item.Key">
6054 @item.Value
6055 </div>
6056 </td>
6057 }
6058 <td class="u-bold u-va-middle u-ta-right matrix-label-field-right dw-mod" align="right">
6059 <div class="js-total-quantity">@totalProducts</div>
6060 </td>
6061 <td class="u-bold u-va-middle u-ta-right matrix-label-field-right dw-mod">
6062 <div class="js-total-price" data-currency-code="@currencyCode" data-country-code="@countryCode"></div>
6063 </td>
6064 </tr>
6065 <tr>
6066 <td colspan="@(totalColumns + 4)" class="u-ta-right u-no-padding">
6067 <div class="u-padding--lg">
6068 @if (actionType == "update") {
6069 @Render(new Button { OnClick = "Matrix.UpdateCart(this, '" + pageId + "');", Title = Translate("Update"), ButtonLayout = ButtonLayout.Tertiary, Icon = new Icon { Prefix = "fal", Name = "fa-redo", LabelPosition = IconLabelPosition.After }, CssClass = "u-no-margin" })
6070 } else {
6071 @Render(new Button { OnClick = "Matrix.AddToCart(this, '" + pageId + "');", Title = Translate("Add to cart"), ButtonLayout = ButtonLayout.Tertiary, Icon = new Icon { Name = cartIcon, LabelPosition = IconLabelPosition.After }, CssClass = "u-no-margin" })
6072 }
6073 </div>
6074 </td>
6075 </tr>
6076 </tfoot>
6077 </table>
6078 }
6079
6080
6081 Modal optionColorImage = new Modal {
6082 Id = "OptionColorImage",
6083 BodyTemplate = @Render(new Image { Path = "/Files/Images/placeholder.gif", Id = "OptionColorImageElement", DisableImageEngine = true, DisableLazyLoad = true }),
6084 Width = ModalWidth.Full
6085 };
6086
6087 @Render(optionColorImage)
6088 }
6089 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
6090 @using Dynamicweb.Core
6091 @using System
6092 @using System.Web
6093 @using System.Collections.Generic
6094 @using Dynamicweb.Rapido.Blocks
6095 @functions {
6096 BlocksPage productSnippetsPage = BlocksPage.GetBlockPage("Product");
6097 }
6098
6099 @{
6100 Block googleProductSchema = new Block()
6101 {
6102 Id = "GoogleProductSchema",
6103 SortId = 10,
6104 Template = RenderGoogleProductSchema()
6105 };
6106
6107 productSnippetsPage.Add("Snippets", googleProductSchema);
6108 }
6109
6110 @helper RenderGoogleProductSchema()
6111 {
6112 var siteURL = Dynamicweb.Context.Current.Request.Url.Scheme + "://" + Dynamicweb.Context.Current.Request.Url.Host;
6113 var image = GetProductImage();
6114 var brand = GetString("Ecom:Product:Field.brand.Value");
6115 var variantid = !string.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) ? GetString("Ecom:Product.VariantID") : GetString("Ecom:Product.VariantID.Extented");
6116 var url = Dynamicweb.Context.Current.Request.Url.Scheme + "://" + GetGlobalValue("Global:Request.Host") + Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(GetString("Ecom:Product.LinkGroup.Clean") + (!string.IsNullOrWhiteSpace(variantid) ? "&VariantID=" + variantid : ""));
6117
6118 <script type="application/ld+json">
6119 {
6120 "@@context": "http://schema.org/",
6121 "@@type": "Product",
6122 "name": "@GetString("Ecom:Product.Name")",
6123 @if (!string.IsNullOrEmpty(image))
6124 {
6125 <text>"image": [
6126 "@siteURL/Admin/Public/GetImage.ashx?width=400&height=400&crop=0&Compression=75&DoNotUpscale=true&image=@image",
6127 "@siteURL/Admin/Public/GetImage.ashx?width=400&height=300&crop=0&Compression=75&DoNotUpscale=true&image=@image",
6128 "@siteURL/Admin/Public/GetImage.ashx?width=448&height=225&crop=0&Compression=75&DoNotUpscale=true&image=@image"
6129 ],</text>
6130 }
6131 "description": "@GetString("Ecom:Product.ShortDescription")",
6132 "mpn": "925872",
6133 @if (!string.IsNullOrEmpty(brand))
6134 {
6135 <text>"brand": {
6136 "@@type": "Thing",
6137 "name": "@brand"
6138 },</text>
6139 }
6140 "offers": {
6141 "@@type": "Offer",
6142 "priceCurrency": "@GetString("Ecom:Product.Price.Currency.Code")",
6143 "price": "@GetString("Ecom:Product.Price.Price")",
6144 "availability": "@(GetInteger("Ecom:Product.Stock") > 0 ? "InStock" : "OutOfStock")",
6145 "url": "@url"
6146 }
6147 }
6148 </script>
6149 }
6150
6151 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
6152
6153 @using System.Globalization
6154 @using Dynamicweb.Rapido.Blocks
6155 @using Dynamicweb.Rapido.Blocks.Components.General
6156
6157 @functions {
6158 BlocksPage snippetsTemplatesPage = BlocksPage.GetBlockPage("Product");
6159 }
6160
6161 @{
6162 snippetsTemplatesPage.Add(new Block {
6163 Id = "FavoritesTemplates",
6164 SortId = 100,
6165 Template = RenderFavoritesTemplates()
6166 });
6167 }
6168
6169 @helper RenderFavoritesTemplates()
6170 {
6171 var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star";
6172 string favoriteIcon = "fas fa-" + selectedFavoriteIcon;
6173 string favoriteOutlineIcon = "fal fa-" + selectedFavoriteIcon;
6174 bool useFacebookPixel = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("FacebookPixelID"));
6175 string currentFavoriteListId = HttpContext.Current.Request.QueryString.Get("ListID");
6176 string host = HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host;
6177
6178 // Klaviyo "Viewed Product" tracker event
6179 <script type="text/javascript">
6180 var _learnq = _learnq || [];
6181 var item = {
6182 "ProductName": "@GetString("Ecom:Product.Name")",
6183 "ProductID": "@GetString("Ecom:Product.ID")",
6184 "SKU": "@GetString("Ecom:Product.Number")",
6185 "Categories": ["@GetString("Ecom:Group.Name")"],
6186 "ImageURL": "@GetString("Ecom:Product.ImageDefault")",
6187 "URL": "@host@Pageview.SearchFriendlyUrl",
6188 "Price": @Convert.ToDecimal(GetDouble("Ecom:Product.Price.Price")).ToString("F", CultureInfo.GetCultureInfo("en-US"))
6189 };
6190 _learnq.push(["track", "Viewed Product", item]);
6191 </script>
6192
6193 <script id="FavoriteTemplate" type="text/x-template">
6194 <div class="favorites-list u-ta-left js-favorites-list">
6195 @Render(new Button {
6196 CssClass = "u-no-margin js-favorite-btn",
6197 Icon = new Icon
6198 {
6199 Name = "{{#if isInAnyFavoriteList}}" + favoriteIcon + "{{else}}" + favoriteOutlineIcon + "{{/if}}",
6200 CssClass = "fa-1_5x",
6201 LabelPosition = IconLabelPosition.After
6202 },
6203 ButtonLayout = ButtonLayout.LinkClean,
6204 ButtonType = ButtonType.Button,
6205 OnClick = "document.getElementById('FavoriteTrigger_{{id}}').checked = true"
6206 })
6207 <input type="checkbox" id="FavoriteTrigger_{{id}}" class="dropdown-trigger" />
6208 <div class="dropdown dropdown--position-32px">
6209 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod">
6210 <ul class="list list--clean dw-mod">
6211 {{#FavoriteLists}}
6212 {{>FavoriteListItem}}
6213 {{/FavoriteLists}}
6214 </ul>
6215 </div>
6216 <label class="dropdown-trigger-off" for="FavoriteTrigger_{{id}}"></label>
6217 </div>
6218 </div>
6219 </script>
6220
6221 <script id="FavoriteListItem" type="text/x-template">
6222 <li>
6223 @{
6224 var button = new Button {
6225 CssClass = "list__link u-no-underline",
6226 OnClick = "toggleFavAction(this, event)",
6227 Icon = new Icon { Name = "{{#if isInFavoriteList}}" + favoriteIcon + "{{else}}" + favoriteOutlineIcon + "{{/if}}", LabelPosition = IconLabelPosition.After },
6228 AltText = "{{#if isInFavoriteList}}" + Translate("Remove from") + " {{name}}{{else}}" + Translate("Add to") + " {{name}}{{/if}}",
6229 Title = "{{name}}",
6230 ButtonType = ButtonType.Button,
6231 ButtonLayout = ButtonLayout.LinkClean,
6232 ExtraAttributes = new Dictionary<string, string>
6233 {
6234 { "data-list-id", "{{listId}}" },
6235 { "data-list-name", "{{name}}" },
6236 { "data-remove-link", "{{removeLink}}" },
6237 { "data-add-link", "{{addLink}}" },
6238 { "data-is-in-list", "{{isInFavoriteList}}" },
6239
6240 }
6241 };
6242 if (useFacebookPixel)
6243 {
6244 button.ExtraAttributes.Add("data-facebook-object", "{{facebookPixelAddAction}}");
6245 }
6246 }
6247 <div class="grid__cell">
6248 @Render(button)
6249 </div>
6250 </li>
6251 </script>
6252
6253 <script>
6254 @if (!string.IsNullOrEmpty(currentFavoriteListId))
6255 {
6256 <text>
6257 window.currentFavoriteListId = "@currentFavoriteListId";
6258 </text>
6259 }
6260 function toggleFavAction(button, event) {
6261 if (button.getAttribute('data-add-link').indexOf('CCCreateNewList') > -1) {
6262 Scroll.SavePosition(event);
6263 @if (useFacebookPixel)
6264 {
6265 <text>
6266 fbq('track', 'AddToWishlist', JSON.parse(button.getAttribute('data-facebook-object')));
6267 </text>
6268 }
6269 location.href = button.getAttribute('data-add-link');
6270 return;
6271 }
6272 let isAdd = button.getAttribute('data-is-in-list') == "false";
6273 Request.Fetch().get(
6274 isAdd ? button.getAttribute('data-add-link') : button.getAttribute('data-remove-link'),
6275 function (result) {
6276 button.querySelector('i').className = isAdd ? '@favoriteIcon u-margin-right--lg' : '@favoriteOutlineIcon u-margin-right--lg';
6277 button.setAttribute('data-is-in-list', isAdd);
6278 button.setAttribute('title', (!isAdd ? '@Translate("Add to") ' : '@Translate("Remove from") ') + button.getAttribute('data-list-name'))
6279 let favList = button.closest('.js-favorites-list');
6280 let favBtn = favList.querySelector('.js-favorite-btn i');
6281 let isInAnyFavoriteList = favList.querySelector('[data-is-in-list=true]') != null;
6282 if (isInAnyFavoriteList) {
6283 favBtn.className = '@favoriteIcon' + ' fa-1_5x';
6284 } else {
6285 favBtn.className = '@favoriteOutlineIcon' + ' fa-1_5x';
6286 }
6287 @if (useFacebookPixel)
6288 {
6289 <text>
6290 if (isAdd) {
6291 fbq('track', 'AddToWishlist', JSON.parse(button.getAttribute('data-facebook-object')));
6292 }
6293 </text>
6294 }
6295 if (window.currentFavoriteListId != null) { //if this page is favorite list
6296 let listId = button.getAttribute("data-list-id");
6297 if (listId == window.currentFavoriteListId && !isAdd) {
6298 location.reload();
6299 }
6300 }
6301 },
6302 function () {
6303 console.error("FavoriteLists: Error in ToggleFavAction request");
6304 },
6305 false
6306 );
6307 }
6308 </script>
6309 }
6310 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
6311 @using Dynamicweb.Core
6312 @using System
6313 @using System.Web
6314 @using System.Collections.Generic
6315 @using Dynamicweb.Rapido.Blocks
6316
6317 @{
6318 BlocksPage customProductBlocks = BlocksPage.GetBlockPage("Product");
6319
6320 }
6321 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
6322 @using Dynamicweb.Core
6323 @using System
6324 @using System.Web
6325 @using System.Collections.Generic
6326 @using Dynamicweb.Rapido.Blocks
6327 @using Dynamicweb.Rapido.Blocks.Components.General
6328 @using System.Linq;
6329
6330 @functions {
6331 BlocksPage productCompaniesPage = BlocksPage.GetBlockPage("Product");
6332 }
6333
6334 @{
6335 string productCompanies = "Section";
6336
6337 Block productsCompaniesBlock = new Block()
6338 {
6339 Name = productCompanies,
6340 Id = "productCompanies",
6341 SortId = 29,
6342 Template = RenderCompanies(),
6343 Design = new Design
6344 {
6345 Size = "12",
6346 RenderType = RenderType.Column,
6347 HidePadding = true
6348 }
6349 };
6350 productCompaniesPage.Add(productCompanies, productsCompaniesBlock);
6351
6352 }
6353
6354 <link rel="stylesheet" href="/Files/Templates/Designs/Rapido/node_modules/swiper/swiper-bundle.min.css">
6355 <script src="/Files/Templates/Designs/Rapido/node_modules/swiper/swiper-bundle.min.js"></script>
6356 <script>
6357
6358 document.addEventListener('DOMContentLoaded', function() {
6359
6360 var weDeliverTo = new Swiper('.weDeliverToSlider', {
6361 loop: true,
6362 slidesPerView: 4,
6363 allowTouchMove: false,
6364 autoplay: {
6365 delay: 0,
6366 disableOnInteraction: false,
6367 },
6368 spaceBetween: 50,
6369 speed: 3500,
6370 breakpoints: {
6371 // when window width is >= 320px
6372 320: {
6373 slidesPerView: 2,
6374 spaceBetween: 50
6375 },
6376 // when window width is >= 480px
6377 480: {
6378 slidesPerView: 3,
6379 spaceBetween: 50
6380 },
6381
6382 1040: {
6383 slidesPerView: 4,
6384 spaceBetween: 50
6385 }
6386 }
6387
6388 });
6389 });
6390
6391 </script>
6392
6393 @helper RenderCompanies()
6394 {
6395
6396 if (!string.IsNullOrEmpty(GetString("Ecom:Product:Field.WeDeliverTo.Value.FullPath")))
6397 {
6398 string tableWidth = "grid__col-md-6";
6399
6400 <div class="center-container dw-mod">
6401 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12 companies">
6402 <div class="companies__header">@Translate("We deliver to")</div>
6403 <div class="weDeliverToSlider">
6404
6405 @{
6406 List<string> weDeliverToPaths = GetString("Ecom:Product:Field.WeDeliverTo.Value.FullPath").Split(',').ToList();
6407 }
6408
6409 <div class="swiper-wrapper">
6410 @{
6411
6412 foreach(string path in weDeliverToPaths)
6413 {
6414 string fileName = Path.GetFileNameWithoutExtension(path);
6415 <div class="swiper-slide">
6416 <img src="@path" alt="@fileName" />
6417 </div>
6418 }
6419 }
6420
6421 </div>
6422 </div>
6423 </div>
6424 </div>
6425 }
6426
6427 }
6428 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
6429 @using Dynamicweb.Core
6430 @using System
6431 @using System.Web
6432 @using System.Collections.Generic
6433 @using Dynamicweb.Rapido.Blocks
6434 @using Dynamicweb.Rapido.Blocks.Components.General
6435 @using System.Linq;
6436
6437 @functions {
6438 BlocksPage productTrustpilotPage = BlocksPage.GetBlockPage("Product");
6439 }
6440
6441 @{
6442 string productTrustpilot = "Section";
6443
6444 Block productsTrustpilotBlock = new Block()
6445 {
6446 Name = productTrustpilot,
6447 Id = "productTrustpilot",
6448 SortId = 31,
6449 Template = RenderTrustPilot(),
6450 Design = new Design
6451 {
6452 Size = "12",
6453 RenderType = RenderType.Column,
6454 HidePadding = true
6455 }
6456 };
6457 productTrustpilotPage.Add(productTrustpilot, productsTrustpilotBlock);
6458 }
6459
6460 <link rel="stylesheet" href="/Files/Templates/Designs/Rapido/node_modules/swiper/swiper-bundle.min.css">
6461 <script src="/Files/Templates/Designs/Rapido/node_modules/swiper/swiper-bundle.min.js"></script>
6462 <script>
6463 document.addEventListener('DOMContentLoaded', function() {
6464 var trustpilotSlider = new Swiper('.trustpilotSlider', {
6465 loop: true,
6466 slidesPerView: 5,
6467 allowTouchMove: false,
6468 autoplay: {
6469 delay: 0,
6470 disableOnInteraction: false,
6471 },
6472 spaceBetween: 25,
6473 speed: 3500,
6474 breakpoints: {
6475 // when window width is >= 320px
6476 320: {
6477 slidesPerView: 2,
6478 spaceBetween: 25
6479 },
6480 // when window width is >= 480px
6481 480: {
6482 slidesPerView: 2,
6483 spaceBetween: 25
6484 },
6485 1040: {
6486 slidesPerView: 3,
6487 spaceBetween: 25
6488 },
6489 1500: {
6490 slidesPerView: 5,
6491 spaceBetween: 25
6492 }
6493 }
6494 });
6495 });
6496 </script>
6497
6498
6499 @helper RenderTrustPilot()
6500 {
6501
6502 if(Pageview.Area.Item["TPImages"] == null)
6503 {
6504 return;
6505 }
6506
6507 int itemListRelationId = (int)Pageview.Area.Item["TPImages"];
6508 var images = Dynamicweb.Content.Items.ItemList.GetItemListById(itemListRelationId).Relations.ToList();
6509 bool showTrustpilotSlider = GetBoolean("Ecom:Product:Field.ShowTrustpilotSlider");
6510
6511 if (images != null && images.Count > 0 && showTrustpilotSlider)
6512 {
6513 string tableWidth = "grid__col-md-12";
6514
6515 <div class="center-container dw-mod">
6516 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12 trustpilot">
6517 <div class="trustpilot__header">
6518 @Pageview.Area.Item["TPHeader"]
6519 </div>
6520 <div class="trustpilotSlider">
6521 <div class="swiper-wrapper">
6522 @{
6523 foreach(Dynamicweb.Content.Items.Item image in images)
6524 {
6525 string imagePath = (string)image["ImagePath"];
6526 string fileName = Path.GetFileNameWithoutExtension(imagePath);
6527
6528 <div class="swiper-slide">
6529 <img src="@imagePath" alt="@fileName" />
6530 </div>
6531
6532 }
6533 }
6534 </div>
6535 </div>
6536 <div class="trustpilot__text">
6537 @Pageview.Area.Item["TPText"]
6538 </div>
6539 <div class="trustpilot__logo-container">
6540 <img class="trustpilot__logo-container__image" style="width: 19px" src="\Files\Images\Trustpilot\tplogo.png"/>
6541 <div class="trustpilot__logo-container__text">Trustpilot</div>
6542 </div>
6543 </div>
6544 </div>
6545 }
6546 }
6547 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
6548 @using Dynamicweb.Core
6549 @using System
6550 @using System.Web
6551 @using System.Collections.Generic
6552 @using Dynamicweb.Rapido.Blocks
6553 @using Dynamicweb.Rapido.Blocks.Components.General
6554 @using System.Linq;
6555
6556 @functions {
6557 BlocksPage productVideoPage2 = BlocksPage.GetBlockPage("Product");
6558 }
6559
6560 @{
6561 string productVideo = "Section";
6562
6563 Block productVideoBlock = new Block()
6564 {
6565 Name = productVideo,
6566 Id = "productVideo",
6567 SortId = 29,
6568 Template = RenderProductVideo(),
6569 Design = new Design
6570 {
6571 Size = "12",
6572 RenderType = RenderType.Column,
6573 HidePadding = true
6574 }
6575 };
6576 productVideoPage2.Add(productVideo, productVideoBlock);
6577 }
6578
6579 @helper RenderProductVideo()
6580 {
6581
6582 string videoPath = GetString("Ecom:Product:Field.Video.FullPath");
6583
6584 if (!string.IsNullOrEmpty(videoPath))
6585 {
6586 videoPath += "#t=0.001";
6587 string tableWidth = "grid__col-md-6";
6588 <div class="center-container dw-mod">
6589 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12 " style="padding: 0;">
6590 <video class="" controls="" muted="" playsinline="" disablepictureinpicture="" width="1920" height="auto">
6591 <source src="@videoPath" type="video/mp4">
6592 </video>
6593 </div>
6594 </div>
6595 }
6596 }
6597
6598
6599 <div class="nc-product marble-white-section js-product">
6600 <div class="grid">
6601 @* The @RenderBlockList base helper is included in Components/GridBuilder.cshtml *@
6602 @RenderBlockList(productsPage.BlocksRoot.BlocksList)
6603 </div>
6604 </div>
6605
6606 @helper RenderProductTop()
6607 {
6608 List<Block> subBlocks = productsPage.GetBlockListById("Top").OrderBy(item => item.SortId).ToList();
6609
6610 <div class="nc-product__top">
6611 <div class="nc-product__top-grid grid">
6612 @RenderBlockList(subBlocks)
6613 </div>
6614 </div>
6615 }
6616
6617 @helper RenderProductMiniTabs()
6618 {
6619 List<Block> subBlocks = productsPage.GetBlockListById("MiniTabs").OrderBy(item => item.SortId).ToList();
6620
6621 if (subBlocks.Count > 0)
6622 {
6623 <div class="grid__col-12 product__info tabs u-no-padding u-margin-bottom--lg dw-mod">
6624 @{
6625 bool firstTab = true;
6626 foreach (Block item in subBlocks)
6627 {
6628 string isChecked = firstTab ? "checked" : "";
6629 firstTab = false;
6630
6631 <input type="radio" class="tabs__trigger" name="productMiniTabs" id="@item.Id" onchange="bLazy.revalidate()" @isChecked />
6632 }
6633 }
6634
6635 <div class="tabs__list dw-mod">
6636 @foreach (Block item in subBlocks)
6637 {
6638 <label for="@item.Id" class="tabs__label dw-mod">@item.Name</label>
6639 }
6640 </div>
6641
6642 <div class="tabs__blocks dw-mod">
6643 @foreach (Block item in subBlocks)
6644 {
6645 string hidePadding = item.Design.HidePadding ? "u-no-padding" : "";
6646
6647 if (item.Design.RenderType != RenderType.Hide)
6648 {
6649 <div class="tabs__block u-border dw-mod" id="Block__@item.Id">
6650 <block class="product__block paragraph-container product__block--bordered dw-mod">
6651 <div class="center-container dw-mod">
6652 @RenderBlock(item)
6653 </div>
6654 </block>
6655 </div>
6656 }
6657 }
6658 </div>
6659 </div>
6660 }
6661 }
6662
6663 @helper RenderProductTabs()
6664 {
6665 List<Block> subBlocks = productsPage.GetBlockListById("Tabs").OrderBy(item => item.SortId).ToList();
6666
6667 if (Pageview.Device.ToString() != "Mobile") {
6668 <div class="grid__col-12 product__info product__info--tabs tabs dw-mod">
6669 @{
6670 bool firstTab = true;
6671 foreach (Block item in subBlocks)
6672 {
6673 string isChecked = firstTab ? "checked" : "";
6674 firstTab = false;
6675
6676 <input type="radio" class="tabs__trigger" name="productTabs" id="@item.Id" onchange="bLazy.revalidate()" @isChecked />
6677 }
6678 }
6679
6680 <div class="tabs__list dw-mod">
6681 @foreach (Block item in subBlocks)
6682 {
6683 if (item.Design.RenderType != RenderType.Hide)
6684 {
6685 <label for="@item.Id" class="tabs__label dw-mod">@item.Name</label>
6686 }
6687 }
6688 </div>
6689
6690 <div class="tabs__blocks dw-mod">
6691 @foreach (Block item in subBlocks)
6692 {
6693 if (item.Design.RenderType != RenderType.Hide)
6694 {
6695 <div class="tabs__block dw-mod" id="Block__@item.Id">
6696 <section class="product__section paragraph-container paragraph-container--full-width product__section--bordered dw-mod">
6697 <div class="center-container u-padding--lg dw-mod">
6698 @RenderBlock(item)
6699 </div>
6700 </section>
6701 </div>
6702 }
6703 }
6704 </div>
6705 </div>
6706 <div class="product-overlay-overlap"> </div>
6707
6708
6709 } else {
6710 foreach (Block item in subBlocks)
6711 {
6712 if (item.Design.RenderType != RenderType.Hide)
6713 {
6714 <div class="center-container dw-mod">
6715 <div class="padding-position-left padding-size-sm">
6716 @Render(new Heading { Title = item.Name, Level = 2 })
6717 </div>
6718
6719 @RenderBlock(item)
6720 </div>
6721 }
6722 }
6723 }
6724 }