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("&nbsp;", " "); 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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</td> 2331 </tr> 2332 </tbody> 2333 } 2334 @if (groupCount == 3) 2335 { 2336 <thead> 2337 <tr> 2338 <td>&nbsp;</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>&nbsp;</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>&nbsp;</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&amp;height=800&amp;crop=5&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;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">&nbsp;</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>&nbsp;</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&amp;height=220&amp;crop=5&amp;Compression=75&amp;image={{image}}" alt="{{name}}{{#if variantName}}, {{variantName}}{{/if}}" /> 4961 <div class="u-margin-right {{noImage}}"> 4962 <img src="/Admin/Public/GetImage.ashx?width=75&amp;height=55&amp;crop=5&FillCanvas=true&amp;Compression=75&amp;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>&nbsp;</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)">&nbsp;</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">&nbsp;</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>&nbsp;</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>&nbsp;</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 }