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_83d854cacb904f7ea6c78661c1d66c16.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.Collections
4452 @using System.Web
4453 @using System.Globalization;
4454 @using System.Collections.Generic
4455 @using Dynamicweb.Content
4456 @using Dynamicweb.Content.Items
4457 @using Dynamicweb.Ecommerce.Products.Categories
4458 @using Dynamicweb.Ecommerce.Products.FieldDisplayGroups
4459 @using Dynamicweb.Ecommerce.Synchronization
4460 @using Dynamicweb.Rapido.Blocks
4461 @using VestjyskMarketing.Models
4462 @using Page = System.Web.UI.Page
4463
4464
4465
4466 @functions {
4467 BlocksPage productFieldsPage = BlocksPage.GetBlockPage("Product");
4468
4469
4470 static string ConvertBytes(long bytes)
4471 {
4472 double size = bytes / 1024; //KB
4473 if (size > 1024)
4474 {
4475 size = (bytes / 1024f) / 1024f; //MB
4476 return string.Format("{0:n1} MB", size);
4477 }
4478 else
4479 {
4480 return string.Format("{0:n0} KB", size);
4481 }
4482 }
4483
4484 static bool isImage(string path)
4485 {
4486 return new List<string> { ".jpg", ".jpeg", ".gif", ".png", ".svg" }.Contains(Path.GetExtension(path).ToLower());
4487 }
4488
4489 string getIconForFile(string fileName)
4490 {
4491 string ext = Path.GetExtension(fileName);
4492 string icon = "";
4493 switch (ext.ToLower())
4494 {
4495 case ".xls":
4496 case ".xlsx":
4497 icon = "fa-file-excel";
4498 break;
4499 case ".ppt":
4500 case ".pptx":
4501 icon = "fa-file-powerpoint";
4502 break;
4503 case ".doc":
4504 case ".docx":
4505 icon = "fa-file-word";
4506 break;
4507 case ".jpg":
4508 case ".jpeg":
4509 case ".png":
4510 case ".gif":
4511 case ".pdf":
4512 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 + "' />";
4513 default:
4514 icon = "fa-file";
4515 break;
4516 }
4517 return "<i class='product__document-icon far " + icon + "'></i> ";
4518 }
4519
4520 }
4521
4522 @*downloadDocuments variable, declared in Product.cshtml - this variable also will be used in ProductAssets.cshtml*@
4523
4524
4525
4526 @{
4527 var selectedDownloadCategories = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadAssets").SelectedValues;
4528 var downloadsFromAssets = GetLoop("ImageCategories").Where(x => selectedDownloadCategories.Contains(x.GetString("Category.Id")));
4529
4530 if (string.IsNullOrEmpty(selectedDownloadCategories.ToString()))
4531 {
4532 foreach (LoopItem customField in GetLoop("CustomFieldValues"))
4533 {
4534 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")
4535 {
4536 if (!string.IsNullOrEmpty(customField.GetString("Document.FullPath")))
4537 {
4538 downloadDocuments.Add(customField);
4539 }
4540 }
4541 }
4542
4543 foreach (LoopItem customField in GetLoop("ProductCategories"))
4544 {
4545 foreach (LoopItem field in customField.GetLoop("ProductCategoryFields"))
4546 {
4547 if (!string.IsNullOrEmpty(field.GetString("Ecom:Product.CategoryField.Label")) && !string.IsNullOrEmpty(field.GetString("Ecom:Product.CategoryField.Value")))
4548 {
4549 if (field.GetString("Ecom:Product.CategoryField.TypeID") == "9")
4550 {
4551 downloadDocuments.Add(field);
4552 }
4553 }
4554 }
4555 }
4556 }
4557 else
4558 {
4559 foreach (LoopItem category in downloadsFromAssets)
4560 {
4561 foreach (LoopItem asset in category.GetLoop("Category.Images"))
4562 {
4563 downloadDocuments.Add(asset);
4564 }
4565 }
4566 }
4567
4568 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true;
4569 string detailFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout").SelectedValue : "Section";
4570 detailFieldsLayout = detailFieldsLayout == "Ribbon" || string.IsNullOrEmpty(detailFieldsLayout) ? "Section" : detailFieldsLayout;
4571 string categoryFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout").SelectedValue : "Section";
4572 categoryFieldsLayout = categoryFieldsLayout == "Ribbon" || string.IsNullOrEmpty(categoryFieldsLayout) ? "Section" : categoryFieldsLayout;
4573 string displayGroupsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DisplayGroupsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DisplayGroupsLayout").SelectedValue : "Section";
4574 displayGroupsLayout = displayGroupsLayout == "Ribbon" || string.IsNullOrEmpty(displayGroupsLayout) ? "Section" : displayGroupsLayout;
4575 string downloadsFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout").SelectedValue : "Section";
4576 downloadsFieldsLayout = downloadsFieldsLayout == "Ribbon" || string.IsNullOrEmpty(downloadsFieldsLayout) ? "Section" : downloadsFieldsLayout;
4577
4578 string detailFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsView").SelectedValue : "grid";
4579 string categoryFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsView").SelectedValue : "grid";
4580 string downloadsFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsFieldsView").SelectedValue : "grid";
4581
4582 if (GetLoop("CustomFieldValues").Count > 0 && detailFieldsLayout != "hide")
4583 {
4584 if (string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("ProductDetailFields")))
4585 {
4586 Block detailsCustom = new Block()
4587 {
4588 Name = detailFieldsLayout != "MainInformation" ? Translate("Details") : "",
4589 Id = "CustomFields",
4590 SortId = 30,
4591 Design = new Design
4592 {
4593 Size = "12",
4594 RenderType = RenderType.Column,
4595 HidePadding = true
4596 }
4597 };
4598
4599 detailsCustom.Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Information"), RenderCustomFields(GetLoop("CustomFieldValues"), detailFieldsView));
4600 productFieldsPage.Add(detailFieldsLayout, detailsCustom);
4601 }
4602 else
4603 {
4604 var detailFieldsDisplayGroups = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductDetailFields").SelectedValues;
4605 var displayGroups = GetLoop("FieldDisplayGroups").Where(x => detailFieldsDisplayGroups.Contains(x.GetString("Ecom:FieldDisplayGroup.ID")));
4606
4607
4608 foreach (var group in displayGroups)
4609 {
4610 Block detailsCustom = new Block()
4611 {
4612 Name = detailFieldsLayout != "MainInformation" ? group.GetString("Ecom:FieldDisplayGroup.Name") : "",
4613 Id = "DetailFields_" + group.GetString("Ecom:FieldDisplayGroup.ID"),
4614 SortId = 30,
4615 Design = new Design
4616 {
4617 Size = "12",
4618 RenderType = RenderType.Column,
4619 HidePadding = true
4620 }
4621 };
4622
4623 detailsCustom.Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Information"), RenderDetailsFields(group.GetLoop("Fields"), detailFieldsView));
4624 productFieldsPage.Add(detailFieldsLayout, detailsCustom);
4625 }
4626 }
4627 }
4628
4629 if (categoryFieldsLayout != "hide")
4630 {
4631 foreach (LoopItem categoryGroup in GetLoop("ProductCategories"))
4632 {
4633 bool hasFields = categoryGroup.GetLoop("ProductCategoryFields").FirstOrDefault(cf => !string.IsNullOrEmpty(cf.GetString("Ecom:Product.CategoryField.Value"))) != null;
4634
4635
4636 if (collectAllDownloads)
4637 {
4638 int downloadableCount = 0;
4639 foreach (LoopItem field in categoryGroup.GetLoop("ProductCategoryFields"))
4640 {
4641 if (field.GetString("Ecom:Product.CategoryField.TypeID") == "9")
4642 {
4643 downloadableCount++;
4644 }
4645 }
4646
4647 if (downloadableCount == categoryGroup.GetLoop("ProductCategoryFields").Count)
4648 {
4649 hasFields = false;
4650 }
4651 }
4652
4653 //hasFields needs to be true, if not description will not be shown, even if it is not empty
4654 hasFields = true;
4655
4656 if (hasFields)
4657 {
4658 Block detailsCategoryFields = new Block()
4659 {
4660 Name = categoryFieldsLayout != "MainInformation" ? categoryGroup.GetString("Ecom:Product.Category.Name") : "",
4661 Id = ToPascalCase(categoryGroup.GetString("Ecom:Product.Category.Name")),
4662 SortId = 40,
4663 Template = RenderProductSection(categoryFieldsLayout, categoryFieldsView, categoryGroup.GetString("Ecom:Product.Category.Name"), RenderProductCategoryFields(categoryGroup.GetLoop("ProductCategoryFields"), categoryFieldsView)),
4664 Design = new Design
4665 {
4666 Size = "12",
4667 RenderType = RenderType.Column,
4668 HidePadding = true
4669 }
4670 };
4671
4672 productFieldsPage.Add(categoryFieldsLayout, detailsCategoryFields);
4673 }
4674 }
4675 }
4676
4677 if (displayGroupsLayout != "hide")
4678 {
4679 var detailFieldsDisplayGroups = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductDetailFields").SelectedValues;
4680 var displayGroups = GetLoop("FieldDisplayGroups").Where(x => !detailFieldsDisplayGroups.Contains(x.GetString("Ecom:FieldDisplayGroup.ID")));
4681
4682
4683 foreach (LoopItem group in displayGroups)
4684 {
4685 int fieldsCount = 0;
4686
4687 foreach (LoopItem field in group.GetLoop("Fields"))
4688 {
4689 if (!string.IsNullOrEmpty(field.GetString("Ecom:FieldDisplayGroup.Field.Name")) && !string.IsNullOrEmpty(field.GetString("Ecom:FieldDisplayGroup.Field.Value")))
4690 {
4691 fieldsCount++;
4692 }
4693 }
4694
4695 if (fieldsCount != 0)
4696 {
4697 Block displayGroup = new Block()
4698 {
4699 Name = displayGroupsLayout != "MainInformation" ? group.GetString("Ecom:FieldDisplayGroup.Name") : "",
4700 Id = "DisplayGroup_" + group.GetString("Ecom:FieldDisplayGroup.ID"),
4701 SortId = 40,
4702 Template = RenderProductSection(displayGroupsLayout, categoryFieldsView, group.GetString("Ecom:FieldDisplayGroup.Name"), RenderDetailsFields(group.GetLoop("Fields"), categoryFieldsView)),
4703 Design = new Design
4704 {
4705 Size = "12",
4706 RenderType = RenderType.Column,
4707 HidePadding = true
4708 }
4709 };
4710 productFieldsPage.Add(displayGroupsLayout, displayGroup);
4711 }
4712 else
4713 {
4714 Block displayGroup = new Block()
4715 {
4716 Name = displayGroupsLayout != "MainInformation" ? group.GetString("Ecom:FieldDisplayGroup.Name") : "",
4717 Id = "DisplayGroup_" + group.GetString("Ecom:FieldDisplayGroup.ID"),
4718 SortId = 40,
4719 Template = RenderProductDescription(displayGroupsLayout, categoryFieldsView, group.GetString("Ecom:FieldDisplayGroup.Name"), RenderDetailsFields(group.GetLoop("Fields"), categoryFieldsView)),
4720 Design = new Design
4721 {
4722 Size = "12",
4723 RenderType = RenderType.Column,
4724 HidePadding = true
4725 }
4726 };
4727 productFieldsPage.Add(displayGroupsLayout, displayGroup);
4728 }
4729 }
4730 }
4731
4732 if (downloadDocuments.Count > 0 && downloadsFieldsLayout != "hide" && collectAllDownloads == true)
4733 {
4734 Block detailsDownloads = new Block()
4735 {
4736 Name = downloadsFieldsLayout != "MainInformation" ? Translate("Downloads") : "",
4737 Id = "StandardDownloads",
4738 SortId = 50,
4739 Template = RenderProductSection(downloadsFieldsLayout, downloadsFieldsView, Translate("Downloads"), RenderProductDownloadsFields(downloadDocuments, downloadsFieldsView)),
4740 Design = new Design
4741 {
4742 Size = "12",
4743 RenderType = RenderType.Column,
4744 HidePadding = true
4745 }
4746 };
4747
4748 productFieldsPage.Add(downloadsFieldsLayout, detailsDownloads);
4749 }
4750 }
4751
4752 @helper RenderCustomFields(List<LoopItem> fieldsLoop, string viewType)
4753 {
4754 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true;
4755
4756 foreach (LoopItem customField in fieldsLoop)
4757 {
4758 string fieldValue = customField.GetString("Product.CustomField.Value.Clean");
4759 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue;
4760 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue;
4761
4762 if (customField.GetLoop("Product.CustomField.Options").Count > 0)
4763 {
4764 List<string> accumulatedValues = new List<string>();
4765
4766 foreach (var option in customField.GetLoop("Product.CustomField.Options"))
4767 {
4768 if (option.GetBoolean("Product.CustomField.Option.IsSelected"))
4769 {
4770 accumulatedValues.Add(option.GetString("Product.CustomField.Option.Name"));
4771 }
4772 }
4773 fieldValue = string.Join(", ", accumulatedValues);
4774 }
4775
4776 if (!string.IsNullOrEmpty(customField.GetString("Product.CustomField.Name")) && !string.IsNullOrEmpty(fieldValue) && customField.GetString("Product.CustomField.Name") != "Custom sticker" && customField.GetString("Product.CustomField.Name") != "RRP")
4777 {
4778 if (string.IsNullOrEmpty(customField.GetString("Document.FullPath")))
4779 {
4780 @RenderFieldItem(customField.GetString("Product.CustomField.Name"), fieldValue, viewType)
4781 ;
4782 }
4783 else if (collectAllDownloads == false)
4784 {
4785 @RenderFieldItem(customField.GetString("Product.CustomField.Name"), fieldValue, viewType, "download")
4786 ;
4787 }
4788 }
4789 }
4790 }
4791
4792 @helper RenderProductSection(string layout, string viewType, string name, RazorEngine.Templating.TemplateWriter writer)
4793 {
4794 string ribbonClasses = layout == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
4795 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses;
4796 string ribbonSubClasses = layout == "Ribbon" ? "center-container--ribbon" : "";
4797
4798
4799 <div class="product__section @ribbonClasses dw-mod js-product-detail-info">
4800
4801 <div class="center-container @ribbonSubClasses dw-mod">
4802 @if (viewType != "table")
4803 {
4804 <div class="grid grid--bleed u-margin-bottom--lg">
4805
4806 </div>
4807 }
4808 else
4809 {
4810 string tableWidth = layout != "MainInformation" ? "grid__col-md-6" : "grid__col-md-12";
4811
4812
4813 Dynamicweb.Ecommerce.Products.ProductService productService = new Dynamicweb.Ecommerce.Products.ProductService();
4814
4815 var product = productService.GetProductById(GetString("Ecom:Product.ID"), GetString("Ecom:Product.VariantID"), GetString("Ecom:Product.LanguageID"));
4816 var categoryService = new ProductCategoryService();
4817
4818
4819 List<string> labels = new List<string>();
4820 List<string> values = new List<string>();
4821
4822 if (categoryService.GetCategories(product, true) != null && categoryService.GetCategories(product, true).FirstOrDefault() != null)
4823 {
4824 var data = categoryService.GetCategories(product, true).FirstOrDefault().Fields.ToArray();
4825
4826
4827 if (data != null)
4828 {
4829 foreach (var field in data)
4830 {
4831 var lang = GetString("Ecom:Product.LanguageID");
4832
4833 if (categoryService.GetProductCategoryFieldValue(product, field).Value != null)
4834 {
4835 var fieldData = categoryService.GetProductCategoryFieldValue(product, field).Value.ToString();
4836 labels.Add(field.GetLabel(lang));
4837 values.Add((fieldData));
4838 }
4839 }
4840 }
4841 }
4842
4843
4844 if (name != "")
4845 {
4846 @* Details about the product card *@
4847 <div class="grid u-margin-bottom--lg nc-grid">
4848 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12 table__white extra-specs" id="ProductDetails">
4849 <table class="table--no-borders">
4850 <h3>@Translate("ProductDetails", "Detaljer om produktet")</h3>
4851 <div class="more-info">
4852 @GetString("Ecom:Product.LongDescription")
4853
4854 </div>
4855 <button class="expand-info--box accordion" data-info="@Translate("DataInfo", "Udvid info")" data-info-close="@Translate("DataInfoClose", "Fold info ind")">
4856 </button>
4857 </table>
4858
4859 </div>
4860 </div>
4861 if (labels.Count > 1)
4862 {
4863 @* Specifications for the product card *@
4864 <div class="grid u-margin-bottom--lg nc-grid">
4865 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12 table__white extra-specs" id="ProductSpecs">
4866 <table class="table--no-borders">
4867 <h3>@Translate("ProductSpecs", "Specifikationer")</h3>
4868 <tbody>
4869 @for (int i = 0; i < labels.Count; i++)
4870 {
4871 if (!string.IsNullOrEmpty(values[i]) && !string.IsNullOrEmpty(labels[i]))
4872 {
4873 <tr>
4874 <th style="padding: 0">@labels[i]</th>
4875 @if (values[i] == "True")
4876 {
4877 <td style="padding: 0">@Translate("Yes")</td>
4878 }
4879 else if (values[i] == "False")
4880 {
4881 <td style="padding: 0">@Translate("No")</td>
4882 }
4883 else
4884 {
4885 <td style="padding: 0">@values[i]</td>
4886 }
4887 </tr>
4888 }
4889 }
4890
4891 </tbody>
4892 <button class="expand-info--box accordion" data-info="@Translate("DataInfo", "Udvid info")" data-info-close="@Translate("DataInfoClose", "Fold info ind")">
4893 </button>
4894 </table>
4895 </div>
4896 </div>
4897 }
4898
4899 @* Guarantee for the product card *@
4900 string pageLink = GetString("Ecom:Product:Field.ProductGuarantee");
4901 string pageUrl = !string.IsNullOrEmpty(pageLink) ? pageLink.Split('=')[1] : "";
4902 int pageId;
4903 bool productGuaranteeFound = Int32.TryParse(pageUrl, out pageId);
4904
4905 if (productGuaranteeFound)
4906 {
4907 ItemService itemService = new ItemService();
4908 var productGuarantee = itemService.GetItemByPageId(pageId, false);
4909
4910 if (productGuarantee != null && productGuarantee["ProductGuarantees"] != null)
4911 {
4912 int productGuaranteeListId = (int)productGuarantee["ProductGuarantees"];
4913 var productGuaranteeList = ItemList.GetItemListById(productGuaranteeListId).Relations;
4914
4915 foreach (Item productGuaranteeModule in productGuaranteeList)
4916 {
4917 string guaranteeVideo = (string)productGuaranteeModule["Video"];
4918 string guaranteeImage = (string)productGuaranteeModule["Image"];
4919 string guaranteeImageAlt = (string)productGuaranteeModule["ImageAlt"];
4920 string guaranteeText = (string)productGuaranteeModule["Text"];
4921
4922 <div class="grid u-margin-bottom--lg nc-grid">
4923 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12 padding-none" id="ProductGuarantee">
4924
4925 @if (!string.IsNullOrEmpty(guaranteeVideo))
4926 {
4927 <video class="" muted="" playsinline="" disablepictureinpicture="" width="1920" height="auto" autoplay="true" loop>
4928 <source src="@guaranteeVideo" type="video/mp4">
4929 </video>
4930 }
4931 else
4932 {
4933 <img class="guarantee-image" src="@guaranteeImage" alt="@guaranteeImageAlt"/>
4934 }
4935
4936 @if (!string.IsNullOrEmpty(guaranteeText))
4937 {
4938 <div class="guarantee-text">
4939 @guaranteeText
4940 </div>
4941 }
4942 </div>
4943 </div>
4944 }
4945 }
4946 }
4947 }
4948 }
4949 </div>
4950 </div>
4951 }
4952
4953 @helper RenderProductDescription(string layout, string viewType, string name, RazorEngine.Templating.TemplateWriter writer, int fieldsCount = 0)
4954 {
4955 string ribbonClasses = layout == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
4956 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses;
4957 string ribbonSubClasses = layout == "Ribbon" ? "center-container--ribbon" : "";
4958
4959
4960 <div class="product__section @ribbonClasses dw-mod js-product-detail-info">
4961 <div class="center-container @ribbonSubClasses dw-mod">
4962 @if (viewType != "table")
4963 {
4964 <div class="grid grid--bleed u-margin-bottom--lg">
4965
4966 @writer
4967 </div>
4968 }
4969 else
4970 {
4971 string tableWidth = layout != "MainInformation" ? "grid__col-md-6" : "grid__col-md-12";
4972
4973 @* Details about the product card *@
4974 <div class="grid u-margin-bottom--lg nc-grid">
4975 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12 table__white extra-specs" id="ProductDetails">
4976 <table class="table--no-borders">
4977 <h3>@Translate("ProductDetails", "Detaljer om produktet")</h3>
4978 <div class="more-info">
4979 @GetString("Ecom:Product.LongDescription")
4980 </div>
4981 <button class="expand-info--box accordion" data-info="@Translate("DataInfo", "Udvid info")" data-info-close="@Translate("DataInfoClose", "Fold info ind")">
4982 </button>
4983 </table>
4984
4985 </div>
4986 </div>
4987 }
4988 </div>
4989 </div>
4990 }
4991
4992 @helper RenderProductCategoryFields(List<LoopItem> fieldsLoop, string viewType)
4993 {
4994 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true;
4995
4996 foreach (LoopItem categoryField in fieldsLoop)
4997 {
4998 string fieldValue = categoryField.GetString("Ecom:Product.CategoryField.Value");
4999 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue;
5000 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue;
5001
5002 if (!string.IsNullOrEmpty(categoryField.GetString("Ecom:Product.CategoryField.Label")) && !string.IsNullOrEmpty(fieldValue))
5003 {
5004 if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") != "9" || collectAllDownloads == false)
5005 {
5006 if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "15")
5007 {
5008 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), categoryField.GetString("Ecom:Product.CategoryField.OptionLabel"), viewType)
5009 ;
5010 }
5011 else if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "8")
5012 {
5013 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType, "link")
5014 ;
5015 }
5016 else if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "9")
5017 {
5018 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType, "download")
5019 ;
5020 }
5021 else
5022 {
5023 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType)
5024 ;
5025 }
5026 }
5027 }
5028 }
5029 }
5030
5031 @helper RenderDetailsFields(IEnumerable<LoopItem> fields, string viewType)
5032 {
5033 foreach (LoopItem field in fields)
5034 {
5035 string fieldValue = field.GetString("Ecom:FieldDisplayGroup.Field.Value");
5036 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue;
5037 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue;
5038
5039 if (!string.IsNullOrEmpty(field.GetString("Ecom:FieldDisplayGroup.Field.Name")) && !string.IsNullOrEmpty(fieldValue))
5040 {
5041 if (field.GetString("Ecom:FieldDisplayGroup.Field.TypeId") == "15")
5042 {
5043 @RenderFieldItem(field.GetString("Ecom:FieldDisplayGroup.Field.Name"), field.GetString("Ecom:FieldDisplayGroup.Field.OptionLabel"), viewType)
5044 ;
5045 }
5046 else if (field.GetString("Ecom:FieldDisplayGroup.Field.TypeId") == "8")
5047 {
5048 @RenderFieldItem(field.GetString("Ecom:Product.CategoryField.Name"), fieldValue, viewType, "link")
5049 ;
5050 }
5051 else if (field.GetString("Ecom:FieldDisplayGroup.Field.TypeId") == "9")
5052 {
5053 @RenderFieldItem(field.GetString("Ecom:FieldDisplayGroup.Field.Name"), fieldValue, viewType, "download")
5054 ;
5055 }
5056 else
5057 {
5058 @RenderFieldItem(field.GetString("Ecom:FieldDisplayGroup.Field.Name"), fieldValue, viewType)
5059 ;
5060 }
5061 }
5062 }
5063 }
5064
5065 @helper RenderProductDownloadsFields(List<LoopItem> fieldsLoop, string viewType)
5066 {
5067 foreach (LoopItem document in fieldsLoop)
5068 {
5069 string fieldValue;
5070 if (!string.IsNullOrEmpty(document.GetString("Document.FullPath")))
5071 {
5072 fieldValue = document.GetString("Product.CustomField.Value.Clean");
5073 @RenderFieldItem(fieldValue, document.GetString("Document.FullPath"), viewType, "download")
5074 }
5075
5076 if (document.GetString("Ecom:Product.CategoryField.TypeID") == "9")
5077 {
5078 fieldValue = document.GetString("Ecom:Product.CategoryField.Value");
5079 @RenderFieldItem(fieldValue, fieldValue, viewType, "download")
5080 }
5081 if (!string.IsNullOrEmpty(document.GetString("Ecom:Product:Detail.Image.Clean")))
5082 {
5083 fieldValue = document.GetString("Ecom:Product:Detail.Image.Clean");
5084 @RenderFieldItem("", fieldValue, viewType, "download")
5085 }
5086 }
5087 }
5088
5089 @helper RenderFieldItem(string name, string value, string viewType, string fieldType = "clean")
5090 {
5091 if (viewType != "table")
5092 {
5093 string fieldColumns = viewType == "list" ? "12" : "4";
5094 <div class="grid__col-md-@fieldColumns grid__col-sm-12 u-margin-bottom">
5095 <div class="u-bold">
5096 @name
5097 </div>
5098 <div>
5099 @RenderFieldItemContent(name, value, fieldType)
5100 </div>
5101 </div>
5102 }
5103 else
5104 {
5105 <tr>
5106 <th>@name</th>
5107 <td>
5108 @RenderFieldItemContent(name, value, fieldType)
5109 </td>
5110 </tr>
5111 }
5112 }
5113
5114 @helper RenderFieldItemContent(string name, string value, string fieldType = "clean")
5115 {
5116 if (fieldType == "link")
5117 {
5118 <a target="_blank" rel="noopener" href="@value">
5119 @if (isImage(value))
5120 {
5121 @getIconForFile(value)
5122 }
5123 else
5124 {
5125 @value
5126 }
5127 </a>
5128 }
5129 else if (fieldType == "download")
5130 {
5131 FileInfo info = new FileInfo(Dynamicweb.Core.SystemInformation.MapPath(value));
5132
5133 if (info.Exists)
5134 {
5135 <div class="grid grid--no-wrap">
5136 <a href="@value" download title="@Translate("Download")" class="product__document dw-mod">@getIconForFile(value)</a>
5137 <div class="product__document-info dw-mod">
5138 <a href="@value" download title="@Translate("Download")" class="product__document dw-mod">@Path.GetFileName(value)</a>
5139 <small class="u-block u-margin-top">@ConvertBytes(info.Length)</small>
5140 </div>
5141 </div>
5142 }
5143 }
5144 else
5145 {
5146 @value
5147 }
5148 }
5149 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
5150 @using Dynamicweb.Core
5151 @using System.Text.RegularExpressions
5152 @using System
5153 @using System.Web
5154 @using System.Collections.Generic
5155 @using Dynamicweb.Rapido.Blocks
5156 @using Dynamicweb.Rapido.Blocks.Components.General
5157
5158 @functions{
5159 BlocksPage productVideoPage = BlocksPage.GetBlockPage("Product");
5160 }
5161
5162 @{
5163 var selectedVideoCategories = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideoAssets").SelectedValues;
5164 var videosFromAssets = GetLoop("ImageCategories").Where(x => selectedVideoCategories.Contains(x.GetString("Category.Id")));
5165
5166 string videosLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue : "Section";
5167 videosLayout = videosLayout == "Ribbon" || string.IsNullOrEmpty(videosLayout) ? "Section" : videosLayout;
5168
5169 int videosCount = 0;
5170
5171 if (videosFromAssets != null)
5172 {
5173 foreach (LoopItem category in videosFromAssets) {
5174 foreach (LoopItem asset in category.GetLoop("Category.Images")) {
5175 videosCount++;
5176 }
5177 }
5178 } else {
5179 foreach (LoopItem detailField in GetLoop("Details"))
5180 {
5181 if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("youtube.com/embed") != -1)
5182 {
5183 videosCount++;
5184 }
5185 if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("vimeo.com") != -1)
5186 {
5187 videosCount++;
5188 }
5189 }
5190 }
5191
5192 if (videosCount > 0 && videosLayout != "hide")
5193 {
5194 Block detailsVideos = new Block()
5195 {
5196 Name = videosLayout != "MainInformation" ? Translate("Videos") : "",
5197 Id = "Videos",
5198 SortId = 60,
5199 Template = RenderProductVideos(videosCount, videosLayout),
5200 Design = new Design
5201 {
5202 Size = "12",
5203 RenderType = RenderType.Column,
5204 HidePadding = true
5205 }
5206 };
5207 productVideoPage.Add(videosLayout, detailsVideos);
5208 }
5209 }
5210
5211 @helper RenderProductVideos(int videosCount, string layout) {
5212 var selectedVideoCategories = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideoAssets").SelectedValues;
5213 var videosFromAssets = GetLoop("ImageCategories").Where(x => selectedVideoCategories.Contains(x.GetString("Category.Id")));
5214
5215 string videoColumn = "12";
5216 videoColumn = videosCount == 2 ? "6" : videoColumn;
5217 videoColumn = videosCount > 2 ? "4" : videoColumn;
5218 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
5219 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses;
5220 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : "";
5221
5222 <div class="product__section @ribbonClasses dw-mod">
5223 <div class="center-container @ribbonSubClasses dw-mod">
5224 @if (layout == "Section") {
5225 @Render(new Heading { Title = Translate("Videos"), Level = 2 })
5226 }
5227
5228 <div class="grid u-margin-bottom--lg">
5229 @if (videosFromAssets != null) {
5230 foreach (LoopItem category in videosFromAssets) {
5231 foreach (LoopItem asset in category.GetLoop("Category.Images")) {
5232 //getting video ID from youtube URL
5233 string videoCode = asset.GetString("Ecom:Product:Detail.Image.Clean");
5234 Regex regex = new Regex(@".be\/(.[^?]*)");
5235 Match match = regex.Match(videoCode);
5236 string videoId = "";
5237 if (match.Success)
5238 {
5239 videoId = match.Groups[1].Value;
5240 }
5241 else
5242 {
5243 regex = new Regex(@"v=([^&]+)");
5244 match = regex.Match(videoCode);
5245 if (match.Success)
5246 {
5247 videoId = match.Groups[1].Value;
5248 }
5249 }
5250
5251 <div class="grid__col-md-@videoColumn grid__col-lg-@videoColumn">
5252 <div class="video-wrapper">
5253 <div class="js-youtube-video" data-video="@videoId" id="ytPlayer@(Guid.NewGuid().ToString("N"))" data-auto-play="False" data-enable-controls="1"></div>
5254 </div>
5255 </div>
5256 }
5257 }
5258 } else {
5259 foreach (LoopItem detailField in GetLoop("Details"))
5260 {
5261 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)
5262 {
5263 <div class="grid__col-md-@videoColumn grid__col-lg-@videoColumn">
5264 <div class="video-wrapper">
5265 @detailField.GetString("Ecom:Product:Detail.Text")
5266 </div>
5267 </div>
5268 }
5269 }
5270 }
5271 </div>
5272 </div>
5273 </div>
5274 }
5275 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
5276 @using Dynamicweb.Core
5277 @using System
5278 @using System.Web
5279 @using System.Collections.Generic
5280 @using Denform.Website.CustomModules
5281 @using Dynamicweb.Rapido.Blocks
5282 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce
5283 @using Dynamicweb.Rapido.Blocks.Components.General
5284 @using Dynamicweb.Rapido.Services
5285
5286
5287 @functions{
5288 BlocksPage productRelatedPage = BlocksPage.GetBlockPage("Product");
5289 }
5290
5291 @{
5292 string relatedProductsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue : "Section";
5293 relatedProductsLayout = relatedProductsLayout == "Ribbon" || string.IsNullOrEmpty(relatedProductsLayout) ? "Section" : relatedProductsLayout;
5294 bool relatedShowStock = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowStockAndShipping");
5295 bool showAddToDownloadButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToDownloadButton");
5296 bool relatedShowPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice");
5297 bool relatedShowFavoriteButton = !Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("HideFavoriteButton") && Pageview.User != null;
5298 bool relatedPointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly");
5299 bool relatedShowCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToCartButton");
5300 bool relatedShowViewButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowViewButton");
5301 string relatedCartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart";
5302 string relatedMoreText = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText")) ? Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText") : "View";
5303 bool relatedShowNumber = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowProductNumber");
5304 //string relatedImageZoomOnHover = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("HoverImageZoom") ? "image-hover--zoom" : "";
5305
5306 int pageId = Pageview.Page.ID;
5307 string pageUrl = TemplateHelper.GetPageUrl(pageId);
5308
5309 string relatedGroupId = "";
5310
5311 int relatedProductsPageSize = 5;
5312
5313 if (Pageview.Device.ToString() == "Mobile")
5314 {
5315 relatedProductsPageSize = 2;
5316 }
5317
5318 if (Pageview.Device.ToString() == "Tablet")
5319 {
5320 relatedProductsPageSize = 4;
5321 }
5322
5323 int relatedProductsColumnWidth = 12 / relatedProductsPageSize;
5324
5325 if (relatedProductsLayout != "hide")
5326 {
5327 var i = 0;
5328 foreach (LoopItem relatedGroup in GetLoop("ProductRelatedGroups"))
5329 {
5330
5331 relatedGroupId = ToPascalCase(relatedGroup.GetString("Ecom:Product:RelatedGroup.Name"));
5332 string baseFeedPageUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + relatedProductsPageSize + "&ProdID=" + GetString("Ecom:Product.ID") + "&feed=true";
5333 string relatedFeed = baseFeedPageUrl + "&" + relatedGroupId + "=" + GetString("Ecom:Product.ID")+ GetString("Ecom:Product.VariantID") + "&GroupName=" + relatedGroupId;
5334 string relatedGroupName = relatedProductsLayout != "maininformation" ? relatedGroup.GetString("Ecom:Product:RelatedGroup.Name") : "";
5335
5336 i++;
5337
5338 Block detailsRelated = new Block()
5339 {
5340 Name = relatedGroupId,
5341 Id = relatedGroupId,
5342 SortId = 70 + i,
5343 Template = RenderRelatedProducts(Translate("Related_Products_heading", "Did you remember?"), relatedGroupId, relatedFeed, relatedProductsLayout),
5344 Design = new Design
5345 {
5346 Size = "12",
5347 RenderType = RenderType.Column,
5348 HidePadding = true
5349 }
5350 };
5351
5352 productRelatedPage.Add(relatedProductsLayout, detailsRelated);
5353 }
5354 }
5355 }
5356
5357 @helper RenderRelatedProducts(string name, string groupId, string relatedFeedUrl, string layout)
5358 {
5359 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
5360 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses;
5361 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : "";
5362
5363 <div class="nc-related-products @ribbonClasses ">
5364 <div class="center-container @ribbonSubClasses dw-mod">
5365 @if (layout == "Section") {
5366 <div style="text-align:center;" class="u-margin-bottom--xl">
5367 @Render(new Heading { Title = name, Level = 2 })
5368 </div>
5369 }
5370 <div class="js-handlebars-root" id="ProductList_@groupId" data-template="ProductContainer" data-pre-render-template="ProductPreRenderContainer" data-json-feed="@relatedFeedUrl" data-preloader="overlay"></div>
5371 </div>
5372 </div>
5373 }
5374 @* Script templates for related products *@
5375 <script id="ProductPreRenderContainer" type="text/x-template">
5376 <div class="u-h600px u-full-width">
5377 <div class="grid">
5378 <div class="grid__col-12">
5379 <div class="pre-render-element pre-render-element--md"></div>
5380 </div>
5381 </div>
5382 </div>
5383 </script>
5384
5385
5386 <script id="ProductContainer" type="text/x-template">
5387 {{#.}}
5388 {{log this}}
5389 <div class="nc-product-list__wrap dw-mod">
5390 <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">
5391 {{#ProductsContainer}}
5392 <div id="Product{{productId}}" class="product-list-item dw-mod">
5393 {{#Product}}
5394 <div class="dw-mod {{noImage}}">
5395 <a href="{{link}}" class="product-list-item__link dw-mod">
5396 @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" })
5397 {{#StickersContainers}}
5398 {{>StickersContainer}}
5399 {{/StickersContainers}}
5400 </a>
5401 </div>
5402 <div class="product-list-item__content-container">
5403 {{log this}}
5404 <div class="product-list-item__item-content">
5405 <div class="product-list-item__header">
5406 <a href="{{link}}" class="product-list-item__title-container" title="{{ name }}">
5407 <h4 class="product-list-item__title">
5408 {{ name }}
5409 </h4>
5410 @*{{#if description}}
5411 <h6 class="product-list-item__sub-title">
5412 {{ description }}
5413 </h6>
5414 {{/if}}*@
5415 </a>
5416 </div>
5417 <div class="product-list-price">
5418 <div class="product-list-price__container">
5419 <div class="product-list-price__valuta">
5420 {{currency}}
5421 </div>
5422 {{#if discount}}
5423 <div class="product-list-price__price">
5424 {{discount}}
5425 </div>
5426 {{/if}}
5427 @*{{#if price}}
5428 <div class="product-list-price__vat">
5429 {{price}}
5430 </div>
5431 {{/if}}*@
5432 </div>
5433 <div class="product-list-price__link-container">
5434 @{
5435 var addToCartBtn = new AddToCart
5436 {
5437 WrapperCssClass = "",
5438 AddButton = new AddToCartButton
5439 {
5440 ProductId = "{{productId}}",
5441 VariantId = "{{variantid}}",
5442 UnitId = "{{unitId}}", ProductInfo = "{{productInfo}}",
5443 OnClick = "{{facebookPixelAction}}",
5444 ButtonLayout = ButtonLayout.None,
5445 ExtraAttributes = new Dictionary<string, string>
5446 {
5447 { "{{disabledBuyButton}}", "" }
5448 },
5449 CssClass = "product-list-price__link product-list-price__button btn",
5450 Icon = new Icon {
5451 Prefix = "u-hidden",
5452 Label = Translate("Add to basket", "Læg i kurv"),
5453 CssClass = "u-full-width"
5454 }
5455 }
5456 };
5457 @Render(addToCartBtn)
5458 }
5459 </div>
5460 </div>
5461 </div>
5462 </div>
5463 {{/Product}}
5464 </div>
5465 {{/ProductsContainer}}
5466 </div>
5467 </div>
5468 <div style="display:flex; justify-content:center">
5469 <div class="grid__col-45px grid__col--bleed-x">
5470 <div class="grid__cell grid__cell--align-middle-left">
5471 <button type="button" class="btn--condensed btn btn--clean dw-mod {{prevdisabled}} u-position-relative" OnClick="HandlebarsBolt.UpdateContent('ProductList_@relatedGroupId', '{{prevPage}}')" {{prevdisabled}}>
5472 <i class="fas fa-chevron-left fa-2x u-flex--align-center arrow-prev-page"></i>
5473 </button>
5474 </div>
5475 </div>
5476 <div class="grid__col-45px grid__col--bleed-x">
5477 <div class="grid__cell grid__cell--align-middle-right">
5478 <h4>{{currentPage}}/{{totalPages}}</h4>
5479 </div>
5480 </div>
5481 <div class="grid__col-45px grid__col--bleed-x">
5482 <div class="grid__cell grid__cell--align-middle-right">
5483 <button type="button" class="btn--condensed btn btn--clean dw-mod {{nextdisabled}} u-position-relative" OnClick="HandlebarsBolt.UpdateContent('ProductList_@relatedGroupId', '{{nextPage}}')" {{nextdisabled}}>
5484 <i class="fas fa-chevron-right fa-2x u-flex--align-center arrow-next-page"></i>
5485 </button>
5486 </div>
5487 </div>
5488 </div>
5489 {{/.}}
5490 </script>
5491
5492 <script id="StickersContainer" type="text/x-template">
5493 <div class="stickers-container stickers-container--{{{convertStickerPositionToClassName Position}}} dw-mod">
5494 {{#Stickers}}
5495 {{>Sticker}}
5496 {{/Stickers}}
5497 </div>
5498 </script>
5499
5500 <script id="Sticker" type="text/x-template">
5501 @Render(new Sticker { Title = "{{Title}}", CssClass = "{{CssClass}}" })
5502 </script>
5503 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
5504 @using Dynamicweb.Core
5505 @using System
5506 @using System.Web
5507 @using System.Collections.Generic
5508 @using Dynamicweb.Rapido.Blocks
5509 @using Dynamicweb.Rapido.Blocks.Components.General
5510 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce
5511 @using Dynamicweb.Rapido.Services
5512
5513 @functions {
5514 BlocksPage productVariantsListPage = BlocksPage.GetBlockPage("Product");
5515 Dictionary<string, object> variantListSettings = new Dictionary<string, object> {
5516 { "RenderVariantsAsProducts", false },
5517 { "RenderVariantGroupsInTable", false },
5518 { "HideImage", false },
5519 { "HideProductNumbers", false }
5520 };
5521 }
5522
5523 @{
5524 var variantsCount = GetInteger("Ecom:Product.VariantCount");
5525 string variantsListLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue : "Section";
5526 variantsListLayout = variantsListLayout == "Ribbon" ? "Section" : variantsListLayout;
5527
5528 //family members
5529 bool isFamilyMember = false;
5530 var variantGroups = GetLoop("VariantGroups");
5531 var variantGroupCount = variantGroups.Count;
5532 if (variantGroupCount == 1)
5533 {
5534 var firstVariantGroup = Dynamicweb.Ecommerce.Services.VariantGroups.GetVariantGroup(Dynamicweb.Ecommerce.Common.Context.LanguageID, variantGroups[0]?.GetString("Ecom:VariantGroup.ID"));
5535 if (firstVariantGroup != null)
5536 {
5537 isFamilyMember = firstVariantGroup.Family;
5538 }
5539 }
5540 if (isFamilyMember)
5541 {
5542 variantListSettings["RenderVariantsAsProducts"] = variantsCount > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderFamilyVariantsAsProducts");
5543 variantListSettings["RenderVariantGroupsInTable"] = false;
5544 variantListSettings["HideImage"] = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideImageForEachFamilyVariant");
5545 variantListSettings["HideProductNumbers"] = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideFamilyProductNumbers");
5546 }
5547 else
5548 {
5549 variantListSettings["RenderVariantsAsProducts"] = variantsCount > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList");
5550 variantListSettings["RenderVariantGroupsInTable"] = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantGroupsInTable");
5551 variantListSettings["HideImage"] = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideImageForEachVariant");
5552 variantListSettings["HideProductNumbers"] = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideProductNumbers");
5553 }
5554
5555 if (Converter.ToBoolean(variantListSettings["RenderVariantsAsProducts"]) && variantsListLayout != "hide" && (isFamilyMember || !isFamilyMember))
5556 {
5557 productVariantsListPage.Add(variantsListLayout, new Block
5558 {
5559 Name = variantsListLayout != "MainInformation" ? Translate("Variants list") : "",
5560 Id = "VariantsList",
5561 SortId = 20,
5562 Template = RenderVariantsProductList(variantsListLayout),
5563 Design = new Design
5564 {
5565 Size = "12",
5566 RenderType = RenderType.Column,
5567 HidePadding = true
5568 }
5569 });
5570
5571 productVariantsListPage.Add("Section", new Block
5572 {
5573 Id = "VariantListScripts",
5574 SortId = 100,
5575 Template = RenderVariantListScripts(),
5576 Design = new Design {}
5577 });
5578 }
5579 }
5580
5581 @helper RenderVariantsProductList(string layout)
5582 {
5583 string variantsListPageSize = HttpContext.Current.Request.QueryString.Get("PageSize") ?? "30";
5584 string variantsFeedUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + variantsListPageSize + "&MainProductID=" + GetString("Ecom:Product.ID") + "&OnlyShowVariants=true&feed=true";
5585 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
5586 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses;
5587 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : "";
5588
5589 <div class="product__section @ribbonClasses dw-mod">
5590 <div class="center-container @ribbonSubClasses dw-mod">
5591 @if (layout == "Section")
5592 {
5593 @Render(new Heading { Title = Translate("Variants"), Level = 2 })
5594 }
5595 <div class="js-handlebars-root" id="VariantsListRoot" data-template="VariantProductsContainer" data-json-feed="@variantsFeedUrl" data-preloader="minimal"></div>
5596 </div>
5597 </div>
5598 }
5599
5600 @helper RenderVariantListScripts()
5601 {
5602 bool showProductNumberForVariants = !Converter.ToBoolean(variantListSettings["HideProductNumbers"]);
5603 bool showImageForEachVariant = !Converter.ToBoolean(variantListSettings["HideImage"]);
5604 bool variantsPointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly");
5605 string variantsListPageSize = HttpContext.Current.Request.QueryString.Get("PageSize") ?? "30";
5606 string variantsFeedUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + variantsListPageSize + "&MainProductID=" + GetString("Ecom:Product.ID") + "&OnlyShowVariants=true&feed=true";
5607 string variantsCartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart";
5608
5609 <script id="VariantProductsContainer" type="text/x-template">
5610 {{#.}}
5611 <div>
5612 <table id="VariantsProductsContainer" class="table u-position-relative dw-mod">
5613 <thead>
5614 <tr>
5615 @if (showImageForEachVariant)
5616 {
5617 <td width="75"> </td>
5618 }
5619 <td>@Translate("Product")</td>
5620 {{#AvailableCustomFields}}
5621 {{>TableFieldNameTemplate}}
5622 {{/AvailableCustomFields}}
5623 @if (Converter.ToBoolean(variantListSettings["RenderVariantGroupsInTable"])) {
5624 foreach (LoopItem variantgroup in GetLoop("VariantGroups"))
5625 {
5626 <td>@variantgroup.GetString("Ecom:VariantGroup.Name")</td>
5627 }
5628 }
5629 <td> </td>
5630 </tr>
5631 </thead>
5632
5633 <tbody id="VariantProductListContainer" data-template="VariantProductItemContainer" data-save-cookie="true">
5634 {{#ProductsContainer}}
5635 {{>VariantProductItemContainer}}
5636 {{/ProductsContainer}}
5637 </tbody>
5638 </table>
5639 </div>
5640
5641 <div class="grid">
5642 <div class="grid__col-12 grid__col--bleed-y">
5643 @{
5644 Button moreButton = new Button { Id = "LoadMoreButton", ButtonLayout = ButtonLayout.Primary, CssClass = "btn--full {{nextdisabled}}", Title = Translate("Load") + " " + Translate("more"), OnClick = "LoadMore.Next(this)" };
5645 moreButton.ExtraAttributes.Add("data-current", "{{currentPage}}");
5646 moreButton.ExtraAttributes.Add("data-page-size", "{{pageSize}}");
5647 moreButton.ExtraAttributes.Add("data-total", "{{totalPages}}");
5648 moreButton.ExtraAttributes.Add("data-container", "VariantProductListContainer");
5649 moreButton.ExtraAttributes.Add("data-feed-url", variantsFeedUrl + "{{loadMoreFeedParams}}");
5650 moreButton.ExtraAttributes.Add("", "{{nextdisabled}}");
5651 }
5652 @Render(moreButton)
5653 </div>
5654 </div>
5655 {{/.}}
5656 </script>
5657
5658 <script id="VariantProductItemContainer" type="text/x-template">
5659 {{#.}}
5660 <tr id="VariantProduct{{id}}" class="js-product" data-template="VariantProductItem" data-preloader="overlay" style="z-index: {{zIndex}}">
5661 {{#Product}}
5662 {{>VariantProductItem}}
5663 {{/Product}}
5664 </tr>
5665 {{/.}}
5666 </script>
5667
5668 <script id="VariantProductItem" type="text/x-template">
5669 {{#.}}
5670 @if (showImageForEachVariant)
5671 {
5672 <td width="75">
5673 <div class="lightbox u-hidden-xxs">
5674 <a href="{{link}}" onclick="Scroll.SavePosition(event)" title="{{name}}{{#if variantName}}, {{variantName}}{{/if}}">
5675 <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}}" />
5676 <div class="u-margin-right {{noImage}}">
5677 <img src="/Admin/Public/GetImage.ashx?width=75&height=55&crop=5&FillCanvas=true&Compression=75&image={{image}}" alt="{{name}}{{#if variantName}}, {{variantName}}{{/if}}" />
5678 </div>
5679 </a>
5680 </div>
5681 </td>
5682 }
5683
5684 <td class="u-va-middle">
5685 <a href="{{link}}" onclick="Scroll.SavePosition(event)" title="{{name}}{{#if variantName}}, {{variantName}}{{/if}}">
5686 <h6 class="u-no-margin">{{name}}{{#if variantName}}, {{variantName}}{{/if}}</h6>
5687 </a>
5688 @if (showProductNumberForVariants)
5689 {
5690 <div class="item-number item-number--compressed u-margin-bottom dw-mod">
5691 <div>{{number}}</div>
5692 </div>
5693 }
5694 @if (User.IsStockInfoAllowed())
5695 {
5696 <text>{{#if stockText}}</text>
5697 <div class="item-number item-number--compressed dw-mod">
5698 <span>
5699 <span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span>
5700 <span class="u-margin-right--lg"> {{stockText}}</span>
5701 {{deliveryText}}
5702 </span>
5703 </div>
5704 <text>{{/if}}</text>
5705 }
5706 else
5707 {
5708 <div class="grid__cell-footer stickers-container stickers-container--block dw-mod">
5709 {{#Stickers}}
5710 {{>MiniSticker}}
5711 {{/Stickers}}
5712 </div>
5713 }
5714 </td>
5715 {{#CustomFields}}
5716 {{>TableFieldValueTemplate}}
5717 {{/CustomFields}}
5718 @if (Converter.ToBoolean(variantListSettings["RenderVariantGroupsInTable"]))
5719 {
5720 <text>
5721 {{#VariantSelectionNames}}
5722 {{>TableFieldNameTemplate}}
5723 {{/VariantSelectionNames}}
5724 </text>
5725 }
5726 <td class="u-va-middle">
5727 @if (Dynamicweb.Rapido.Services.User.IsPricesAllowed() && !Dynamicweb.Rapido.Services.User.IsBuyingAllowed())
5728 {
5729 <div class="u-hidden-sm">
5730 <div class="u-full-width u-ta-right u-padding-right">
5731 <div class="before-price {{onSale}} before-price--micro dw-mod">{{discount}}</div>
5732 <div class="price price--product-list price--micro dw-mod">{{price}}</div>
5733 </div>
5734 </div>
5735 }
5736
5737 <div class="grid grid--align-center grid--justify-end">
5738 <div class="u-margin-right u-hidden-xs u-hidden-xxs">
5739 @if (variantsPointShopOnly)
5740 {
5741 <text>
5742 {{#if canBePurchasedWithPoints}}
5743 <div class="price price--product-list price--micro dw-mod">{{points}} @Translate("points")</div>
5744 {{else}}
5745 {{#if havePointPrice}}
5746 <small class="help-text u-no-margin u-margin-top">@Translate("Not enough points to buy this")</small>
5747 {{else}}
5748 <small class="help-text u-no-margin u-margin-top">@Translate("Not available")</small>
5749 {{/if}}
5750 {{/if}}
5751 </text>
5752 }
5753 else if (Dynamicweb.Rapido.Services.User.IsPricesAllowed())
5754 {
5755 <div class="before-price before-price--micro {{onSale}} dw-mod">{{discount}}</div>
5756 <div class="price price--condensed price--product-list dw-mod">{{price}}</div>
5757 }
5758 </div>
5759
5760 @if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed())
5761 {
5762 var addToCartBtn = new AddToCart
5763 {
5764 AddButton = new AddToCartButton
5765 {
5766 HideTitle = true,
5767 ProductId = "{{productId}}",
5768 VariantId = "{{variantid}}",
5769 UnitId = "{{unitId}}",
5770 ProductInfo = "{{productInfo}}",
5771 BuyForPoints = variantsPointShopOnly,
5772 OnClick = "{{facebookPixelAction}}"
5773 },
5774 UnitSelector = new UnitSelector
5775 {
5776 OptionsContent = "{{#unitOptions}}{{>VariantUnitOption}}{{/unitOptions}}",
5777 Id = "UnitOptions_{{id}}",
5778 SelectedOption = "{{unitName}}",
5779 CssClass = "{{hasUnits}}"
5780 }
5781 };
5782
5783 if (!variantsPointShopOnly)
5784 {
5785 addToCartBtn.QuantitySelector = new QuantitySelector
5786 {
5787 Id = "Quantity_{{id}}"
5788 };
5789 }
5790
5791 <div class="grid__cell u-flex-grow--0">
5792 @Render(addToCartBtn)
5793 </div>
5794 }
5795 <div class="favorites u-margin-left dw-mod">
5796 {{#Favorite}}
5797 {{>FavoriteTemplate}}
5798 {{/Favorite}}
5799 </div>
5800 </div>
5801 </td>
5802 {{/.}}
5803 </script>
5804
5805 <script id="TableFieldNameTemplate" type="text/x-template">
5806 <td class="u-va-middle">{{name}}</td>
5807 </script>
5808
5809 <script id="TableFieldValueTemplate" type="text/x-template">
5810 <td class="u-va-middle">{{value}}</td>
5811 </script>
5812
5813 <script id="MiniSticker" type="text/x-template">
5814 <div class="stickers-container__tag stickers-container__tag--micro {{CssClass}} dw-mod">{{Title}}</div>
5815 </script>
5816
5817 <script id="VariantUnitOption" type="text/x-template">
5818 <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent(this.closest('.js-product').id, '{{link}}&feed=true&UnitID={{value}}')">{{name}}</div>
5819 </script>
5820 }
5821
5822
5823 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
5824 @using Dynamicweb.Core
5825 @using System
5826 @using System.Web
5827 @using System.Collections.Generic
5828 @using Dynamicweb.Rapido.Blocks
5829 @using Dynamicweb.Rapido.Blocks.Components.General
5830 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce
5831
5832 @functions {
5833 BlocksPage productVariantsMatrixPage = BlocksPage.GetBlockPage("Product");
5834 }
5835
5836
5837 @{
5838 var matrixLayoutSetting = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsMatrixLayout");
5839 string variantsMatrixLayout = matrixLayoutSetting != null && !string.IsNullOrEmpty(matrixLayoutSetting.SelectedValue) ? matrixLayoutSetting.SelectedValue : "Section";
5840 variantsMatrixLayout = variantsMatrixLayout == "Ribbon" ? "Section" : variantsMatrixLayout;
5841 bool renderVariantsAsMatrix = GetInteger("Ecom:Product.VariantCount") > 1 && variantsMatrixLayout.ToLower() != "hide" && Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("EnableVariantMatrix");
5842
5843 if (renderVariantsAsMatrix)
5844 {
5845 Block variantsMatrix = new Block()
5846 {
5847 Name = Translate("Variants"),
5848 Id = "VariantsMatrix",
5849 SortId = 15,
5850 Template = RenderVariantsMatrixSection(variantsMatrixLayout),
5851 Design = new Design
5852 {
5853 Size = "12",
5854 RenderType = RenderType.Column,
5855 HidePadding = true
5856 }
5857 };
5858
5859 if (variantsMatrixLayout == "Section") {
5860 productVariantsMatrixPage.Add(variantsMatrix);
5861 } else {
5862 productVariantsMatrixPage.Add(variantsMatrixLayout, variantsMatrix);
5863 }
5864 }
5865 }
5866
5867 @helper RenderVariantsMatrixSection(string layout)
5868 {
5869 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart";
5870 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "";
5871 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses;
5872 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : "";
5873
5874 List<LoopItem> variantInfos = GetLoop("VariantInfos");
5875 string productId = GetString("Ecom:Product.ID");
5876 string pageId = Pageview.Page.ID.ToString();
5877
5878
5879 <div class="product__section u-no-padding @ribbonClasses dw-mod">
5880 <div class="center-container @ribbonSubClasses dw-mod">
5881 @RenderVariantInfoMatrix(variantInfos, productId, pageId, 0, "add")
5882 </div>
5883 </div>
5884 }
5885
5886 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
5887 @using Dynamicweb.Rendering
5888 @using Dynamicweb.Core
5889 @using System
5890 @using System.Web
5891 @using System.Collections.Generic
5892 @using Dynamicweb.Rapido.Blocks
5893 @using Dynamicweb.Rapido.Blocks.Components
5894 @using Dynamicweb.Rapido.Blocks.Components.General
5895
5896
5897 @* Component - Variant Info Matrix. This replaces the old Variant Matrix with a much cleaner approach *@
5898
5899 @helper RenderVariantInfoMatrix(List<LoopItem> variantInfos, string productId, string pageId, double totalPrice = 0, string actionType = "update") {
5900 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart";
5901 bool hideAddToCartButton = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("hideAddToCartButton");
5902
5903 string currencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code;
5904 string countryCode = Pageview.Area.CultureInfo != null ? Pageview.Area.CultureInfo.Name : "en-US";
5905
5906 int loopCount = 0;
5907 int dimensionsCount = 0;
5908 bool firstRun = true;
5909 List<string> headerLabels = new List<string>();
5910
5911 //Collect the missing data needed to render matrixes
5912 foreach (var variantInfoFirst in variantInfos)
5913 {
5914 dimensionsCount = 1;
5915
5916 foreach (var variantInfoSecond in variantInfoFirst.GetLoop("VariantInfos"))
5917 {
5918 dimensionsCount = 2;
5919
5920 if (firstRun) {
5921 headerLabels.Add(variantInfoSecond.GetString("OptionName"));
5922 }
5923
5924 foreach (var variantInfoThird in variantInfoSecond.GetLoop("VariantInfos"))
5925 {
5926 dimensionsCount = 3;
5927 }
5928 }
5929
5930 firstRun = false;
5931 }
5932
5933 @*One dimension*@
5934 if (dimensionsCount == 1)
5935 {
5936 int totalQuantity = 0;
5937
5938 <table cellspacing="0" class="table matrix js-matrix dw-mod">
5939 <thead class="matrix__head dw-mod">
5940 <tr>
5941 @foreach (var variantInfoFirst in variantInfos)
5942 {
5943 <td class="u-bold u-ta-center" width="80" >
5944 <div>@variantInfoFirst.GetString("OptionName")</div>
5945 <small>@variantInfoFirst.GetString("VariantId")</small>
5946 </td>
5947 }
5948 <td width="80px" align="right" class="matrix-label-field-right dw-mod">@Translate("Totals")</td>
5949 <td> </td>
5950 </tr>
5951 </thead>
5952 <tbody>
5953 <tr>
5954 @foreach (var variantInfoFirst in variantInfos)
5955 {
5956 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;
5957
5958 loopCount++;
5959 totalQuantity += variantInfoFirst.GetInteger("Quantity");
5960
5961 <td class="matrix__input-cell dw-mod">
5962 @if (variantInfoFirst.GetBoolean("IsProduct"))
5963 {
5964 <input type="hidden" name="ProductLoopCounter@(loopCount)" value="@(loopCount)" />
5965 <input type="hidden" name="ProductID@(loopCount)" value="@productId" />
5966 <input type="hidden" name="VariantID@(loopCount)" value="@variantInfoFirst.GetString("VariantId")" />
5967 <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">
5968 } else {
5969 <div class="matrix__cell-disabled dw-mod"></div>
5970 }
5971 </td>
5972 }
5973 <td class="u-va-middle">
5974 <div class="u-bold u-ta-right matrix-label-field-right dw-mod" data-row-total="ONE">
5975 @totalQuantity
5976 </div>
5977 </td>
5978 <td class="u-bold u-va-middle u-ta-right matrix-label-field-right dw-mod">
5979 <div class="js-total-price" data-currency-code="@currencyCode" data-country-code="@countryCode"></div>
5980 </td>
5981 </tr>
5982 </tbody>
5983 <tfoot>
5984 <tr>
5985 <td colspan="@(variantInfos.Count + 2)"> </td>
5986 </tr>
5987 @if (!hideAddToCartButton)
5988 {
5989 <tr>
5990 <td colspan="@(variantInfos.Count + 2)" class="u-ta-right">
5991 <div class="u-padding--lg">
5992 @if (actionType == "update") {
5993 @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" })
5994 } else if (actionType == "justadd") {
5995 @Render(new Button { OnClick = "Matrix.AddToCart(this, '" + pageId + "');", Title = Translate("Add"), ButtonLayout = ButtonLayout.Tertiary, CssClass = "u-no-margin" })
5996 } else {
5997 @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" })
5998 }
5999 </div>
6000 </td>
6001 </tr>
6002 }
6003 </tfoot>
6004 </table>
6005 }
6006
6007 @*Two dimensions*@
6008 if (dimensionsCount == 2)
6009 {
6010 Dictionary<string, int> columnTotals = new Dictionary<string, int>();
6011 int counter = 0;
6012 int totalProducts = 0;
6013 int totalColumns = 0;
6014
6015 <table class="table matrix js-matrix dw-mod" cellspacing="0">
6016 <thead class="matrix__head dw-mod">
6017 <tr>
6018 <td width="160"> </td>
6019 @foreach (string label in headerLabels)
6020 {
6021 <td class="u-bold u-ta-center" width="80">@label</td>
6022 }
6023 <td align="right" width="80" class="matrix-label-field-right dw-mod">@Translate("Totals")</td>
6024 <td> </td>
6025 </tr>
6026 </thead>
6027 <tbody>
6028 @foreach (var variantInfoFirst in variantInfos)
6029 {
6030 int totalRowQuantity = 0;
6031 counter += variantInfoFirst.GetInteger("Quantity");
6032 totalColumns = variantInfoFirst.GetLoop("VariantInfos").Count;
6033
6034 <tr>
6035 <td class="matrix-label-field-left dw-mod">
6036 <div class="u-pull--left">
6037 <div>@variantInfoFirst.GetString("OptionName")</div>
6038 <small>@variantInfoFirst.GetString("VariantId")</small>
6039 </div>
6040
6041 @if (!string.IsNullOrEmpty(variantInfoFirst.GetString("Image"))) {
6042 <div class="matrix-option-image u-pull--right dw-mod" onclick="Matrix.ShowOptionImageModal(this)" data-img-src="/files/@variantInfoFirst.GetString("Image")">
6043 @Render(new Image {
6044 Path = variantInfoFirst.GetString("Image"),
6045 ImageDefault = new ImageSettings {
6046 Width = 28,
6047 Height = 28
6048 },
6049 ImageMedium = new ImageSettings {
6050 Width = 28,
6051 Height = 28
6052 },
6053 ImageSmall = new ImageSettings {
6054 Width = 28,
6055 Height = 28
6056 }
6057 })
6058 </div>
6059 }
6060 </td>
6061 @foreach (var variantInfoSecond in variantInfoFirst.GetLoop("VariantInfos"))
6062 {
6063 loopCount++;
6064 totalRowQuantity += variantInfoSecond.GetInteger("Quantity");
6065
6066 string optionName = variantInfoSecond.GetString("OptionName");
6067 int optionQuantity = variantInfoSecond.GetInteger("Quantity");
6068 if (columnTotals.ContainsKey(optionName)) {
6069 columnTotals[optionName] += optionQuantity;
6070 } else {
6071 columnTotals.Add(optionName, optionQuantity);
6072 }
6073
6074 <td class="matrix__input-cell dw-mod">
6075 @if (variantInfoSecond.GetBoolean("IsProduct")) {
6076 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;
6077
6078 <input type="hidden" name="ProductLoopCounter@(loopCount)" value="@(loopCount)" />
6079 <input type="hidden" name="ProductID@(loopCount)" value="@productId" />
6080 <input type="hidden" name="VariantID@(loopCount)" value="@variantInfoSecond.GetString("VariantId")" />
6081 <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")">
6082 } else {
6083 <div class="matrix__cell-disabled dw-mod"></div>
6084 }
6085 </td>
6086 }
6087 <td class="u-va-middle matrix-label-field-right dw-mod">
6088 <div class="u-bold u-ta-right" data-row-total="@variantInfoFirst.GetString("OptionName")">
6089 @totalRowQuantity
6090 </div>
6091 </td>
6092 <td> </td>
6093 </tr>
6094 }
6095 </tbody>
6096 <tfoot>
6097 <tr>
6098 <td class="u-bold u-va-middle matrix-label-field-left dw-mod">@Translate("Totals")</td>
6099 @foreach (var item in columnTotals)
6100 {
6101 totalProducts += item.Value;
6102
6103 <td>
6104 <div class="u-bold u-ta-center u-padding--lg" data-column-total="@item.Key">
6105 @item.Value
6106 </div>
6107 </td>
6108 }
6109 <td class="u-bold u-va-middle u-ta-right matrix-label-field-right dw-mod" align="right">
6110 <div class="js-total-quantity">@totalProducts</div>
6111 </td>
6112 <td class="u-bold u-va-middle u-ta-right matrix-label-field-right dw-mod">
6113 <div class="js-total-price" data-currency-code="@currencyCode" data-country-code="@countryCode"></div>
6114 </td>
6115 </tr>
6116 <tr>
6117 <td colspan="@(totalColumns + 4)" class="u-ta-right u-no-padding">
6118 <div class="u-padding--lg">
6119 @if (actionType == "update") {
6120 @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" })
6121 } else {
6122 @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" })
6123 }
6124 </div>
6125 </td>
6126 </tr>
6127 </tfoot>
6128 </table>
6129 }
6130
6131
6132 Modal optionColorImage = new Modal {
6133 Id = "OptionColorImage",
6134 BodyTemplate = @Render(new Image { Path = "/Files/Images/placeholder.gif", Id = "OptionColorImageElement", DisableImageEngine = true, DisableLazyLoad = true }),
6135 Width = ModalWidth.Full
6136 };
6137
6138 @Render(optionColorImage)
6139 }
6140 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
6141 @using Dynamicweb.Core
6142 @using System
6143 @using System.Web
6144 @using System.Collections.Generic
6145 @using Dynamicweb.Rapido.Blocks
6146 @functions {
6147 BlocksPage productSnippetsPage = BlocksPage.GetBlockPage("Product");
6148 }
6149
6150 @{
6151 Block googleProductSchema = new Block()
6152 {
6153 Id = "GoogleProductSchema",
6154 SortId = 10,
6155 Template = RenderGoogleProductSchema()
6156 };
6157
6158 productSnippetsPage.Add("Snippets", googleProductSchema);
6159 }
6160
6161 @helper RenderGoogleProductSchema()
6162 {
6163 var siteURL = Dynamicweb.Context.Current.Request.Url.Scheme + "://" + Dynamicweb.Context.Current.Request.Url.Host;
6164 var image = GetProductImage();
6165 var brand = GetString("Ecom:Product:Field.brand.Value");
6166 var variantid = !string.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) ? GetString("Ecom:Product.VariantID") : GetString("Ecom:Product.VariantID.Extented");
6167 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 : ""));
6168
6169 <script type="application/ld+json">
6170 {
6171 "@@context": "http://schema.org/",
6172 "@@type": "Product",
6173 "name": "@GetString("Ecom:Product.Name")",
6174 @if (!string.IsNullOrEmpty(image))
6175 {
6176 <text>"image": [
6177 "@siteURL/Admin/Public/GetImage.ashx?width=400&height=400&crop=0&Compression=75&DoNotUpscale=true&image=@image",
6178 "@siteURL/Admin/Public/GetImage.ashx?width=400&height=300&crop=0&Compression=75&DoNotUpscale=true&image=@image",
6179 "@siteURL/Admin/Public/GetImage.ashx?width=448&height=225&crop=0&Compression=75&DoNotUpscale=true&image=@image"
6180 ],</text>
6181 }
6182 "description": "@GetString("Ecom:Product.ShortDescription")",
6183 "mpn": "925872",
6184 @if (!string.IsNullOrEmpty(brand))
6185 {
6186 <text>"brand": {
6187 "@@type": "Thing",
6188 "name": "@brand"
6189 },</text>
6190 }
6191 "offers": {
6192 "@@type": "Offer",
6193 "priceCurrency": "@GetString("Ecom:Product.Price.Currency.Code")",
6194 "price": "@GetString("Ecom:Product.Price.Price")",
6195 "availability": "@(GetInteger("Ecom:Product.Stock") > 0 ? "InStock" : "OutOfStock")",
6196 "url": "@url"
6197 }
6198 }
6199 </script>
6200 }
6201
6202 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
6203
6204 @using System.Globalization
6205 @using Dynamicweb.Rapido.Blocks
6206 @using Dynamicweb.Rapido.Blocks.Components.General
6207
6208 @functions {
6209 BlocksPage snippetsTemplatesPage = BlocksPage.GetBlockPage("Product");
6210 }
6211
6212 @{
6213 snippetsTemplatesPage.Add(new Block {
6214 Id = "FavoritesTemplates",
6215 SortId = 100,
6216 Template = RenderFavoritesTemplates()
6217 });
6218 }
6219
6220 @helper RenderFavoritesTemplates()
6221 {
6222 var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star";
6223 string favoriteIcon = "fas fa-" + selectedFavoriteIcon;
6224 string favoriteOutlineIcon = "fal fa-" + selectedFavoriteIcon;
6225 bool useFacebookPixel = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("FacebookPixelID"));
6226 string currentFavoriteListId = HttpContext.Current.Request.QueryString.Get("ListID");
6227 string host = HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host;
6228
6229 // Klaviyo "Viewed Product" tracker event
6230 <script type="text/javascript">
6231 var _learnq = _learnq || [];
6232 var item = {
6233 "ProductName": "@GetString("Ecom:Product.Name")",
6234 "ProductID": "@GetString("Ecom:Product.ID")",
6235 "SKU": "@GetString("Ecom:Product.Number")",
6236 "Categories": ["@GetString("Ecom:Group.Name")"],
6237 "ImageURL": "@GetString("Ecom:Product.ImageDefault")",
6238 "URL": "@host@Pageview.SearchFriendlyUrl",
6239 "Price": @Convert.ToDecimal(GetDouble("Ecom:Product.Price.Price")).ToString("F", CultureInfo.GetCultureInfo("en-US"))
6240 };
6241 _learnq.push(["track", "Viewed Product", item]);
6242 </script>
6243
6244 <script id="FavoriteTemplate" type="text/x-template">
6245 <div class="favorites-list u-ta-left js-favorites-list">
6246 @Render(new Button {
6247 CssClass = "u-no-margin js-favorite-btn",
6248 Icon = new Icon
6249 {
6250 Name = "{{#if isInAnyFavoriteList}}" + favoriteIcon + "{{else}}" + favoriteOutlineIcon + "{{/if}}",
6251 CssClass = "fa-1_5x",
6252 LabelPosition = IconLabelPosition.After
6253 },
6254 ButtonLayout = ButtonLayout.LinkClean,
6255 ButtonType = ButtonType.Button,
6256 OnClick = "document.getElementById('FavoriteTrigger_{{id}}').checked = true"
6257 })
6258 <input type="checkbox" id="FavoriteTrigger_{{id}}" class="dropdown-trigger" />
6259 <div class="dropdown dropdown--position-32px">
6260 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod">
6261 <ul class="list list--clean dw-mod">
6262 {{#FavoriteLists}}
6263 {{>FavoriteListItem}}
6264 {{/FavoriteLists}}
6265 </ul>
6266 </div>
6267 <label class="dropdown-trigger-off" for="FavoriteTrigger_{{id}}"></label>
6268 </div>
6269 </div>
6270 </script>
6271
6272 <script id="FavoriteListItem" type="text/x-template">
6273 <li>
6274 @{
6275 var button = new Button {
6276 CssClass = "list__link u-no-underline",
6277 OnClick = "toggleFavAction(this, event)",
6278 Icon = new Icon { Name = "{{#if isInFavoriteList}}" + favoriteIcon + "{{else}}" + favoriteOutlineIcon + "{{/if}}", LabelPosition = IconLabelPosition.After },
6279 AltText = "{{#if isInFavoriteList}}" + Translate("Remove from") + " {{name}}{{else}}" + Translate("Add to") + " {{name}}{{/if}}",
6280 Title = "{{name}}",
6281 ButtonType = ButtonType.Button,
6282 ButtonLayout = ButtonLayout.LinkClean,
6283 ExtraAttributes = new Dictionary<string, string>
6284 {
6285 { "data-list-id", "{{listId}}" },
6286 { "data-list-name", "{{name}}" },
6287 { "data-remove-link", "{{removeLink}}" },
6288 { "data-add-link", "{{addLink}}" },
6289 { "data-is-in-list", "{{isInFavoriteList}}" },
6290
6291 }
6292 };
6293 if (useFacebookPixel)
6294 {
6295 button.ExtraAttributes.Add("data-facebook-object", "{{facebookPixelAddAction}}");
6296 }
6297 }
6298 <div class="grid__cell">
6299 @Render(button)
6300 </div>
6301 </li>
6302 </script>
6303
6304 <script>
6305 @if (!string.IsNullOrEmpty(currentFavoriteListId))
6306 {
6307 <text>
6308 window.currentFavoriteListId = "@currentFavoriteListId";
6309 </text>
6310 }
6311 function toggleFavAction(button, event) {
6312 if (button.getAttribute('data-add-link').indexOf('CCCreateNewList') > -1) {
6313 Scroll.SavePosition(event);
6314 @if (useFacebookPixel)
6315 {
6316 <text>
6317 fbq('track', 'AddToWishlist', JSON.parse(button.getAttribute('data-facebook-object')));
6318 </text>
6319 }
6320 location.href = button.getAttribute('data-add-link');
6321 return;
6322 }
6323 let isAdd = button.getAttribute('data-is-in-list') == "false";
6324 Request.Fetch().get(
6325 isAdd ? button.getAttribute('data-add-link') : button.getAttribute('data-remove-link'),
6326 function (result) {
6327 button.querySelector('i').className = isAdd ? '@favoriteIcon u-margin-right--lg' : '@favoriteOutlineIcon u-margin-right--lg';
6328 button.setAttribute('data-is-in-list', isAdd);
6329 button.setAttribute('title', (!isAdd ? '@Translate("Add to") ' : '@Translate("Remove from") ') + button.getAttribute('data-list-name'))
6330 let favList = button.closest('.js-favorites-list');
6331 let favBtn = favList.querySelector('.js-favorite-btn i');
6332 let isInAnyFavoriteList = favList.querySelector('[data-is-in-list=true]') != null;
6333 if (isInAnyFavoriteList) {
6334 favBtn.className = '@favoriteIcon' + ' fa-1_5x';
6335 } else {
6336 favBtn.className = '@favoriteOutlineIcon' + ' fa-1_5x';
6337 }
6338 @if (useFacebookPixel)
6339 {
6340 <text>
6341 if (isAdd) {
6342 fbq('track', 'AddToWishlist', JSON.parse(button.getAttribute('data-facebook-object')));
6343 }
6344 </text>
6345 }
6346 if (window.currentFavoriteListId != null) { //if this page is favorite list
6347 let listId = button.getAttribute("data-list-id");
6348 if (listId == window.currentFavoriteListId && !isAdd) {
6349 location.reload();
6350 }
6351 }
6352 },
6353 function () {
6354 console.error("FavoriteLists: Error in ToggleFavAction request");
6355 },
6356 false
6357 );
6358 }
6359 </script>
6360 }
6361 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
6362 @using Dynamicweb.Core
6363 @using System
6364 @using System.Web
6365 @using System.Collections.Generic
6366 @using Dynamicweb.Rapido.Blocks
6367
6368 @{
6369 BlocksPage customProductBlocks = BlocksPage.GetBlockPage("Product");
6370
6371 }
6372 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
6373 @using Dynamicweb.Core
6374 @using System
6375 @using System.Web
6376 @using System.Collections.Generic
6377 @using Dynamicweb.Rapido.Blocks
6378 @using Dynamicweb.Rapido.Blocks.Components.General
6379 @using System.Linq;
6380
6381 @functions {
6382 BlocksPage productCompaniesPage = BlocksPage.GetBlockPage("Product");
6383 }
6384
6385 @{
6386 string productCompanies = "Section";
6387
6388 Block productsCompaniesBlock = new Block()
6389 {
6390 Name = productCompanies,
6391 Id = "productCompanies",
6392 SortId = 29,
6393 Template = RenderCompanies(),
6394 Design = new Design
6395 {
6396 Size = "12",
6397 RenderType = RenderType.Column,
6398 HidePadding = true
6399 }
6400 };
6401 productCompaniesPage.Add(productCompanies, productsCompaniesBlock);
6402
6403 }
6404
6405 <link rel="stylesheet" href="/Files/Templates/Designs/Rapido/node_modules/swiper/swiper-bundle.min.css">
6406 <script src="/Files/Templates/Designs/Rapido/node_modules/swiper/swiper-bundle.min.js"></script>
6407 <script>
6408
6409 document.addEventListener('DOMContentLoaded', function() {
6410
6411 var weDeliverTo = new Swiper('.weDeliverToSlider', {
6412 loop: true,
6413 slidesPerView: 4,
6414 allowTouchMove: false,
6415 autoplay: {
6416 delay: 0,
6417 disableOnInteraction: false,
6418 },
6419 spaceBetween: 50,
6420 speed: 3500,
6421 breakpoints: {
6422 // when window width is >= 320px
6423 320: {
6424 slidesPerView: 2,
6425 spaceBetween: 50
6426 },
6427 // when window width is >= 480px
6428 480: {
6429 slidesPerView: 3,
6430 spaceBetween: 50
6431 },
6432
6433 1040: {
6434 slidesPerView: 4,
6435 spaceBetween: 50
6436 }
6437 }
6438
6439 });
6440 });
6441
6442 </script>
6443
6444 @helper RenderCompanies()
6445 {
6446
6447 if (!string.IsNullOrEmpty(GetString("Ecom:Product:Field.WeDeliverTo.Value.FullPath")))
6448 {
6449 string tableWidth = "grid__col-md-6";
6450
6451 <div class="center-container dw-mod">
6452 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12 companies">
6453 <div class="companies__header">@Translate("We deliver to")</div>
6454 <div class="weDeliverToSlider">
6455
6456 @{
6457 List<string> weDeliverToPaths = GetString("Ecom:Product:Field.WeDeliverTo.Value.FullPath").Split(',').ToList();
6458 }
6459
6460 <div class="swiper-wrapper">
6461 @{
6462
6463 foreach(string path in weDeliverToPaths)
6464 {
6465 string fileName = Path.GetFileNameWithoutExtension(path);
6466 <div class="swiper-slide">
6467 <img src="@path" alt="@fileName" />
6468 </div>
6469 }
6470 }
6471
6472 </div>
6473 </div>
6474 </div>
6475 </div>
6476 }
6477
6478 }
6479 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
6480 @using Dynamicweb.Core
6481 @using System
6482 @using System.Web
6483 @using System.Collections.Generic
6484 @using Dynamicweb.Rapido.Blocks
6485 @using Dynamicweb.Rapido.Blocks.Components.General
6486 @using System.Linq;
6487
6488 @functions {
6489 BlocksPage productTrustpilotPage = BlocksPage.GetBlockPage("Product");
6490 }
6491
6492 @{
6493 string productTrustpilot = "Section";
6494
6495 Block productsTrustpilotBlock = new Block()
6496 {
6497 Name = productTrustpilot,
6498 Id = "productTrustpilot",
6499 SortId = 31,
6500 Template = RenderTrustPilot(),
6501 Design = new Design
6502 {
6503 Size = "12",
6504 RenderType = RenderType.Column,
6505 HidePadding = true
6506 }
6507 };
6508 productTrustpilotPage.Add(productTrustpilot, productsTrustpilotBlock);
6509 }
6510
6511 <link rel="stylesheet" href="/Files/Templates/Designs/Rapido/node_modules/swiper/swiper-bundle.min.css">
6512 <script src="/Files/Templates/Designs/Rapido/node_modules/swiper/swiper-bundle.min.js"></script>
6513 <script>
6514 document.addEventListener('DOMContentLoaded', function() {
6515 var trustpilotSlider = new Swiper('.trustpilotSlider', {
6516 loop: true,
6517 slidesPerView: 5,
6518 allowTouchMove: false,
6519 autoplay: {
6520 delay: 0,
6521 disableOnInteraction: false,
6522 },
6523 spaceBetween: 25,
6524 speed: 3500,
6525 breakpoints: {
6526 // when window width is >= 320px
6527 320: {
6528 slidesPerView: 2,
6529 spaceBetween: 25
6530 },
6531 // when window width is >= 480px
6532 480: {
6533 slidesPerView: 2,
6534 spaceBetween: 25
6535 },
6536 1040: {
6537 slidesPerView: 3,
6538 spaceBetween: 25
6539 },
6540 1500: {
6541 slidesPerView: 5,
6542 spaceBetween: 25
6543 }
6544 }
6545 });
6546 });
6547 </script>
6548
6549
6550 @helper RenderTrustPilot()
6551 {
6552
6553 if(Pageview.Area.Item["TPImages"] == null)
6554 {
6555 return;
6556 }
6557
6558 int itemListRelationId = (int)Pageview.Area.Item["TPImages"];
6559 var images = Dynamicweb.Content.Items.ItemList.GetItemListById(itemListRelationId).Relations.ToList();
6560 bool showTrustpilotSlider = GetBoolean("Ecom:Product:Field.ShowTrustpilotSlider");
6561
6562 if (images != null && images.Count > 0 && showTrustpilotSlider)
6563 {
6564 string tableWidth = "grid__col-md-12";
6565
6566 <div class="center-container dw-mod">
6567 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12 trustpilot">
6568 <div class="trustpilot__header">
6569 @Pageview.Area.Item["TPHeader"]
6570 </div>
6571 <div class="trustpilotSlider">
6572 <div class="swiper-wrapper">
6573 @{
6574 foreach(Dynamicweb.Content.Items.Item image in images)
6575 {
6576 string imagePath = (string)image["ImagePath"];
6577 string fileName = Path.GetFileNameWithoutExtension(imagePath);
6578
6579 <div class="swiper-slide">
6580 <img src="@imagePath" alt="@fileName" />
6581 </div>
6582
6583 }
6584 }
6585 </div>
6586 </div>
6587 <div class="trustpilot__text">
6588 @Pageview.Area.Item["TPText"]
6589 </div>
6590 <div class="trustpilot__logo-container">
6591 <img class="trustpilot__logo-container__image" style="width: 19px" src="\Files\Images\Trustpilot\tplogo.png"/>
6592 <div class="trustpilot__logo-container__text">Trustpilot</div>
6593 </div>
6594 </div>
6595 </div>
6596 }
6597 }
6598 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
6599 @using Dynamicweb.Core
6600 @using System
6601 @using System.Web
6602 @using System.Collections.Generic
6603 @using Dynamicweb.Rapido.Blocks
6604 @using Dynamicweb.Rapido.Blocks.Components.General
6605 @using System.Linq;
6606
6607 @functions {
6608 BlocksPage productVideoPage2 = BlocksPage.GetBlockPage("Product");
6609 }
6610
6611 @{
6612 string productVideo = "Section";
6613
6614 Block productVideoBlock = new Block()
6615 {
6616 Name = productVideo,
6617 Id = "productVideo",
6618 SortId = 29,
6619 Template = RenderProductVideo(),
6620 Design = new Design
6621 {
6622 Size = "12",
6623 RenderType = RenderType.Column,
6624 HidePadding = true
6625 }
6626 };
6627 productVideoPage2.Add(productVideo, productVideoBlock);
6628 }
6629
6630 @helper RenderProductVideo()
6631 {
6632
6633 string videoPath = GetString("Ecom:Product:Field.Video.FullPath");
6634
6635 if (!string.IsNullOrEmpty(videoPath))
6636 {
6637 videoPath += "#t=0.001";
6638 string tableWidth = "grid__col-md-6";
6639 <div class="center-container dw-mod">
6640 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12 " style="padding: 0;">
6641 <video class="" controls="" muted="" playsinline="" disablepictureinpicture="" width="1920" height="auto">
6642 <source src="@videoPath" type="video/mp4">
6643 </video>
6644 </div>
6645 </div>
6646 }
6647 }
6648
6649
6650 <div class="nc-product marble-white-section js-product">
6651 <div class="grid">
6652 @* The @RenderBlockList base helper is included in Components/GridBuilder.cshtml *@
6653 @RenderBlockList(productsPage.BlocksRoot.BlocksList)
6654 </div>
6655 </div>
6656
6657 @helper RenderProductTop()
6658 {
6659 List<Block> subBlocks = productsPage.GetBlockListById("Top").OrderBy(item => item.SortId).ToList();
6660
6661 <div class="nc-product__top">
6662 <div class="nc-product__top-grid grid">
6663 @RenderBlockList(subBlocks)
6664 </div>
6665 </div>
6666 }
6667
6668 @helper RenderProductMiniTabs()
6669 {
6670 List<Block> subBlocks = productsPage.GetBlockListById("MiniTabs").OrderBy(item => item.SortId).ToList();
6671
6672 if (subBlocks.Count > 0)
6673 {
6674 <div class="grid__col-12 product__info tabs u-no-padding u-margin-bottom--lg dw-mod">
6675 @{
6676 bool firstTab = true;
6677 foreach (Block item in subBlocks)
6678 {
6679 string isChecked = firstTab ? "checked" : "";
6680 firstTab = false;
6681
6682 <input type="radio" class="tabs__trigger" name="productMiniTabs" id="@item.Id" onchange="bLazy.revalidate()" @isChecked />
6683 }
6684 }
6685
6686 <div class="tabs__list dw-mod">
6687 @foreach (Block item in subBlocks)
6688 {
6689 <label for="@item.Id" class="tabs__label dw-mod">@item.Name</label>
6690 }
6691 </div>
6692
6693 <div class="tabs__blocks dw-mod">
6694 @foreach (Block item in subBlocks)
6695 {
6696 string hidePadding = item.Design.HidePadding ? "u-no-padding" : "";
6697
6698 if (item.Design.RenderType != RenderType.Hide)
6699 {
6700 <div class="tabs__block u-border dw-mod" id="Block__@item.Id">
6701 <block class="product__block paragraph-container product__block--bordered dw-mod">
6702 <div class="center-container dw-mod">
6703 @RenderBlock(item)
6704 </div>
6705 </block>
6706 </div>
6707 }
6708 }
6709 </div>
6710 </div>
6711 }
6712 }
6713
6714 @helper RenderProductTabs()
6715 {
6716 List<Block> subBlocks = productsPage.GetBlockListById("Tabs").OrderBy(item => item.SortId).ToList();
6717
6718 if (Pageview.Device.ToString() != "Mobile") {
6719 <div class="grid__col-12 product__info product__info--tabs tabs dw-mod">
6720 @{
6721 bool firstTab = true;
6722 foreach (Block item in subBlocks)
6723 {
6724 string isChecked = firstTab ? "checked" : "";
6725 firstTab = false;
6726
6727 <input type="radio" class="tabs__trigger" name="productTabs" id="@item.Id" onchange="bLazy.revalidate()" @isChecked />
6728 }
6729 }
6730
6731 <div class="tabs__list dw-mod">
6732 @foreach (Block item in subBlocks)
6733 {
6734 if (item.Design.RenderType != RenderType.Hide)
6735 {
6736 <label for="@item.Id" class="tabs__label dw-mod">@item.Name</label>
6737 }
6738 }
6739 </div>
6740
6741 <div class="tabs__blocks dw-mod">
6742 @foreach (Block item in subBlocks)
6743 {
6744 if (item.Design.RenderType != RenderType.Hide)
6745 {
6746 <div class="tabs__block dw-mod" id="Block__@item.Id">
6747 <section class="product__section paragraph-container paragraph-container--full-width product__section--bordered dw-mod">
6748 <div class="center-container u-padding--lg dw-mod">
6749 @RenderBlock(item)
6750 </div>
6751 </section>
6752 </div>
6753 }
6754 }
6755 </div>
6756 </div>
6757 <div class="product-overlay-overlap"> </div>
6758
6759
6760 } else {
6761 foreach (Block item in subBlocks)
6762 {
6763 if (item.Design.RenderType != RenderType.Hide)
6764 {
6765 <div class="center-container dw-mod">
6766 <div class="padding-position-left padding-size-sm">
6767 @Render(new Heading { Title = item.Name, Level = 2 })
6768 </div>
6769
6770 @RenderBlock(item)
6771 </div>
6772 }
6773 }
6774 }
6775 }