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