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