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