Error executing template "Designs/Rapido/eCom/Productlist/ProductsRender.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_995b92dc95af4ee7ac2643572ef52735.<RenderListActionsCustom>b__219_0(TextWriter __razor_helper_writer) in F:\Domains\Sites\wineb2b.mydwsite4.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 7847
   at RazorEngine.Templating.TemplateWriter.ToString()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_995b92dc95af4ee7ac2643572ef52735.<>c__DisplayClass6_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in F:\Domains\Sites\wineb2b.mydwsite4.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 220
   at CompiledRazorTemplates.Dynamic.RazorEngine_995b92dc95af4ee7ac2643572ef52735.<>c__DisplayClass5_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in F:\Domains\Sites\wineb2b.mydwsite4.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 136
   at CompiledRazorTemplates.Dynamic.RazorEngine_995b92dc95af4ee7ac2643572ef52735.<RenderProductListHeader>b__222_0(TextWriter __razor_helper_writer) in F:\Domains\Sites\wineb2b.mydwsite4.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 7989
   at RazorEngine.Templating.TemplateWriter.ToString()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_995b92dc95af4ee7ac2643572ef52735.<>c__DisplayClass6_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in F:\Domains\Sites\wineb2b.mydwsite4.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 220
   at CompiledRazorTemplates.Dynamic.RazorEngine_995b92dc95af4ee7ac2643572ef52735.<>c__DisplayClass5_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in F:\Domains\Sites\wineb2b.mydwsite4.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 130
   at CompiledRazorTemplates.Dynamic.RazorEngine_995b92dc95af4ee7ac2643572ef52735.<RenderPageContainer>b__220_0(TextWriter __razor_helper_writer) in F:\Domains\Sites\wineb2b.mydwsite4.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 7952
   at RazorEngine.Templating.TemplateWriter.ToString()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_995b92dc95af4ee7ac2643572ef52735.<>c__DisplayClass6_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in F:\Domains\Sites\wineb2b.mydwsite4.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 220
   at CompiledRazorTemplates.Dynamic.RazorEngine_995b92dc95af4ee7ac2643572ef52735.<>c__DisplayClass5_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in F:\Domains\Sites\wineb2b.mydwsite4.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 130
   at CompiledRazorTemplates.Dynamic.RazorEngine_995b92dc95af4ee7ac2643572ef52735.Execute() in F:\Domains\Sites\wineb2b.mydwsite4.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 7928
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2 @using Dynamicweb.Frontend.Devices 3 @using Dynamicweb.Extensibility 4 @using Dynamicweb.Content 5 @using Dynamicweb.Core 6 @using System 7 @using System.IO 8 @using System.Web 9 @using System.Collections.Generic; 10 @using System.Linq 11 @using System.Text.RegularExpressions 12 @using Dynamicweb.Rapido.Blocks 13 @using Dynamicweb.Rapido.Blocks.Components.General 14 @using Dynamicweb.Ecommerce.Products; 15 16 @functions { 17 BlocksPage productListPage = BlocksPage.GetBlockPage("ProductList"); 18 Dynamicweb.Frontend.ItemViewModel productListSettings = null; 19 20 string favoriteListId = HttpContext.Current.Request.QueryString.Get("ListID"); 21 bool isFavoriteList = !string.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("ListID")); 22 bool isLiveProductInfoActive; 23 } 24 25 @{ 26 productListSettings = Pageview.AreaSettings.GetItem("ProductList"); 27 isLiveProductInfoActive = Converter.ToBoolean(GetGlobalValue("Global:LiveIntegration.IsLazyLoadingForProductInfoEnabled")); 28 Block pageContainer = new Block() 29 { 30 Id = "PageContainer", 31 Template = RenderPageContainer(), 32 SkipRenderBlocksList = true, 33 BlocksList = new List<Block> { 34 new Block 35 { 36 Id = "ProductListHeader", 37 SortId = 10, 38 Template = RenderProductListHeader(), 39 SkipRenderBlocksList = true, 40 BlocksList = new List<Block> { 41 new Block 42 { 43 Id = "ProductListTitle", 44 SortId = 10, 45 Design = new Design 46 { 47 CssClass = isFavoriteList ? "grid__col-sm-4" : "grid__col-sm-6" 48 }, 49 Template = RenderProductListTitle() 50 } 51 } 52 } 53 } 54 }; 55 productListPage.Add(pageContainer); 56 57 Block productListNavigation = new Block() 58 { 59 Id = "Navigation", 60 SortId = 20, 61 Design = new Design 62 { 63 RenderType = RenderType.Column, 64 Size = "3" 65 } 66 }; 67 productListPage.Add("PageContainer", productListNavigation); 68 69 Block productListContainer = new Block() 70 { 71 Id = "ProductList", 72 SortId = 30, 73 Template = RenderProductList(), 74 SkipRenderBlocksList = true 75 }; 76 productListPage.Add("PageContainer", productListContainer); 77 78 if (isFavoriteList) 79 { 80 productListPage.Add("ProductListHeader", new Block 81 { 82 Id = "FavoriteListSearch", 83 SortId = 20, 84 Template = RenderFavoriteListSearch(), 85 Design = new Design 86 { 87 CssClass = "grid__col-sm-4 u-margin-bottom u-margin-top grid--align-self-center" 88 } 89 }); 90 } 91 92 Block productListSnippets = new Block() 93 { 94 Id = "BottomSnippets", 95 SortId = 40 96 }; 97 productListPage.Add(productListSnippets); 98 } 99 100 @* This is required for the product list feed to work *@ 101 @GetValue("DoNotRenderProductListTemplate") 102 103 @* Include the required Grid builder (Contains the methods @RenderBlockList and @RenderBlock) *@ 104 @using System.Text.RegularExpressions 105 @using System.Collections.Generic 106 @using System.Reflection 107 @using System.Web 108 @using System.Web.UI.HtmlControls 109 @using Dynamicweb.Rapido.Blocks.Components 110 @using Dynamicweb.Rapido.Blocks.Components.Articles 111 @using Dynamicweb.Rapido.Blocks.Components.Documentation 112 @using Dynamicweb.Rapido.Blocks 113 114 115 @*--- START: Base block renderers ---*@ 116 117 @helper RenderBlockList(List<Block> blocks) 118 { 119 bool debug = !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("debug")) ? Convert.ToBoolean(HttpContext.Current.Request.QueryString.Get("debug")) : false; 120 blocks = blocks.OrderBy(item => item.SortId).ToList(); 121 122 foreach (Block item in blocks) 123 { 124 if (debug) { 125 <!-- Block START: @item.Id --> 126 } 127 128 if (item.Design == null) 129 { 130 @RenderBlock(item) 131 } 132 else if (item.Design.RenderType == RenderType.None) { 133 string cssClass = item.Design.CssClass != null ? item.Design.CssClass : ""; 134 135 <div class="@cssClass dw-mod"> 136 @RenderBlock(item) 137 </div> 138 } 139 else if (item.Design.RenderType != RenderType.Hide) 140 { 141 string cssClass = item.Design.CssClass != null ? item.Design.CssClass : ""; 142 143 if (!item.SkipRenderBlocksList) { 144 if (item.Design.RenderType == RenderType.Row) 145 { 146 <div class="grid grid--align-content-start @cssClass dw-mod" id="Block__@item.Id"> 147 @RenderBlock(item) 148 </div> 149 } 150 151 if (item.Design.RenderType == RenderType.Column) 152 { 153 string hidePadding = item.Design.HidePadding ? "u-no-padding" : ""; 154 string size = item.Design.Size ?? "12"; 155 size = Regex.IsMatch(size, @"\d") ? "md-" + item.Design.Size : item.Design.Size; 156 157 <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"> 158 @RenderBlock(item) 159 </div> 160 } 161 162 if (item.Design.RenderType == RenderType.Table) 163 { 164 <table class="table @cssClass dw-mod" id="Block__@item.Id"> 165 @RenderBlock(item) 166 </table> 167 } 168 169 if (item.Design.RenderType == RenderType.TableRow) 170 { 171 <tr class="@cssClass dw-mod" id="Block__@item.Id"> 172 @RenderBlock(item) 173 </tr> 174 } 175 176 if (item.Design.RenderType == RenderType.TableColumn) 177 { 178 <td class="@cssClass dw-mod" id="Block__@item.Id"> 179 @RenderBlock(item) 180 </td> 181 } 182 183 if (item.Design.RenderType == RenderType.CardHeader) 184 { 185 <div class="card-header @cssClass dw-mod"> 186 @RenderBlock(item) 187 </div> 188 } 189 190 if (item.Design.RenderType == RenderType.CardBody) 191 { 192 <div class="card @cssClass dw-mod"> 193 @RenderBlock(item) 194 </div> 195 } 196 197 if (item.Design.RenderType == RenderType.CardFooter) 198 { 199 <div class="card-footer @cssClass dw-mod"> 200 @RenderBlock(item) 201 </div> 202 } 203 } 204 else 205 { 206 @RenderBlock(item) 207 } 208 } 209 210 if (debug) { 211 <!-- Block END: @item.Id --> 212 } 213 } 214 } 215 216 @helper RenderBlock(Block item) 217 { 218 bool debug = !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("debug")) ? Convert.ToBoolean(HttpContext.Current.Request.QueryString.Get("debug")) : false; 219 220 if (item.Template != null) 221 { 222 @BlocksPage.RenderTemplate(item.Template) 223 } 224 225 if (item.Component != null) 226 { 227 string customSufix = "Custom"; 228 string methodName = item.Component.HelperName; 229 230 ComponentBase[] methodParameters = new ComponentBase[1]; 231 methodParameters[0] = item.Component; 232 Type methodType = this.GetType(); 233 234 MethodInfo customMethod = methodType.GetMethod(methodName + customSufix); 235 MethodInfo generalMethod = methodType.GetMethod(methodName); 236 237 try { 238 if (debug) { 239 <!-- Component: @methodName.Replace("Render", "") --> 240 } 241 @customMethod.Invoke(this, methodParameters).ToString(); 242 } catch { 243 try { 244 @generalMethod.Invoke(this, methodParameters).ToString(); 245 } catch(Exception ex) { 246 throw new Exception(item.Component.GetType().Name + " method '" + methodName +"' could not be invoked", ex); 247 } 248 } 249 } 250 251 if (item.BlocksList.Count > 0 && !item.SkipRenderBlocksList) 252 { 253 @RenderBlockList(item.BlocksList) 254 } 255 } 256 257 @*--- END: Base block renderers ---*@ 258 259 @using Dynamicweb.Rapido.Blocks.Components 260 @using Dynamicweb.Rapido.Blocks.Components.General 261 @using Dynamicweb.Rapido.Blocks 262 @using System.IO 263 264 @* Required *@ 265 @using Dynamicweb.Rapido.Blocks.Components 266 @using Dynamicweb.Rapido.Blocks.Components.General 267 @using Dynamicweb.Rapido.Blocks 268 269 270 @helper Render(ComponentBase component) 271 { 272 if (component != null) 273 { 274 @component.Render(this) 275 } 276 } 277 278 @* Components *@ 279 @using System.Reflection 280 @using Dynamicweb.Rapido.Blocks.Components.General 281 282 283 @* Component *@ 284 285 @helper RenderIcon(Icon settings) 286 { 287 if (settings != null) 288 { 289 string color = settings.Color != null ? "style=\"color: " + settings.Color + "\"" : ""; 290 291 if (settings.Name != null) 292 { 293 if (string.IsNullOrEmpty(settings.Label)) 294 { 295 <i class="@settings.Prefix @settings.Name @settings.CssClass" @color></i> 296 } 297 else 298 { 299 if (settings.LabelPosition == IconLabelPosition.Before) 300 { 301 <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> 302 } 303 else 304 { 305 <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> 306 } 307 } 308 } 309 else if (!string.IsNullOrEmpty(settings.Label)) 310 { 311 @settings.Label 312 } 313 } 314 } 315 @using System.Reflection 316 @using Dynamicweb.Rapido.Blocks.Components.General 317 @using Dynamicweb.Rapido.Blocks.Components 318 @using Dynamicweb.Core 319 320 @* Component *@ 321 322 @helper RenderButton(Button settings) 323 { 324 if (settings != null && (!string.IsNullOrEmpty(settings.Title) || settings.Icon != null)) 325 { 326 Dictionary<string, string> attributes = new Dictionary<string, string>(); 327 List<string> classList = settings.CssClass != null ? settings.CssClass.Split(' ').ToList() : new List<string>(); 328 if (settings.Disabled) { 329 attributes.Add("disabled", "true"); 330 classList.Add("disabled"); 331 } 332 333 if (!string.IsNullOrEmpty(settings.ConfirmText) || !string.IsNullOrEmpty(settings.ConfirmTitle)) 334 { 335 settings.Id = !string.IsNullOrEmpty(settings.Id) ? settings.Id : Guid.NewGuid().ToString("N"); 336 @RenderConfirmDialog(settings); 337 settings.OnClick = "document.getElementById('" + settings.Id + "ModalTrigger').checked = true"; 338 } 339 340 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 341 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 342 if (!string.IsNullOrEmpty(settings.AltText)) 343 { 344 attributes.Add("title", settings.AltText); 345 } 346 347 var onClickEvents = new List<string>(); 348 if (!string.IsNullOrEmpty(settings.OnClick)) 349 { 350 onClickEvents.Add(settings.OnClick); 351 } 352 if (!string.IsNullOrEmpty(settings.Href)) 353 { 354 if (settings.Href.StartsWith("http") || settings.Href.StartsWith("/Files")) 355 { 356 onClickEvents.Add($"javascript:window.open('{settings.Href}', '_blank');"); 357 } 358 else 359 { 360 onClickEvents.Add("location.href='" + settings.Href + "'"); 361 } 362 } 363 if (onClickEvents.Count > 0) 364 { 365 attributes.Add("onClick", string.Join(";", onClickEvents)); 366 } 367 368 if (settings.ButtonLayout != ButtonLayout.None) 369 { 370 classList.Add("btn"); 371 string btnLayout = Enum.GetName(typeof(ButtonLayout), settings.ButtonLayout).ToLower(); 372 if (btnLayout == "linkclean") 373 { 374 btnLayout = "link-clean"; //fix 375 } 376 classList.Add("btn--" + btnLayout); 377 } 378 379 if (settings.Icon == null) 380 { 381 settings.Icon = new Icon(); 382 } 383 384 settings.Icon.CssClass += Enum.GetName(typeof(ButtonLayout), settings.ButtonLayout).ToLower() != "linkclean" ? " u-flex--align-center" : ""; 385 settings.Icon.Label = settings.Title; 386 387 attributes.Add("type", Enum.GetName(typeof(ButtonType), settings.ButtonType).ToLower()); 388 389 <button class="@string.Join(" ", classList) dw-mod" @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@Render(settings.Icon)</button> 390 } 391 } 392 393 @helper RenderConfirmDialog(Button settings) 394 { 395 Modal confirmDialog = new Modal { 396 Id = settings.Id, 397 Width = ModalWidth.Sm, 398 Heading = new Heading 399 { 400 Level = 2, 401 Title = settings.ConfirmTitle 402 }, 403 BodyText = settings.ConfirmText 404 }; 405 406 confirmDialog.AddAction(new Button { Title = Translate("Cancel"), ButtonLayout = ButtonLayout.Secondary, OnClick = "document.getElementById('" + settings.Id + "ModalTrigger').checked = false"}); 407 confirmDialog.AddAction(new Button { Title = Translate("OK"), ButtonLayout = ButtonLayout.Primary, OnClick = "document.getElementById('" + settings.Id + "ModalTrigger').checked = false;" + settings.OnClick }); 408 409 @Render(confirmDialog) 410 } 411 @using Dynamicweb.Rapido.Blocks.Components.General 412 @using Dynamicweb.Rapido.Blocks.Components 413 @using Dynamicweb.Core 414 415 @helper RenderDashboard(Dashboard settings) 416 { 417 var widgets = settings.GetWidgets(); 418 419 if (!string.IsNullOrEmpty(settings.WidgetsBaseBackgroundColor)) 420 { 421 //set bg color for them 422 423 System.Drawing.Color color = System.Drawing.ColorTranslator.FromHtml(settings.WidgetsBaseBackgroundColor); 424 int r = Convert.ToInt16(color.R); 425 int g = Convert.ToInt16(color.G); 426 int b = Convert.ToInt16(color.B); 427 428 var count = widgets.Length; 429 var max = Math.Max(r, Math.Max(g, b)); 430 double step = 255.0 / (max * count); 431 var i = 0; 432 foreach (var widget in widgets) 433 { 434 i++; 435 436 var shade = "rgb(" + Converter.ToString(r * step * i).Replace(",", ".") + ", " + Converter.ToString(g * step * i).Replace(",", ".") + ", " + Converter.ToString(b * step * i).Replace(",", ".") + ")"; 437 widget.BackgroundColor = shade; 438 } 439 } 440 441 <div class="dashboard @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 442 @foreach (var widget in widgets) 443 { 444 <div class="dashboard__widget"> 445 @Render(widget) 446 </div> 447 } 448 </div> 449 } 450 @using Dynamicweb.Rapido.Blocks.Components.General 451 @using Dynamicweb.Rapido.Blocks.Components 452 453 @helper RenderDashboardWidgetLink(DashboardWidgetLink settings) 454 { 455 if (!string.IsNullOrEmpty(settings.Link)) 456 { 457 var backgroundStyles = ""; 458 if (!string.IsNullOrEmpty(settings.BackgroundColor)) 459 { 460 backgroundStyles = "style=\"background-color:" + settings.BackgroundColor + "\""; 461 } 462 463 <a href="@settings.Link" class="widget widget--link @settings.CssClass dw-mod" @backgroundStyles title="@settings.Title" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 464 <div class="u-center-middle u-color-light"> 465 @if (settings.Icon != null) 466 { 467 settings.Icon.CssClass += "widget__icon"; 468 @Render(settings.Icon) 469 } 470 <div class="widget__title">@settings.Title</div> 471 </div> 472 </a> 473 } 474 } 475 @using Dynamicweb.Rapido.Blocks.Components.General 476 @using Dynamicweb.Rapido.Blocks.Components 477 478 @helper RenderDashboardWidgetCounter(DashboardWidgetCounter settings) 479 { 480 var backgroundStyles = ""; 481 if (!string.IsNullOrEmpty(settings.BackgroundColor)) 482 { 483 backgroundStyles = "style='background-color:" + settings.BackgroundColor + "'"; 484 } 485 486 <div class="widget @settings.CssClass dw-mod" @backgroundStyles @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 487 <div class="u-center-middle u-color-light"> 488 @if (settings.Icon != null) 489 { 490 settings.Icon.CssClass += "widget__icon"; 491 @Render(settings.Icon) 492 } 493 <div class="widget__counter">@settings.Count</div> 494 <div class="widget__title">@settings.Title</div> 495 </div> 496 </div> 497 } 498 @using System.Reflection 499 @using Dynamicweb.Rapido.Blocks.Components.General 500 @using Dynamicweb.Rapido.Blocks.Components 501 @using Dynamicweb.Core 502 503 @* Component *@ 504 505 @helper RenderLink(Link settings) 506 { 507 if (settings != null && !string.IsNullOrEmpty(settings.Href) && (!string.IsNullOrEmpty(settings.Title) || settings.Icon != null)) 508 { 509 Dictionary<string, string> attributes = new Dictionary<string, string>(); 510 List<string> classList = settings.CssClass != null ? settings.CssClass.Split(' ').ToList() : new List<string>(); 511 if (settings.Disabled) 512 { 513 attributes.Add("disabled", "true"); 514 classList.Add("disabled"); 515 } 516 517 if (!string.IsNullOrEmpty(settings.AltText)) 518 { 519 attributes.Add("title", settings.AltText); 520 } 521 522 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 523 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 524 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onClick", settings.OnClick); } 525 attributes.Add("href", settings.Href); 526 527 if (settings.ButtonLayout != ButtonLayout.None) 528 { 529 classList.Add("btn"); 530 string btnLayout = Enum.GetName(typeof(ButtonLayout), settings.ButtonLayout).ToLower(); 531 if (btnLayout == "linkclean") 532 { 533 btnLayout = "link-clean"; //fix 534 } 535 classList.Add("btn--" + btnLayout); 536 } 537 538 if (settings.Icon == null) 539 { 540 settings.Icon = new Icon(); 541 } 542 settings.Icon.Label = settings.Title; 543 544 if (settings.Target == LinkTargetType.Blank && settings.Rel == LinkRelType.None) 545 { 546 settings.Rel = LinkRelType.Noopener; 547 } 548 if (settings.Target != LinkTargetType.None) 549 { 550 attributes.Add("target", "_" + Enum.GetName(typeof(LinkTargetType), settings.Target).ToLower()); 551 } 552 else if (settings.Href.StartsWith("http") || settings.Href.StartsWith("/Files")) 553 { 554 attributes.Add("target", "_blank"); 555 } 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() != "" ? "&" + 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() != "" ? "&" + 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() != "" ? "&" + 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 } 887 else 888 { 889 optionalAttributes.Add("alt", ""); 890 } 891 892 if (settings.DisableLazyLoad) 893 { 894 <img id="@settings.Id" class="@imageStyle @settings.CssClass dw-mod" src="@defaultImage" @ComponentMethods.AddAttributes(optionalAttributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes) /> 895 } 896 else 897 { 898 <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) /> 899 } 900 } 901 } 902 @using System.Reflection 903 @using Dynamicweb.Rapido.Blocks.Components.General 904 @using Dynamicweb.Rapido.Blocks.Components 905 906 @* Component *@ 907 908 @helper RenderFileField(FileField settings) 909 { 910 var attributes = new Dictionary<string, string>(); 911 if (string.IsNullOrEmpty(settings.Id)) 912 { 913 settings.Id = Guid.NewGuid().ToString("N"); 914 } 915 916 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 917 if (settings.Disabled) { attributes.Add("disabled", "true"); } 918 if (settings.Required) { attributes.Add("required", "true"); } 919 if (settings.Multiple) { attributes.Add("multiple", "true"); } 920 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 921 if (string.IsNullOrEmpty(settings.ChooseFileText)) 922 { 923 settings.ChooseFileText = Translate("Choose file"); 924 } 925 if (string.IsNullOrEmpty(settings.NoFilesChosenText)) 926 { 927 settings.NoFilesChosenText = Translate("No files chosen..."); 928 } 929 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 930 931 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 932 933 string setValueToFakeInput = "FileUpload.setValueToFakeInput(this)"; 934 attributes.Add("onchange", setValueToFakeInput + (!string.IsNullOrEmpty(settings.OnChange) ? settings.OnChange : "")); 935 936 attributes.Add("type", "file"); 937 if (settings.Value != null) { attributes.Add("value", settings.Value); } 938 settings.CssClass = "u-full-width " + settings.CssClass; 939 940 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 941 942 <div class="form__field-group u-full-width @settings.WrapperCssClass dw-mod"> 943 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null ) 944 { 945 <div class="u-full-width"> 946 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> } 947 @if (settings.Link != null) { 948 <div class="u-pull--right"> 949 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; } 950 @Render(settings.Link) 951 </div> 952 } 953 </div> 954 955 } 956 957 @if (!string.IsNullOrEmpty(settings.HelpText)) 958 { 959 <small class="form__help-text">@settings.HelpText</small> 960 } 961 962 <div class="form__field-combi file-input u-no-margin dw-mod"> 963 <input @ComponentMethods.AddAttributes(resultAttributes) class="file-input__real-input u-visually-hidden hidden-required-input" data-no-files-text="@settings.NoFilesChosenText" data-many-files-text="@Translate("files")" /> 964 <label for="@settings.Id" class="file-input__btn btn--secondary btn dw-mod">@settings.ChooseFileText</label> 965 <label for="@settings.Id" class="@settings.CssClass file-input__fake-input js-fake-input dw-mod">@settings.NoFilesChosenText</label> 966 @if (settings.UploadButton != null) 967 { 968 settings.UploadButton.CssClass += " btn--condensed u-no-margin"; 969 @Render(settings.UploadButton) 970 } 971 </div> 972 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 973 </div> 974 } 975 @using System.Reflection 976 @using Dynamicweb.Rapido.Blocks.Components.General 977 @using Dynamicweb.Rapido.Blocks.Components 978 @using Dynamicweb.Core 979 @using System.Linq 980 981 @* Component *@ 982 983 @helper RenderDateTimeField(DateTimeField settings) 984 { 985 if (string.IsNullOrEmpty(settings.Id)) 986 { 987 settings.Id = Guid.NewGuid().ToString("N"); 988 } 989 990 var textField = new TextField { 991 Name = settings.Name, 992 Id = settings.Id, 993 Label = settings.Label, 994 HelpText = settings.HelpText, 995 Value = settings.Value, 996 Disabled = settings.Disabled, 997 Required = settings.Required, 998 ErrorMessage = settings.ErrorMessage, 999 CssClass = settings.CssClass, 1000 WrapperCssClass = settings.WrapperCssClass, 1001 OnChange = settings.OnChange, 1002 OnClick = settings.OnClick, 1003 Link = settings.Link, 1004 ExtraAttributes = settings.ExtraAttributes, 1005 // 1006 Placeholder = settings.Placeholder 1007 }; 1008 1009 @Render(textField) 1010 1011 List<string> jsAttributes = new List<string>(); 1012 1013 jsAttributes.Add("mode: '" + Enum.GetName(typeof(DateTimeFieldMode), settings.Mode).ToLower() + "'"); 1014 1015 if (!string.IsNullOrEmpty(settings.DateFormat)) 1016 { 1017 jsAttributes.Add("dateFormat: '" + settings.DateFormat + "'"); 1018 } 1019 if (!string.IsNullOrEmpty(settings.MinDate)) 1020 { 1021 jsAttributes.Add("minDate: '" + settings.MinDate + "'"); 1022 } 1023 if (!string.IsNullOrEmpty(settings.MaxDate)) 1024 { 1025 jsAttributes.Add("maxDate: '" + settings.MaxDate + "'"); 1026 } 1027 if (settings.IsInline) 1028 { 1029 jsAttributes.Add("inline: " + Converter.ToString(settings.IsInline).ToLower()); 1030 } 1031 if (settings.EnableTime) 1032 { 1033 jsAttributes.Add("enableTime: " + Converter.ToString(settings.EnableTime).ToLower()); 1034 } 1035 if (settings.EnableWeekNumbers) 1036 { 1037 jsAttributes.Add("weekNumbers: " + Converter.ToString(settings.EnableWeekNumbers).ToLower()); 1038 } 1039 1040 jsAttributes.AddRange(settings.GetFlatPickrOptions().Select(x => x.Key + ": " + x.Value)); 1041 1042 <script> 1043 document.addEventListener("DOMContentLoaded", function () { 1044 flatpickr("#@textField.Id", { 1045 @string.Join(",", jsAttributes) 1046 }); 1047 }); 1048 </script> 1049 } 1050 @using System.Reflection 1051 @using Dynamicweb.Rapido.Blocks.Components.General 1052 @using Dynamicweb.Rapido.Blocks.Components 1053 1054 @* Component *@ 1055 1056 @helper RenderTextField(TextField settings) 1057 { 1058 var attributes = new Dictionary<string, string>(); 1059 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id)) 1060 { 1061 settings.Id = Guid.NewGuid().ToString("N"); 1062 } 1063 1064 /*base settings*/ 1065 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1066 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1067 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1068 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1069 if (settings.Required) { attributes.Add("required", "true"); } 1070 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1071 /*end*/ 1072 1073 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); } 1074 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); } 1075 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); } 1076 if (settings.ReadOnly) { attributes.Add("readonly", "true"); } 1077 if (settings.MaxLength != 0) { attributes.Add("maxlength", settings.MaxLength.ToString()); } 1078 if (!string.IsNullOrEmpty(settings.Placeholder)) { attributes.Add("placeholder", settings.Placeholder); } 1079 attributes.Add("type", Enum.GetName(typeof(TextFieldType), settings.Type).ToLower()); 1080 if (settings.Type == TextFieldType.Password) { attributes.Add("autocomplete", "off"); }; 1081 if (settings.Value != null) { attributes.Add("value", settings.Value); } 1082 1083 settings.CssClass = "u-full-width " + settings.CssClass; 1084 1085 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1086 1087 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1088 1089 string noMargin = "u-no-margin"; 1090 if (!settings.ReadOnly) { 1091 noMargin = ""; 1092 } 1093 1094 <div class="form__field-group u-full-width @noMargin @settings.WrapperCssClass dw-mod"> 1095 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null ) 1096 { 1097 <div class="u-full-width"> 1098 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> } 1099 @if (settings.Link != null) { 1100 <div class="u-pull--right"> 1101 @Render(settings.Link) 1102 </div> 1103 } 1104 </div> 1105 1106 } 1107 1108 @if (!string.IsNullOrEmpty(settings.HelpText)) 1109 { 1110 <small class="form__help-text">@settings.HelpText</small> 1111 } 1112 1113 @if (settings.ActionButton != null) 1114 { 1115 settings.ActionButton.CssClass += " btn--condensed u-no-margin"; 1116 <div class="form__field-combi u-no-margin dw-mod"> 1117 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1118 @Render(settings.ActionButton) 1119 </div> 1120 } 1121 else 1122 { 1123 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1124 } 1125 1126 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1127 </div> 1128 } 1129 @using System.Reflection 1130 @using Dynamicweb.Rapido.Blocks.Components.General 1131 @using Dynamicweb.Rapido.Blocks.Components 1132 1133 @* Component *@ 1134 1135 @helper RenderNumberField(NumberField settings) 1136 { 1137 var attributes = new Dictionary<string, string>(); 1138 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id)) 1139 { 1140 settings.Id = Guid.NewGuid().ToString("N"); 1141 } 1142 1143 /*base settings*/ 1144 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1145 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1146 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1147 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1148 if (settings.Required) { attributes.Add("required", "true"); } 1149 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1150 /*end*/ 1151 1152 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); } 1153 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); } 1154 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); } 1155 if (settings.ReadOnly) { attributes.Add("readonly", "true"); } 1156 if (settings.Max != null) { attributes.Add("max", settings.Max.ToString()); } 1157 if (settings.Min != null) { attributes.Add("min", settings.Min.ToString()); } 1158 if (settings.Step != 0) { attributes.Add("step", settings.Step.ToString()); } 1159 if (settings.Value != null && !string.IsNullOrEmpty(settings.Value.ToString())) { attributes.Add("value", settings.Value.ToString()); } 1160 attributes.Add("type", "number"); 1161 1162 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1163 1164 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1165 <div class="form__field-group u-full-width @settings.WrapperCssClass dw-mod"> 1166 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null ) 1167 { 1168 <div class="u-full-width"> 1169 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> } 1170 @if (settings.Link != null) { 1171 <div class="u-pull--right"> 1172 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; } 1173 @Render(settings.Link) 1174 </div> 1175 } 1176 </div> 1177 1178 } 1179 1180 @if (!string.IsNullOrEmpty(settings.HelpText)) 1181 { 1182 <small class="form__help-text">@settings.HelpText</small> 1183 } 1184 1185 @if (settings.ActionButton != null) 1186 { 1187 settings.ActionButton.CssClass += " btn--condensed u-no-margin"; 1188 <div class="form__field-combi u-no-margin dw-mod"> 1189 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1190 @Render(settings.ActionButton) 1191 </div> 1192 } 1193 else 1194 { 1195 <div class="form__field-combi u-no-margin dw-mod"> 1196 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1197 </div> 1198 } 1199 1200 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1201 </div> 1202 } 1203 @using System.Reflection 1204 @using Dynamicweb.Rapido.Blocks.Components.General 1205 @using Dynamicweb.Rapido.Blocks.Components 1206 1207 1208 @* Component *@ 1209 1210 @helper RenderTextareaField(TextareaField settings) 1211 { 1212 Dictionary<string, string> attributes = new Dictionary<string, string>(); 1213 string id = settings.Id; 1214 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(id)) 1215 { 1216 id = Guid.NewGuid().ToString("N"); 1217 } 1218 1219 if (!string.IsNullOrEmpty(id)) { attributes.Add("id", id); } 1220 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1221 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); } 1222 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); } 1223 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); } 1224 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1225 if (!string.IsNullOrEmpty(settings.Placeholder)) { attributes.Add("placeholder", settings.Placeholder); } 1226 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1227 if (settings.Required) { attributes.Add("required", "true"); } 1228 if (settings.ReadOnly) { attributes.Add("readonly", "true"); } 1229 if (settings.MaxLength != 0) { attributes.Add("maxlength", settings.MaxLength.ToString()); } 1230 if (settings.Rows != 0) { attributes.Add("rows", settings.Rows.ToString()); } 1231 attributes.Add("name", settings.Name); 1232 1233 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1234 1235 <div class="form__field-group @settings.WrapperCssClass dw-mod"> 1236 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null ) 1237 { 1238 <div class="u-full-width"> 1239 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> } 1240 @if (settings.Link != null) { 1241 <div class="u-pull--right"> 1242 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; } 1243 @Render(settings.Link) 1244 </div> 1245 } 1246 </div> 1247 } 1248 1249 @if (!string.IsNullOrEmpty(settings.HelpText)) 1250 { 1251 <small class="form__help-text">@settings.HelpText</small> 1252 } 1253 1254 <textarea class="u-full-width @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@settings.Value</textarea> 1255 1256 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1257 </div> 1258 } 1259 @using System.Reflection 1260 @using Dynamicweb.Rapido.Blocks.Components.General 1261 @using Dynamicweb.Rapido.Blocks.Components 1262 1263 1264 @* Component *@ 1265 1266 @helper RenderHiddenField(HiddenField settings) { 1267 var attributes = new Dictionary<string, string>(); 1268 attributes.Add("type", "hidden"); 1269 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1270 if (settings.Value != null) { attributes.Add("value", settings.Value); } 1271 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1272 1273 <input @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)/> 1274 } 1275 @using System.Reflection 1276 @using Dynamicweb.Rapido.Blocks.Components.General 1277 @using Dynamicweb.Rapido.Blocks.Components 1278 1279 @* Component *@ 1280 1281 @helper RenderCheckboxField(CheckboxField settings) 1282 { 1283 var attributes = new Dictionary<string, string>(); 1284 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id)) 1285 { 1286 settings.Id = Guid.NewGuid().ToString("N"); 1287 } 1288 1289 /*base settings*/ 1290 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1291 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1292 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1293 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1294 if (settings.Required) { attributes.Add("required", "true"); } 1295 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1296 /*end*/ 1297 1298 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1299 1300 attributes.Add("type", "checkbox"); 1301 if (settings.Checked) { attributes.Add("checked", "true"); } 1302 settings.CssClass = "form__control " + settings.CssClass; 1303 if (settings.Value != null) { attributes.Add("value", settings.Value); } 1304 1305 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1306 1307 <div class="form__field-group @settings.WrapperCssClass dw-mod"> 1308 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1309 @if (!string.IsNullOrEmpty(settings.Label)) 1310 { 1311 <label for="@settings.Id" class="dw-mod">@settings.Label</label> 1312 } 1313 1314 @if (settings.Link != null) { 1315 <span> 1316 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; } 1317 @Render(settings.Link) 1318 </span> 1319 } 1320 1321 @if (!string.IsNullOrEmpty(settings.HelpText)) 1322 { 1323 <small class="form__help-text checkbox-help dw-mod">@settings.HelpText</small> 1324 } 1325 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1326 </div> 1327 } 1328 @using System.Reflection 1329 @using Dynamicweb.Rapido.Blocks.Components.General 1330 @using Dynamicweb.Rapido.Blocks.Components 1331 1332 1333 @* Component *@ 1334 1335 @helper RenderCheckboxListField(CheckboxListField settings) 1336 { 1337 <div class="form__field-group @settings.WrapperCssClass u-margin-bottom dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 1338 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null ) 1339 { 1340 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1341 if (!string.IsNullOrEmpty(settings.Label)) { <label class="u-pull--left">@settings.Label</label> } 1342 // Adding input type radio as a work around for HTML5 validation for checkbox list 1343 if (settings.Required) {<input type="radio" name="@settings.Name" class="u-visually-hidden hidden-required-input" required /> } 1344 if (!string.IsNullOrEmpty(settings.HelpText)) { <small class="form__help-text">@settings.HelpText</small> } 1345 if (settings.Link != null) { 1346 <div class="u-pull--right"> 1347 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; } 1348 @Render(settings.Link) 1349 </div> 1350 } 1351 } 1352 1353 <div class="forms__fields-options"> 1354 @foreach (var item in settings.Options) 1355 { 1356 if (settings.Required) 1357 { 1358 item.OnChange = "Forms.ValidateRequiredList(this, 'checkbox')"; 1359 } 1360 if (settings.Disabled) 1361 { 1362 item.Disabled = true; 1363 } 1364 if (!string.IsNullOrEmpty(settings.Name)) 1365 { 1366 item.Name = settings.Name; 1367 } 1368 if (!string.IsNullOrEmpty(settings.CssClass)) 1369 { 1370 item.CssClass += settings.CssClass; 1371 } 1372 1373 /* value is not supported */ 1374 1375 if (!string.IsNullOrEmpty(settings.OnClick)) 1376 { 1377 item.OnClick += settings.OnClick; 1378 } 1379 if (!string.IsNullOrEmpty(settings.OnChange)) 1380 { 1381 item.OnChange += settings.OnChange; 1382 } 1383 @Render(item) 1384 } 1385 </div> 1386 1387 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1388 </div> 1389 } 1390 @using Dynamicweb.Rapido.Blocks.Components.General 1391 1392 @* Component *@ 1393 1394 @helper RenderSearch(Search settings) 1395 { 1396 var searchValue = HttpContext.Current.Request.QueryString.Get(settings.SearchParameter) ?? ""; 1397 var groupValue = HttpContext.Current.Request.QueryString.Get(settings.GroupsParameter) ?? ""; 1398 1399 if (string.IsNullOrEmpty(settings.Id)) 1400 { 1401 settings.Id = Guid.NewGuid().ToString("N"); 1402 } 1403 1404 var resultAttributes = new Dictionary<string, string>(); 1405 1406 if (settings.PageSize != 0) 1407 { 1408 resultAttributes.Add("data-page-size", settings.PageSize.ToString()); 1409 } 1410 if (!string.IsNullOrEmpty(settings.GroupItemsFeedUrl)) 1411 { 1412 resultAttributes.Add("data-groups-feed-url", settings.GroupItemsFeedUrl); 1413 if (!string.IsNullOrEmpty(groupValue)) 1414 { 1415 resultAttributes.Add("data-selected-group", groupValue); 1416 } 1417 if (!string.IsNullOrEmpty(settings.GroupsParameter)) 1418 { 1419 resultAttributes.Add("data-groups-parameter", settings.GroupsParameter); 1420 } 1421 } 1422 resultAttributes.Add("data-force-init", "true"); 1423 if (settings.GoToFirstSearchResultOnEnter) 1424 { 1425 resultAttributes.Add("data-go-to-first-search-result-on-enter", settings.GoToFirstSearchResultOnEnter.ToString().ToLower()); 1426 } 1427 if (!string.IsNullOrEmpty(settings.SearchParameter)) 1428 { 1429 resultAttributes.Add("data-search-parameter", settings.SearchParameter); 1430 } 1431 resultAttributes.Add("data-search-feed-url", settings.SearchData.SearchFeedUrl); 1432 resultAttributes.Add("data-results-template-id", settings.SearchData.ResultsTemplateId); 1433 1434 if (settings.SecondSearchData != null) 1435 { 1436 resultAttributes.Add("data-second-search-feed-url", settings.SecondSearchData.SearchFeedUrl); 1437 resultAttributes.Add("data-second-results-template-id", settings.SecondSearchData.ResultsTemplateId); 1438 } 1439 if (!string.IsNullOrEmpty(settings.ResultsPageUrl)) 1440 { 1441 resultAttributes.Add("data-results-page-url", settings.ResultsPageUrl); 1442 } 1443 1444 resultAttributes = resultAttributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1445 1446 string searchFieldCss = (settings.SearchButton == null) ? "search--with-icon" : ""; 1447 1448 <div class="search @settings.CssClass @searchFieldCss js-search-data-source dw-mod" id="@settings.Id" @ComponentMethods.AddAttributes(resultAttributes)> 1449 @if (!string.IsNullOrEmpty(settings.GroupItemsFeedUrl)) 1450 { 1451 <button type="button" class="search__groups-btn dw-mod js-search-groups-btn">@Translate("All")</button> 1452 <ul class="dropdown dropdown--absolute-position dw-mod search__groups-results js-search-groups-list"></ul> 1453 } 1454 1455 <input type="text" class="search__field dw-mod js-search-field" placeholder="@settings.Placeholder" value="@searchValue"> 1456 1457 <div class="dropdown dropdown--absolute-position search__results dw-mod js-search-results @(settings.SecondSearchData != null ? "search__results--combined" : "")"> 1458 @if (settings.SecondSearchData != null) 1459 { 1460 <div class="search__column search__column--products dw-mod"> 1461 <div class="search__column-header dw-mod">@Translate("Products")</div> 1462 <ul class="search__results-list dw-mod js-search-results-list" id="@(settings.Id)_ResultsList"></ul> 1463 @if (!string.IsNullOrEmpty(settings.SearchData.ResultsPageUrl)) 1464 { 1465 @Render(new Link { 1466 Title = Translate("View all"), 1467 CssClass = "js-view-all-button u-margin", 1468 Href = settings.SearchData.ResultsPageUrl 1469 }); 1470 } 1471 </div> 1472 <div class="search__column search__column--pages dw-mod"> 1473 <div class="search__column-header">@Translate("Pages")</div> 1474 <ul class="search__results-list dw-mod js-search-results-second-list" id="@(settings.Id)_SecondResultsList"></ul> 1475 @if (!string.IsNullOrEmpty(settings.SecondSearchData.ResultsPageUrl)) 1476 { 1477 @Render(new Link 1478 { 1479 Title = Translate("View all"), 1480 CssClass = "js-view-all-button u-margin", 1481 Href = settings.SecondSearchData.ResultsPageUrl 1482 }); 1483 } 1484 </div> 1485 } 1486 else 1487 { 1488 <div class="search__column search__column--only dw-mod"> 1489 <ul class="search__results-list dw-mod js-search-results-list" id="@(settings.Id)_ResultsList"></ul> 1490 @if (!string.IsNullOrEmpty(settings.SearchData.ResultsPageUrl)) 1491 { 1492 @Render(new Link { 1493 Title = Translate("View all"), 1494 CssClass = "js-view-all-button u-margin", 1495 Href = settings.SearchData.ResultsPageUrl 1496 }); 1497 } 1498 </div> 1499 } 1500 </div> 1501 1502 @if (settings.SearchButton != null) 1503 { 1504 settings.SearchButton.CssClass += " search__btn js-search-btn"; 1505 if (settings.RenderDefaultSearchIcon) 1506 { 1507 settings.SearchButton.Icon = new Icon { Name = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SearchIcon").SelectedValue }; 1508 } 1509 @Render(settings.SearchButton); 1510 } 1511 </div> 1512 } 1513 @using System.Reflection 1514 @using Dynamicweb.Rapido.Blocks.Components.General 1515 @using Dynamicweb.Rapido.Blocks.Components 1516 1517 1518 @* Component *@ 1519 1520 @helper RenderSelectField(SelectField settings) 1521 { 1522 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id)) 1523 { 1524 settings.Id = Guid.NewGuid().ToString("N"); 1525 } 1526 1527 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1528 1529 <div class="form__field-group u-full-width @settings.WrapperCssClass dw-mod"> 1530 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null ) 1531 { 1532 <div class="u-full-width"> 1533 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> } 1534 @if (settings.Link != null) { 1535 <div class="u-pull--right"> 1536 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; } 1537 @Render(settings.Link) 1538 </div> 1539 } 1540 </div> 1541 } 1542 1543 @if (!string.IsNullOrEmpty(settings.HelpText)) 1544 { 1545 <small class="form__help-text">@settings.HelpText</small> 1546 } 1547 1548 @if (settings.ActionButton != null) 1549 { 1550 settings.ActionButton.CssClass += " btn--condensed u-no-margin"; 1551 <div class="form__field-combi u-no-margin dw-mod"> 1552 @RenderSelectBase(settings) 1553 @Render(settings.ActionButton) 1554 </div> 1555 } 1556 else 1557 { 1558 @RenderSelectBase(settings) 1559 } 1560 1561 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1562 </div> 1563 } 1564 1565 @helper RenderSelectBase(SelectField settings) 1566 { 1567 var attributes = new Dictionary<string, string>(); 1568 1569 /*base settings*/ 1570 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1571 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1572 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1573 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1574 if (settings.Required) { attributes.Add("required", "true"); } 1575 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1576 /*end*/ 1577 1578 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1579 1580 <select @ComponentMethods.AddAttributes(resultAttributes) class="u-full-width @settings.CssClass dw-mod"> 1581 @if (settings.Default != null) 1582 { 1583 @Render(settings.Default) 1584 } 1585 1586 @foreach (var item in settings.Options) 1587 { 1588 if (settings.Value != null) { 1589 item.Checked = item.Value == settings.Value; 1590 } 1591 @Render(item) 1592 } 1593 </select> 1594 } 1595 @using System.Reflection 1596 @using Dynamicweb.Rapido.Blocks.Components.General 1597 @using Dynamicweb.Rapido.Blocks.Components 1598 1599 @* Component *@ 1600 1601 @helper RenderRadioButtonField(RadioButtonField settings) 1602 { 1603 var attributes = new Dictionary<string, string>(); 1604 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id)) 1605 { 1606 settings.Id = Guid.NewGuid().ToString("N"); 1607 } 1608 1609 /*base settings*/ 1610 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1611 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1612 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1613 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1614 if (settings.Required) { attributes.Add("required", "true"); } 1615 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1616 /*end*/ 1617 1618 attributes.Add("type", "radio"); 1619 if (settings.Checked) { attributes.Add("checked", "true"); } 1620 settings.CssClass = "form__control " + settings.CssClass; 1621 if (settings.Value != null) { attributes.Add("value", settings.Value); } 1622 1623 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1624 1625 <div class="form__field-group @settings.WrapperCssClass dw-mod"> 1626 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1627 @if (!string.IsNullOrEmpty(settings.Label)) 1628 { 1629 <label for="@settings.Id" class="dw-mod">@settings.Label</label> 1630 } 1631 @if (!string.IsNullOrEmpty(settings.HelpText)) 1632 { 1633 <small class="form__help-text">@settings.HelpText</small> 1634 } 1635 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1636 </div> 1637 } 1638 @using System.Reflection 1639 @using Dynamicweb.Rapido.Blocks.Components.General 1640 @using Dynamicweb.Rapido.Blocks.Components 1641 1642 1643 @* Component *@ 1644 1645 @helper RenderRadioButtonListField(RadioButtonListField settings) 1646 { 1647 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1648 1649 <div class="form__field-group @settings.WrapperCssClass u-margin-bottom dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 1650 @if (!string.IsNullOrEmpty(settings.Label)) 1651 { 1652 <label>@settings.Label</label> 1653 } 1654 @if (settings.Required) {<input type="radio" name="@settings.Name" class="u-visually-hidden hidden-required-input" required /> } 1655 1656 @if (!string.IsNullOrEmpty(settings.HelpText)) 1657 { 1658 <small class="form__help-text">@settings.HelpText</small> 1659 } 1660 1661 <div class="forms__fields-options"> 1662 @foreach (var item in settings.Options) 1663 { 1664 if (settings.Required) 1665 { 1666 item.OnChange = "Forms.ValidateRequiredList(this, 'checkbox')"; 1667 } 1668 if (settings.Disabled) 1669 { 1670 item.Disabled = true; 1671 } 1672 if (!string.IsNullOrEmpty(settings.Name)) 1673 { 1674 item.Name = settings.Name; 1675 } 1676 if (settings.Value != null && settings.Value == item.Value) 1677 { 1678 item.Checked = true; 1679 } 1680 if (!string.IsNullOrEmpty(settings.OnClick)) 1681 { 1682 item.OnClick += settings.OnClick; 1683 } 1684 if (!string.IsNullOrEmpty(settings.OnChange)) 1685 { 1686 item.OnChange += settings.OnChange; 1687 } 1688 if (!string.IsNullOrEmpty(settings.CssClass)) 1689 { 1690 item.CssClass += settings.CssClass; 1691 } 1692 @Render(item) 1693 } 1694 </div> 1695 1696 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1697 </div> 1698 } 1699 @using System.Reflection 1700 @using Dynamicweb.Rapido.Blocks.Components.General 1701 @using Dynamicweb.Rapido.Blocks.Components 1702 1703 1704 @* Component *@ 1705 1706 @helper RenderNotificationMessage(NotificationMessage settings) 1707 { 1708 if (!string.IsNullOrEmpty(settings.Message)) 1709 { 1710 var attributes = new Dictionary<string, string>(); 1711 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1712 1713 string messageTypeClass = Enum.GetName(typeof(NotificationMessageType), settings.MessageType).ToLower(); 1714 string messageLayoutClass = Enum.GetName(typeof(NotificationMessageLayout), settings.MessageLayout).ToLower(); 1715 string minHeightClass = settings.Icon != null ? "u-min-h70px" : ""; 1716 1717 <div class="notification-message-@messageTypeClass notification-message-@messageLayoutClass @messageLayoutClass @minHeightClass @settings.CssClass u-full-width dw-mod" @ComponentMethods.AddAttributes(attributes)> 1718 @if (settings.Icon != null) { 1719 settings.Icon.Label = !string.IsNullOrEmpty(settings.Icon.Label) ? settings.Message + settings.Icon.Label : settings.Message; 1720 @Render(settings.Icon) 1721 } else { 1722 @settings.Message 1723 } 1724 </div> 1725 } 1726 } 1727 @using Dynamicweb.Rapido.Blocks.Components.General 1728 1729 1730 @* Component *@ 1731 1732 @helper RenderHandlebarsRoot(HandlebarsRoot settings) { 1733 string preRender = !String.IsNullOrEmpty(settings.PreRenderScriptTemplate) ? "data-pre-render-template=\"" + settings.PreRenderScriptTemplate + "\"" : ""; 1734 1735 <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> 1736 @if (settings.SubBlocks != null) { 1737 @RenderBlockList(settings.SubBlocks) 1738 } 1739 </div> 1740 } 1741 @using System.Reflection 1742 @using Dynamicweb.Rapido.Blocks.Components.General 1743 @using Dynamicweb.Rapido.Blocks.Components 1744 @using System.Text.RegularExpressions 1745 1746 1747 @* Component *@ 1748 1749 @helper RenderSticker(Sticker settings) { 1750 if (!String.IsNullOrEmpty(settings.Title)) { 1751 string size = settings.Size.ToString() != "None" ? "" + "stickers-container__tag--" + settings.Size.ToString().ToLower() : ""; 1752 string style = settings.Style.ToString() != "None" ? "" + "stickers-container__tag--" + settings.Style.ToString().ToLower() : ""; 1753 1754 Dictionary<String, String> optionalAttributes = new Dictionary<string, string>(); 1755 if (!String.IsNullOrEmpty(settings.Color) || !String.IsNullOrEmpty(settings.BackgroundColor)) { 1756 string styleTag = !String.IsNullOrEmpty(settings.Color) ? "color: " + settings.Color + "; " : ""; 1757 styleTag += !String.IsNullOrEmpty(settings.BackgroundColor) ? "background-color: " + settings.BackgroundColor + "; " : ""; 1758 optionalAttributes.Add("style", styleTag); 1759 } 1760 1761 <div class="stickers-container__tag @size @style @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(optionalAttributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@settings.Title</div> 1762 } 1763 } 1764 1765 @using System.Reflection 1766 @using Dynamicweb.Rapido.Blocks.Components.General 1767 @using Dynamicweb.Rapido.Blocks.Components 1768 1769 1770 @* Component *@ 1771 1772 @helper RenderStickersCollection(StickersCollection settings) 1773 { 1774 if (settings.Stickers.Count > 0) 1775 { 1776 string position = "stickers-container--" + Regex.Replace(settings.Position.ToString(), "([a-z])([A-Z])", "$1-$2").ToLower(); 1777 1778 <div class="stickers-container @position @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 1779 @foreach (Sticker sticker in settings.Stickers) 1780 { 1781 @Render(sticker) 1782 } 1783 </div> 1784 } 1785 } 1786 1787 @using Dynamicweb.Rapido.Blocks.Components.General 1788 1789 1790 @* Component *@ 1791 1792 @helper RenderForm(Form settings) { 1793 if (settings != null) 1794 { 1795 Dictionary<string, string> optionalAttributes = new Dictionary<string, string>(); 1796 if (!string.IsNullOrEmpty(settings.Action)) { optionalAttributes.Add("action", settings.Action); }; 1797 if (!string.IsNullOrEmpty(settings.Name)) { optionalAttributes.Add("name", settings.Name); }; 1798 if (!string.IsNullOrEmpty(settings.OnSubmit)) { optionalAttributes.Add("onsubmit", settings.OnSubmit); }; 1799 var enctypes = new Dictionary<string, string> 1800 { 1801 { "multipart", "multipart/form-data" }, 1802 { "text", "text/plain" }, 1803 { "application", "application/x-www-form-urlencoded" } 1804 }; 1805 if (settings.Enctype != FormEnctype.none) { optionalAttributes.Add("enctype", enctypes[Enum.GetName(typeof(FormEnctype), settings.Enctype).ToLower()]); }; 1806 optionalAttributes.Add("method", settings.Method.ToString()); 1807 1808 if (!string.IsNullOrEmpty(settings.FormStartMarkup)) 1809 { 1810 @settings.FormStartMarkup 1811 } 1812 else 1813 { 1814 @:<form class="@settings.CssClass u-no-margin dw-mod" @ComponentMethods.AddAttributes(optionalAttributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 1815 } 1816 1817 foreach (var field in settings.GetFields()) 1818 { 1819 @Render(field) 1820 } 1821 1822 @:</form> 1823 } 1824 } 1825 @using System.Reflection 1826 @using Dynamicweb.Rapido.Blocks.Components.General 1827 @using Dynamicweb.Rapido.Blocks.Components 1828 1829 1830 @* Component *@ 1831 1832 @helper RenderText(Text settings) 1833 { 1834 @settings.Content 1835 } 1836 @using System.Reflection 1837 @using Dynamicweb.Rapido.Blocks.Components.General 1838 @using Dynamicweb.Rapido.Blocks.Components 1839 1840 1841 @* Component *@ 1842 1843 @helper RenderContentModule(ContentModule settings) { 1844 if (!string.IsNullOrEmpty(settings.Content)) 1845 { 1846 @settings.Content 1847 } 1848 } 1849 @using System.Reflection 1850 @using Dynamicweb.Rapido.Blocks.Components.General 1851 @using Dynamicweb.Rapido.Blocks.Components 1852 1853 1854 @* Component *@ 1855 1856 @helper RenderModal(Modal settings) { 1857 if (settings != null) 1858 { 1859 string modalId = !string.IsNullOrEmpty(settings.Id) ? settings.Id : Guid.NewGuid().ToString("N"); 1860 1861 string onchange = !string.IsNullOrEmpty(settings.OnClose) ? "onchange=\"if(!this.checked){" + settings.OnClose + "}\"" : ""; 1862 1863 <input type="checkbox" id="@(modalId)ModalTrigger" class="modal-trigger" @onchange /> 1864 1865 <div class="modal-container"> 1866 @if (!settings.DisableDarkOverlay) 1867 { 1868 <label for="@(modalId)ModalTrigger" id="@(modalId)ModalOverlay" class="modal-overlay"></label> 1869 } 1870 <div class="modal modal--@settings.Width.ToString().ToLower() modal-height--@settings.Height.ToString().ToLower()" id="@(modalId)Modal"> 1871 @if (settings.Heading != null) 1872 { 1873 if (!string.IsNullOrEmpty(settings.Heading.Title)) 1874 { 1875 <div class="modal__header"> 1876 @Render(settings.Heading) 1877 </div> 1878 } 1879 } 1880 <div class="modal__body @(settings.Width.ToString().ToLower() == "full" ? "modal__body--full" : "")"> 1881 @if (!string.IsNullOrEmpty(settings.BodyText)) 1882 { 1883 @settings.BodyText 1884 } 1885 @if (settings.BodyTemplate != null) 1886 { 1887 @settings.BodyTemplate 1888 } 1889 @{ 1890 var actions = settings.GetActions(); 1891 } 1892 </div> 1893 @if (actions.Length > 0) 1894 { 1895 <div class="modal__footer"> 1896 @foreach (var action in actions) 1897 { 1898 if (Pageview.Device.ToString() != "Mobile") { 1899 action.CssClass += " u-no-margin"; 1900 } else { 1901 action.CssClass += " u-full-width u-margin-bottom"; 1902 } 1903 1904 @Render(action) 1905 } 1906 </div> 1907 } 1908 <label class="modal__close-btn" for="@(modalId)ModalTrigger"></label> 1909 </div> 1910 </div> 1911 } 1912 } 1913 @using Dynamicweb.Rapido.Blocks.Components.General 1914 1915 @* Component *@ 1916 1917 @helper RenderMediaListItem(MediaListItem settings) 1918 { 1919 <div class="media-list-item @settings.CssClass dw-mod" @(!string.IsNullOrEmpty(settings.Id) ? "id=\"" + settings.Id + "\"" : "")> 1920 @if (!string.IsNullOrEmpty(settings.Label)) 1921 { 1922 if (!string.IsNullOrEmpty(settings.Link)) 1923 { 1924 @Render(new Link 1925 { 1926 Href = settings.Link, 1927 CssClass = "media-list-item__sticker dw-mod", 1928 ButtonLayout = ButtonLayout.None, 1929 Title = settings.Label, 1930 OnClick = !string.IsNullOrEmpty(settings.OnClick) ? settings.OnClick : "" 1931 }) 1932 } 1933 else if (!string.IsNullOrEmpty(settings.OnClick)) 1934 { 1935 <span class="media-list-item__sticker dw-mod" onclick="@(settings.OnClick)"> 1936 <span class="u-uppercase">@settings.Label</span> 1937 </span> 1938 } 1939 else 1940 { 1941 <span class="media-list-item__sticker media-list-item__sticker--no-link dw-mod"> 1942 <span class="u-uppercase">@settings.Label</span> 1943 </span> 1944 } 1945 } 1946 <div class="media-list-item__wrap"> 1947 <div class="media-list-item__info dw-mod"> 1948 <div class="media-list-item__header dw-mod"> 1949 @if (!string.IsNullOrEmpty(settings.Title)) 1950 { 1951 if (!string.IsNullOrEmpty(settings.Link)) 1952 { 1953 @Render(new Link 1954 { 1955 Href = settings.Link, 1956 CssClass = "media-list-item__name dw-mod", 1957 ButtonLayout = ButtonLayout.None, 1958 Title = settings.Title, 1959 OnClick = !string.IsNullOrEmpty(settings.OnClick) ? settings.OnClick : "" 1960 }) 1961 } 1962 else if (!string.IsNullOrEmpty(settings.OnClick)) 1963 { 1964 <span class="media-list-item__name dw-mod" onclick="@(settings.OnClick)">@settings.Title</span> 1965 } 1966 else 1967 { 1968 <span class="media-list-item__name media-list-item__name--no-link dw-mod">@settings.Title</span> 1969 } 1970 } 1971 1972 @if (!string.IsNullOrEmpty(settings.Status)) 1973 { 1974 <div class="media-list-item__state dw-mod">@settings.Status</div> 1975 } 1976 </div> 1977 @{ 1978 settings.InfoTable.CssClass += " media-list-item__parameters-table"; 1979 } 1980 1981 @Render(settings.InfoTable) 1982 </div> 1983 <div class="media-list-item__actions dw-mod"> 1984 <div class="media-list-item__actions-list dw-mod"> 1985 @{ 1986 var actions = settings.GetActions(); 1987 1988 foreach (ButtonBase action in actions) 1989 { 1990 action.ButtonLayout = ButtonLayout.None; 1991 action.CssClass += " media-list-item__action link"; 1992 1993 @Render(action) 1994 } 1995 } 1996 </div> 1997 1998 @if (settings.SelectButton != null && !string.IsNullOrEmpty(settings.SelectButton.Title)) 1999 { 2000 settings.SelectButton.CssClass += " u-no-margin"; 2001 2002 <div class="media-list-item__action-button"> 2003 @Render(settings.SelectButton) 2004 </div> 2005 } 2006 </div> 2007 </div> 2008 </div> 2009 } 2010 @using Dynamicweb.Rapido.Blocks.Components.General 2011 @using Dynamicweb.Rapido.Blocks.Components 2012 2013 @helper RenderTable(Table settings) 2014 { 2015 Dictionary<string, string> attributes = new Dictionary<string, string>(); 2016 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 2017 2018 var enumToClasses = new Dictionary<TableDesign, string> 2019 { 2020 { TableDesign.Clean, "table--clean" }, 2021 { TableDesign.Bordered, "table--bordered" }, 2022 { TableDesign.Striped, "table--striped" }, 2023 { TableDesign.Hover, "table--hover" }, 2024 { TableDesign.Compact, "table--compact" }, 2025 { TableDesign.Condensed, "table--condensed" }, 2026 { TableDesign.NoTopBorder, "table--no-top-border" } 2027 }; 2028 string tableDesignClass = ""; 2029 if (settings.Design != TableDesign.None) 2030 { 2031 tableDesignClass = enumToClasses[settings.Design]; 2032 } 2033 2034 if (!string.IsNullOrEmpty(settings.CssClass) || settings.Design != TableDesign.None) { attributes.Add("class", "table " + tableDesignClass + " " + settings.CssClass + " dw-mod"); } 2035 2036 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.Last().Value); 2037 2038 <table @ComponentMethods.AddAttributes(resultAttributes)> 2039 @if (settings.Header != null) 2040 { 2041 <thead> 2042 @Render(settings.Header) 2043 </thead> 2044 } 2045 <tbody> 2046 @foreach (var row in settings.Rows) 2047 { 2048 @Render(row) 2049 } 2050 </tbody> 2051 @if (settings.Footer != null) 2052 { 2053 <tfoot> 2054 @Render(settings.Footer) 2055 </tfoot> 2056 } 2057 </table> 2058 } 2059 @using Dynamicweb.Rapido.Blocks.Components.General 2060 @using Dynamicweb.Rapido.Blocks.Components 2061 2062 @helper RenderTableRow(TableRow settings) 2063 { 2064 Dictionary<string, string> attributes = new Dictionary<string, string>(); 2065 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 2066 2067 var enumToClasses = new Dictionary<TableRowDesign, string> 2068 { 2069 { TableRowDesign.NoBorder, "table__row--no-border" }, 2070 { TableRowDesign.Border, "table__row--border" }, 2071 { TableRowDesign.TopBorder, "table__row--top-line" }, 2072 { TableRowDesign.BottomBorder, "table__row--bottom-line" }, 2073 { TableRowDesign.Solid, "table__row--solid" } 2074 }; 2075 2076 string tableRowDesignClass = ""; 2077 if (settings.Design != TableRowDesign.None) 2078 { 2079 tableRowDesignClass = enumToClasses[settings.Design]; 2080 } 2081 2082 if (!string.IsNullOrEmpty(settings.CssClass) || settings.Design != TableRowDesign.None) { attributes.Add("class", "table__row " + tableRowDesignClass + " " + settings.CssClass + " dw-mod"); } 2083 2084 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.Last().Value); 2085 2086 <tr @ComponentMethods.AddAttributes(resultAttributes)> 2087 @foreach (var cell in settings.Cells) 2088 { 2089 if (settings.IsHeaderRow) 2090 { 2091 cell.IsHeader = true; 2092 } 2093 @Render(cell) 2094 } 2095 </tr> 2096 } 2097 @using Dynamicweb.Rapido.Blocks.Components.General 2098 @using Dynamicweb.Rapido.Blocks.Components 2099 @using Dynamicweb.Core 2100 2101 @helper RenderTableCell(TableCell settings) 2102 { 2103 Dictionary<string, string> attributes = new Dictionary<string, string>(); 2104 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 2105 if (settings.Colspan != 0) { attributes.Add("colspan", Converter.ToString(settings.Colspan)); } 2106 if (settings.Rowspan != 0) { attributes.Add("rowspan", Converter.ToString(settings.Rowspan)); } 2107 if (!string.IsNullOrEmpty(settings.CssClass)) { attributes.Add("class", settings.CssClass + " dw-mod"); } 2108 2109 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.Last().Value); 2110 2111 string tagName = settings.IsHeader ? "th" : "td"; 2112 2113 @("<" + tagName + " " + ComponentMethods.AddAttributes(resultAttributes) + ">") 2114 @settings.Content 2115 @("</" + tagName + ">"); 2116 } 2117 @using System.Linq 2118 @using Dynamicweb.Rapido.Blocks.Components.General 2119 2120 @* Component *@ 2121 2122 @helper RenderPagination(Dynamicweb.Rapido.Blocks.Components.General.Pagination settings) 2123 { 2124 var pageNumberQueryStringName = Dynamicweb.Rapido.Services.Pagination.GetPageNumberQueryStringName(settings); // Get the proper 'page number' query string parameter 2125 var queryParameters = Dynamicweb.Rapido.Services.Url.GetQueryParameters(pageNumberQueryStringName); // Get the NameValueCollection from the querystring 2126 2127 if (settings.NumberOfPages > 1) 2128 { 2129 string url = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + "/Default.aspx"; 2130 string ariaLabel = !string.IsNullOrWhiteSpace(settings.AriaLabel) ? settings.AriaLabel : Translate("Page navigation"); 2131 Dictionary<string, int> startAndEndPageNumber = Dynamicweb.Rapido.Services.Pagination.GetStartAndEndPageNumber(settings); 2132 2133 <div class="pager u-margin-top dw-mod @settings.CssClass" aria-label="@ariaLabel"> 2134 @if (settings.ShowPagingInfo) 2135 { 2136 <div class="pager__info dw-mod"> 2137 @Translate("Page") @settings.CurrentPageNumber @Translate("of") @settings.NumberOfPages 2138 </div> 2139 } 2140 <ul class="pager__list dw-mod"> 2141 @if (!string.IsNullOrWhiteSpace(settings.FirstPageUrl) && settings.ShowFirstAndLastControls) 2142 { 2143 @Render(new PaginationItem { Link = settings.FirstPageUrl, Icon = settings.FirstIcon }) 2144 } 2145 @if (!string.IsNullOrWhiteSpace(settings.PreviousPageUrl) && settings.ShowNextAndPrevControls) 2146 { 2147 @Render(new PaginationItem { Link = settings.PreviousPageUrl, Icon = settings.PrevIcon }) 2148 } 2149 @if (settings.GetPages().Any()) 2150 { 2151 foreach (var page in settings.GetPages()) 2152 { 2153 @Render(page) 2154 } 2155 } 2156 else 2157 { 2158 for (var page = startAndEndPageNumber["StartPage"]; page <= startAndEndPageNumber["EndPage"]; page++) 2159 { 2160 queryParameters = Dynamicweb.Rapido.Services.Url.UpdateQueryStringParameter(queryParameters, pageNumberQueryStringName, page.ToString()); 2161 @Render(new PaginationItem { Label = page.ToString(), Link = Dynamicweb.Rapido.Services.Url.BuildUri(url, queryParameters).PathAndQuery, IsActive = (settings.CurrentPageNumber == page) }); 2162 } 2163 } 2164 @if (!string.IsNullOrWhiteSpace(settings.NextPageUrl) && settings.ShowNextAndPrevControls) 2165 { 2166 @Render(new PaginationItem { Link = settings.NextPageUrl, Icon = settings.NextIcon }) 2167 } 2168 @if (!string.IsNullOrWhiteSpace(settings.LastPageUrl) && settings.ShowFirstAndLastControls) 2169 { 2170 @Render(new PaginationItem { Link = settings.LastPageUrl, Icon = settings.LastIcon }) 2171 } 2172 </ul> 2173 </div> 2174 } 2175 } 2176 2177 @helper RenderPaginationItem(PaginationItem settings) 2178 { 2179 if (settings.Icon == null) 2180 { 2181 settings.Icon = new Icon(); 2182 } 2183 2184 settings.Icon.Label = settings.Label; 2185 <li class="pager__btn dw-mod"> 2186 @if (settings.IsActive) 2187 { 2188 <span class="pager__num pager__num--current dw-mod"> 2189 @Render(settings.Icon) 2190 </span> 2191 } 2192 else 2193 { 2194 <a href="@settings.Link" class="pager__num dw-mod"> 2195 @Render(settings.Icon) 2196 </a> 2197 } 2198 </li> 2199 } 2200 2201 2202 @using Dynamicweb.Rapido.Blocks.Components.General 2203 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 2204 @using System.Linq 2205 @using Dynamicweb.Core 2206 @using Dynamicweb.Rapido.Blocks.Components.General 2207 2208 @* Component *@ 2209 2210 @helper RenderAlertNotification(AlertNotification settings) 2211 { 2212 if (settings != null && (!string.IsNullOrEmpty(settings.Title) || !string.IsNullOrEmpty(settings.Message))) 2213 { 2214 @(string.Format("AlertNotification.ShowNotification('{0}','{1}'{2})", Converter.ToString(settings.Title), Converter.ToString(settings.Message), GetAlertNotificationConfiguration(settings))) 2215 } 2216 } 2217 2218 @functions 2219 { 2220 private string GetAlertNotificationConfiguration(AlertNotification settings) 2221 { 2222 string[] configuration = 2223 { 2224 AppendProperty("closeOnClick", settings.CloseOnClick), 2225 AppendProperty("displayCloseButton", settings.DisplayCloseButton), 2226 AppendProperty("onClick", settings.OnClick), 2227 AppendProperty("showDuration", settings.ShowDuration), 2228 AppendProperty("positionClass", settings.Position), 2229 AppendProperty("theme", settings.Theme) 2230 }; 2231 2232 configuration = configuration.Where(c => !string.IsNullOrEmpty(c)).ToArray(); 2233 2234 if (!configuration.Any()) 2235 { 2236 return string.Empty; 2237 } 2238 2239 return string.Concat(",{", string.Join(",", configuration), "}"); 2240 } 2241 2242 private static string AppendProperty(string propertyName, bool? propertyValue) 2243 { 2244 return propertyValue != null ? string.Format("{0}: {1}",propertyName, propertyValue.ToString().ToLowerInvariant()) : null; 2245 } 2246 2247 private static string AppendProperty(string propertyName, int? propertyValue) 2248 { 2249 return propertyValue != null ? string.Format("{0}: {1}",propertyName, propertyValue.ToString().ToLowerInvariant()) : null; 2250 } 2251 2252 private static string AppendProperty(string propertyName, AlertNotificationPosition.Position? propertyValue) 2253 { 2254 return propertyValue != null ? string.Format("{0}: positionConfig.{1}",propertyName, propertyValue) : null; 2255 } 2256 2257 private static string AppendProperty(string propertyName, AlertNotificationTheme.Theme? propertyValue) 2258 { 2259 return propertyValue != null ? string.Format("{0}: themeConfig.{1}",propertyName, propertyValue) : null; 2260 } 2261 } 2262 2263 @using System.Linq 2264 @using Dynamicweb.Core 2265 @using Dynamicweb.Rapido.Blocks.Components.General 2266 2267 @helper RenderMonthYearField(DateTimeField settings) 2268 { 2269 if (string.IsNullOrEmpty(settings.Id)) 2270 { 2271 settings.Id = Guid.NewGuid().ToString("N"); 2272 } 2273 2274 var textField = new TextField { 2275 Name = settings.Name, 2276 Id = settings.Id, 2277 Label = settings.Label, 2278 HelpText = settings.HelpText, 2279 Value = settings.Value, 2280 Disabled = settings.Disabled, 2281 Required = settings.Required, 2282 ErrorMessage = settings.ErrorMessage, 2283 CssClass = settings.CssClass, 2284 WrapperCssClass = settings.WrapperCssClass, 2285 OnChange = settings.OnChange, 2286 OnClick = settings.OnClick, 2287 ExtraAttributes = settings.ExtraAttributes, 2288 // 2289 Placeholder = settings.Placeholder 2290 }; 2291 2292 @Render(textField) 2293 2294 List<string> jsAttributes = new List<string>(); 2295 2296 jsAttributes.Add("mode: '" + Enum.GetName(typeof(DateTimeFieldMode), settings.Mode).ToLower() + "'"); 2297 2298 if (!string.IsNullOrEmpty(settings.DateFormat)) 2299 { 2300 jsAttributes.Add("dateFormat: '" + settings.DateFormat + "'"); 2301 } 2302 if (!string.IsNullOrEmpty(settings.MinDate)) 2303 { 2304 jsAttributes.Add("minDate: '" + settings.MinDate + "'"); 2305 } 2306 if (!string.IsNullOrEmpty(settings.MaxDate)) 2307 { 2308 jsAttributes.Add("maxDate: '" + settings.MaxDate + "'"); 2309 } 2310 if (settings.IsInline) 2311 { 2312 jsAttributes.Add("inline: " + Converter.ToString(settings.IsInline).ToLower()); 2313 } 2314 if (settings.EnableTime) 2315 { 2316 jsAttributes.Add("enableTime: " + Converter.ToString(settings.EnableTime).ToLower()); 2317 } 2318 if (settings.EnableWeekNumbers) 2319 { 2320 jsAttributes.Add("weekNumbers: " + Converter.ToString(settings.EnableWeekNumbers).ToLower()); 2321 } 2322 jsAttributes.Add("plugins: " + "[new monthSelectPlugin({shorthand: true, dateFormat: 'F Y', altFormat: 'F Y'})]"); 2323 2324 jsAttributes.AddRange(settings.GetFlatPickrOptions().Select(x => x.Key + ": " + x.Value)); 2325 2326 <script> 2327 document.addEventListener("DOMContentLoaded", function () { 2328 flatpickr("#@textField.Id", { 2329 @string.Join(",", jsAttributes) 2330 }); 2331 }); 2332 </script> 2333 } 2334 @using Dna.Rizzo.Components 2335 @* Component *@ 2336 2337 @helper RenderProgressionBar(ProgressionBar settings) 2338 { 2339 var secondaryValue = settings.TotalValue - settings.Value; 2340 var label = !string.IsNullOrEmpty(settings.Label) ? $"{settings.Label}: " : ""; 2341 var defaultColorClass = !string.IsNullOrEmpty(settings.Color) ? "" : "u-brand-color-one--bg"; 2342 2343 <div class="progress-bar"> 2344 <span class="u-pull--left u-margin">@($"{label}{FormatValue(settings.Value, settings.TotalValue, settings.RenderType)}")</span> 2345 @if (!settings.HideRemainingLabel) 2346 { 2347 var remainingLabel = !string.IsNullOrEmpty(settings.RemainingLabel) ? $"{settings.RemainingLabel}: " : ""; 2348 2349 <span class="u-pull--right u-margin">@($"{remainingLabel}{FormatValue(secondaryValue, settings.TotalValue, settings.RenderType)}")</span> 2350 } 2351 <div class="u-color-light-gray--bg progress-bar__line"> 2352 <div class="progress-bar__line progress-bar__line--complete @defaultColorClass" style="width:@GetCompletionPercentage(settings.Value, settings.TotalValue);background-color:@settings.Color"></div> 2353 </div> 2354 </div> 2355 } 2356 2357 @functions 2358 { 2359 private static string GetCompletionPercentage(double value, double total) 2360 { 2361 var percentage = value * 100 / total; 2362 return Math.Round(percentage) + "%"; 2363 } 2364 2365 private static dynamic FormatValue(double value, double total, ProgressionBarRenderType.RenderType? renderType) 2366 { 2367 switch (renderType) 2368 { 2369 case ProgressionBarRenderType.RenderType.Price: 2370 return Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Common.Context.Currency, value, true); 2371 case ProgressionBarRenderType.RenderType.Percentage: 2372 return GetCompletionPercentage(value, total); 2373 case ProgressionBarRenderType.RenderType.NoFormat: 2374 default: 2375 return value; 2376 } 2377 } 2378 } 2379 2380 2381 @using Dynamicweb.Rapido.Blocks.Components 2382 @using Dynamicweb.Rapido.Blocks.Components.General 2383 @using Dynamicweb.Rapido.Blocks 2384 @using System.IO 2385 2386 2387 @using Dynamicweb.Rapido.Blocks.Components.General 2388 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 2389 2390 2391 @* Component *@ 2392 2393 @helper RenderVariantMatrix(VariantMatrix settings) { 2394 if (settings != null) 2395 { 2396 int productLoopCounter = 0; 2397 int groupCount = 0; 2398 List<VariantOption> firstDimension = new List<VariantOption>(); 2399 List<VariantOption> secondDimension = new List<VariantOption>(); 2400 List<VariantOption> thirdDimension = new List<VariantOption>(); 2401 2402 foreach (VariantGroup variantGroup in settings.GetVariantGroups()) 2403 { 2404 foreach (VariantOption variantOptions in variantGroup.GetVariantOptions()) 2405 { 2406 if (groupCount == 0) { 2407 firstDimension.Add(variantOptions); 2408 } 2409 if (groupCount == 1) 2410 { 2411 secondDimension.Add(variantOptions); 2412 } 2413 if (groupCount == 2) 2414 { 2415 thirdDimension.Add(variantOptions); 2416 } 2417 } 2418 groupCount++; 2419 } 2420 2421 int rowCount = 0; 2422 int columnCount = 0; 2423 2424 <script> 2425 var variantsCollection = []; 2426 </script> 2427 2428 <table class="table table--compact js-variants-matrix dw-mod" id="VariantMatrixTable_@settings.ProductId"> 2429 @if (groupCount == 1) 2430 { 2431 <tbody> 2432 @foreach (VariantOption firstVariantOption in firstDimension) 2433 { 2434 var variantId = firstVariantOption.Id; 2435 <tr> 2436 <td class="u-bold"> 2437 @firstVariantOption.Name 2438 </td> 2439 <td> 2440 @RenderVariantMatrixQuantityField(variantId, settings, productLoopCounter, rowCount, columnCount) 2441 </td> 2442 </tr> 2443 productLoopCounter++; 2444 } 2445 2446 <tr> 2447 <td>&nbsp;</td> 2448 <td> 2449 <div class="qty-field js-total-qty-column-@columnCount dw-mod">0</div> 2450 </td> 2451 </tr> 2452 </tbody> 2453 } 2454 @if (groupCount == 2) 2455 { 2456 <thead> 2457 <tr> 2458 <td>&nbsp;</td> 2459 @foreach (VariantOption variant in secondDimension) 2460 { 2461 <td>@variant.Name</td> 2462 } 2463 </tr> 2464 </thead> 2465 <tbody> 2466 @foreach (VariantOption firstVariantOption in firstDimension) 2467 { 2468 string variantId = ""; 2469 columnCount = 0; 2470 2471 <tr> 2472 <td class="u-min-w120px">@firstVariantOption.Name</td> 2473 2474 @foreach (VariantOption secondVariantOption in secondDimension) 2475 { 2476 variantId = firstVariantOption.Id + "." + secondVariantOption.Id; 2477 <td> 2478 @RenderVariantMatrixQuantityField(variantId, settings, productLoopCounter, rowCount, columnCount) 2479 </td> 2480 2481 columnCount++; 2482 2483 productLoopCounter++; 2484 } 2485 2486 <td> 2487 <div class="qty-field js-total-qty-row-@rowCount dw-mod">0</div> 2488 </td> 2489 </tr> 2490 2491 rowCount++; 2492 } 2493 2494 @{ 2495 columnCount = 0; 2496 } 2497 2498 <tr> 2499 <td>&nbsp;</td> 2500 @foreach (VariantOption secondVariantOption in secondDimension) 2501 { 2502 <td> 2503 <div class="qty-field js-total-qty-column-@columnCount dw-mod">0</div> 2504 </td> 2505 2506 columnCount++; 2507 } 2508 <td>&nbsp;</td> 2509 </tr> 2510 </tbody> 2511 } 2512 @if (groupCount == 3) 2513 { 2514 <thead> 2515 <tr> 2516 <td>&nbsp;</td> 2517 @foreach (VariantOption thirdVariantOption in thirdDimension) 2518 { 2519 <td>@thirdVariantOption.Name</td> 2520 } 2521 </tr> 2522 </thead> 2523 <tbody> 2524 @foreach (VariantOption firstVariantOption in firstDimension) 2525 { 2526 int colspan = (thirdDimension.Count + 1); 2527 2528 <tr> 2529 <td colspan="@colspan" class="u-color-light-gray--bg u-bold">@firstVariantOption.Name</td> 2530 </tr> 2531 2532 foreach (VariantOption secondVariantOption in secondDimension) 2533 { 2534 string variantId = ""; 2535 columnCount = 0; 2536 2537 <tr> 2538 <td class="u-min-w120px">@secondVariantOption.Name</td> 2539 2540 @foreach (VariantOption thirdVariantOption in thirdDimension) 2541 { 2542 variantId = firstVariantOption.Id + "." + secondVariantOption.Id + "." + thirdVariantOption.Id; 2543 2544 <td> 2545 @RenderVariantMatrixQuantityField(variantId, settings, productLoopCounter, rowCount, columnCount) 2546 </td> 2547 2548 columnCount++; 2549 productLoopCounter++; 2550 } 2551 2552 <td> 2553 <div class="qty-field js-total-qty-row-@rowCount dw-mod">0</div> 2554 </td> 2555 </tr> 2556 rowCount++; 2557 } 2558 } 2559 2560 @{ 2561 columnCount = 0; 2562 } 2563 2564 <tr> 2565 <td>&nbsp;</td> 2566 @foreach (VariantOption thirdVariantOption in thirdDimension) 2567 { 2568 <td> 2569 <div class="qty-field js-total-qty-column-@columnCount dw-mod">0</div> 2570 </td> 2571 2572 columnCount++; 2573 } 2574 <td>&nbsp;</td> 2575 </tr> 2576 </tbody> 2577 } 2578 </table> 2579 2580 <script> 2581 document.addEventListener("DOMContentLoaded", function (event) { 2582 MatrixUpdateQuantity("@settings.ProductId"); 2583 }); 2584 2585 MatrixUpdateQuantity = function (productId) { 2586 var currentMatrix = document.getElementById("VariantMatrixTable_" + productId); 2587 var allQtyFields = currentMatrix.getElementsByClassName("js-qty"); 2588 2589 var qtyRowArr = []; 2590 var qtyColumnArr = []; 2591 2592 var totalQty = 0; 2593 2594 for (var i = 0; i < allQtyFields.length; i++) { 2595 qtyRowArr[allQtyFields[i].getAttribute("data-qty-row-group")] = 0; 2596 qtyColumnArr[allQtyFields[i].getAttribute("data-qty-column-group")] = 0; 2597 } 2598 2599 for (var i = 0; i < allQtyFields.length; i++) { 2600 qtyRowArr[allQtyFields[i].getAttribute("data-qty-row-group")] += parseFloat(allQtyFields[i].value); 2601 qtyColumnArr[allQtyFields[i].getAttribute("data-qty-column-group")] += parseFloat(allQtyFields[i].value); 2602 totalQty += parseFloat(allQtyFields[i].value); 2603 } 2604 2605 //Update row counters 2606 for (var i = 0; i < qtyRowArr.length; i++) { 2607 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-row-" + i)[0]; 2608 2609 if (qtyRowArr[i] != undefined && qtyCounter != null) { 2610 var currentCount = qtyCounter.innerHTML; 2611 qtyCounter.innerHTML = qtyRowArr[i]; 2612 2613 if (currentCount != qtyCounter.innerHTML) { 2614 qtyCounter.classList.add("qty-field--active"); 2615 } 2616 } 2617 2618 } 2619 2620 //Update column counters 2621 for (var i = 0; i < qtyColumnArr.length; i++) { 2622 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-column-" + i)[0]; 2623 2624 if (qtyColumnArr[i] != undefined && qtyCounter != null) { 2625 var currentCount = qtyCounter.innerHTML; 2626 qtyCounter.innerHTML = qtyColumnArr[i]; 2627 2628 if (currentCount != qtyCounter.innerHTML) { 2629 qtyCounter.classList.add("qty-field--active"); 2630 } 2631 } 2632 } 2633 2634 if (document.getElementById("TotalQtyCount_" + productId)) { 2635 document.getElementById("TotalQtyCount_" + productId).innerHTML = totalQty; 2636 } 2637 2638 //Clean up animations 2639 setTimeout(function () { 2640 for (var i = 0; i < qtyRowArr.length; i++) { 2641 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-row-" + i)[0]; 2642 if (qtyCounter != null) { 2643 qtyCounter.classList.remove("qty-field--active"); 2644 } 2645 } 2646 for (var i = 0; i < qtyColumnArr.length; i++) { 2647 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-column-" + i)[0]; 2648 if (qtyCounter != null) { 2649 qtyCounter.classList.remove("qty-field--active"); 2650 } 2651 } 2652 }, 1000); 2653 } 2654 </script> 2655 } 2656 } 2657 2658 @helper RenderVariantMatrixQuantityField(string variantId, VariantMatrix settings, int productLoopCounter, int rowCount, int columnCount) 2659 { 2660 string loopCount = productLoopCounter.ToString(); 2661 2662 bool combinationFound = false; 2663 double stock = 0; 2664 double quantityValue = 0; 2665 string note = ""; 2666 2667 VariantProduct variantProduct = null; 2668 2669 if (settings.GetVariantProducts().TryGetValue(variantId, out variantProduct)) 2670 { 2671 stock = variantProduct.Stock; 2672 quantityValue = variantProduct.Quantity; 2673 combinationFound = true; 2674 } 2675 2676 if (combinationFound) 2677 { 2678 <input type="hidden" name="ProductLoopCounter@(loopCount)" value="@loopCount" /> 2679 <input type="hidden" name="ProductID@(loopCount)" value="@settings.ProductId" /> 2680 <input type="hidden" name="VariantID@(loopCount)" value="@variantId" /> 2681 <input type="hidden" name="CurrentNote@(loopCount)" id="CurrentNote_@(settings.ProductId)_@variantId" value="@note" /> 2682 <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"> 2683 2684 if (stock != 0) 2685 { 2686 <small>@Translate("Stock") @stock</small> 2687 } 2688 2689 <script> 2690 var variants = '{ "ProductId" :' + '"@settings.ProductId"' + ', "VariantId": ' + '"@variantId"' +'}'; 2691 variantsCollection.push(variants); 2692 document.getElementById("Quantity_@(settings.ProductId)_@variantId").closest(".js-variants-matrix").setAttribute("data-variants-collection", "[" + variantsCollection + "]" ); 2693 </script> 2694 } 2695 else 2696 { 2697 <div class="use-btn-height" style="background-color: #a8a8a8"></div> 2698 } 2699 } 2700 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 2701 2702 @* Component *@ 2703 2704 @helper RenderAddToCart(AddToCart settings) 2705 { 2706 //set Id for quantity selector to get it's value from button 2707 if (settings.QuantitySelector != null) 2708 { 2709 if (string.IsNullOrEmpty(settings.QuantitySelector.Id)) 2710 { 2711 settings.QuantitySelector.Id = Guid.NewGuid().ToString("N"); 2712 } 2713 2714 settings.AddButton.QuantitySelectorId = settings.QuantitySelector.Id; 2715 2716 if (settings.Disabled) 2717 { 2718 settings.QuantitySelector.Disabled = true; 2719 } 2720 2721 if (string.IsNullOrEmpty(settings.QuantitySelector.Name)) 2722 { 2723 settings.QuantitySelector.Name = settings.QuantitySelector.Id; 2724 } 2725 2726 settings.QuantitySelector.Max = "{{availableAmount}}"; 2727 } 2728 2729 if (settings.Disabled) 2730 { 2731 settings.AddButton.Disabled = true; 2732 } 2733 2734 settings.AddButton.CssClass += " btn--condensed"; 2735 2736 //unitsSelector 2737 if (settings.UnitSelector != null) 2738 { 2739 if (settings.Disabled) 2740 { 2741 settings.QuantitySelector.Disabled = true; 2742 } 2743 } 2744 2745 <div class="buttons-collection @settings.WrapperCssClass" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 2746 @if (settings.UnitSelector != null) 2747 { 2748 @Render(settings.UnitSelector) 2749 } 2750 @if (settings.QuantitySelector != null) 2751 { 2752 @Render(settings.QuantitySelector) 2753 } 2754 @Render(settings.AddButton) 2755 </div> 2756 } 2757 @using Dynamicweb.Core 2758 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 2759 @using Dynamicweb.Rapido.Blocks.Components.General 2760 @* Component *@ 2761 2762 @helper RenderAddToCartButton(AddToCartButton settings) 2763 { 2764 if (!settings.HideTitle) 2765 { 2766 if (string.IsNullOrEmpty(settings.Title)) 2767 { 2768 if (settings.BuyForPoints) 2769 { 2770 settings.Title = Translate("Buy with points"); 2771 } 2772 else 2773 { 2774 settings.Title = Translate("Add to cart"); 2775 } 2776 } 2777 } 2778 else 2779 { 2780 settings.Title = ""; 2781 2782 if (settings.BuyForPoints) 2783 { 2784 settings.AltText = Translate("Buy with points"); 2785 } 2786 else 2787 { 2788 settings.AltText = Translate("Add to cart"); 2789 } 2790 } 2791 2792 var webServiceConnectionAvailableTag = Pageview.GlobalTags.GetTagByName("Global:LiveIntegration.IsWebServiceConnectionAvailable"); 2793 var erpDownDisableAddToCart = Pageview.AreaSettings.GetItem("Rizzo").GetBoolean("ErpDownDisableAddToCart"); 2794 if (webServiceConnectionAvailableTag != null && !Converter.ToBoolean(webServiceConnectionAvailableTag.Value) && erpDownDisableAddToCart) 2795 { 2796 settings.Disabled = true; 2797 settings.AltText = Translate("Temporarily unavailable"); 2798 } 2799 2800 if (settings.Icon == null) 2801 { 2802 settings.Icon = new Icon(); 2803 settings.Icon.LabelPosition = Dynamicweb.Rapido.Blocks.Components.General.IconLabelPosition.After; 2804 } 2805 2806 if (string.IsNullOrEmpty(settings.Icon.Name)) 2807 { 2808 settings.Icon.Name = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue; 2809 } 2810 2811 string cartArgs = "{ " + 2812 "id: '" + settings.ProductId + "'," + 2813 (!string.IsNullOrEmpty(settings.VariantId) ? "variantId: '" + settings.VariantId + "'," : "") + 2814 (!string.IsNullOrEmpty(settings.UnitId) ? "unitId: '" + settings.UnitId + "'," : "") + 2815 (settings.BuyForPoints ? "buyForPoints: true," : "") + 2816 (!string.IsNullOrEmpty(settings.ProductInfo) ? "productInfo: " + settings.ProductInfo + "," : "") + 2817 "quantity: " + (string.IsNullOrEmpty(settings.QuantitySelectorId) ? "1" : "parseFloat(document.getElementById('" + settings.QuantitySelectorId + "').value)") + 2818 "}"; 2819 string stockValidationUrl = Dna.StockValidation.Product.GetValidationUrl(GetPageIdByNavigationTag("StockValidation"), settings.ProductId, settings.VariantId, settings.UnitId, Pageview.Area.EcomLanguageId); 2820 2821 settings.OnClick = "StockValidation.AddToCartValidation(event, " + cartArgs + ", '" + stockValidationUrl + "');" + settings.OnClick; 2822 2823 @RenderButton(settings) 2824 } 2825 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 2826 2827 @* Component *@ 2828 2829 @helper RenderUnitSelector(UnitSelector settings) 2830 { 2831 if (string.IsNullOrEmpty(settings.Id)) 2832 { 2833 settings.Id = Guid.NewGuid().ToString("N"); 2834 } 2835 var disabledClass = settings.Disabled ? "disabled" : ""; 2836 2837 <input type="checkbox" id="@settings.Id" class="dropdown-trigger" /> 2838 <div class="dropdown unit-selector @settings.CssClass @disabledClass dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 2839 <label class="dropdown__header dropdown__btn dropdown__btn--unit-selector dw-mod" for="@settings.Id">@settings.SelectedOption</label> 2840 <div class="dropdown__content dw-mod"> 2841 @settings.OptionsContent 2842 </div> 2843 <label class="dropdown-trigger-off" for="@settings.Id"></label> 2844 </div> 2845 } 2846 @using System.Reflection 2847 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 2848 2849 @* Component *@ 2850 2851 @helper RenderQuantitySelector(QuantitySelector settings) 2852 { 2853 var attributes = new Dictionary<string, string>(); 2854 2855 /*base settings*/ 2856 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 2857 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 2858 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 2859 if (settings.Disabled) { attributes.Add("disabled", "true"); } 2860 if (settings.Required) { attributes.Add("required", "true"); } 2861 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 2862 /*end*/ 2863 2864 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); } 2865 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); } 2866 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); } 2867 if (settings.ReadOnly) { attributes.Add("readonly", "true"); } 2868 if (settings.Max != null) { attributes.Add("max", settings.Max.ToString()); } 2869 if (settings.Min == null) { settings.Min = 1; } 2870 attributes.Add("min", settings.Min.ToString()); 2871 if (settings.Step != null && !string.IsNullOrEmpty(settings.Step.ToString())) { attributes.Add("step", settings.Step.ToString()); } 2872 if (settings.Value == null) { settings.Value = 1; } 2873 attributes.Add("value", settings.Value.ToString()); 2874 attributes.Add("type", "number"); 2875 attributes.Add("aria-label", Translate("Quantity")); 2876 2877 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 2878 2879 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 2880 } 2881 @using Dynamicweb.Rapido.Blocks.Components 2882 2883 @using Dynamicweb.Frontend 2884 @using Dynamicweb.Frontend.Devices 2885 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 2886 @using Dynamicweb.Rapido.Blocks.Components.General 2887 @using System.Collections.Generic; 2888 @using HtmlAgilityPack 2889 2890 @* Component *@ 2891 @functions 2892 { 2893 private static string GetListHeaderItem(CustomerCenterList settings, int index) 2894 { 2895 var headers = settings.GetHeaders(); 2896 2897 if (headers.Length < 1 || headers.Length < index) return ""; 2898 2899 CustomerCenterListHeaderItem header = (CustomerCenterListHeaderItem)headers[index]; 2900 2901 if (header == null) return ""; 2902 2903 var doc = new HtmlDocument(); 2904 doc.LoadHtml(header.Title); 2905 2906 return doc.DocumentNode.SelectNodes("//div")?.First().InnerText ?? header.Title; 2907 } 2908 } 2909 @helper RenderCustomerCenterList(CustomerCenterList settings) 2910 { 2911 bool isTouchDevice = Pageview.Device.ToString() == "Mobile" || Pageview.Device.ToString() == "Tablet" ? true : false; 2912 string hideActions = isTouchDevice ? "u-block" : ""; 2913 2914 <table class="table data-list table--responsive dw-mod"> 2915 @if (settings.GetHeaders().Length > 0) { 2916 <thead> 2917 <tr class="u-bold"> 2918 @foreach (CustomerCenterListHeaderItem header in settings.GetHeaders()) 2919 { 2920 var attributes = new Dictionary<string, string>(); 2921 if (!string.IsNullOrEmpty(header.Id)) { attributes.Add("id", header.Id); } 2922 if (!string.IsNullOrEmpty(header.CssClass)) { attributes.Add("class", header.CssClass); } 2923 attributes.Add("align", header.Align.ToString()); 2924 attributes = attributes.Concat(header.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 2925 2926 <td @ComponentMethods.AddAttributes(attributes)>@header.Title</td> 2927 } 2928 </tr> 2929 </thead> 2930 } 2931 @foreach (CustomerCenterListItem listItem in settings.GetItems()) 2932 { 2933 int columnCount = 0; 2934 int headerIndex = 0; 2935 int totalColumns = listItem.GetInfoItems().Length; 2936 string rowHasActions = listItem.GetActions().Length > 0 ? "data-list__item--has-actions" : ""; 2937 listItem.Id = !string.IsNullOrEmpty(listItem.Id) ? listItem.Id : Guid.NewGuid().ToString("N"); 2938 2939 var attributes = new Dictionary<string, string>(); 2940 if (!string.IsNullOrEmpty(listItem.Title)) { attributes.Add("title", listItem.Title); }; 2941 2942 attributes = attributes.Concat(listItem.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 2943 <tbody class="data-list__item @rowHasActions @listItem.CssClass dw-mod" @ComponentMethods.AddAttributes(attributes)> 2944 <tr> 2945 @if (!string.IsNullOrEmpty(listItem.Title) || !string.IsNullOrEmpty(listItem.Description)) { 2946 string onClick = !string.IsNullOrEmpty(listItem.OnClick) ? "onclick=\"" + listItem.OnClick + "\"" : ""; 2947 headerIndex++; 2948 2949 <td rowspan="2" @onClick class="data-list__main-item dw-mod"> 2950 @if (!string.IsNullOrEmpty(listItem.Title)) { 2951 <div class="u-bold">@listItem.Title</div> 2952 } 2953 @if (!string.IsNullOrEmpty(listItem.Description)) { 2954 <div>@listItem.Description</div> 2955 } 2956 </td> 2957 } 2958 2959 @foreach (CustomerCenterListInfoItem infoItem in listItem.GetInfoItems()) 2960 { 2961 var infoAttributes = new Dictionary<string, string>(); 2962 if (!string.IsNullOrEmpty(infoItem.Id)) { infoAttributes.Add("id", infoItem.Id); }; 2963 if (!string.IsNullOrEmpty(infoItem.OnClick)) { infoAttributes.Add("onclick", infoItem.OnClick); }; 2964 infoAttributes.Add("data-th", GetListHeaderItem(settings, headerIndex)); 2965 infoAttributes.Add("align", infoItem.Align.ToString()); 2966 2967 infoAttributes = infoAttributes.Concat(infoItem.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 2968 string columnClick = columnCount < (totalColumns-1) && !string.IsNullOrEmpty(listItem.OnClick) ? "onclick=\"" + listItem.OnClick + "\"" : ""; 2969 2970 <td @ComponentMethods.AddAttributes(infoAttributes) @columnClick class="data-list__info-item dw-mod"> 2971 @if (!string.IsNullOrEmpty(infoItem.Title)) { 2972 <div>@infoItem.Title</div> 2973 } 2974 @if (!string.IsNullOrEmpty(infoItem.Subtitle)) { 2975 <div><small>@infoItem.Subtitle</small></div> 2976 } 2977 </td> 2978 2979 columnCount++; 2980 headerIndex++; 2981 } 2982 </tr> 2983 @if (listItem.GetActions().Any()) 2984 { 2985 <tr> 2986 <td colspan="@totalColumns" align="right" class="data-list__actions-row u-va-bottom u-no-border"> 2987 <div class="data-list__actions @hideActions dw-mod" id="ActionsMenu_@listItem.Id"> 2988 @foreach (ButtonBase action in listItem.GetActions()) 2989 { 2990 action.ButtonLayout = ButtonLayout.LinkClean; 2991 action.Icon.CssClass += " u-full-height"; 2992 action.CssClass += " data-list__action-button link"; 2993 2994 @Render(action) 2995 } 2996 </div> 2997 </td> 2998 </tr> 2999 } 3000 </tbody> 3001 } 3002 </table> 3003 } 3004 3005 @* Include the Blocks for the page *@ 3006 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 3007 @using Dynamicweb.Core 3008 @using System 3009 @using System.Web 3010 @using System.Collections.Generic 3011 @using Dynamicweb.Rapido.Blocks 3012 3013 @{ 3014 BlocksPage productListProductsBlocksPage = BlocksPage.GetBlockPage("ProductList"); 3015 3016 Block productsBlock = new Block 3017 { 3018 Id = "Views", 3019 SortId = 30, 3020 Template = RenderProducts() 3021 }; 3022 3023 productListProductsBlocksPage.Add("ProductList", productsBlock); 3024 } 3025 3026 @helper RenderProducts() 3027 { 3028 @*This is part of a script template *@ 3029 3030 <div id="ProductsContainer" data-template="{{listTemplate}}" class="grid product-list grid--external-bleed-x dw-mod grid--align-content-start" data-save-cookie="true"> 3031 {{#ProductsContainer}} 3032 {{> (lookup . 'template') }} 3033 {{/ProductsContainer}} 3034 </div> 3035 } 3036 3037 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 3038 @using Dynamicweb.Core 3039 @using System 3040 @using System.Web 3041 @using System.Collections.Generic 3042 @using Dynamicweb.Rapido.Blocks 3043 @using Dynamicweb.Rapido.Blocks.Components.General 3044 @using Dynamicweb.Rapido.Services 3045 3046 @functions { 3047 BlocksPage listViewPage = BlocksPage.GetBlockPage("ProductList"); 3048 Dynamicweb.Frontend.ItemViewModel listViewSettings = null; 3049 } 3050 3051 @if (Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableListView")) 3052 { 3053 listViewSettings = Pageview.AreaSettings.GetItem("ProductList").GetItem("ListView"); 3054 3055 listViewPage.Add("Views", new Block 3056 { 3057 Id = "ProductItemContainer", 3058 Name = "th-list", 3059 SortId = 10 3060 }); 3061 3062 Block listViewScripts = new Block 3063 { 3064 Id = "ListViewScripts", 3065 SortId = 20, 3066 Template = ListView(), 3067 BlocksList = new List<Block> { 3068 new Block 3069 { 3070 Id = "ListViewItem", 3071 SortId = 10, 3072 Template = RenderListViewItem(), 3073 SkipRenderBlocksList = true, 3074 BlocksList = new List<Block> { 3075 new Block 3076 { 3077 Id = "ListViewItemHiddenProperties", 3078 SortId = 10, 3079 Template = RenderListViewItemHiddenProperties() 3080 }, 3081 new Block 3082 { 3083 Id = "ListViewItemLeft", 3084 SortId = 10, 3085 SkipRenderBlocksList = true, 3086 Template = RenderListViewItemLeft(), 3087 BlocksList = new List<Block> { 3088 new Block 3089 { 3090 Id = "ListViewItemImage", 3091 SortId = 10, 3092 Template = RenderListViewItemImage() 3093 }, 3094 new Block 3095 { 3096 Id = "ListViewItemStickers", 3097 SortId = 20, 3098 Template = RenderListViewItemStickers() 3099 } 3100 } 3101 }, 3102 new Block 3103 { 3104 Id = "ListViewItemRight", 3105 SortId = 20, 3106 Design = new Design 3107 { 3108 RenderType = RenderType.Column, 3109 Size = "auto", 3110 CssClass = "product-list__list-item__right" 3111 }, 3112 BlocksList = new List<Block> { 3113 new Block 3114 { 3115 Id = "ListViewItemInfoContainer", 3116 SortId = 10, 3117 Design = new Design 3118 { 3119 RenderType = RenderType.None 3120 }, 3121 BlocksList = new List<Block> { 3122 new Block { 3123 Id = "ListViewItemInfoContainerLeft", 3124 SortId = 10, 3125 Design = new Design 3126 { 3127 CssClass = "u-pull--left" 3128 }, 3129 BlocksList = new List<Block> { 3130 new Block 3131 { 3132 Id = "ListViewItemTitle", 3133 SortId = 10, 3134 Template = RenderListViewItemTitle() 3135 } 3136 } 3137 }, 3138 new Block { 3139 Id = "ListViewItemInfoContainerRight", 3140 SortId = 20, 3141 Design = new Design 3142 { 3143 CssClass = "u-pull--right" 3144 } 3145 } 3146 } 3147 }, 3148 new Block 3149 { 3150 Id = "ListViewItemDescription", 3151 SortId = 20, 3152 Template = RenderListViewItemDescription() 3153 }, 3154 new Block 3155 { 3156 Id = "ListViewItemFooter", 3157 SortId = 50, 3158 SkipRenderBlocksList = true, 3159 Template = RenderListViewItemFooter(), 3160 BlocksList = new List<Block> { 3161 new Block 3162 { 3163 Id = "ListViewItemActions", 3164 SortId = 20, 3165 Template = RenderListViewItemActions() 3166 } 3167 } 3168 } 3169 } 3170 } 3171 } 3172 }, 3173 new Block 3174 { 3175 Id = "ListViewPrice", 3176 SortId = 20, 3177 Template = RenderListViewPrice() 3178 }, 3179 new Block 3180 { 3181 Id = "ListViewAddToCart", 3182 SortId = 20, 3183 Template = RenderListViewAddToCart() 3184 } 3185 } 3186 }; 3187 listViewPage.Add("BottomSnippets", listViewScripts); 3188 3189 //number 3190 bool listViewShowNumber = listViewSettings.GetBoolean("ShowProductNumber"); 3191 3192 if (listViewShowNumber) 3193 { 3194 listViewPage.Add("ListViewItemInfoContainerLeft", new Block 3195 { 3196 Id = "ListViewItemNumber", 3197 SortId = 20, 3198 Template = RenderListViewItemNumber() 3199 }); 3200 } 3201 3202 //stock 3203 bool listViewShowStock = listViewSettings.GetBoolean("ShowStockAndShipping"); 3204 if (User.IsStockInfoAllowed() && listViewShowStock) 3205 { 3206 listViewPage.Add("ListViewItemInfoContainerLeft", new Block 3207 { 3208 Id = "ListViewItemStock", 3209 SortId = 30, 3210 Template = RenderListViewItemStock() 3211 }); 3212 } 3213 3214 //favorites 3215 bool listViewShowFavoriteButton = !listViewSettings.GetBoolean("HideFavoriteButton"); 3216 3217 if (listViewShowFavoriteButton) 3218 { 3219 listViewPage.Add("ListViewItemInfoContainerRight", new Block 3220 { 3221 Id = "ListViewItemFavorites", 3222 SortId = 10, 3223 Template = RenderListViewItemFavorites() 3224 }); 3225 } 3226 3227 //variant selector 3228 bool listViewShowCartButton = listViewSettings.GetBoolean("ShowAddToCartButton"); 3229 bool listViewShowVariantSelector = listViewSettings.GetList("Variants").SelectedValue == "selector"; 3230 if (listViewShowCartButton && listViewShowVariantSelector) 3231 { 3232 listViewPage.Add("ListViewItemRight", new Block 3233 { 3234 Id = "ListViewItemVariantSelector", 3235 SortId = 30, 3236 Template = RenderListViewItemVariantSelector() 3237 }); 3238 } 3239 3240 //static variants 3241 bool listViewShowStaticVariants = listViewSettings.GetList("Variants").SelectedValue == "static"; 3242 3243 if (listViewShowStaticVariants) 3244 { 3245 listViewPage.Add("ListViewItemRight", new Block 3246 { 3247 Id = "ListViewItemStaticVariants", 3248 SortId = 40, 3249 Template = RenderListViewItemStaticVariants() 3250 }); 3251 } 3252 3253 //download button 3254 bool listViewShowAddToDownloadButton = listViewSettings.GetBoolean("ShowAddToDownloadButton"); 3255 if (listViewShowAddToDownloadButton && Pageview.User != null) 3256 { 3257 listViewPage.Add("ListViewItemRight", new Block 3258 { 3259 Id = "ListViewItemDownloadButton", 3260 SortId = 60, 3261 Template = RenderListViewItemDownloadButton() 3262 }); 3263 } 3264 3265 //price 3266 bool listViewShowPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice"); 3267 if (listViewShowPrice && Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 3268 { 3269 listViewPage.Add("ListViewItemFooter", new Block 3270 { 3271 Id = "ListViewItemPrice", 3272 SortId = 10, 3273 Template = RenderListViewItemPrice() 3274 }); 3275 } 3276 } 3277 3278 @helper ListView() 3279 { 3280 <script id="ProductItemContainer" type="text/x-template"> 3281 {{#.}} 3282 <div id="Product{{id}}" class="grid__col-12 js-product dw-mod" data-template="ListViewItem" data-preloader="overlay"> 3283 {{#Product}} 3284 {{>ListViewItem}} 3285 {{/Product}} 3286 </div> 3287 {{/.}} 3288 </script> 3289 } 3290 3291 @helper RenderListViewItem() 3292 { 3293 List<Block> subBlocks = listViewPage.GetBlockListById("ListViewItem"); 3294 3295 <script id="ListViewItem" type="text/x-template"> 3296 {{#.}} 3297 <div class="grid product-list__list-item dw-mod js-product-scroll-trigger" data-params="{{googleImpression}}"> 3298 @RenderBlockList(subBlocks) 3299 </div> 3300 {{/.}} 3301 </script> 3302 } 3303 3304 @helper RenderListViewPrice() 3305 { 3306 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductList").GetBoolean("ShowBothPricesWithWithoutVAT"); 3307 bool isPricesWithVATEnabled = Dynamicweb.Ecommerce.Common.Context.DisplayPricesWithVat; 3308 3309 <script id="ListViewPriceContainer" type="text/x-template"> 3310 <div class="price price--product-list dw-mod">{{price}}</div> 3311 <div class="before-price {{onSale}} dw-mod">{{discount}}</div> 3312 @if (showVATPrice) 3313 { 3314 <div class="vat-price vat-price--product-list u-margin-top dw-mod"> 3315 @if (isPricesWithVATEnabled) 3316 { 3317 <span>@Translate("excl. VAT")</span><span> ({{priceWithoutVAT}})</span> 3318 } 3319 else 3320 { 3321 <span>@Translate("incl. VAT")</span><span> ({{priceWithVAT}})</span> 3322 } 3323 </div> 3324 } 3325 <text> 3326 {{#if priceRRP}} 3327 <div><small>@Translate("RRP") {{priceRRP}}</small></div> 3328 {{/if}} 3329 </text> 3330 </script> 3331 } 3332 3333 @helper RenderListViewAddToCart() 3334 { 3335 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 3336 3337 var addToCartBtn = new AddToCart 3338 { 3339 WrapperCssClass = "buttons-collection--right", 3340 AddButton = new AddToCartButton 3341 { 3342 HideTitle = false, 3343 ProductId = "{{productId}}", 3344 VariantId = "{{variantid}}", 3345 UnitId = "{{unitId}}", 3346 ProductInfo = "{{productInfo}}", 3347 BuyForPoints = pointShopOnly, 3348 OnClick = "{{facebookPixelAction}}", 3349 ExtraAttributes = new Dictionary<string, string> 3350 { 3351 { "{{disabledBuyButton}}", "" }, 3352 { "{{outOfStock}}", "" } 3353 } 3354 } 3355 }; 3356 3357 if (!pointShopOnly) 3358 { 3359 addToCartBtn.QuantitySelector = new QuantitySelector 3360 { 3361 Id = "Quantity{{id}}", 3362 ExtraAttributes = new Dictionary<string, string> 3363 { 3364 { "{{outOfStock}}", "" } 3365 } 3366 }; 3367 } 3368 3369 addToCartBtn.UnitSelector = new UnitSelector 3370 { 3371 OptionsContent = "{{#unitOptions}}{{>UnitOption}}{{/unitOptions}}", 3372 Id = "UnitOptions_{{id}}", 3373 SelectedOption = "{{unitName}}", 3374 CssClass = "{{#if hasOnlyOneUnit}}unit-selector--readonly{{/if}} {{hasUnits}}" 3375 }; 3376 3377 <script id="ListViewAddToCartContainer" type="text/x-template"> 3378 @Render(addToCartBtn) 3379 </script> 3380 } 3381 3382 @helper RenderListViewItemHiddenProperties() 3383 { 3384 <input type="hidden" name="ProductLoopCounter{{id}}" value="{{id}}" /> 3385 <input type="hidden" name="ProductID{{id}}" value="{{productId}}" /> 3386 <input type="hidden" name="VariantID{{id}}" value="{{variantid}}" id="Variant_{{id}}" /> 3387 <input type="hidden" name="UnitID{{id}}" value="{{unitId}}" id="Unit_{{id}}" /> 3388 <input type="hidden" name="Quantity{{id}}" value="1" id="Quantity_{{id}}" /> 3389 } 3390 3391 @helper RenderListViewItemLeft() 3392 { 3393 List<Block> subBlocks = listViewPage.GetBlockListById("ListViewItemLeft"); 3394 3395 string imageZoomOnHover = listViewSettings.GetBoolean("HoverImageZoom") ? "image-hover--zoom" : ""; 3396 3397 <div class="grid__col-md-4 {{noImage}} product-list__list-item__left u-no-padding u-color-light--bg dw-mod @imageZoomOnHover"> 3398 <div class="grid__cell"> 3399 @RenderBlockList(subBlocks) 3400 </div> 3401 </div> 3402 } 3403 3404 @helper RenderListViewItemImage() 3405 { 3406 bool secondaryImage = listViewSettings.GetString("HoverAlternatineImage") != null ? listViewSettings.GetBoolean("HoverAlternatineImage") : false; 3407 string alternativeImage = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("AlternativeImage")) ? Pageview.AreaSettings.GetItem("Settings").GetFile("AlternativeImage").PathUrlEncoded : "/Images/missing_image.jpg"; 3408 3409 var image = new Image() 3410 { 3411 Path = "{{image}}", 3412 Title = "{{name}}{{#if variantName}}, {{variantName}}{{/if}}", 3413 CssClass = "grid__cell-img grid__cell-img--centered", 3414 ImageDefault = new ImageSettings {Width = 300, Height = 300, Crop = 5, FillCanvas = true}, 3415 }; 3416 3417 if (secondaryImage) 3418 { 3419 image.ExtraAttributes.Add( 3420 "{{#if secondaryImage}}data-secondary-image-src{{/if}}", 3421 "{{#if secondaryImage}}/Admin/Public/GetImage.ashx?width=300&amp;height=300&amp;crop=5&amp;Compression=75&amp;FillCanvas=true&amp;DoNotUpscale=true&amp;image={{secondaryImage}}&AlternativeImage=" + alternativeImage + "{{/if}}" 3422 ); 3423 } 3424 <a href="{{link}}" 3425 onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" 3426 title="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}" 3427 class="u-position-relative u-block image-hover__wrapper dw-mod" 3428 tabindex="-1"> 3429 @Render(image) 3430 </a> 3431 } 3432 3433 @helper RenderListViewItemStickers() 3434 { 3435 <text> 3436 {{#StickersContainers}} 3437 {{>StickersContainer}} 3438 {{/StickersContainers}} 3439 </text> 3440 } 3441 3442 @helper RenderListViewItemTitle() 3443 { 3444 <a href="{{link}}" onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" title="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}"> 3445 <h2 class="u-no-margin">{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}</h2> 3446 </a> 3447 } 3448 3449 @helper RenderListViewItemNumber() 3450 { 3451 <div class="item-number dw-mod">{{number}}</div> 3452 } 3453 3454 @helper RenderListViewItemStock() 3455 { 3456 <text>{{#unless hideStockDisallowOrdering}}</text> 3457 <text>{{#if stockText}}</text> 3458 <div> 3459 <span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span> 3460 <span class="u-margin-right--lg"> {{stockText}}</span> 3461 {{deliveryText}} 3462 </div> 3463 <text>{{/if}}</text> 3464 <text>{{/unless}}</text> 3465 } 3466 3467 @helper RenderListViewItemFavorites() 3468 { 3469 <div class="favorites u-pull--right {{hasVariants}} dw-mod" {{hasVariants}}> 3470 {{#Favorite}} 3471 {{>FavoriteTemplate}} 3472 {{/Favorite}} 3473 </div> 3474 } 3475 3476 @helper RenderListViewItemDescription() 3477 { 3478 <div class="u-margin-top u-margin-bottom"> 3479 {{{description}}} 3480 </div> 3481 } 3482 3483 @helper RenderListViewItemVariantSelector() 3484 { 3485 string pageId = GetGlobalValue("Global:Page.ID"); 3486 var ecommerceSettings = Pageview.AreaSettings.GetItem("Ecommerce"); 3487 string variantsLayout = ecommerceSettings.GetString("VariantsLayout") != null ? ecommerceSettings.GetList("VariantsLayout").SelectedValue : "buttons"; 3488 bool isLiveProductInfoActive = Converter.ToBoolean(GetGlobalValue("Global:LiveIntegration.IsLazyLoadingForProductInfoEnabled")); 3489 3490 <div data-template="VariantsTemplate" class="js-variants grid__cell" data-combinations="{{combinationsStringArray}}" data-variants="{{variantsStringArray}}" data-variant-selections="{{variantSelections}}" data-total-variant-groups="{{variantGroupsCount}}" data-selection-complete="UpdateData" data-page-id="@pageId" data-product-id="{{productId}}" data-live-product-info="@(isLiveProductInfoActive.ToString().ToLowerInvariant())"> 3491 {{#Variants}} 3492 @if (variantsLayout == "buttons") { 3493 <text>{{>VariantsTemplate}}</text> 3494 } else { 3495 <text>{{>DropdownVariantsTemplate}}</text> 3496 } 3497 {{/Variants}} 3498 </div> 3499 <small class="js-help-text help-text {{hideViewMore}} {{hideHelpText}}">@Translate("Please select variant!")</small> 3500 } 3501 3502 @helper RenderListViewItemStaticVariants() 3503 { 3504 string variantsSize = listViewSettings.GetList("StaticVariantsDisplay") != null ? listViewSettings.GetList("StaticVariantsDisplay").SelectedValue : "sm"; 3505 3506 <text> 3507 {{#Variants}} 3508 @if ( variantsSize == "lg" ) { 3509 <text> 3510 {{>StaticVariantsLgTemplate}} 3511 </text> 3512 } else { 3513 <text> 3514 {{>StaticVariantsTemplate}} 3515 </text> 3516 } 3517 {{/Variants}} 3518 3519 {{#ifCond variantGroupsCount '>' 1}} 3520 <div class="static-variant"> 3521 @Translate("More options available") 3522 </div> 3523 {{/ifCond}} 3524 </text> 3525 } 3526 3527 @helper RenderListViewItemFooter() 3528 { 3529 List<Block> subBlocks = listViewPage.GetBlockListById("ListViewItemFooter"); 3530 3531 if (Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 3532 { 3533 <div class="grid__cell-footer"> 3534 <div class="grid__cell"> 3535 <div class="product-list__list-item__price-actions dw-mod"> 3536 @RenderBlockList(subBlocks) 3537 </div> 3538 </div> 3539 </div> 3540 } 3541 else 3542 { 3543 <button type="button" id="CartButton_{{id}}" class="u-hidden"></button> 3544 } 3545 } 3546 3547 @helper RenderListViewItemPrice() 3548 { 3549 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 3550 bool showCartButton = listViewSettings.GetBoolean("ShowAddToCartButton"); 3551 3552 <text> 3553 {{#unless hidePriceDisallowOrdering}} 3554 <div class="u-margin-bottom"> 3555 @if (pointShopOnly) 3556 { 3557 <text> 3558 {{#if havePointPrice}} 3559 <div class="price price--product-list dw-mod">{{points}} @Translate("points")</div> 3560 @if (showCartButton) 3561 { 3562 <text> 3563 {{#unless canBePurchasedWithPoints}} 3564 <small class="help-text u-no-margin">@Translate("Not enough points to buy this")</small> 3565 {{/unless}} 3566 </text> 3567 } 3568 {{else}} 3569 @Translate("Not available") 3570 {{/if}} 3571 </text> 3572 3573 } 3574 else 3575 { 3576 <text> 3577 {{#if isLiveProductInfoActive}} 3578 <div class="js-handlebars-root js-live-info-container" 3579 data-template="ListViewPriceContainer" 3580 data-preloader="minimal" 3581 data-product-id="{{productId}}"> 3582 </div> 3583 {{else}} 3584 {{>ListViewPriceContainer}} 3585 {{/if}} 3586 </text> 3587 } 3588 </div> 3589 {{/unless}} 3590 </text> 3591 } 3592 3593 @helper RenderListViewItemViewButton() 3594 { 3595 string viewMoreText = listViewSettings.GetString("ViewMoreText"); 3596 viewMoreText = !string.IsNullOrEmpty(viewMoreText) ? viewMoreText : "View"; 3597 3598 @Render(new Link 3599 { 3600 Href = "{{link}}", 3601 Id = "CartButton_{{id}}", 3602 Title = Translate(viewMoreText), 3603 OnClick = "{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}", 3604 ButtonLayout = ButtonLayout.Secondary, 3605 CssClass = "u-no-margin" 3606 }); 3607 } 3608 3609 @helper RenderListViewItemAddToCart() 3610 { 3611 <text> 3612 {{#if isLiveProductInfoActive}} 3613 <div class="js-handlebars-root js-live-info-container" 3614 data-template="ListViewAddToCartContainer" 3615 data-preloader="none" 3616 data-product-id="{{productId}}"> 3617 </div> 3618 {{else}} 3619 {{>ListViewAddToCartContainer}} 3620 {{/if}} 3621 </text> 3622 } 3623 3624 @helper RenderListViewItemActions() 3625 { 3626 bool showCartButton = listViewSettings.GetBoolean("ShowAddToCartButton"); 3627 bool showViewButton = listViewSettings.GetBoolean("ShowViewButton"); 3628 bool hasVariantSelector = listViewSettings.GetList("Variants") != null && listViewSettings.GetList("Variants").SelectedValue == "selector"; 3629 3630 if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 3631 { 3632 if (showCartButton) 3633 { 3634 if (!showViewButton || hasVariantSelector) 3635 { 3636 <text>{{#if hideAddToCartButton}}</text> 3637 <div>@RenderListViewItemViewButton()</div> 3638 <text>{{else}}</text> 3639 @RenderListViewItemAddToCart() 3640 <text>{{/if}}</text> 3641 } 3642 else 3643 { 3644 <div>@RenderListViewItemViewButton()</div> 3645 } 3646 } 3647 else if (showViewButton) 3648 { 3649 <div>@RenderListViewItemViewButton()</div> 3650 } 3651 } 3652 else if (showViewButton) 3653 { 3654 <div>@RenderListViewItemViewButton()</div> 3655 } 3656 } 3657 3658 @helper RenderListViewItemDownloadButton() 3659 { 3660 <div class="grid__cell-footer u-margin-top"> 3661 <div class="grid__cell"> 3662 <button type="button" class="btn btn--primary btn--condensed u-no-margin u-pull--right dw-mod js-add-to-downloads" title="@Translate("Add")" data-product-id="{{productId}}"> 3663 <i class="fas fa-plus js-button-icon"></i> 3664 <span class="js-button-text">@Translate("Add")</span> 3665 </button> 3666 </div> 3667 </div> 3668 } 3669 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 3670 @using Dynamicweb.Core 3671 @using System 3672 @using System.Web 3673 @using System.Collections.Generic 3674 @using Dynamicweb.Rapido.Blocks 3675 @using Dynamicweb.Rapido.Blocks.Components 3676 @using Dynamicweb.Rapido.Blocks.Components.General 3677 @using Dynamicweb.Rapido.Services 3678 3679 @functions { 3680 BlocksPage gridViewPage = BlocksPage.GetBlockPage("ProductList"); 3681 Dynamicweb.Frontend.ItemViewModel gridViewSettings = null; 3682 } 3683 3684 @if (Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableGridView")) 3685 { 3686 gridViewSettings = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView"); 3687 3688 BlocksPage gridViewPage = BlocksPage.GetBlockPage("ProductList"); 3689 3690 gridViewPage.Add("Views", new Block 3691 { 3692 Id = "ProductGridItemContainer", 3693 Name = "th", 3694 SortId = 20 3695 }); 3696 3697 Block gridViewScripts = new Block 3698 { 3699 Id = "GridViewScripts", 3700 SortId = 20, 3701 Template = GridView(), 3702 BlocksList = new List<Block> { 3703 new Block 3704 { 3705 Id = "GridViewItem", 3706 SortId = 10, 3707 Template = RenderGridViewItem(), 3708 SkipRenderBlocksList = true, 3709 BlocksList = new List<Block> { 3710 new Block 3711 { 3712 Id = "GridViewItemHiddenProperties", 3713 SortId = 10, 3714 Template = RenderGridViewItemHiddenProperties() 3715 }, 3716 new Block 3717 { 3718 Id = "GridViewItemImageContainer", 3719 SortId = 20, 3720 SkipRenderBlocksList = true, 3721 Template = RenderGridViewItemImageContainer(), 3722 BlocksList = new List<Block> { 3723 new Block 3724 { 3725 Id = "GridViewItemImage", 3726 SortId = 10, 3727 Template = RenderGridViewItemImage() 3728 }, 3729 new Block 3730 { 3731 Id = "GridViewItemStickers", 3732 SortId = 20, 3733 Template = RenderGridViewItemStickers() 3734 } 3735 } 3736 }, 3737 new Block 3738 { 3739 Id = "GridViewItemInfoContainer", 3740 SortId = 30, 3741 SkipRenderBlocksList = true, 3742 Template = RenderGridViewItemInfoContainer(), 3743 BlocksList = new List<Block> { 3744 new Block 3745 { 3746 Id = "GridViewItemTitle", 3747 SortId = 10, 3748 Template = RenderGridViewItemTitle() 3749 } 3750 } 3751 }, 3752 new Block 3753 { 3754 Id = "GridViewItemFooter", 3755 SortId = 40, 3756 SkipRenderBlocksList = true, 3757 Template = RenderGridViewItemFooter(), 3758 BlocksList = new List<Block> { 3759 new Block 3760 { 3761 Id = "GridViewItemActions", 3762 SortId = 10, 3763 Template = RenderGridViewItemActions() 3764 } 3765 } 3766 } 3767 } 3768 }, 3769 new Block 3770 { 3771 Id = "GridViewPrice", 3772 SortId = 20, 3773 Template = RenderGridViewPrice() 3774 }, 3775 new Block 3776 { 3777 Id = "GridViewAddToCart", 3778 SortId = 20, 3779 Template = RenderGridViewAddToCart() 3780 } 3781 } 3782 }; 3783 gridViewPage.Add("BottomSnippets", gridViewScripts); 3784 3785 //favorites 3786 bool gridViewShowFavoriteButton = !gridViewSettings.GetBoolean("HideFavoriteButton"); 3787 3788 if (gridViewShowFavoriteButton) 3789 { 3790 gridViewPage.Add("GridViewItemImageContainer", new Block 3791 { 3792 Id = "GridViewItemFavorites", 3793 SortId = 30, 3794 Template = RenderGridViewItemFavorites() 3795 }); 3796 } 3797 3798 //number 3799 bool gridViewShowNumber = gridViewSettings.GetBoolean("ShowProductNumber"); 3800 3801 if (gridViewShowNumber) 3802 { 3803 gridViewPage.Add("GridViewItemInfoContainer", new Block 3804 { 3805 Id = "GridViewItemNumber", 3806 SortId = 20, 3807 Template = RenderGridViewItemNumber() 3808 }); 3809 } 3810 3811 //price 3812 bool gridViewShowPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice"); 3813 if (gridViewShowPrice && Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 3814 { 3815 gridViewPage.Add("GridViewItemInfoContainer", new Block 3816 { 3817 Id = "GridViewItemPrice", 3818 SortId = 30, 3819 Template = RenderGridViewItemPrice() 3820 }); 3821 } 3822 3823 //stock 3824 bool gridViewShowStock = gridViewSettings.GetBoolean("ShowStockAndShipping"); 3825 3826 if (User.IsStockInfoAllowed() && gridViewShowStock) 3827 { 3828 gridViewPage.Add("GridViewItemFooter", new Block 3829 { 3830 Id = "GridViewItemStockAndDelivery", 3831 SortId = 20, 3832 Template = RenderGridViewItemStockAndDelivery() 3833 }); 3834 } 3835 3836 //static variants 3837 bool gridViewShowStaticVariants = gridViewSettings.GetBoolean("ShowStaticVariants"); 3838 3839 if (gridViewShowStaticVariants) 3840 { 3841 gridViewPage.Add("GridViewItemFooter", new Block 3842 { 3843 Id = "GridViewItemStaticVariants", 3844 SortId = 30, 3845 Template = RenderGridViewItemStaticVariants() 3846 }); 3847 } 3848 3849 //download button 3850 bool gridViewShowAddToDownloadButton = gridViewSettings.GetBoolean("ShowAddToDownloadButton"); 3851 3852 if (gridViewShowAddToDownloadButton && Pageview.User != null) 3853 { 3854 gridViewPage.Add("GridViewItemFooter", new Block 3855 { 3856 Id = "GridViewItemDownloadButton", 3857 SortId = 40, 3858 Template = RenderGridViewItemDownloadButton() 3859 }); 3860 } 3861 } 3862 3863 @helper GridView() 3864 { 3865 int columnsCount = gridViewSettings.GetList("Columns") != null ? Converter.ToInt32(gridViewSettings.GetList("Columns").SelectedValue) : 3; 3866 string imageZoomOnHover = gridViewSettings.GetBoolean("HoverImageZoom") ? "image-hover--zoom" : ""; 3867 3868 <script id="ProductGridItemContainer" type="text/x-template"> 3869 {{#.}} 3870 <div id="Product{{id}}" data-template="GridViewItem" data-preloader="overlay" class="grid__col-lg-@(12 / columnsCount) grid__col-md-@(12 / columnsCount) grid__col-sm-@(12 / columnsCount) grid__col-xs-6 product-list__grid-item @imageZoomOnHover dw-mod"> 3871 {{#Product}} 3872 {{>GridViewItem}} 3873 {{/Product}} 3874 </div> 3875 {{/.}} 3876 </script> 3877 } 3878 3879 @helper RenderGridViewItem() 3880 { 3881 List<Block> subBlocks = gridViewPage.GetBlockListById("GridViewItem"); 3882 3883 <script id="GridViewItem" type="text/x-template"> 3884 {{#.}} 3885 <div class="grid__col--auto js-product-scroll-trigger u-no-padding u-full-height" data-params="{{googleImpression}}"> 3886 @RenderBlockList(subBlocks) 3887 </div> 3888 {{/.}} 3889 </script> 3890 } 3891 3892 @helper RenderGridViewPrice() 3893 { 3894 int columnsCount = gridViewSettings.GetList("Columns") != null ? Converter.ToInt32(gridViewSettings.GetList("Columns").SelectedValue) : 4; 3895 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductList").GetBoolean("ShowBothPricesWithWithoutVAT"); 3896 bool isPricesWithVATEnabled = Dynamicweb.Ecommerce.Common.Context.DisplayPricesWithVat; 3897 3898 <script id="GridViewPriceContainer" type="text/x-template"> 3899 <div class="price price--product-list dw-mod">{{price}}</div> 3900 <div class="before-price {{onSale}} dw-mod">{{discount}}</div> 3901 @if (showVATPrice) 3902 { 3903 <div class="vat-price vat-price--product-list u-margin-top dw-mod"> 3904 @if (columnsCount <= 4) { 3905 if (isPricesWithVATEnabled) 3906 { 3907 <span>@Translate("excl. VAT")</span><span> ({{priceWithoutVAT}})</span> 3908 } 3909 else 3910 { 3911 <span>@Translate("incl. VAT")</span><span> ({{priceWithVAT}})</span> 3912 } 3913 } else { 3914 if (isPricesWithVATEnabled) 3915 { 3916 <div>@Translate("excl. VAT")</div><div>({{priceWithoutVAT}})</div> 3917 } 3918 else 3919 { 3920 <div>@Translate("incl. VAT")</div><div>({{priceWithVAT}})</div> 3921 } 3922 } 3923 </div> 3924 } 3925 <text> 3926 {{#if priceRRP}} 3927 <div><small>@Translate("RRP") {{priceRRP}}</small></div> 3928 {{/if}} 3929 </text> 3930 </script> 3931 } 3932 3933 @helper RenderGridViewAddToCart() 3934 { 3935 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 3936 string wrapperClass = "buttons-collection--center"; 3937 int columnsCount = gridViewSettings.GetList("Columns") != null ? Converter.ToInt32(gridViewSettings.GetList("Columns").SelectedValue) : 4; 3938 bool hideButtonText = columnsCount >= 4 || Pageview.Device.ToString() == "Mobile" || Pageview.Device.ToString() == "Tablet"; 3939 3940 if (pointShopOnly && columnsCount <= 4) 3941 { 3942 hideButtonText = false; 3943 } 3944 3945 var addToCartBtn = new AddToCart 3946 { 3947 WrapperCssClass = wrapperClass, 3948 AddButton = new AddToCartButton 3949 { 3950 HideTitle = hideButtonText, 3951 ProductId = "{{productId}}", 3952 VariantId = "{{variantid}}", 3953 UnitId = "{{unitId}}", 3954 ProductInfo = "{{productInfo}}", 3955 BuyForPoints = pointShopOnly, 3956 OnClick = "{{facebookPixelAction}}", 3957 ExtraAttributes = new Dictionary<string, string> 3958 { 3959 { "{{disabledBuyButton}}", "" }, 3960 { "{{outOfStock}}", "" } 3961 } 3962 } 3963 }; 3964 3965 if (!pointShopOnly) 3966 { 3967 addToCartBtn.QuantitySelector = new QuantitySelector 3968 { 3969 Id = "Quantity{{id}}", 3970 ExtraAttributes = new Dictionary<string, string> 3971 { 3972 { "{{outOfStock}}", "" } 3973 } 3974 3975 }; 3976 } 3977 3978 <script id="GridViewAddToCartContainer" type="text/x-template"> 3979 @Render(addToCartBtn) 3980 </script> 3981 } 3982 3983 @helper RenderGridViewItemHiddenProperties() 3984 { 3985 <input type="hidden" name="ProductLoopCounter{{id}}" value="{{id}}" /> 3986 <input type="hidden" name="ProductID{{id}}" value="{{productId}}" /> 3987 <input type="hidden" name="VariantID{{id}}" value="{{variantid}}" id="Variant_{{id}}" /> 3988 <input type="hidden" name="UnitID{{id}}" value="{{unitId}}" id="Unit_{{id}}" /> 3989 <input type="hidden" name="Quantity{{id}}" value="1" id="Quantity_{{id}}" /> 3990 } 3991 3992 @helper RenderGridViewItemImageContainer() 3993 { 3994 List<Block> subBlocks = gridViewPage.GetBlockListById("GridViewItemImageContainer"); 3995 3996 <div class="grid__cell product-list__grid-item__image dw-mod {{noImage}}"> 3997 @RenderBlockList(subBlocks) 3998 </div> 3999 } 4000 4001 @helper RenderGridViewItemImage() 4002 { 4003 bool secondaryImage = gridViewSettings.GetString("HoverAlternatineImage") != null ? gridViewSettings.GetBoolean("HoverAlternatineImage") : false; 4004 string alternativeImage = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("AlternativeImage")) ? Pageview.AreaSettings.GetItem("Settings").GetFile("AlternativeImage").PathUrlEncoded : "/Images/missing_image.jpg"; 4005 4006 var image = new Image() 4007 { 4008 Path = "{{image}}", 4009 Title = "{{name}}{{#if variantName}}, {{variantName}}{{/if}}", 4010 CssClass = "grid__cell-img grid__cell-img--centered u-padding", 4011 ImageDefault = new ImageSettings {Width = 300, Height = 300, Crop = 5, FillCanvas = true}, 4012 }; 4013 4014 if (secondaryImage) 4015 { 4016 image.ExtraAttributes.Add( 4017 "{{#if secondaryImage}}data-secondary-image-src{{/if}}", 4018 "{{#if secondaryImage}}/Admin/Public/GetImage.ashx?width=300&amp;height=300&amp;crop=5&amp;Compression=75&amp;FillCanvas=true&amp;DoNotUpscale=true&amp;image={{secondaryImage}}&AlternativeImage=" + alternativeImage + "{{/if}}" 4019 ); 4020 } 4021 4022 <a href="{{link}}" 4023 onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" 4024 title="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}" 4025 class="u-block u-position-relative image-hover__wrapper dw-mod" 4026 tabindex="-1"> 4027 @Render(image) 4028 </a> 4029 } 4030 4031 @helper RenderGridViewItemStickers() 4032 { 4033 <text> 4034 {{#StickersContainers}} 4035 {{>StickersContainer}} 4036 {{/StickersContainers}} 4037 </text> 4038 } 4039 4040 @helper RenderGridViewItemFavorites() 4041 { 4042 <div class="favorites favorites--for-grid-view u-pull--right {{hasVariants}} dw-mod" {{hasVariants}}> 4043 {{#Favorite}} 4044 {{>FavoriteTemplate}} 4045 {{/Favorite}} 4046 </div> 4047 } 4048 4049 @helper RenderGridViewItemInfoContainer() 4050 { 4051 List<Block> subBlocks = gridViewPage.GetBlockListById("GridViewItemInfoContainer"); 4052 4053 <div class="grid__cell product-list__grid-item__price-info dw-mod"> 4054 @RenderBlockList(subBlocks) 4055 </div> 4056 } 4057 4058 @helper RenderGridViewItemTitle() 4059 { 4060 <a href="{{link}}" class="u-color-inherit" onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" title="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}"> 4061 <h6 class="u-condensed-text u-bold">{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}</h6> 4062 </a> 4063 } 4064 4065 @helper RenderGridViewItemNumber() 4066 { 4067 <div class="item-number dw-mod">{{number}}</div> 4068 } 4069 4070 @helper RenderGridViewItemPrice() 4071 { 4072 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 4073 bool showCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToCartButton"); 4074 4075 if (pointShopOnly) 4076 { 4077 <text> 4078 {{#unless hidePriceDisallowOrdering}} 4079 {{#if havePointPrice}} 4080 <div class="price price--product-list dw-mod">{{points}} @Translate("points")</div> 4081 @if (showCartButton) 4082 { 4083 <text> 4084 {{#unless canBePurchasedWithPoints}} 4085 <small class="help-text u-no-margin">@Translate("Not enough points to buy this")</small> 4086 {{/unless}} 4087 </text> 4088 } 4089 {{else}} 4090 @Translate("Not available") 4091 {{/if}} 4092 {{/unless}} 4093 </text> 4094 4095 } 4096 else 4097 { 4098 <text>{{#unless hidePriceDisallowOrdering}}</text> 4099 <text> 4100 {{#if isLiveProductInfoActive}} 4101 <div class="js-handlebars-root js-live-info-container" 4102 data-template="GridViewPriceContainer" 4103 data-preloader="minimal" 4104 data-product-id="{{productId}}"> 4105 </div> 4106 {{else}} 4107 {{>GridViewPriceContainer}} 4108 {{/if}} 4109 </text> 4110 <text>{{/unless}}</text> 4111 } 4112 } 4113 4114 @helper RenderGridViewItemFooter() 4115 { 4116 List<Block> subBlocks = gridViewPage.GetBlockListById("GridViewItemFooter"); 4117 bool showStaticVariants = gridViewSettings.GetBoolean("ShowStaticVariants"); 4118 string footerClasses = showStaticVariants ? "u-min-h120px" : ""; 4119 4120 <div class="product-list__grid-item__footer @footerClasses dw-mod"> 4121 @RenderBlockList(subBlocks) 4122 </div> 4123 } 4124 4125 @helper RenderGridViewItemViewButton() 4126 { 4127 string viewMoreText = gridViewSettings.GetString("ViewMoreText"); 4128 viewMoreText = !string.IsNullOrEmpty(viewMoreText) ? viewMoreText : "View"; 4129 4130 @Render(new Link 4131 { 4132 Href = "{{link}}", 4133 Id = "CartButton_{{id}}", 4134 Title = Translate(viewMoreText), 4135 OnClick = "{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}", 4136 ButtonLayout = ButtonLayout.Secondary, 4137 CssClass = "u-no-margin" 4138 }); 4139 } 4140 4141 @helper RenderGridViewItemAddToCart() 4142 { 4143 <text> 4144 {{#if isLiveProductInfoActive}} 4145 <div class="js-handlebars-root js-live-info-container" 4146 data-template="GridViewAddToCartContainer" 4147 data-preloader="none" 4148 data-product-id="{{productId}}"> 4149 </div> 4150 {{else}} 4151 {{>GridViewAddToCartContainer}} 4152 {{/if}} 4153 </text> 4154 } 4155 4156 @helper RenderGridViewItemActions() 4157 { 4158 bool showCartButton = gridViewSettings.GetBoolean("ShowAddToCartButton"); 4159 bool showViewButton = gridViewSettings.GetBoolean("ShowViewButton"); 4160 4161 if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 4162 { 4163 if (showCartButton) 4164 { 4165 if (!showViewButton) 4166 { 4167 <text>{{#if hideAddToCartButton}}</text> 4168 <div>@RenderGridViewItemViewButton()</div> 4169 <text>{{else}}</text> 4170 @RenderGridViewItemAddToCart() 4171 <text>{{/if}}</text> 4172 } 4173 else 4174 { 4175 @RenderGridViewItemViewButton() 4176 } 4177 } 4178 else if (showViewButton) 4179 { 4180 <div>@RenderGridViewItemViewButton()</div> 4181 } 4182 } 4183 else if (showViewButton) 4184 { 4185 <div>@RenderGridViewItemViewButton()</div> 4186 } 4187 } 4188 4189 @helper RenderGridViewItemStockAndDelivery() 4190 { 4191 <text>{{#unless hideStockDisallowOrdering}}</text> 4192 <text>{{#if stockText}}</text> 4193 <div class="u-margin-top"> 4194 <div><span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span> <span class="stock-text">{{stockText}}</span></div> 4195 <div> 4196 {{#if deliveryText}} 4197 {{deliveryText}} 4198 {{else}} 4199 - 4200 {{/if}} 4201 </div> 4202 </div> 4203 <text>{{/if}}</text> 4204 <text>{{/unless}}</text> 4205 } 4206 4207 @helper RenderGridViewItemStaticVariants() 4208 { 4209 string variantsSize = gridViewSettings.GetList("StaticVariantsDisplay") != null ? gridViewSettings.GetList("StaticVariantsDisplay").SelectedValue : "sm"; 4210 4211 <text> 4212 {{#Variants}} 4213 @if ( variantsSize == "lg" ) { 4214 <text> 4215 {{>StaticVariantsLgTemplate}} 4216 </text> 4217 } else { 4218 <text> 4219 {{>StaticVariantsTemplate}} 4220 </text> 4221 } 4222 {{/Variants}} 4223 4224 {{#ifCond variantGroupsCount '>' 1}} 4225 <div class="static-variant"> 4226 @Translate("More options available") 4227 </div> 4228 {{/ifCond}} 4229 4230 {{#ifCond variantGroupsCount '==' 0}} 4231 <div class="static-variant"></div> 4232 {{/ifCond}} 4233 </text> 4234 } 4235 4236 @helper RenderGridViewItemDownloadButton() 4237 { 4238 <button type="button" class="btn btn--primary u-no-margin u-margin-top btn--condensed dw-mod js-add-to-downloads" title="@Translate("Add")" data-product-id="{{productId}}"> 4239 @Render(new Icon { Prefix = "fas", Name = "fa-plus", CssClass = "js-button-icon" }) 4240 <span class="js-button-text">@Translate("Add")</span> 4241 </button> 4242 } 4243 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 4244 @using Dynamicweb.Core 4245 @using System 4246 @using System.Web 4247 @using System.Collections.Generic 4248 @using Dynamicweb.Rapido.Blocks 4249 @using Dynamicweb.Rapido.Blocks.Components 4250 @using Dynamicweb.Rapido.Blocks.Components.General 4251 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 4252 @using Dynamicweb.Rapido.Services 4253 4254 @functions { 4255 BlocksPage detailsViewPage = BlocksPage.GetBlockPage("ProductList"); 4256 Dynamicweb.Frontend.ItemViewModel detailsViewSettings = null; 4257 4258 /* this function need because in details view we have specipfic situation 4259 * when price need to be placed between unit selector and quantity selector 4260 */ 4261 4262 UnitSelector getUnitsSelector() 4263 { 4264 return new UnitSelector 4265 { 4266 OptionsContent = "{{#unitOptions}}{{>UnitOption}}{{/unitOptions}}", 4267 Id = "UnitOptions_{{id}}", 4268 SelectedOption = "{{unitName}}", 4269 CssClass = "product-list__details-units-selector {{#if hasOnlyOneUnit}}unit-selector--readonly{{/if}} {{hasUnits}}" 4270 }; 4271 } 4272 } 4273 4274 @if (Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableDetailsView")) 4275 { 4276 detailsViewSettings = Pageview.AreaSettings.GetItem("ProductList").GetItem("DetailsView"); 4277 4278 detailsViewPage.Add("Views", new Block 4279 { 4280 Id = "ProductDetailsItemContainer", 4281 Name = "list", 4282 SortId = 30 4283 }); 4284 4285 Block detailsViewScripts = new Block 4286 { 4287 Id = "DetailsViewScripts", 4288 SortId = 30, 4289 Template = DetailsView(), 4290 BlocksList = new List<Block> 4291 { 4292 new Block 4293 { 4294 Id = "DetailsViewItem", 4295 SortId = 10, 4296 Template = RenderDetailsViewItem(), 4297 SkipRenderBlocksList = true, 4298 BlocksList = new List<Block> { 4299 new Block 4300 { 4301 Id = "DetailsViewItemHiddenProperties", 4302 SortId = 10, 4303 Template = RenderDetailsViewItemHiddenProperties() 4304 }, 4305 new Block 4306 { 4307 Id = "DetailsViewItemLeft", 4308 SortId = 10, 4309 Design = new Design 4310 { 4311 CssClass = "product-list__details-item__left grid__cell dw-mod" 4312 }, 4313 BlocksList = new List<Block> { 4314 new Block 4315 { 4316 Id = "DetailsViewItemInfoContainer", 4317 SortId = 20, 4318 Design = new Design 4319 { 4320 CssClass = "product-list__details-info dw-mod" 4321 }, 4322 BlocksList = new List<Block> { 4323 new Block 4324 { 4325 Id = "DetailsViewItemTitle", 4326 SortId = 10, 4327 Template = RenderDetailsViewItemTitle() 4328 }, 4329 new Block 4330 { 4331 Id = "DetailsViewItemStickers", 4332 SortId = 50, 4333 Template = RenderDetailsViewItemStickers() 4334 } 4335 } 4336 } 4337 } 4338 }, 4339 new Block 4340 { 4341 Id = "DetailsViewItemRight", 4342 SortId = 20, 4343 Design = new Design 4344 { 4345 CssClass = "product-list__details-item__right grid__cell dw-mod" 4346 }, 4347 BlocksList = new List<Block> { 4348 new Block { 4349 Id = "DetailsViewItemRightBottom", 4350 SortId = 20, 4351 Design = new Design 4352 { 4353 CssClass = "u-flex product-list__details-right-bottom-section dw-mod" 4354 }, 4355 BlocksList = new List<Block> { 4356 new Block 4357 { 4358 Id = "DetailsViewItemActions", 4359 SortId = 30, 4360 Template = RenderDetailsViewItemActions() 4361 } 4362 } 4363 } 4364 } 4365 } 4366 } 4367 }, 4368 new Block 4369 { 4370 Id = "DetailsViewPrice", 4371 SortId = 20, 4372 Template = RenderDetailsViewPrice() 4373 }, 4374 new Block 4375 { 4376 Id = "DetailsViewAddToCart", 4377 SortId = 20, 4378 Template = RenderDetailsViewAddToCart() 4379 }, 4380 new Block 4381 { 4382 Id = "DetailsViewUnitSelector", 4383 SortId = 30, 4384 Template = RenderDetailsViewUnitSelector() 4385 } 4386 } 4387 }; 4388 detailsViewPage.Add("BottomSnippets", detailsViewScripts); 4389 4390 //image 4391 bool detailsViewShowImage = detailsViewSettings.GetBoolean("ShowImage"); 4392 4393 if (detailsViewShowImage) 4394 { 4395 detailsViewPage.Add("DetailsViewItemLeft", new Block 4396 { 4397 Id = "DetailsViewItemImage", 4398 SortId = 10, 4399 Template = RenderDetailsViewItemImage() 4400 }); 4401 } 4402 4403 //number 4404 bool detailsViewShowNumber = detailsViewSettings.GetBoolean("ShowProductNumber"); 4405 4406 if (detailsViewShowNumber) 4407 { 4408 detailsViewPage.Add("DetailsViewItemInfoContainer", new Block 4409 { 4410 Id = "ProductDetailsItemNumber", 4411 SortId = 30, 4412 Template = RenderDetailsViewItemNumber() 4413 }); 4414 } 4415 4416 //static variants 4417 bool detailsViewShowStaticVariants = detailsViewSettings.GetBoolean("ShowStaticVariants"); 4418 4419 if (detailsViewShowStaticVariants) 4420 { 4421 detailsViewPage.Add("DetailsViewItemInfoContainer", new Block 4422 { 4423 Id = "DetailsViewItemStaticVariants", 4424 SortId = 30, 4425 Template = RenderDetailsViewItemStaticVariants() 4426 }); 4427 } 4428 4429 //stock 4430 bool detailsViewShowStock = detailsViewSettings.GetBoolean("ShowStockAndShipping"); 4431 4432 if (User.IsStockInfoAllowed() && detailsViewShowStock) 4433 { 4434 detailsViewPage.Add("DetailsViewItemInfoContainer", new Block 4435 { 4436 Id = "DetailsViewItemStock", 4437 SortId = 40, 4438 Template = RenderDetailsViewItemStock() 4439 }); 4440 } 4441 4442 //price 4443 bool detailsViewShowPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice"); 4444 if (detailsViewShowPrice && Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 4445 { 4446 detailsViewPage.Add("DetailsViewItemRightBottom", new Block { 4447 Id = "DetailsViewUnitSelector", 4448 SortId = 10, 4449 Template = RenderDetailsViewItemUnitSelector() 4450 }); 4451 4452 detailsViewPage.Add("DetailsViewItemRightBottom", new Block 4453 { 4454 Id = "ProductDetailsItemPrice", 4455 SortId = 20, 4456 Template = RenderDetailsViewItemPrice() 4457 }); 4458 } 4459 4460 //favorites 4461 bool detailsViewShowFavoriteButton = !detailsViewSettings.GetBoolean("HideFavoriteButton"); 4462 4463 if (detailsViewShowFavoriteButton && Pageview.User != null) 4464 { 4465 detailsViewPage.Add("DetailsViewItemRightBottom", new Block 4466 { 4467 Id = "DetailsViewItemFavorites", 4468 SortId = 40, 4469 Template = RenderDetailsViewItemFavorites() 4470 }); 4471 } 4472 4473 //download button 4474 bool detailsViewShowAddToDownloadButton = detailsViewSettings.GetBoolean("ShowAddToDownloadButton"); 4475 4476 if (detailsViewShowAddToDownloadButton && Pageview.User != null) 4477 { 4478 detailsViewPage.Add("DetailsViewItemRightBottom", new Block 4479 { 4480 Id = "DetailsViewItemDownloadButton", 4481 SortId = 20, 4482 Template = RenderDetailsViewItemDownloadButton() 4483 }); 4484 } 4485 } 4486 4487 @helper DetailsView() 4488 { 4489 <script id="ProductDetailsItemContainer" type="text/x-template"> 4490 {{#.}} 4491 <div id="Product{{id}}" data-template="DetailsViewItem" data-preloader="overlay" class="grid__col-12 u-no-padding-y js-product dw-mod" style="z-index: {{zIndex}}"> 4492 {{#Product}} 4493 {{>DetailsViewItem}} 4494 {{/Product}} 4495 </div> 4496 {{/.}} 4497 </script> 4498 } 4499 4500 @helper RenderDetailsViewItem() 4501 { 4502 List<Block> subBlocks = detailsViewPage.GetBlockListById("DetailsViewItem"); 4503 4504 <script id="DetailsViewItem" type="text/x-template"> 4505 {{#.}} 4506 <div class="product-list__details-item grid__col-12 dw-mod js-product-scroll-trigger" data-params="{{googleImpression}}"> 4507 @RenderBlockList(subBlocks) 4508 </div> 4509 {{/.}} 4510 </script> 4511 } 4512 4513 @helper RenderDetailsViewPrice() 4514 { 4515 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductList").GetBoolean("ShowBothPricesWithWithoutVAT"); 4516 bool isPricesWithVATEnabled = Dynamicweb.Ecommerce.Common.Context.DisplayPricesWithVat; 4517 4518 <script id="DetailsViewPriceContainer" type="text/x-template"> 4519 <div class="price price--product-list price--micro dw-mod">{{price}}</div> 4520 <div class="before-price {{onSale}} before-price--micro dw-mod">{{discount}}</div> 4521 @if (showVATPrice) 4522 { 4523 <div class="vat-price vat-price--product-list u-margin-top dw-mod"> 4524 @if (isPricesWithVATEnabled) 4525 { 4526 <span>@Translate("excl. VAT")</span><span> ({{priceWithoutVAT}})</span> 4527 } 4528 else 4529 { 4530 <span>@Translate("incl. VAT")</span><span> ({{priceWithVAT}})</span> 4531 } 4532 </div> 4533 } 4534 <text> 4535 {{#if priceRRP}} 4536 <div><small>@Translate("RRP") {{priceRRP}}</small></div> 4537 {{/if}} 4538 </text> 4539 </script> 4540 } 4541 4542 @helper RenderDetailsViewAddToCart() 4543 { 4544 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 4545 bool showPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice"); 4546 4547 var addToCartBtn = new AddToCart 4548 { 4549 AddButton = new AddToCartButton 4550 { 4551 HideTitle = true, 4552 ProductId = "{{productId}}", 4553 VariantId = "{{variantid}}", 4554 UnitId = "{{unitId}}", 4555 ProductInfo = "{{productInfo}}", 4556 BuyForPoints = pointShopOnly, 4557 OnClick = "{{facebookPixelAction}}", 4558 ExtraAttributes = new Dictionary<string, string> 4559 { 4560 { "{{disabledBuyButton}}", "" }, 4561 { "{{outOfStock}}", "" } 4562 } 4563 } 4564 }; 4565 4566 if (!pointShopOnly) 4567 { 4568 addToCartBtn.QuantitySelector = new QuantitySelector 4569 { 4570 Id = "Quantity{{id}}", 4571 ExtraAttributes = new Dictionary<string, string> 4572 { 4573 { "{{outOfStock}}", "" } 4574 } 4575 }; 4576 } 4577 4578 if (!showPrice) 4579 { 4580 addToCartBtn.UnitSelector = getUnitsSelector(); 4581 } 4582 4583 <script id="DetailsViewAddToCartContainer" type="text/x-template"> 4584 <div class="product-list__details-actions"> 4585 @Render(addToCartBtn) 4586 </div> 4587 </script> 4588 } 4589 4590 @helper RenderDetailsViewUnitSelector() 4591 { 4592 var separatedUnitSelector = getUnitsSelector(); 4593 separatedUnitSelector.CssClass += " product-list__details-units-selector--separated"; 4594 4595 <script id="DetailsViewUnitSelectorContainer" type="text/x-template"> 4596 @Render(separatedUnitSelector) 4597 </script> 4598 } 4599 4600 @helper RenderDetailsViewItemHiddenProperties() 4601 { 4602 <input type="hidden" name="ProductLoopCounter{{id}}" value="{{id}}" /> 4603 <input type="hidden" name="ProductID{{id}}" value="{{productId}}" /> 4604 <input type="hidden" name="VariantID{{id}}" value="{{variantid}}" id="Variant_{{id}}" /> 4605 <input type="hidden" name="UnitID{{id}}" value="{{unitId}}" id="Unit_{{id}}" /> 4606 <input type="hidden" name="Quantity{{id}}" value="1" id="Quantity_{{id}}" /> 4607 } 4608 4609 @helper RenderDetailsViewItemImage() 4610 { 4611 <div class="lightbox"> 4612 <a href="{{link}}" onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" title="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}" tabindex="-1"> 4613 @Render(new Image() 4614 { 4615 Path = "{{image}}", 4616 Title = "{{name}}{{#if variantName}}, {{variantName}}{{/if}}", 4617 CssClass = "lightbox__image {{noImage}}", 4618 DisableLazyLoad = true, 4619 ImageDefault = new ImageSettings { Width = 220, Height = 220, Crop = 5 } 4620 }) 4621 <div class="u-margin-right {{noImage}}"> 4622 @Render(new Image() 4623 { 4624 Path = "{{image}}", 4625 Title = "{{name}}{{#if variantName}}, {{variantName}}{{/if}}", 4626 CssClass = "product-list__details-image", 4627 ImageDefault = new ImageSettings { Width = 75, Height = 55, Crop = 5, FillCanvas = true } 4628 }) 4629 </div> 4630 </a> 4631 </div> 4632 } 4633 4634 @helper RenderDetailsViewItemTitle() 4635 { 4636 <a href="{{link}}" onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" title="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}" class="product-list__details-title u-color-inherit dw-mod"> 4637 <h6 class="u-no-margin u-bold">{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}</h6> 4638 </a> 4639 } 4640 4641 @helper RenderDetailsViewItemNumber() 4642 { 4643 <div class="item-number item-number--compressed dw-mod"> 4644 <div class="item-number dw-mod">{{number}}</div> 4645 </div> 4646 } 4647 4648 @helper RenderDetailsViewItemStaticVariants() 4649 { 4650 string variantsSize = detailsViewSettings.GetList("StaticVariantsDisplay") != null ? detailsViewSettings.GetList("StaticVariantsDisplay").SelectedValue : "sm"; 4651 4652 <text> 4653 <span> 4654 {{#Variants}} 4655 @if ( variantsSize == "lg" ) { 4656 <text> 4657 {{>StaticVariantsLgTemplate}} 4658 </text> 4659 } else { 4660 <text> 4661 {{>StaticVariantsTemplate}} 4662 </text> 4663 } 4664 {{/Variants}} 4665 </span> 4666 4667 {{#ifCond variantGroupsCount '>' 1}} 4668 <div class="static-variant"> 4669 @Translate("More options available") 4670 </div> 4671 {{/ifCond}} 4672 </text> 4673 } 4674 4675 @helper RenderDetailsViewItemStock() 4676 { 4677 <text>{{#unless hideStockDisallowOrdering}}</text> 4678 <text>{{#if stockText}}</text> 4679 <div class="item-number item-number--compressed dw-mod"> 4680 <span> 4681 <span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span> 4682 <span class="u-margin-right--lg"> {{stockText}}</span> 4683 {{deliveryText}} 4684 </span> 4685 </div> 4686 <text>{{/if}}</text> 4687 <text>{{/unless}}</text> 4688 } 4689 4690 @helper RenderDetailsViewItemStickers() 4691 { 4692 <div class="grid__cell-footer stickers-container stickers-container--row u-margin-top dw-mod"> 4693 {{#StickersContainers}} 4694 {{#Stickers}} 4695 {{>MiniSticker}} 4696 {{/Stickers}} 4697 {{/StickersContainers}} 4698 </div> 4699 } 4700 4701 @helper RenderDetailsViewItemUnitSelector() 4702 { 4703 <text> 4704 {{#unless hideStockDisallowOrdering}} 4705 {{#if isLiveProductInfoActive}} 4706 <div class="js-handlebars-root js-live-info-container" 4707 data-template="DetailsViewUnitSelectorContainer" 4708 data-preloader="none" 4709 data-product-id="{{productId}}"> 4710 </div> 4711 {{else}} 4712 {{>DetailsViewUnitSelectorContainer}} 4713 {{/if}} 4714 {{/unless}} 4715 </text> 4716 } 4717 4718 @helper RenderDetailsViewItemPrice() 4719 { 4720 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 4721 bool showCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("DetailsView").GetBoolean("ShowAddToCartButton"); 4722 4723 <text> 4724 {{#unless hidePriceDisallowOrdering}} 4725 <div class="product-list__details-price"> 4726 @if (pointShopOnly) 4727 { 4728 <text> 4729 {{#if havePointPrice}} 4730 <div class="price price--product-list price--micro dw-mod">{{points}} @Translate("points")</div> 4731 @if (showCartButton) 4732 { 4733 <text> 4734 {{#unless canBePurchasedWithPoints}} 4735 <small class="help-text u-no-margin">@Translate("Not enough points to buy this")</small> 4736 {{/unless}} 4737 </text> 4738 } 4739 {{else}} 4740 @Translate("Not available") 4741 {{/if}} 4742 </text> 4743 4744 } 4745 else 4746 { 4747 <text> 4748 {{#if isLiveProductInfoActive}} 4749 <div class="js-handlebars-root js-live-info-container" 4750 data-template="DetailsViewPriceContainer" 4751 data-preloader="minimal" 4752 data-product-id="{{productId}}"> 4753 </div> 4754 {{else}} 4755 {{>DetailsViewPriceContainer}} 4756 {{/if}} 4757 </text> 4758 } 4759 </div> 4760 {{/unless}} 4761 </text> 4762 } 4763 4764 @helper RenderDetailsViewItemFavorites() 4765 { 4766 <div class="favorites product-list__details-favorites {{hasVariants}} dw-mod" {{hasVariants}}> 4767 {{#Favorite}} 4768 {{>FavoriteTemplate}} 4769 {{/Favorite}} 4770 </div> 4771 } 4772 4773 @helper RenderDetailsViewItemViewButton() 4774 { 4775 string viewMoreText = detailsViewSettings.GetString("ViewMoreText"); 4776 viewMoreText = !string.IsNullOrEmpty(viewMoreText) ? viewMoreText : "View"; 4777 4778 <div class="product-list__details-actions"> 4779 @Render(new Link 4780 { 4781 Href = "{{link}}", 4782 Id = "CartButton_{{id}}", 4783 Title = Translate(viewMoreText), 4784 OnClick = "{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}", 4785 ButtonLayout = ButtonLayout.Secondary, 4786 CssClass = "u-no-margin" 4787 }) 4788 </div> 4789 } 4790 4791 @helper RenderDetailsViewItemAddToCart() 4792 { 4793 <text> 4794 {{#if isLiveProductInfoActive}} 4795 <div class="js-handlebars-root js-live-info-container" 4796 data-template="DetailsViewAddToCartContainer" 4797 data-preloader="none" 4798 data-product-id="{{productId}}"> 4799 </div> 4800 {{else}} 4801 {{>DetailsViewAddToCartContainer}} 4802 {{/if}} 4803 </text> 4804 } 4805 4806 @helper RenderDetailsViewItemActions() 4807 { 4808 bool showCartButton = detailsViewSettings.GetBoolean("ShowAddToCartButton"); 4809 bool showViewButton = detailsViewSettings.GetBoolean("ShowViewButton"); 4810 4811 if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 4812 { 4813 if (showCartButton) 4814 { 4815 if (!showViewButton) 4816 { 4817 <text>{{#if hideAddToCartButton}}</text> 4818 @RenderDetailsViewItemViewButton() 4819 <text>{{else}}</text> 4820 @RenderDetailsViewItemAddToCart() 4821 <text>{{/if}}</text> 4822 } 4823 else 4824 { 4825 @RenderDetailsViewItemViewButton() 4826 } 4827 } 4828 else if (showViewButton) 4829 { 4830 @RenderDetailsViewItemViewButton() 4831 } 4832 } 4833 else if (showViewButton) 4834 { 4835 @RenderDetailsViewItemViewButton() 4836 } 4837 } 4838 4839 @helper RenderDetailsViewItemDownloadButton() 4840 { 4841 <button type="button" class="btn btn--primary u-no-margin u-margin-left btn--condensed dw-mod js-add-to-downloads" title="@Translate("Add")" data-product-id="{{productId}}"> 4842 @Render(new Icon { Prefix = "fas", Name = "fa-plus", CssClass = "js-button-icon" }) 4843 </button> 4844 } 4845 4846 4847 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 4848 @using Dynamicweb.Core 4849 @using System 4850 @using System.Web 4851 @using System.Collections.Generic 4852 @using Dynamicweb.Rapido.Blocks 4853 @using Dynamicweb.Rapido.Blocks.Components 4854 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 4855 @using Dynamicweb.Rapido.Blocks.Components.General 4856 @using Dynamicweb.Rapido.Services 4857 @using System.Web.Helpers 4858 4859 @functions { 4860 BlocksPage tilesView = BlocksPage.GetBlockPage("ProductList"); 4861 Dynamicweb.Frontend.ItemViewModel tilesViewSettings = null; 4862 } 4863 4864 @{ 4865 var settings = Pageview.AreaSettings.GetItem("ProductList"); 4866 var enableTiles = settings.GetBoolean("EnableTilesView"); 4867 4868 if ( enableTiles ) { 4869 tilesViewSettings = settings.GetItem("TilesView"); 4870 BlocksPage tilesView = BlocksPage.GetBlockPage("ProductList"); 4871 4872 Block tiles = new Block { 4873 Id = "ProductTilesViewContainer", 4874 Name ="grip-horizontal", 4875 SortId = 50, 4876 }; 4877 4878 tilesView.Add("Views", tiles); 4879 4880 4881 Block tilesViewScripts = new Block { 4882 Id = "TilesViewScripts", 4883 SortId = 20, 4884 Template = TilesView(), 4885 BlocksList = new List<Block> { 4886 new Block { 4887 Id = "TilesViewItem", 4888 SortId = 10, 4889 Template = RenderTilesViewItem(), 4890 SkipRenderBlocksList = true, 4891 BlocksList = new List<Block> { 4892 new Block { 4893 Id = "TilesViewItemHiddenProperties", 4894 SortId = 10, 4895 Template = RenderTilesViewItemHiddenProperties() 4896 }, 4897 new Block { 4898 Id = "TilesViewItemImageContainer", 4899 SortId = 20, 4900 Template = RenderTilesViewItemImageContainer(), 4901 SkipRenderBlocksList = true, 4902 BlocksList = new List<Block> { 4903 new Block { 4904 Id = "TilesViewItemImage", 4905 SortId = 10, 4906 Template = RenderTilesViewItemImage(), 4907 }, 4908 new Block 4909 { 4910 Id = "TilesViewItemStickers", 4911 SortId = 20, 4912 Template = RenderTilesViewItemStickers() 4913 }, 4914 new Block { 4915 Id = "TilesViewItemFavorites", 4916 SortId = 20, 4917 Template = RenderTilesViewItemFavorites() 4918 }, 4919 }, 4920 }, 4921 new Block { 4922 Id = "TilesViewItemContentContainer", 4923 SortId = 30, 4924 Template = RenderTilesViewItemContentContainer(), 4925 SkipRenderBlocksList = true, 4926 BlocksList = new List<Block> { 4927 new Block { 4928 Id = "TilesViewItemContent", 4929 SortId = 30, 4930 Template = RenderTilesViewItemContent(), 4931 SkipRenderBlocksList = true, 4932 BlocksList = new List<Block> { 4933 new Block { 4934 Id = "TilesViewItemHeader", 4935 SortId = 10, 4936 Template = RenderTilesViewItemHeader(), 4937 SkipRenderBlocksList = true, 4938 BlocksList = new List<Block> { 4939 new Block { 4940 Id = "TilesViewItemTitle", 4941 SortId = 10, 4942 Template = RenderTilesViewItemTitle(), 4943 }, 4944 new Block { 4945 Id = "TilesViewItemNumber", 4946 SortId = 20, 4947 Template = RenderTilesViewItemNumber(), 4948 }, 4949 } 4950 }, 4951 new Block { 4952 Id = "TilesViewItemPrice", 4953 SortId = 30, 4954 Template = RenderTilesViewItemPrice(), 4955 }, 4956 } 4957 }, 4958 new Block { 4959 Id = "TilesViewItemFooter", 4960 SortId = 40, 4961 Template = RenderTilesViewItemFooter(), 4962 SkipRenderBlocksList = true 4963 } 4964 } 4965 } 4966 } 4967 }, 4968 new Block 4969 { 4970 Id = "GridViewPrice", 4971 SortId = 20, 4972 Template = RenderTilesViewPrice() 4973 } 4974 } 4975 }; 4976 tilesView.Add("BottomSnippets", tilesViewScripts); 4977 4978 if (tilesViewSettings.GetBoolean("ShowStaticVariants")) { 4979 Block staticVariants = new Block { 4980 Id = "TilesViewItemVariants", 4981 SortId = 10, 4982 Template = RenderTilesViewItemVariants(), 4983 }; 4984 tilesView.Add("TilesViewItemContentContainer", staticVariants); 4985 } 4986 4987 //download button 4988 bool tilesViewShowAddToDownloadButton = tilesViewSettings.GetBoolean("ShowAddToDownloadButton"); 4989 4990 if (tilesViewShowAddToDownloadButton && Pageview.User != null) 4991 { 4992 tilesView.Add("TilesViewItemFooter", new Block 4993 { 4994 Id = "TilesViewItemDownloadButton", 4995 SortId = 20, 4996 Template = RenderTilesViewItemDownloadButton() 4997 }); 4998 } 4999 } 5000 } 5001 5002 @helper TilesView() { 5003 int columnsCount = tilesViewSettings.GetList("Columns") != null ? Converter.ToInt32(tilesViewSettings.GetList("Columns").SelectedValue) : 3; 5004 5005 <script id="ProductTilesViewContainer" type="text/x-template"> 5006 {{#.}} 5007 <div id="Product{{id}}" data-template="TilesViewItem" data-preloader="overlay" class="grid__col-lg-@(12 / columnsCount) grid__col-md-@(12 / columnsCount) grid__col-sm-@(12 / columnsCount) grid__col-xs-6 product-list__tiles-item js-product dw-mod"> 5008 {{#Product}} 5009 {{>TilesViewItem}} 5010 {{/Product}} 5011 </div> 5012 {{/.}} 5013 </script> 5014 } 5015 5016 5017 @helper RenderTilesViewItem() { 5018 List<Block> subBlocks = tilesView.GetBlockListById("TilesViewItem"); 5019 bool showShadow = tilesViewSettings.GetBoolean("HoverShowShadow"); 5020 string addShadow = ( showShadow != null && showShadow ) ? "product-list--shadow" : ""; 5021 5022 <script id="TilesViewItem" type="text/x-template"> 5023 {{#.}} 5024 <div class="grid__col--auto js-product-scroll-trigger u-no-padding u-full-height @addShadow" data-params="{{googleImpression}}"> 5025 @RenderBlockList(subBlocks) 5026 </div> 5027 {{/.}} 5028 </script> 5029 } 5030 5031 @helper RenderTilesViewPrice() 5032 { 5033 <script id="TilesViewPriceContainer" type="text/x-template"> 5034 <div class="price__wrapper u-flex u-flex--wrap u-justify-content--between"> 5035 <div class="price__inner u-margin-right"> 5036 <div class="price price--product-list u-bold dw-mod">{{price}}</div> 5037 <div class="before-price {{onSale}} dw-mod">{{discount}}</div> 5038 </div> 5039 5040 {{#if priceRRP}} 5041 <div class="price--rrp dw-mod">{{priceRRP}}</div> 5042 {{/if}} 5043 </div> 5044 </script> 5045 } 5046 5047 5048 @helper RenderTilesViewItemContentContainer() { 5049 List<Block> subBlocks = tilesView.GetBlockListById("TilesViewItemContentContainer"); 5050 5051 <text> 5052 {{#.}} 5053 <div class="grid__cell product-list__tiles-item__price-info u-padding--lg u-flex u-flex--column dw-mod"> 5054 @RenderBlockList(subBlocks) 5055 </div> 5056 {{/.}} 5057 </text> 5058 } 5059 5060 5061 5062 @helper RenderTilesViewItemVariants() { 5063 string variantsSize = tilesViewSettings.GetList("StaticVariantsDisplay") != null ? tilesViewSettings.GetList("StaticVariantsDisplay").SelectedValue : "sm"; 5064 5065 <text> 5066 {{#Variants}} 5067 @if ( variantsSize == "lg" ) { 5068 <text> 5069 {{>StaticVariantsLgTemplate}} 5070 </text> 5071 } else { 5072 <text> 5073 {{>StaticVariantsTemplate}} 5074 </text> 5075 } 5076 {{/Variants}} 5077 5078 {{#ifCond variantGroupsCount '==' 0}} 5079 <div class="static-variant"></div> 5080 {{/ifCond}} 5081 </text> 5082 } 5083 5084 @helper RenderTilesViewItemFavorites() { 5085 bool showFavoriteButton = !tilesViewSettings.GetBoolean("HideFavoriteButton"); 5086 5087 if ( !showFavoriteButton ) { 5088 return; 5089 } 5090 5091 <div class="favorites favorites--for-tiles-view u-pull--right {{hasVariants}} dw-mod" {{hasVariants}}> 5092 {{#Favorite}} 5093 {{>FavoriteTemplate}} 5094 {{/Favorite}} 5095 </div> 5096 } 5097 5098 @helper RenderTilesViewItemImageContainer() { 5099 List<Block> subBlocks = tilesView.GetBlockListById("TilesViewItemImageContainer"); 5100 5101 <div class="grid__cell dw-mod {{noImage}}"> 5102 @RenderBlockList(subBlocks) 5103 </div> 5104 } 5105 5106 @helper RenderTilesViewItemStickers() 5107 { 5108 <text> 5109 {{#StickersContainers}} 5110 {{>StickersContainer}} 5111 {{/StickersContainers}} 5112 </text> 5113 } 5114 5115 @helper RenderTilesViewItemImage() { 5116 string imageZoomOnHover = tilesViewSettings.GetBoolean("HoverImageZoom") ? "image-hover--zoom" : ""; 5117 bool secondaryImage = tilesViewSettings.GetString("HoverAlternativeImage") != null ? tilesViewSettings.GetBoolean("HoverAlternativeImage") : false; 5118 string alternativeImage = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("AlternativeImage")) ? Pageview.AreaSettings.GetItem("Settings").GetFile("AlternativeImage").PathUrlEncoded : "/Images/missing_image.jpg"; 5119 5120 var image = new Image() 5121 { 5122 Path = "{{image}}", 5123 Title = "{{name}}{{#if variantName}}, {{variantName}}{{/if}}", 5124 CssClass = "grid__cell-img u-middle-horizontal", 5125 ImageDefault = new ImageSettings {Width = 450, Height = 450, Crop = 5, FillCanvas = true}, 5126 }; 5127 5128 if (secondaryImage) 5129 { 5130 image.ExtraAttributes.Add( 5131 "{{#if secondaryImage}}data-secondary-image-src{{/if}}", 5132 "{{#if secondaryImage}}/Admin/Public/GetImage.ashx?width=450&amp;height=450&amp;crop=5&amp;Compression=75&amp;FillCanvas=true&amp;DoNotUpscale=true&amp;image={{secondaryImage}}&AlternativeImage=" + alternativeImage + "{{/if}}" 5133 ); 5134 } 5135 5136 <a href="{{link}}" 5137 onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" 5138 title="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}" 5139 class="product-list__tiles-item__image u-block u-position-relative image-hover__wrapper @imageZoomOnHover dw-mod" 5140 tabindex="-1"> 5141 @Render(image) 5142 </a> 5143 } 5144 5145 5146 @helper RenderTilesViewItemHiddenProperties() { 5147 <input type="hidden" name="ProductLoopCounter{{id}}" value="{{id}}" /> 5148 <input type="hidden" name="ProductID{{id}}" value="{{productId}}" /> 5149 <input type="hidden" name="VariantID{{id}}" value="{{variantid}}" id="Variant_{{id}}" /> 5150 <input type="hidden" name="UnitID{{id}}" value="{{unitId}}" id="Unit_{{id}}" /> 5151 <input type="hidden" name="Quantity{{id}}" value="1" id="Quantity_{{id}}" /> 5152 } 5153 5154 5155 @helper RenderTilesViewItemContent() { 5156 List<Block> subBlocks = tilesView.GetBlockListById("TilesViewItemContent"); 5157 5158 <div class="grid__cell dw-mod"> 5159 @RenderBlockList(subBlocks) 5160 </div> 5161 } 5162 5163 5164 @helper RenderTilesViewItemHeader() { 5165 List<Block> subBlocks = tilesView.GetBlockListById("TilesViewItemHeader"); 5166 5167 <div class="u-flex u-justify-content--between u-margin-bottom dw-mod"> 5168 @RenderBlockList(subBlocks) 5169 </div> 5170 } 5171 5172 5173 @helper RenderTilesViewItemTitle() { 5174 <a href="{{link}}" class="u-color-inherit u-flex-basis--50 u-flex-grow--1" onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" title="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}"> 5175 <h6 class="u-bold u-capitalize">{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}</h6> 5176 </a> 5177 } 5178 5179 5180 @helper RenderTilesViewItemNumber() { 5181 bool showNumber = tilesViewSettings.GetBoolean("ShowProductNumber"); 5182 5183 if ( !showNumber ) { 5184 return; 5185 } 5186 5187 <div class="item-number u-margin-left--lg dw-mod">{{number}}</div> 5188 } 5189 5190 5191 @helper RenderTilesViewItemPrice() { 5192 <text> 5193 {{#unless hidePriceDisallowOrdering}} 5194 {{#if isLiveProductInfoActive}} 5195 <div class="js-handlebars-root js-live-info-container" 5196 data-template="TilesViewPriceContainer" 5197 data-preloader="minimal" 5198 data-product-id="{{productId}}"> 5199 </div> 5200 {{else}} 5201 {{>TilesViewPriceContainer}} 5202 {{/if}} 5203 {{/unless}} 5204 </text> 5205 } 5206 5207 5208 @helper RenderTilesViewItemFooter() { 5209 List<Block> subBlocks = tilesView.GetBlockListById("TilesViewItemFooter"); 5210 5211 <div class="product-list__tiles-item__footer u-margin-top--auto dw-mod"> 5212 @RenderBlockList(subBlocks) 5213 </div> 5214 } 5215 5216 @helper RenderTilesViewItemDownloadButton() { 5217 <button type="button" class="btn btn--primary u-no-margin u-margin-top btn--condensed dw-mod js-add-to-downloads" title="@Translate("Add")" data-product-id="{{productId}}"> 5218 @Render(new Icon { Prefix = "fas", Name = "fa-plus", CssClass = "js-button-icon" }) 5219 <span class="js-button-text">@Translate("Add")</span> 5220 </button> 5221 } 5222 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 5223 @using Dynamicweb.Core 5224 @using System 5225 @using System.Web 5226 @using System.Collections.Generic 5227 @using Dynamicweb.Rapido.Blocks 5228 5229 @{ 5230 BlocksPage productListPromotionsBlocksPage = BlocksPage.GetBlockPage("ProductList"); 5231 5232 Block productListPromotions = new Block 5233 { 5234 Id = "Promotions", 5235 SortId = 10, 5236 Template = RenderProductListPromotions() 5237 }; 5238 productListPromotionsBlocksPage.Add("PageContainer", productListPromotions); 5239 } 5240 5241 @helper RenderProductListPromotions() 5242 { 5243 @*This is part of a script template *@ 5244 5245 string listId = HttpContext.Current.Request.QueryString.Get("ListID"); 5246 bool isFavoriteList = !string.IsNullOrEmpty(listId); 5247 string smallDeviceCss = Pageview.Device.ToString() == "Mobile" ? "u-no-padding" : ""; 5248 5249 if (!isFavoriteList) 5250 { 5251 switch (Pageview.AreaSettings.GetItem("ProductList").GetList("PromotionBlockDesign").SelectedValue) 5252 { 5253 case "OnlyText": 5254 <article class="grid__col-12 u-margin-bottom @smallDeviceCss"> 5255 <h1>{{groupName}}</h1> 5256 {{{groupDescription}}} 5257 {{#ifCond groupPromotionLink "!==" ""}} 5258 <div> 5259 <a href="{{groupPromotionLink}}" class="btn btn--primary">{{groupPromotionLinkText}}</a> 5260 </div> 5261 {{/ifCond}} 5262 </article> 5263 break; 5264 case "TextAndImage": 5265 <article class="grid__col-12 u-margin-bottom @smallDeviceCss"> 5266 <div class="grid grid--bleed"> 5267 <div class="grid__col-md-6"> 5268 <h1>{{groupName}}</h1> 5269 {{{groupDescription}}} 5270 {{#ifCond groupPromotionLink "!==" ""}} 5271 <div> 5272 <a href="{{groupPromotionLink}}" class="btn btn--primary">{{groupPromotionLinkText}}</a> 5273 </div> 5274 {{/ifCond}} 5275 </div> 5276 {{#ifCond groupPromotionImage "!==" ""}} 5277 <div class="grid__col-md-6"> 5278 <img src="/Admin/Public/GetImage.ashx?width=600&crop=5&Compression=75&DoNotUpscale=true&image={{groupPromotionImage}}" alt="{{groupName}}" class="background-image__cover" /> 5279 </div> 5280 {{/ifCond}} 5281 </div> 5282 </article> 5283 break; 5284 case "Banner": 5285 <text> 5286 {{#ifCond groupPromotionImage "!==" ""}} 5287 <article class="grid__col-12 u-margin-bottom @smallDeviceCss"> 5288 <div class="u-color-light grid center-container center-container--with-background-image grid__col--bg" style="background-image:url('{{groupPromotionImage}}');"> 5289 <div class="grid__col-12 u-middle"> 5290 <div class="grid__cell"> 5291 {{{groupDescription}}} 5292 {{#ifCond groupPromotionLink "!==" ""}} 5293 <div> 5294 <a href="{{groupPromotionLink}}" class="btn btn--primary">{{groupPromotionLinkText}}</a> 5295 </div> 5296 {{/ifCond}} 5297 </div> 5298 </div> 5299 </div> 5300 </article> 5301 {{/ifCond}} 5302 </text> 5303 break; 5304 } 5305 } 5306 } 5307 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 5308 @using Dynamicweb.Core 5309 @using System 5310 @using System.Web 5311 @using System.Collections.Generic 5312 @using Dynamicweb.Rapido.Blocks 5313 5314 @{ 5315 BlocksPage productListMenuBlocksPage = BlocksPage.GetBlockPage("ProductList"); 5316 5317 if (Pageview.Device.ToString() != "Mobile" && Pageview.Device.ToString() != "Tablet" && 5318 Converter.ToString(Pageview.Page.PropertyItem["LeftMenu"]) == "True" && 5319 Pageview.Page.NavigationSettings != null && 5320 Pageview.Page.NavigationSettings.UseEcomGroups) { 5321 5322 Block productListMenuBlock = new Block 5323 { 5324 Id = "Menu", 5325 SortId = 20, 5326 Template = RenderProductListMenu() 5327 }; 5328 5329 productListMenuBlocksPage.Add("Navigation", productListMenuBlock); 5330 } 5331 } 5332 5333 @helper RenderProductListMenu() 5334 { 5335 var navigationMarkup = RenderNavigation(new 5336 { 5337 id = "leftnav", 5338 cssclass = "dwnavigation", 5339 startLevel = 1, 5340 endlevel = 5, 5341 template = "LeftNavigation.xslt", 5342 mode = "ecom" 5343 }); 5344 5345 <h2 class="u-margin-bottom">@Translate("Product categories")</h2> 5346 5347 <div class="u-padding-bottom--lg"> 5348 @navigationMarkup 5349 </div> 5350 } 5351 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 5352 @using Dynamicweb.Core 5353 @using System 5354 @using System.Web 5355 @using System.Collections.Generic 5356 @using Dynamicweb.Rapido.Blocks 5357 @using Dynamicweb.Rapido.Blocks.Components.General 5358 5359 @{ 5360 BlocksPage productListFacetsBlocksPage = BlocksPage.GetBlockPage("ProductList"); 5361 string facetsBlockViewMode = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductList").GetString("FacetsViewMode")) ? Pageview.AreaSettings.GetItem("ProductList").GetString("FacetsViewMode").ToLower() : "left"; 5362 5363 if (facetsBlockViewMode == "left" && Pageview.Device.ToString() != "Mobile" && Pageview.Device.ToString() != "Tablet") 5364 { 5365 Block facetsBlock = new Block 5366 { 5367 Id = "Facets", 5368 SortId = 30, 5369 Template = RenderProductListFacets() 5370 }; 5371 productListFacetsBlocksPage.Add("Navigation", facetsBlock); 5372 } 5373 5374 if (facetsBlockViewMode == "top" || Pageview.Device.ToString() == "Mobile" || Pageview.Device.ToString() == "Tablet") 5375 { 5376 Block facetsBlock = new Block 5377 { 5378 Id = "Facets", 5379 SortId = 10, 5380 Template = RenderProductListTopFacets() 5381 }; 5382 productListFacetsBlocksPage.Add("ProductList", facetsBlock); 5383 } 5384 5385 Block facetSelections = new Block 5386 { 5387 Id = "FacetSelections", 5388 SortId = 20, 5389 Template = RenderFacetSelections() 5390 }; 5391 productListFacetsBlocksPage.Add("ProductList", facetSelections); 5392 5393 Block checkboxFacetTemplate = new Block 5394 { 5395 Id = "CheckboxFacet", 5396 SortId = 30, 5397 Template = RenderCheckboxFacets() 5398 }; 5399 productListFacetsBlocksPage.Add("BottomSnippets", checkboxFacetTemplate); 5400 5401 Block tagsFacetTemplate = new Block 5402 { 5403 Id = "TagsFacet", 5404 SortId = 40, 5405 Template = RenderTagsFacets() 5406 }; 5407 productListFacetsBlocksPage.Add("BottomSnippets", tagsFacetTemplate); 5408 5409 Block colorsFacetTemplate = new Block 5410 { 5411 Id = "ColorFacet", 5412 SortId = 50, 5413 Template = RenderColorFacets() 5414 }; 5415 productListFacetsBlocksPage.Add("BottomSnippets", colorsFacetTemplate); 5416 5417 Block selectedFilter = new Block 5418 { 5419 Id = "SelectedFilter", 5420 SortId = 60, 5421 Template = RenderSelectedFilter() 5422 }; 5423 productListFacetsBlocksPage.Add("BottomSnippets", selectedFilter); 5424 5425 Block selectedColorFilter = new Block 5426 { 5427 Id = "SelectedColorFilter", 5428 SortId = 70, 5429 Template = RenderSelectedColorFilter() 5430 }; 5431 productListFacetsBlocksPage.Add("BottomSnippets", selectedColorFilter); 5432 5433 Block resetFilters = new Block 5434 { 5435 Id = "ResetFilters", 5436 SortId = 80, 5437 Template = RenderResetFilters() 5438 }; 5439 productListFacetsBlocksPage.Add("BottomSnippets", resetFilters); 5440 } 5441 5442 @helper RenderFacetSelections() 5443 { 5444 @*This is part of a script template *@ 5445 <text> 5446 {{#if FacetSelections}} 5447 <div class="buttons-collection u-margin-bottom" id="selectedFacets"> 5448 {{#FacetSelections}} 5449 {{>(lookup . 'template')}} 5450 {{/FacetSelections}} 5451 </div> 5452 {{/if}} 5453 </text> 5454 } 5455 5456 @helper RenderProductListFacets() { 5457 var facetSettings = Pageview.AreaSettings.GetItem("ProductList").GetItem("Facets"); 5458 string boxDisplay = facetSettings.GetList("BoxDisplay") != null ? facetSettings.GetList("BoxDisplay").SelectedValue : "scroll"; 5459 5460 string facetMoreClass = ( boxDisplay == "view-more" ? "facets-container__list--more" : ""); 5461 5462 @*This is part of a script template *@ 5463 5464 <input type="checkbox" id="CheckFacetGroups" class="js-remember-state u-hidden" data-expand="CheckFacetGroups" /> 5465 <div class="facets-container facets-container--left expandable--collapsed dw-mod" data-trigger="CheckFacetGroups"> 5466 {{#FacetGroups}} 5467 <input type="checkbox" id="OptionsGroup_{{name}}" class="expand-trigger js-remember-state" {{defaultState}} /> 5468 5469 <div class="expand-container facets-container__box dw-mod js-filter"> 5470 <label class="expand-container__btn facets-container__header dw-mod" for="OptionsGroup_{{name}}">{{name}}</label> 5471 <div class="expand-container__content js-facet-container dw-mod" data-input="OptionsGroup_{{name}}"> 5472 <div class="facets-container__search {{showFilter}} dw-mod"> 5473 <input type="text" class="u-full-width u-no-margin" onkeyup="Filter.FilterItems(event)" placeholder="@Translate("Search")" /> 5474 </div> 5475 <div id="facetList{{queryParameter}}" class="facets-container__list @facetMoreClass dw-mod"> 5476 {{#FacetOptions}} 5477 {{#ifCond template "===" "Checkboxes"}} 5478 {{>Checkboxes}} 5479 {{/ifCond}} 5480 {{#ifCond template "===" "Range"}} 5481 {{>Checkboxes}} 5482 {{/ifCond}} 5483 {{#ifCond template "===" "Weight"}} 5484 {{>Checkboxes}} 5485 {{/ifCond}} 5486 {{#ifCond template "===" "Tags"}} 5487 {{>Tags}} 5488 {{/ifCond}} 5489 {{#ifCond template "===" "Colors"}} 5490 {{>Colors}} 5491 {{/ifCond}} 5492 {{/FacetOptions}} 5493 <div class="u-hidden js-filter-not-found"> 5494 @Translate("Your search gave 0 results") 5495 </div> 5496 </div> 5497 5498 @if ( boxDisplay == "view-more" ) { 5499 <div class="facets-container__more js-facet-expand"> 5500 @Render(new Button { 5501 Title = "<span class=js-facet-trigger-text>" + Translate("View more") + "</span>", 5502 ButtonType = ButtonType.Button, 5503 ButtonLayout = ButtonLayout.Clean, 5504 CssClass = "facets-container__more-button js-facet-trigger u-flex u-no-margin u-full-width", 5505 OnClick = "Facets.ExpandToggle(this)", 5506 ExtraAttributes = new Dictionary<string, string>{ 5507 {"data-target", "facetList{{queryParameter}}"}, 5508 {"data-toggle-text", Translate("Show less")}, 5509 }, 5510 Icon = new Icon { 5511 Prefix = "fal", 5512 Name = "fa-angle-down", 5513 } 5514 }) 5515 </div> 5516 } 5517 </div> 5518 </div> 5519 {{/FacetGroups}} 5520 </div> 5521 <label for="CheckFacetGroups" class="btn btn--primary btn--full u-no-margin dw-mod js-expand-hide facets-container-trigger" data-trigger="CheckFacetGroups">@Translate("Select filters")</label> 5522 <label for="CheckFacetGroups" class="btn btn--primary btn--full u-no-margin dw-mod expandable--collapsed facets-container-trigger" data-trigger="CheckFacetGroups">@Translate("Close filters")</label> 5523 } 5524 5525 @helper RenderProductListTopFacets() 5526 { 5527 @*This is part of a script template *@ 5528 <input type="checkbox" id="CheckFacetGroups" class="js-remember-state u-hidden" data-expand="CheckFacetGroups" /> 5529 <div class="grid grid--external-bleed dw-mod expandable--collapsed facets-container facets-container--top u-margin-bottom" data-trigger="CheckFacetGroups"> 5530 {{#FacetGroups}} 5531 <div class="grid__col-lg-3 grid__col-md-3 grid__col-sm-4 grid__col-xs-12"> 5532 <input type="checkbox" id="OptionsGroup_{{counter}}" class="dropdown-trigger" /> 5533 <div class="dropdown dw-mod js-filter"> 5534 <label class="dropdown__header dropdown__btn dw-mod" for="OptionsGroup_{{counter}}">{{name}}</label> 5535 <div class="dropdown__content dropdown__content--padding dw-mod"> 5536 <div class="u-margin-bottom {{showFilter}}"> 5537 <input type="text" class="u-full-width u-no-margin" onkeyup="Filter.FilterItems(event)" placeholder="@Translate("Search")" /> 5538 </div> 5539 {{#FacetOptions}} 5540 {{#ifCond template "===" "Checkboxes"}} 5541 {{>Checkboxes}} 5542 {{/ifCond}} 5543 {{#ifCond template "===" "Range"}} 5544 {{>Checkboxes}} 5545 {{/ifCond}} 5546 {{#ifCond template "===" "Weight"}} 5547 {{>Checkboxes}} 5548 {{/ifCond}} 5549 {{#ifCond template "===" "Tags"}} 5550 {{>Tags}} 5551 {{/ifCond}} 5552 {{#ifCond template "===" "Colors"}} 5553 {{>Colors}} 5554 {{/ifCond}} 5555 {{/FacetOptions}} 5556 <div class="u-hidden js-filter-not-found"> 5557 @Translate("Your search gave 0 results") 5558 </div> 5559 </div> 5560 <label class="dropdown-trigger-off" for="OptionsGroup_{{counter}}"></label> 5561 </div> 5562 </div> 5563 {{/FacetGroups}} 5564 </div> 5565 <label for="CheckFacetGroups" class="btn btn--primary btn--full u-margin-bottom--lg dw-mod js-expand-hide facets-container-trigger" data-trigger="CheckFacetGroups">@Translate("Select filters")</label> 5566 <label for="CheckFacetGroups" class="btn btn--primary btn--full u-margin-bottom--lg dw-mod expandable--collapsed facets-container-trigger" data-trigger="CheckFacetGroups">@Translate("Close filters")</label> 5567 } 5568 5569 @helper RenderCheckboxFacets() 5570 { 5571 <script id="Checkboxes" type="text/x-template"> 5572 <div class="form__field-group u-no-margin dw-mod"> 5573 <input type="checkbox" class="{{selected}} checkbox-facet__checkbox form__control dw-mod" onclick="Facets.UpdateFacets(this);" id="{{queryParameter}}{{value}}" name="{{queryParameter}}" value="[{{value}}]" {{selected}} {{disabled}}> 5574 <label class="{{disabled}} checkbox-facet dw-mod" data-filter-value="{{label}}" for="{{queryParameter}}{{value}}"> 5575 <span class="checkbox-facet__label dw-mod">{{label}}{{#unless isTermFacet}}<span class="checkbox-facet__count dw-mod">({{count}})</span>{{/unless}}</span> 5576 </label> 5577 </div> 5578 </script> 5579 } 5580 5581 @helper RenderTagsFacets() 5582 { 5583 <script id="Tags" type="text/x-template"> 5584 <button type="button" class="btn btn--tag {{selected}} {{disabled}} dw-mod" data-filter-value="{{label}}" data-check="{{selected}}" onclick="Facets.UpdateFacets(this);" name="{{queryParameter}}" value="[{{value}}]" {{disabled}}> 5585 {{label}} {{#unless isTermFacet}}<span class="facets-group__counter dw-mod">({{count}})</span>{{/unless}} 5586 </button> 5587 </script> 5588 } 5589 5590 @helper RenderColorFacets() 5591 { 5592 <script id="Colors" type="text/x-template"> 5593 <button type="button" class="btn btn--colorbox u-margin-right {{selected}} {{disabled}} dw-mod" data-filter-value="{{label}}" style="background-color: {{value}}" title="{{label}}" data-check="{{selected}}" onclick="Facets.UpdateFacets(this);" name="{{queryParameter}}" value="[{{value}}]" {{disabled}}></button> 5594 </script> 5595 } 5596 5597 @helper RenderSelectedFilter() 5598 { 5599 <script id="SelectedFilter" type="text/x-template"> 5600 <button type="button" class="btn btn--tag dw-mod" data-check="checked" onclick="Facets.UpdateFacets(this);" name="{{queryParameter}}" value="[{{value}}]" title="@Translate("Remove filter")"> 5601 {{group}}: {{label}} &nbsp;<i class="fal fa-times"></i> 5602 </button> 5603 </script> 5604 } 5605 5606 @helper RenderSelectedColorFilter() 5607 { 5608 <script id="SelectedColorFilter" type="text/x-template"> 5609 <button type="button" class="btn btn--tag dw-mod" data-check="checked" onclick="Facets.UpdateFacets(this);" name="{{queryParameter}}" value="[{{value}}]" title="@Translate("Remove filter")"> 5610 {{group}}: <div class="btn__colorbox dw-mod" style="background-color: {{value}}"></div> <i class="fas fa-times"></i> 5611 </button> 5612 </script> 5613 } 5614 5615 @helper RenderResetFilters() 5616 { 5617 <script id="ResetFilters" type="text/x-template"> 5618 <button type="button" class="btn btn--tag" onclick="Facets.ResetFacets();"> 5619 @Translate("Reset all filters") &nbsp;<i class="fal fa-redo"></i> 5620 </button> 5621 </script> 5622 } 5623 5624 5625 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 5626 @using Dynamicweb.Core 5627 @using System 5628 @using System.Web 5629 @using System.Collections.Generic 5630 @using Dynamicweb.Rapido.Blocks 5631 5632 @{ 5633 BlocksPage productListMoreBlocksPage = BlocksPage.GetBlockPage("ProductList"); 5634 5635 Block moreBlock = new Block 5636 { 5637 Id = "More", 5638 SortId = 40, 5639 Template = RenderListMore() 5640 }; 5641 5642 productListMoreBlocksPage.Add("ProductList", moreBlock); 5643 } 5644 5645 @helper RenderListMore() 5646 { 5647 @*This is part of a script template *@ 5648 string groupID = HttpContext.Current.Request.QueryString.Get("groupid"); 5649 string listId = HttpContext.Current.Request.QueryString.Get("ListID"); 5650 bool isFavoriteList = !string.IsNullOrEmpty(listId); 5651 string moreFeedFullUrl = GetGlobalValue("Global:Pageview.Url.Raw") + "&feed=true"; 5652 moreFeedFullUrl += !isFavoriteList ? "&DoNotShowVariantsAsSingleProducts=True" : ""; 5653 string columnCss = Pageview.Device.ToString() == "Mobile" ? "grid__col--bleed" : "u-no-padding"; 5654 <text> 5655 {{#if ProductsContainer}} 5656 <div class="grid"> 5657 <div class="grid__col-12 @columnCss"> 5658 <button type="button" id="LoadMoreButton" class="btn btn--primary btn--full {{nextdisabled}} dw-mod" data-current="{{currentPage}}" data-page-size="{{pageSize}}" data-total="{{totalPages}}" data-container="ProductsContainer" data-feed-url="@moreFeedFullUrl&groupid=@groupID{{loadMoreFeedParams}}" onclick="LoadMore.Next(this)" {{nextdisabled}}>@Translate("Load") {{pageSizeText}} @Translate("more")</button> 5659 <button type="button" class="btn btn--clean" onclick="window.scroll(0, 0)">@Translate("Return to top")</button> 5660 </div> 5661 </div> 5662 {{/if}} 5663 </text> 5664 } 5665 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 5666 @using Dynamicweb.Core 5667 @using System 5668 @using System.Web 5669 @using System.Collections.Generic 5670 @using Dynamicweb.Rapido.Blocks 5671 @using Dynamicweb.Rapido.Blocks.Components 5672 @using Dynamicweb.Rapido.Blocks.Components.General 5673 5674 @{ 5675 BlocksPage productListBottomSnippetsPage = BlocksPage.GetBlockPage("ProductList"); 5676 5677 Block productListStickers = new Block 5678 { 5679 Id = "Stickers", 5680 SortId = 10, 5681 Template = RenderStickersTemplates() 5682 }; 5683 productListBottomSnippetsPage.Add("BottomSnippets", productListStickers); 5684 5685 Block productListUnits = new Block 5686 { 5687 Id = "Units", 5688 SortId = 20, 5689 Template = RenderUnitTemplates() 5690 }; 5691 productListBottomSnippetsPage.Add("BottomSnippets", productListUnits); 5692 5693 Block productListVariants = new Block 5694 { 5695 Id = "Variants", 5696 SortId = 30, 5697 Template = RenderVariantTemplates() 5698 }; 5699 productListBottomSnippetsPage.Add("BottomSnippets", productListVariants); 5700 5701 Block productListFavorites = new Block 5702 { 5703 Id = "Favorites", 5704 SortId = 40, 5705 Template = RenderFavoritesTemplates() 5706 }; 5707 productListBottomSnippetsPage.Add("BottomSnippets", productListFavorites); 5708 5709 Block productListPreRender = new Block 5710 { 5711 Id = "PreRenders", 5712 SortId = 50, 5713 Template = RenderPreRenderTemplates() 5714 }; 5715 productListBottomSnippetsPage.Add("BottomSnippets", productListPreRender); 5716 5717 Block productListInitializers = new Block 5718 { 5719 Id = "Initializers", 5720 SortId = 60, 5721 Template = RenderInitializers() 5722 }; 5723 productListBottomSnippetsPage.Add("BottomSnippets", productListInitializers); 5724 } 5725 5726 5727 @helper RenderFavoritesTemplates() 5728 { 5729 var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star"; 5730 string favoriteIcon = "fas fa-" + selectedFavoriteIcon; 5731 string favoriteOutlineIcon = "fal fa-" + selectedFavoriteIcon; 5732 bool useFacebookPixel = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("FacebookPixelID")); 5733 string currentFavoriteListId = HttpContext.Current.Request.QueryString.Get("ListID"); 5734 5735 <script id="FavoriteTemplate" type="text/x-template"> 5736 <div class="favorites-list u-ta-left js-favorites-list"> 5737 @Render(new Button { 5738 CssClass = "u-no-margin js-favorite-btn", 5739 Icon = new Icon 5740 { 5741 Name = "{{#if isInAnyFavoriteList}}" + favoriteIcon + "{{else}}" + favoriteOutlineIcon + "{{/if}}", 5742 CssClass = "fa-1_5x", 5743 LabelPosition = IconLabelPosition.After 5744 }, 5745 ButtonLayout = ButtonLayout.LinkClean, 5746 ButtonType = ButtonType.Button, 5747 OnClick = "document.getElementById('FavoriteTrigger_{{id}}').checked = true" 5748 }) 5749 <input type="checkbox" id="FavoriteTrigger_{{id}}" class="dropdown-trigger" /> 5750 <div class="dropdown dropdown--position-32px"> 5751 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod"> 5752 <ul class="list list--clean dw-mod"> 5753 {{#FavoriteLists}} 5754 {{>FavoriteListItem}} 5755 {{/FavoriteLists}} 5756 </ul> 5757 </div> 5758 <label class="dropdown-trigger-off" for="FavoriteTrigger_{{id}}"></label> 5759 </div> 5760 </div> 5761 </script> 5762 5763 <script id="FavoriteListItem" type="text/x-template"> 5764 <li> 5765 @{ 5766 var button = new Button { 5767 CssClass = "list__link u-no-underline", 5768 OnClick = "toggleFavAction(this, event)", 5769 Icon = new Icon { Name = "{{#if isInFavoriteList}}" + favoriteIcon + "{{else}}" + favoriteOutlineIcon + "{{/if}}", LabelPosition = IconLabelPosition.After }, 5770 AltText = "{{#if isInFavoriteList}}" + Translate("Remove from") + " {{name}}{{else}}" + Translate("Add to") + " {{name}}{{/if}}", 5771 Title = "{{name}}", 5772 ButtonType = ButtonType.Button, 5773 ButtonLayout = ButtonLayout.LinkClean, 5774 ExtraAttributes = new Dictionary<string, string> 5775 { 5776 { "data-list-id", "{{listId}}" }, 5777 { "data-list-name", "{{name}}" }, 5778 { "data-remove-link", "{{removeLink}}" }, 5779 { "data-add-link", "{{addLink}}" }, 5780 { "data-is-in-list", "{{isInFavoriteList}}" }, 5781 5782 } 5783 }; 5784 if (useFacebookPixel) 5785 { 5786 button.ExtraAttributes.Add("data-facebook-object", "{{facebookPixelAddAction}}"); 5787 } 5788 } 5789 @Render(button) 5790 </li> 5791 </script> 5792 5793 <script> 5794 @if (!string.IsNullOrEmpty(currentFavoriteListId)) 5795 { 5796 <text> 5797 window.currentFavoriteListId = "@currentFavoriteListId"; 5798 </text> 5799 } 5800 function toggleFavAction(button, event) { 5801 if (button.getAttribute('data-add-link').indexOf('CCCreateNewList') > -1) { 5802 Scroll.SavePosition(event); 5803 @if (useFacebookPixel) 5804 { 5805 <text> 5806 fbq('track', 'AddToWishlist', JSON.parse(button.getAttribute('data-facebook-object'))); 5807 </text> 5808 } 5809 location.href = button.getAttribute('data-add-link'); 5810 return; 5811 } 5812 let isAdd = button.getAttribute('data-is-in-list') == "false"; 5813 Request.Fetch().get( 5814 isAdd ? button.getAttribute('data-add-link') : button.getAttribute('data-remove-link'), 5815 function (result) { 5816 button.querySelector('i').className = isAdd ? '@favoriteIcon u-margin-right--lg' : '@favoriteOutlineIcon u-margin-right--lg'; 5817 button.setAttribute('data-is-in-list', isAdd); 5818 button.setAttribute('title', (!isAdd ? '@Translate("Add to") ' : '@Translate("Remove from") ') + button.getAttribute('data-list-name')) 5819 let favList = button.closest('.js-favorites-list'); 5820 let favBtn = favList.querySelector('.js-favorite-btn i'); 5821 let isInAnyFavoriteList = favList.querySelector('[data-is-in-list=true]') != null; 5822 if (isInAnyFavoriteList) { 5823 favBtn.className = '@favoriteIcon' + ' fa-1_5x'; 5824 } else { 5825 favBtn.className = '@favoriteOutlineIcon' + ' fa-1_5x'; 5826 } 5827 @if (useFacebookPixel) 5828 { 5829 <text> 5830 if (isAdd) { 5831 fbq('track', 'AddToWishlist', JSON.parse(button.getAttribute('data-facebook-object'))); 5832 } 5833 </text> 5834 } 5835 if (window.currentFavoriteListId != null) { //if this page is favorite list 5836 let listId = button.getAttribute("data-list-id"); 5837 if (listId == window.currentFavoriteListId && !isAdd) { 5838 location.reload(); 5839 } 5840 } 5841 }, 5842 function () { 5843 console.error("FavoriteLists: Error in ToggleFavAction request"); 5844 }, 5845 false 5846 ); 5847 } 5848 </script> 5849 } 5850 5851 @helper RenderStickersTemplates() 5852 { 5853 <script id="StickersContainer" type="text/x-template"> 5854 <div class="stickers-container stickers-container--{{{convertStickerPositionToClassName Position}}} dw-mod"> 5855 {{#Stickers}} 5856 {{>Sticker}} 5857 {{/Stickers}} 5858 </div> 5859 </script> 5860 5861 <script id="Sticker" type="text/x-template"> 5862 <div class="stickers-container__tag {{CssClass}} dw-mod">{{Title}}</div> 5863 </script> 5864 5865 <script id="MiniSticker" type="text/x-template"> 5866 <div class="stickers-container__tag stickers-container__tag--micro {{CssClass}} dw-mod">{{Title}}</div> 5867 </script> 5868 } 5869 5870 @helper RenderUnitTemplates() 5871 { 5872 <script id="UnitOption" type="text/x-template"> 5873 <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent(this.closest('.js-product').id, '{{link}}&feed=true&UnitID={{value}}')">{{name}}</div> 5874 </script> 5875 } 5876 5877 @helper RenderVariantTemplates() { 5878 <script id="VariantsTemplate" type="text/x-template"> 5879 {{#.}} 5880 <div> 5881 <div> 5882 {{#VariantOptions}} 5883 {{>VariantOption}} 5884 {{/VariantOptions}} 5885 </div> 5886 </div> 5887 {{/.}} 5888 </script> 5889 5890 <script id="VariantOption" type="text/x-template"> 5891 {{#if color}} 5892 <button type="button" data-variant-id="{{variantId}}" data-variant-group="{{groupId}}" onclick="MatchVariants.SelectThis(event)" class="btn btn--colorbox u-margin-right {{disabled}} {{selected}} js-variant-option" data-check="{{selected}}" {{disabled}} style="background-color: {{color}}"></button> 5893 {{else}} 5894 {{#if image}} 5895 <img data-variant-id="{{variantId}}" data-variant-group="{{groupId}}" src="{{image}}" onclick="MatchVariants.SelectThis(event)" alt="{{name}}" title="{{name}}" class="btn btn--tag {{selected}} js-variant-option" data-check="{{selected}}" /> 5896 {{else}} 5897 <button type="button" data-variant-id="{{variantId}}" data-variant-group="{{groupId}}" onclick="MatchVariants.SelectThis(event)" class="btn btn--tag {{disabled}} {{selected}} js-variant-option" data-check="{{selected}}" {{disabled}}>{{name}}</button> 5898 {{/if}} 5899 {{/if}} 5900 </script> 5901 5902 <script id="DropdownVariantsTemplate" type="text/x-template"> 5903 {{#.}} 5904 <div> 5905 <div class="u-bold">{{name}}</div> 5906 <select id="VariantSelector_{{id}}" class="u-full-width dw-mod" name="VariantSelector_{{id}}" onchange="MatchVariants.SelectOnChange(event)" > 5907 <option>@Translate("Choose")</option> 5908 {{#VariantOptions}} 5909 {{>DropdownVariantOption}} 5910 {{/VariantOptions}} 5911 </select> 5912 </div> 5913 {{/.}} 5914 </script> 5915 5916 <script id="DropdownVariantOption" type="text/x-template"> 5917 <option class="js-variant-option {{selected}}" id="{{groupId}}_{{variantId}}" value="{{groupId}}_{{variantId}}" data-variant-id="{{variantId}}" data-variant-group="{{groupId}}" {{#if selected}}selected{{/if}} data-check="{{selected}}">{{name}}</option> 5918 </script> 5919 5920 <script id="StaticVariantsTemplate" type="text/x-template"> 5921 {{#.}} 5922 {{#if isFirstGroup}} 5923 <div> 5924 {{#VariantOptions}} 5925 {{>StaticVariantOption}} 5926 {{/VariantOptions}} 5927 </div> 5928 {{/if}} 5929 {{/.}} 5930 </script> 5931 5932 <script id="StaticVariantOption" type="text/x-template"> 5933 {{#if color}} 5934 <div class="static-variant static-variant--color dw-mod" style="background-color: {{color}}" title="{{name}}"></div> 5935 {{else}} 5936 <div class="static-variant dw-mod">{{name}} </div> 5937 {{/if}} 5938 </script> 5939 5940 5941 <script id="StaticVariantsLgTemplate" type="text/x-template"> 5942 {{#.}} 5943 {{#if isFirstGroup}} 5944 <div> 5945 {{#VariantOptions}} 5946 {{>StaticVariantLgOption}} 5947 {{/VariantOptions}} 5948 </div> 5949 {{/if}} 5950 {{/.}} 5951 </script> 5952 5953 <script id="StaticVariantLgOption" type="text/x-template"> 5954 {{#if color}} 5955 <div class="static-variant static-variant--color static-variant--color--lg dw-mod" style="background-color: {{color}}" title="{{name}}"></div> 5956 {{else}} 5957 <div class="static-variant dw-mod">{{name}} </div> 5958 {{/if}} 5959 </script> 5960 5961 <script id="VariantOptionImage" type="text/x-template"> 5962 <img data-variant-id="{{variantId}}" data-friends="{{friendsList}}" data-variant-group="{{groupId}}" onclick="MatchVariants.SelectThis(event)" src="/Admin/Public/GetImage.ashx?width=100&amp;height=50&amp;crop=5&amp;Compression=75&amp;image=/Images/{{image}}" alt="{{name}}" title="{{name}}" class="btn btn--tag {{disabled}} {{selected}} js-variant-option" data-check="{{selected}}" {{disabled}} /> 5963 </script> 5964 } 5965 5966 @helper RenderPreRenderTemplates() { 5967 string facetsViewMode = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductList").GetString("FacetsViewMode")) ? Pageview.AreaSettings.GetItem("ProductList").GetString("FacetsViewMode").ToLower() : "left"; 5968 5969 <script id="ProductPreRenderContainer" type="text/x-template"> 5970 @if (facetsViewMode == "left" && Pageview.Device.ToString() != "Mobile") 5971 { 5972 <div class="grid__col-3"> 5973 <div class="pre-render-element pre-render-element--xs"></div> 5974 <div class="pre-render-element pre-render-element--md"></div> 5975 <div class="pre-render-element pre-render-element--md"></div> 5976 <div class="pre-render-element pre-render-element--md"></div> 5977 </div> 5978 } 5979 <div class="grid__col-auto"> 5980 <div class="pre-render-element pre-render-element--xs"></div> 5981 <div class="pre-render-element pre-render-element--lg"></div> 5982 <div class="pre-render-element pre-render-element--lg"></div> 5983 <div class="pre-render-element pre-render-element--lg"></div> 5984 <div class="pre-render-element pre-render-element--lg"></div> 5985 </div> 5986 </script> 5987 } 5988 5989 @helper RenderInitializers() { 5990 <script> 5991 document.addEventListener("DOMContentLoaded", function (event) { 5992 document.getElementById("productList").addEventListener('contentLoaded', function (e) { 5993 if (getTarget(e).id === "productList") { 5994 Search.Init(); 5995 Facets.Init("selectedFacets", "productList"); 5996 } 5997 }, false); 5998 5999 @{ 6000 bool useGoogleTagManager = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("GoogleTagManagerID")); 6001 6002 if (useGoogleTagManager) 6003 { 6004 <text> 6005 Scroll.AddIsInViewportListener(".js-product-scroll-trigger", function (elem) { 6006 let googleImpression = JSON.parse(elem.getAttribute("data-params")); 6007 googleEnchantImpression(googleImpression); 6008 elem.classList.remove("js-product-scroll-trigger"); 6009 }); 6010 </text> 6011 } 6012 } 6013 6014 }); 6015 </script> 6016 } 6017 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 6018 @using Dynamicweb.Core 6019 @using System 6020 @using System.Web 6021 @using System.Linq 6022 @using System.Collections.Generic 6023 @using Dynamicweb.Rapido.Blocks 6024 @using Dynamicweb.Rapido.Blocks.Components.General 6025 @using Dynamicweb.Rapido.Services 6026 6027 @functions { 6028 BlocksPage productListActionsBlocksPage = BlocksPage.GetBlockPage("ProductList"); 6029 } 6030 6031 @{ 6032 string actionsFavoriteListId = HttpContext.Current.Request.QueryString.Get("ListID"); 6033 bool actionsIsFavoriteList = !string.IsNullOrEmpty(actionsFavoriteListId); 6034 string actionsColumnSize = actionsIsFavoriteList ? "4" : "6"; 6035 6036 productListActionsBlocksPage.Add("ProductListHeader", new Block 6037 { 6038 Id = "Actions", 6039 SortId = 30, 6040 Template = RenderListActions(), 6041 Design = new Design 6042 { 6043 CssClass = "grid__col-sm-" + actionsColumnSize + " grid--align-self-center" 6044 } 6045 }); 6046 6047 productListActionsBlocksPage.Add("BottomSnippets", new Block() { 6048 Id = "ListViewSelectListener", 6049 Template = RenderListViewSelectListener() 6050 }); 6051 6052 } 6053 6054 @helper RenderListActions() 6055 { 6056 @*This is part of a script template *@ 6057 6058 bool showSorting = Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableSorting"); 6059 string listId = HttpContext.Current.Request.QueryString.Get("ListID"); 6060 bool isFavoriteList = !string.IsNullOrEmpty(listId); 6061 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; 6062 6063 List<Block> subBlocks = this.productListActionsBlocksPage.GetBlockListById("Views").OrderBy(item => item.SortId).ToList(); 6064 6065 <div class="buttons-collection buttons-collection--right"> 6066 @if (showSorting) 6067 { 6068 string dropdownCssClass = Pageview.Device.ToString() == "Mobile" ? "u-flex-grow--1" : ""; 6069 6070 <input type="checkbox" id="ProductSort" class="dropdown-trigger" /> 6071 <div class="dropdown u-w150px u-inline-block @dropdownCssClass dw-mod"> 6072 <label class="dropdown__header dropdown__btn dropdown__btn--small dw-mod" for="ProductSort">{{selectedSort}}</label> 6073 <div class="dropdown__content dw-mod"> 6074 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: '', SortOrder: '' }, true);">@Translate("Default")</div> 6075 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'Created', SortOrder: 'DESC'}, true);">@Translate("Newest")</div> 6076 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'NameForSort', SortOrder: 'ASC'}, true);">@Translate("Name A - Z")</div> 6077 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'NameForSort', SortOrder: 'DESC'}, true);">@Translate("Name Z - A")</div> 6078 @if (Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 6079 { 6080 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'Price', SortOrder: 'ASC' }, true);">@Translate("Price low - high")</div> 6081 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'Price', SortOrder: 'DESC' }, true);">@Translate("Price high - low")</div> 6082 } 6083 </div> 6084 <label class="dropdown-trigger-off" for="ProductSort"></label> 6085 </div> 6086 } 6087 6088 @if (subBlocks.Count > 1) 6089 { 6090 <div> 6091 @foreach (Block item in subBlocks) 6092 { 6093 <input type="radio" class="tag-btn-trigger" id="ListViewBtn_@item.Id" name="ViewBtnGroup"> 6094 <label for="ListViewBtn_@item.Id" class="btn btn--tag u-no-margin" onclick="HandlebarsBolt.UpdateTemplate('ProductsContainer', '@item.Id')"><i class="fas fa-@item.Name"></i></label> 6095 } 6096 </div> 6097 } 6098 6099 @if (isFavoriteList && Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 6100 { 6101 string stockValidationUrl = Dna.StockValidation.Product.GetValidationUrl(GetPageIdByNavigationTag("StockValidation")); 6102 Button buyAllButton = new Button 6103 { 6104 ButtonType = ButtonType.Submit, 6105 Title = Translate("Buy all"), 6106 ButtonLayout = ButtonLayout.Secondary, 6107 Icon = new Icon {CssClass = cartIcon}, 6108 CssClass = "buy-all btn--sm dw-mod", 6109 OnClick = "StockValidation.MultiAddToCartValidation(event, '" + stockValidationUrl + "');" 6110 }; 6111 @Render(buyAllButton) 6112 } 6113 </div> 6114 } 6115 6116 @helper RenderListViewSelectListener() 6117 { 6118 /* the same block code placed in ProductListFeed.cshtml */ 6119 Dictionary<string, bool> views = new Dictionary<string, bool>() 6120 { 6121 { "ProductItemContainer", Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableListView") }, 6122 { "ProductGridItemContainer", Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableGridView") }, 6123 { "ProductDetailsItemContainer", Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableDetailsView") }, 6124 { "ProductTilesViewContainer", Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableTilesView") } 6125 }; 6126 6127 string defaultView = Pageview.AreaSettings.GetItem("ProductList").GetList("DefaultListView") != null ? Pageview.AreaSettings.GetItem("ProductList").GetList("DefaultListView").SelectedValue : ""; 6128 6129 if (string.IsNullOrEmpty(defaultView) || !views[defaultView]) 6130 { 6131 defaultView = views.FirstOrDefault(x => x.Value).Key ?? "ProductItemContainer"; 6132 } 6133 6134 <script> 6135 let defaultTemplate = '@defaultView'; 6136 let container = 'productList'; 6137 let cookieName = 'ProductsContainerTemplate'; 6138 6139 document.addEventListener('DOMContentLoaded', function (event) { 6140 document.getElementById(container).addEventListener('contentLoaded', function () { 6141 let selectedMode = RememberState.GetCookie(cookieName); 6142 let element = document.getElementById('ListViewBtn_' + (selectedMode ? selectedMode : defaultTemplate)); 6143 if (element != null) { 6144 element.checked = true; 6145 } 6146 }, false); 6147 }); 6148 </script> 6149 } 6150 6151 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 6152 @using Dynamicweb.Rapido.Blocks 6153 @using Dynamicweb.Rapido.Blocks.Components.General 6154 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 6155 @using Dynamicweb.Rapido.Blocks 6156 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 6157 @using Dynamicweb.Rapido.Blocks 6158 @using Dynamicweb.Rapido.Blocks.Components.General 6159 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 6160 @using Dynamicweb.Rapido.Blocks 6161 @using Dynamicweb.Rapido.Blocks.Components.General 6162 @functions { 6163 6164 static Modal stockValidationWarningModal = new Modal 6165 { 6166 Id = "StockValidationWarning", 6167 Width = ModalWidth.Lg 6168 }; 6169 private static Block GetStockValidationModal() 6170 { 6171 return new Block 6172 { 6173 Id = "StockValidationWarningModal", 6174 SortId = 1, 6175 Component = stockValidationWarningModal 6176 }; 6177 } 6178 6179 } 6180 @{ 6181 stockValidationWarningModal.Heading = new Heading {Title = Translate("Out of stock")}; 6182 stockValidationWarningModal.BodyTemplate = RenderWarningWindow(); 6183 } 6184 6185 @helper RenderWarningWindow() 6186 { 6187 var orderNotFound = Translate("Order not found."); 6188 var unavailableProduct = Translate("{{ProductName}} ({{ProductNumber}}) is not available."); 6189 var insufficientStock = Translate("There are only {{AvailableAmount}} items in stock instead of the {{RequestedAmount}} you requested for {{ProductName}} ({{ProductNumber}})."); 6190 var insufficientStockSingular = Translate("There is only {{AvailableAmount}} item in stock instead of the {{RequestedAmount}} you requested for {{ProductName}} ({{ProductNumber}})."); 6191 var noMoreStock = Translate("There is no more available stock for {{ProductName}} ({{ProductNumber}})."); 6192 var missingVariantCombination = Translate("{{ProductName}} ({{ProductNumber}}) requires additional information before adding to the cart."); 6193 6194 <p id="stockValidationWarningMessage" data-order-not-found="@orderNotFound" data-unavailable-product="@unavailableProduct" data-insufficient-stock="@insufficientStock" data-insufficient-stock-singular="@insufficientStockSingular" data-no-more-stock="@noMoreStock" data-missing-variant-combination="@missingVariantCombination"></p> 6195 6196 @* Cannot use .Actions because of bug. Reported https://doc.dynamicweb.com/forum/templates/modal-component-duplicates-buttons?PID=1605 *@ 6197 // Oct 22: Still bugged 6198 <div class="u-ta-right"> 6199 @Render(new Button 6200 { 6201 ButtonLayout = ButtonLayout.Primary, 6202 CssClass = "u-margin-top u-w120px", 6203 Id = "OkButton", 6204 Title = Translate("Ok"), 6205 OnClick = "toggleWindowModal(document.getElementById('StockValidationWarningModalTrigger'))", 6206 ExtraAttributes = 6207 { 6208 {"data-continue", Translate("Add items in stock")}, 6209 {"data-ok", Translate("Ok")} 6210 } 6211 }) 6212 6213 @Render(new Button 6214 { 6215 ButtonLayout = ButtonLayout.Secondary, 6216 CssClass = "u-margin-top u-w120px u-hidden", 6217 Id = "CancelButton", 6218 Title = Translate("Cancel"), 6219 OnClick = "toggleWindowModal(document.getElementById('StockValidationWarningModalTrigger'))" 6220 }) 6221 </div> 6222 } 6223 @{ 6224 BlocksPage.GetBlockPage("ProductList").Add(GetStockValidationModal()); 6225 } 6226 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 6227 @using Dynamicweb.Frontend.Devices 6228 @using Dynamicweb.Rapido.Blocks 6229 @using Dynamicweb.Rapido.Blocks.Components.General 6230 @{ 6231 BlocksPage skipFilterNavigationBlocksPage = BlocksPage.GetBlockPage("ProductList"); 6232 6233 if (Pageview.Device == DeviceType.Desktop) 6234 { 6235 Block skipFiltersNavigation = new Block 6236 { 6237 Id = "SkipFiltersNavigation", 6238 SortId = 1, 6239 Template = RenderSkipFiltersNavigation() 6240 }; 6241 skipFilterNavigationBlocksPage.Add("PageContainer", skipFiltersNavigation); 6242 } 6243 } 6244 6245 @helper RenderSkipFiltersNavigation() 6246 { 6247 var cssClasses = "u-show-on-focus u-w340px"; 6248 6249 <div class="u-position-absolute u-padding--lg"> 6250 @Render(new Button 6251 { 6252 CssClass = cssClasses, 6253 Title = Translate("Skip filter navigation"), 6254 OnClick = "Accessibility.SkipNavigationTo(event, '#ProductsContainer')", 6255 ExtraAttributes = {{"onkeypress", "Accessibility.FakeClickOnEnter(event, this)"}} 6256 }) 6257 </div> 6258 } 6259 6260 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 6261 @using Dynamicweb.Rapido.Blocks 6262 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 6263 @using System.Collections.Generic 6264 @using Dynamicweb.Rapido.Blocks 6265 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 6266 @using Dynamicweb.Rapido.Blocks.Components.General 6267 6268 @functions { 6269 BlocksPage detailsViewPageCustom = BlocksPage.GetBlockPage("ProductList"); 6270 bool isB2BDetailsView; 6271 } 6272 6273 @if (Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableDetailsView")) 6274 { 6275 isB2BDetailsView = Pageview.AreaSettings.GetItem("Custom").GetBoolean("IsB2B"); 6276 6277 var detailsViewItemInfoContainerBlock = detailsViewPageCustom.GetBlockById("DetailsViewItemInfoContainer"); 6278 var detailsViewItemRightBottomBlock = detailsViewPageCustom.GetBlockById("DetailsViewItemRightBottom"); 6279 var detailsViewItemRightBlock = detailsViewPageCustom.GetBlockById("DetailsViewItemRight"); 6280 6281 if (detailsViewItemInfoContainerBlock != null && detailsViewItemRightBottomBlock != null) 6282 { 6283 detailsViewItemRightBottomBlock.SortId = 60; 6284 detailsViewItemInfoContainerBlock.BlocksList.Add(detailsViewItemRightBottomBlock); 6285 if (detailsViewItemRightBlock != null) 6286 { 6287 detailsViewItemRightBlock.BlocksList.Remove(detailsViewItemRightBottomBlock); 6288 } 6289 } 6290 6291 var detailsViewItemActionsBlock = detailsViewPageCustom.GetBlockById("DetailsViewItemActions"); 6292 if (detailsViewItemActionsBlock != null) 6293 { 6294 detailsViewItemActionsBlock.Template = RenderDetailsViewItemActionsCustom(); 6295 } 6296 6297 if (detailsViewItemInfoContainerBlock != null) 6298 { 6299 detailsViewItemInfoContainerBlock.Add( 6300 new Block 6301 { 6302 Id = "DetailsViewItemQuantityPerUnit", 6303 SortId = 20, 6304 Template = RenderDetailsViewItemQuantityPerUnit() 6305 } 6306 ); 6307 } 6308 6309 if (detailsViewItemRightBlock != null) 6310 { 6311 detailsViewItemRightBlock.Add( 6312 new Block 6313 { 6314 Id = "DetailsViewQuantityPrices", 6315 SortId = 10, 6316 Template = RenderDetailsViewItemPriceTable() 6317 } 6318 ); 6319 } 6320 6321 var detailsViewAddToCartBlock = detailsViewPageCustom.GetBlockById("DetailsViewAddToCart"); 6322 if (detailsViewAddToCartBlock != null) 6323 { 6324 detailsViewAddToCartBlock.Template = RenderDetailsViewAddToCartCustom(); 6325 } 6326 6327 detailsViewPageCustom.GetBlockById("DetailsViewScripts")?.Add(new Block 6328 { 6329 Id = "DetailsViewPriceTable", 6330 SortId = 40, 6331 Template = RenderDetailsViewPriceTable() 6332 }); 6333 6334 if (!isB2BDetailsView) 6335 { 6336 detailsViewPageCustom.GetBlockById("DetailsViewScripts")?.Add(new Block 6337 { 6338 Id = "DetailsViewOrderDraftScripts", 6339 SortId = 50, 6340 Template = DetailsViewOrderDraftScripts() 6341 }); 6342 } 6343 6344 var detailsViewItemTitle = detailsViewPageCustom.GetBlockById("DetailsViewItemTitle"); 6345 if (detailsViewItemTitle != null) 6346 { 6347 detailsViewItemTitle.Template = RenderDetailsViewItemTitleCustom(); 6348 } 6349 } 6350 6351 @helper RenderDetailsViewAddToCartCustom() 6352 { 6353 @* START CUSTOM CODE *@ 6354 var displayDraftButton = !isB2BDetailsView && Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")) && Dynamicweb.Rapido.Services.User.IsBuyingAllowed() && Dna.WilsonDaniels.Helpers.GetNewCartDrafts().Any() && GetPageIdByNavigationTag("OrderDraft") != 0; 6355 @* END CUSTOM CODE *@ 6356 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 6357 bool showPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice"); 6358 6359 var addToCartBtn = new AddToCart 6360 { 6361 AddButton = new AddToCartButton 6362 { 6363 /*START CUSTOM CODE*/ 6364 AltText = isB2BDetailsView ? Translate("Add to cart") : Translate("Add to New Quote"), 6365 /*END CUSTOM CODE*/ 6366 HideTitle = true, 6367 ProductId = "{{productId}}", 6368 VariantId = "{{variantid}}", 6369 UnitId = "{{unitId}}", 6370 ProductInfo = "{{productInfo}}", 6371 BuyForPoints = pointShopOnly, 6372 OnClick = "{{facebookPixelAction}}", 6373 ExtraAttributes = new Dictionary<string, string> 6374 { 6375 { "{{disabledBuyButton}}", "" }, 6376 { "{{outOfStock}}", "" } 6377 } 6378 } 6379 }; 6380 6381 if (!pointShopOnly) 6382 { 6383 /*START CUSTOM CODE*/ 6384 addToCartBtn.QuantitySelector = new QuantitySelector 6385 { 6386 Id = "Quantity{{id}}", 6387 Min = "{{minQuantity}}", 6388 Value = "{{minQuantity}}", 6389 ExtraAttributes = new Dictionary<string, string> 6390 { 6391 { "{{outOfStock}}", "" }, 6392 { "max", "{{maxQuantity}}" } 6393 } 6394 }; 6395 /*END CUSTOM CODE*/ 6396 } 6397 6398 if (!showPrice) 6399 { 6400 addToCartBtn.UnitSelector = getUnitsSelector(); 6401 } 6402 6403 <script id="DetailsViewAddToCartContainer" type="text/x-template"> 6404 <div class="product-list__details-actions"> 6405 @* START CUSTOM CODE *@ 6406 @if (isB2BDetailsView) 6407 { 6408 @Render(addToCartBtn) 6409 } 6410 else 6411 { 6412 var link = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(GetPageIdByNavigationTag("OrderDraft")); 6413 <text> 6414 {{#if hasStock}} 6415 <p>@Translate("This current product is already on an")<a class="u-brand-color-two" href="@link"> @Translate("open order request")</a></p> 6416 {{else}} 6417 @Render(addToCartBtn.UnitSelector) 6418 @Render(addToCartBtn.QuantitySelector) 6419 @if (displayDraftButton) 6420 { 6421 @Render(new Button 6422 { 6423 Title = Translate("Add to existing Order Request"), 6424 ButtonLayout = ButtonLayout.Secondary, 6425 ExtraAttributes = {{"data-product", "{{productId}}"}, {"data-unit", "{{unitId}}"}, {"data-quantityinput", "Quantity{{id}}"}}, 6426 OnClick = "openOrderDraftModal(this)" 6427 }) 6428 } 6429 else 6430 { 6431 @Render(new Button 6432 { 6433 Title = Translate("Add to new Order Request"), 6434 ButtonLayout = ButtonLayout.Primary, 6435 ExtraAttributes = {{"data-product", "{{productId}}"}, {"data-unit", "{{unitId}}"}, {"data-quantityinput", "Quantity{{id}}"}}, 6436 OnClick = "openNewOrderDraftModal(this)" 6437 }) 6438 } 6439 {{/if}} 6440 </text> 6441 } 6442 @* END CUSTOM CODE *@ 6443 </div> 6444 </script> 6445 } 6446 6447 @helper RenderDetailsViewItemActionsCustom() 6448 { 6449 bool showCartButton = detailsViewSettings.GetBoolean("ShowAddToCartButton"); 6450 bool showViewButton = detailsViewSettings.GetBoolean("ShowViewButton"); 6451 @*START CUSTOM CODE: Prevent ordering*@ 6452 if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed() && !Dna.WilsonDaniels.Helpers.IsLoginPreventOrdering()) 6453 //END CUSTOM CODE 6454 { 6455 if (showCartButton) 6456 { 6457 if (!showViewButton) 6458 { 6459 <text>{{#if hideAddToCartButton}}</text> 6460 @RenderDetailsViewItemViewButton() 6461 <text>{{else}}</text> 6462 @RenderDetailsViewItemAddToCart() 6463 <text>{{/if}}</text> 6464 } 6465 else 6466 { 6467 @RenderDetailsViewItemViewButton() 6468 } 6469 } 6470 else if (showViewButton) 6471 { 6472 @RenderDetailsViewItemViewButton() 6473 } 6474 } 6475 else if (showViewButton) 6476 { 6477 @RenderDetailsViewItemViewButton() 6478 } 6479 } 6480 6481 @helper RenderDetailsViewItemQuantityPerUnit() 6482 { 6483 <text> 6484 {{#if quantityPerUnit}} 6485 @*START CUSTOM CODE - conditional on B2B*@ 6486 {{#if isB2B}} 6487 <div class="product-list__details-bottle dw-mod">{{quantityPerUnit}}/{{bottleSize}}</div> 6488 {{else}} 6489 <div class="dw-mod">{{bottleSize}}</div> 6490 {{/if}} 6491 @*END CUSTOM CODE*@ 6492 {{/if}} 6493 </text> 6494 } 6495 6496 @helper RenderDetailsViewItemPriceTable() 6497 { 6498 <text> 6499 {{#unless hidePriceDisallowOrdering}} 6500 {{#if isLiveProductInfoActive}} 6501 <div class="js-handlebars-root js-live-info-container" 6502 data-template="DetailsViewPriceTableContainer" 6503 data-preloader="minimal" 6504 data-product-id="{{productId}}"> 6505 </div> 6506 {{else}} 6507 {{>DetailsViewPriceTableContainer}} 6508 {{/if}} 6509 {{/unless}} 6510 </text> 6511 } 6512 6513 @helper RenderDetailsViewPriceTable() 6514 { 6515 var colorStyle = "color:{{cssClass}} !important"; 6516 <script id="DetailsViewPriceTableContainer" type="text/x-template"> 6517 {{#if ProductPrices}} 6518 @*START CUSTOM CODE: Decrease table size*@ 6519 <table class="price-matrix table table--no-top-border u-margin-top--lg u-font-size--xs dw-mod"> 6520 @*END CUSTOM CODE*@ 6521 <thead> 6522 <tr> 6523 <th></th> 6524 <th class="u-ta-center">@Translate("Case price")</th> @*CUSTOM CODE - Helper Added*@ 6525 <th class="u-ta-center">@Translate("Bottle price")</th> @*CUSTOM CODE - Helper Added*@ 6526 </tr> 6527 </thead> 6528 <tbody> 6529 {{#ProductPrices}} 6530 <tr style="@colorStyle"> 6531 <th class="u-ta-center">{{description}}</th> @*CUSTOM CODE - Helper Added*@ 6532 <td class="u-ta-center">{{price}}</td> @*CUSTOM CODE - Helper Added*@ 6533 <td class="u-ta-center">{{bottlePrice}}</td> @*CUSTOM CODE - Helper Added*@ 6534 </tr> 6535 {{/ProductPrices}} 6536 </tbody> 6537 </table> 6538 {{/if}} 6539 </script> 6540 } 6541 6542 @helper DetailsViewOrderDraftScripts() 6543 { 6544 <script> 6545 function openOrderDraftModal(el) 6546 { 6547 var cartSelector = document.getElementById('CartSelector'); 6548 document.getElementById('OrderDraftSelectModalTrigger').checked = true; 6549 cartSelector.setAttribute("data-product", el.getAttribute("data-product")); 6550 cartSelector.setAttribute("data-unit", el.getAttribute("data-unit")); 6551 cartSelector.setAttribute("data-quantity", document.getElementById(el.getAttribute("data-quantityinput")).value); 6552 } 6553 6554 function openNewOrderDraftModal(el) 6555 { 6556 var form = document.getElementById('NewDraftForm'); 6557 document.getElementById('NewDraftModalTrigger').checked = true; 6558 form.setAttribute("data-product", el.getAttribute("data-product")); 6559 form.setAttribute("data-unit", el.getAttribute("data-unit")); 6560 form.setAttribute("data-quantity", document.getElementById(el.getAttribute("data-quantityinput")).value); 6561 } 6562 </script> 6563 } 6564 6565 @helper RenderDetailsViewItemTitleCustom() 6566 { 6567 <a href="{{link}}" onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" title="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}" class="product-list__details-title u-color-inherit dw-mod"> 6568 <h6 class="u-no-margin u-bold product-list__details-title">{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}</h6> @*CUSTOM CODE - helper class*@ 6569 </a> 6570 } 6571 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 6572 @using System.Collections.Generic 6573 @using Dynamicweb.Core 6574 @using Dynamicweb.Rapido.Blocks 6575 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 6576 @using Dynamicweb.Rapido.Blocks.Components.General 6577 6578 @functions { 6579 BlocksPage gridViewPageCustom = BlocksPage.GetBlockPage("ProductList"); 6580 bool isB2BGridView; 6581 } 6582 6583 @if (Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableGridView")) 6584 { 6585 isB2BGridView = Pageview.AreaSettings.GetItem("Custom").GetBoolean("IsB2B"); 6586 6587 var gridViewScriptsBlock = gridViewPageCustom.GetBlockById("GridViewScripts"); 6588 if (gridViewScriptsBlock != null) 6589 { 6590 gridViewScriptsBlock.Template = GridViewCustom(); 6591 6592 gridViewScriptsBlock.Add(new Block 6593 { 6594 Id = "GridViewUnitSelector", 6595 SortId = 30, 6596 Template = RenderGridViewUnitSelector() 6597 }); 6598 6599 gridViewScriptsBlock.Add(new Block 6600 { 6601 Id = "GridViewPriceTable", 6602 SortId = 40, 6603 Template = RenderGridViewPriceTable() 6604 }); 6605 } 6606 6607 var gridViewItemActionsBlock = gridViewPageCustom.GetBlockById("GridViewItemActions"); 6608 if (gridViewItemActionsBlock != null) 6609 { 6610 gridViewItemActionsBlock.Template = RenderGridViewItemActionsCustom(); 6611 } 6612 6613 var gridViewItemInfoContainerBlock = gridViewPageCustom.GetBlockById("GridViewItemInfoContainer"); 6614 if (gridViewItemInfoContainerBlock != null) 6615 { 6616 gridViewItemInfoContainerBlock.Add( 6617 new Block 6618 { 6619 Id = "GridViewItemQuantityPerUnit", 6620 SortId = 20, 6621 Template = RenderGridViewItemQuantityPerUnit() 6622 } 6623 ); 6624 gridViewItemInfoContainerBlock.Add( 6625 new Block 6626 { 6627 Id = "GridViewQuantityPrices", 6628 SortId = 25, 6629 Template = RenderGridViewItemPriceTable() 6630 } 6631 ); 6632 gridViewItemInfoContainerBlock.Add( 6633 new Block 6634 { 6635 Id = "GridViewItemUnitSelector", 6636 SortId = 27, 6637 Template = RenderGridViewItemUnitSelectorCustom(), 6638 } 6639 ); 6640 } 6641 6642 var gridViewAddToCartBlock = gridViewPageCustom.GetBlockById("GridViewAddToCart"); 6643 6644 if (gridViewAddToCartBlock != null) 6645 { 6646 gridViewAddToCartBlock.Template = RenderGridViewAddToCartCustom(); 6647 } 6648 6649 if (!isB2BGridView) 6650 { 6651 gridViewPageCustom.GetBlockById("GridViewScripts")?.Add(new Block 6652 { 6653 Id = "GridViewOrderDraftScripts", 6654 SortId = 50, 6655 Template = GridViewOrderDraftScripts() 6656 }); 6657 } 6658 6659 var customGridViewItemPrice = gridViewPageCustom.GetBlockById("GridViewItemPrice"); 6660 if (customGridViewItemPrice != null) 6661 { 6662 customGridViewItemPrice.SortId = 26; 6663 customGridViewItemPrice.Design = new Design 6664 { 6665 CssClass = "u-padding" 6666 }; 6667 } 6668 6669 var customGridViewItemFooter = gridViewPageCustom.GetBlockById("GridViewItemFooter"); 6670 if (customGridViewItemFooter != null) 6671 { 6672 customGridViewItemFooter.Template = RenderGridViewItemFooterCustom(); 6673 } 6674 } 6675 6676 @helper GridViewCustom() 6677 { 6678 int columnsCount = gridViewSettings.GetList("Columns") != null ? Converter.ToInt32(gridViewSettings.GetList("Columns").SelectedValue) : 3; 6679 string imageZoomOnHover = gridViewSettings.GetBoolean("HoverImageZoom") ? "image-hover--zoom" : ""; 6680 //START CUSTOM CODE: Add js-product class for onclick 6681 <script id="ProductGridItemContainer" type="text/x-template"> 6682 {{#.}} 6683 <div id="Product{{id}}" data-template="GridViewItem" data-preloader="overlay" class="grid__col-lg-@(12 / columnsCount) grid__col-md-@(12 / columnsCount) grid__col-sm-@(12 / columnsCount) grid__col-xs-6 js-product product-list__grid-item @imageZoomOnHover dw-mod"> 6684 {{#Product}} 6685 {{>GridViewItem}} 6686 {{/Product}} 6687 </div> 6688 {{/.}} 6689 </script> 6690 //END CUSTOM CODE 6691 } 6692 6693 @helper RenderGridViewAddToCartCustom() 6694 { 6695 @* START CUSTOM CODE *@ 6696 var displayDraftButton = !isB2BGridView && Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")) && Dynamicweb.Rapido.Services.User.IsBuyingAllowed() && Dna.WilsonDaniels.Helpers.GetNewCartDrafts().Any() && GetPageIdByNavigationTag("OrderDraft") != 0; 6697 @* END CUSTOM CODE *@ 6698 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 6699 string wrapperClass = "buttons-collection--center"; 6700 int columnsCount = gridViewSettings.GetList("Columns") != null ? Converter.ToInt32(gridViewSettings.GetList("Columns").SelectedValue) : 4; 6701 bool hideButtonText = columnsCount >= 4 || Pageview.Device.ToString() == "Mobile" || Pageview.Device.ToString() == "Tablet"; 6702 6703 if (pointShopOnly && columnsCount <= 4) 6704 { 6705 hideButtonText = false; 6706 } 6707 6708 var addToCartBtn = new AddToCart 6709 { 6710 WrapperCssClass = wrapperClass, 6711 AddButton = new AddToCartButton 6712 { 6713 /*START CUSTOM CODE*/ 6714 Title = isB2BGridView ? Translate("Add to cart") : Translate("Add to New Quote"), 6715 /*END CUSTOM CODE*/ 6716 HideTitle = hideButtonText, 6717 ProductId = "{{productId}}", 6718 VariantId = "{{variantid}}", 6719 UnitId = "{{unitId}}", 6720 ProductInfo = "{{productInfo}}", 6721 BuyForPoints = pointShopOnly, 6722 OnClick = "{{facebookPixelAction}}", 6723 ExtraAttributes = new Dictionary<string, string> 6724 { 6725 { "{{disabledBuyButton}}", "" }, 6726 { "{{outOfStock}}", "" } 6727 } 6728 } 6729 }; 6730 6731 if (!pointShopOnly) 6732 { 6733 /*START CUSTOM CODE*/ 6734 addToCartBtn.QuantitySelector = new QuantitySelector 6735 { 6736 Id = "Quantity{{id}}", 6737 Min = "{{minQuantity}}", 6738 Value = "{{minQuantity}}", 6739 CssClass = "u-hidden", 6740 ExtraAttributes = new Dictionary<string, string> 6741 { 6742 { "{{outOfStock}}", "" }, 6743 { "max", "{{maxQuantity}}" } 6744 } 6745 }; 6746 /*END CUSTOM CODE*/ 6747 } 6748 6749 <script id="GridViewAddToCartContainer" type="text/x-template"> 6750 @* START CUSTOM CODE *@ 6751 @if (isB2BGridView) 6752 { 6753 @Render(addToCartBtn) 6754 } 6755 else 6756 { 6757 var link = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(GetPageIdByNavigationTag("OrderDraft")); 6758 <text> 6759 {{#if hasStock}} 6760 <p>@Translate("This current product is already on an")<a class="u-brand-color-two" href="@link"> @Translate("open order request")</a></p> 6761 {{else}} 6762 @Render(addToCartBtn.UnitSelector) 6763 @Render(addToCartBtn.QuantitySelector) 6764 @if (displayDraftButton) 6765 { 6766 @Render(new Button 6767 { 6768 Title = Translate("Add to existing Order Request"), 6769 ButtonLayout = ButtonLayout.Secondary, 6770 ExtraAttributes = {{"data-product", "{{productId}}"}, {"data-unit", "{{unitId}}"}, {"data-quantityinput", "Quantity{{id}}"}}, 6771 OnClick = "openOrderDraftModal(this)" 6772 }) 6773 } 6774 else 6775 { 6776 @Render(new Button 6777 { 6778 Title = Translate("Add to new Order Request"), 6779 ButtonLayout = ButtonLayout.Primary, 6780 ExtraAttributes = {{"data-product", "{{productId}}"}, {"data-unit", "{{unitId}}"}, {"data-quantityinput", "Quantity{{id}}"}}, 6781 OnClick = "openNewOrderDraftModal(this)" 6782 }) 6783 } 6784 {{/if}} 6785 </text> 6786 } 6787 @* END CUSTOM CODE *@ 6788 </script> 6789 } 6790 6791 @helper RenderGridViewUnitSelector() 6792 { 6793 //START CUSTOM CODE: Add unit selector 6794 var separatedUnitSelector = getUnitsSelector(); 6795 separatedUnitSelector.CssClass += " product-list__details-units-selector--separated"; 6796 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 6797 6798 <script id="GridViewUnitSelectorContainer" type="text/x-template"> 6799 @Render(separatedUnitSelector) 6800 6801 @*START CUSTOM CODE - Moving qty selector to unit selector block*@ 6802 @if (!pointShopOnly) 6803 { 6804 var quantitySelector = new QuantitySelector 6805 { 6806 Id = "Quantity{{id}}", 6807 Min = "{{minQuantity}}", 6808 Value = "{{minQuantity}}", 6809 CssClass = "view__selector-custom", 6810 ExtraAttributes = new Dictionary<string, string> 6811 { 6812 { "{{outOfStock}}", "" }, 6813 { "max", "{{maxQuantity}}" } 6814 } 6815 }; 6816 @Render(quantitySelector) 6817 } 6818 6819 </script> 6820 //END CUSTOM CODE 6821 } 6822 6823 @helper RenderGridViewItemUnitSelectorCustom() 6824 { 6825 //START CUSTOM CODE: Add unit selector 6826 <text> 6827 {{#unless hideStockDisallowOrdering}} 6828 {{#if isLiveProductInfoActive}} 6829 <div class="js-handlebars-root js-live-info-container" 6830 data-template="GridViewUnitSelectorContainer" 6831 data-preloader="none" 6832 data-product-id="{{productId}}"> 6833 </div> 6834 {{else}} 6835 {{>GridViewUnitSelectorContainer}} 6836 {{/if}} 6837 {{/unless}} 6838 </text> 6839 //END CUSTOM CODE 6840 } 6841 6842 @helper RenderGridViewItemActionsCustom() 6843 { 6844 bool showCartButton = gridViewSettings.GetBoolean("ShowAddToCartButton"); 6845 bool showViewButton = gridViewSettings.GetBoolean("ShowViewButton"); 6846 @*START CUSTOM CODE: Prevent ordering*@ 6847 if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed() && !Dna.WilsonDaniels.Helpers.IsLoginPreventOrdering()) 6848 //END CUSTOM CODE 6849 { 6850 if (showCartButton) 6851 { 6852 if (!showViewButton) 6853 { 6854 <text>{{#if hideAddToCartButton}}</text> 6855 <div>@RenderGridViewItemViewButton()</div> 6856 <text>{{else}}</text> 6857 @RenderGridViewItemAddToCart() 6858 <text>{{/if}}</text> 6859 } 6860 else 6861 { 6862 @RenderGridViewItemViewButton() 6863 } 6864 } 6865 else if (showViewButton) 6866 { 6867 <div>@RenderGridViewItemViewButton()</div> 6868 } 6869 } 6870 else if (showViewButton) 6871 { 6872 <div>@RenderGridViewItemViewButton()</div> 6873 } 6874 } 6875 6876 @helper RenderGridViewItemQuantityPerUnit() 6877 { 6878 <text> 6879 {{#if quantityPerUnit}} 6880 @*START CUSTOM CODE - conditional on B2B*@ 6881 {{#if isB2B}} 6882 <div class="u-bold dw-mod">{{quantityPerUnit}}/{{bottleSize}}</div> 6883 {{else}} 6884 <div class="u-bold dw-mod">{{bottleSize}}</div> 6885 {{/if}} 6886 @*END CUSTOM CODE*@ 6887 {{/if}} 6888 </text> 6889 } 6890 6891 @helper RenderGridViewItemPriceTable() 6892 { 6893 <text> 6894 {{#unless hidePriceDisallowOrdering}} 6895 {{#if isLiveProductInfoActive}} 6896 <div class="js-handlebars-root js-live-info-container" 6897 data-template="GridViewPriceTableContainer" 6898 data-preloader="none" 6899 data-product-id="{{productId}}"> 6900 </div> 6901 {{else}} 6902 {{>GridViewPriceTableContainer}} 6903 {{/if}} 6904 {{/unless}} 6905 </text> 6906 } 6907 6908 @helper RenderGridViewPriceTable() 6909 { 6910 var colorStyle = "color:{{cssClass}} !important"; 6911 <script id="GridViewPriceTableContainer" type="text/x-template"> 6912 {{#if ProductPrices}} 6913 @*START CUSTOM CODE: Decrease table size*@ 6914 <table class="table table--no-top-border u-margin-top--lg u-font-size--xs dw-mod"> 6915 @*END CUSTOM CODE*@ 6916 <thead> 6917 <tr> 6918 <th></th> 6919 <th class="u-ta-center">@Translate("Case price")</th> @*CUSTOM CODE - Helper Added*@ 6920 <th class="u-ta-center">@Translate("Bottle price")</th> @*CUSTOM CODE - Helper Added*@ 6921 </tr> 6922 </thead> 6923 <tbody> 6924 {{#ProductPrices}} 6925 <tr style="@colorStyle"> 6926 <th class="u-ta-center">{{description}}</th> @*CUSTOM CODE - Helper Added*@ 6927 <td class="u-ta-center">{{price}}</td> @*CUSTOM CODE - Helper Added*@ 6928 <td class="u-ta-center">{{bottlePrice}}</td> @*CUSTOM CODE - Helper Added*@ 6929 </tr> 6930 {{/ProductPrices}} 6931 </tbody> 6932 </table> 6933 {{/if}} 6934 </script> 6935 } 6936 6937 @helper GridViewOrderDraftScripts() 6938 { 6939 <script> 6940 function openOrderDraftModal(el) 6941 { 6942 var cartSelector = document.getElementById('CartSelector'); 6943 document.getElementById('OrderDraftSelectModalTrigger').checked = true; 6944 cartSelector.setAttribute("data-product", el.getAttribute("data-product")); 6945 cartSelector.setAttribute("data-unit", el.getAttribute("data-unit")); 6946 cartSelector.setAttribute("data-quantity", document.getElementById(el.getAttribute("data-quantityinput")).value); 6947 } 6948 6949 function openNewOrderDraftModal(el) 6950 { 6951 var form = document.getElementById('NewDraftForm'); 6952 document.getElementById('NewDraftModalTrigger').checked = true; 6953 form.setAttribute("data-product", el.getAttribute("data-product")); 6954 form.setAttribute("data-unit", el.getAttribute("data-unit")); 6955 form.setAttribute("data-quantity", document.getElementById(el.getAttribute("data-quantityinput")).value); 6956 } 6957 </script> 6958 } 6959 6960 @helper RenderGridViewItemFooterCustom() 6961 { 6962 List<Block> subBlocks = gridViewPage.GetBlockListById("GridViewItemFooter"); 6963 bool showStaticVariants = gridViewSettings.GetBoolean("ShowStaticVariants"); 6964 string footerClasses = showStaticVariants ? "u-min-h120px" : ""; 6965 6966 <div class="product-list__grid-item__footer @footerClasses u-no-padding-y u-padding-bottom dw-mod"> @*CUSTOM CODE - Adding helper classes*@ 6967 @RenderBlockList(subBlocks) 6968 </div> 6969 } 6970 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 6971 @using Dynamicweb.Rapido.Blocks 6972 @using Dynamicweb.Rapido.Blocks.Components.General 6973 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 6974 6975 @functions { 6976 BlocksPage listViewPageCustom = BlocksPage.GetBlockPage("ProductList"); 6977 bool isB2BListView; 6978 } 6979 6980 @if (Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableListView")) 6981 { 6982 isB2BListView = Pageview.AreaSettings.GetItem("Custom").GetBoolean("IsB2B"); 6983 6984 var favoritesBlock = listViewPageCustom.GetBlockById("ListViewItemFavorites"); 6985 if (favoritesBlock != null) 6986 { 6987 listViewPageCustom.RemoveBlock(favoritesBlock); 6988 listViewPageCustom.Add("ListViewItemInfoContainer", new Block 6989 { 6990 Id = "ListViewItemFavorites", 6991 SortId = 15, 6992 Template = RenderListViewItemFavoritesCustom() 6993 }); 6994 } 6995 6996 var listViewItemInfoContainerBlock = listViewPageCustom.GetBlockById("ListViewItemInfoContainerLeft"); 6997 if (listViewItemInfoContainerBlock != null) 6998 { 6999 listViewItemInfoContainerBlock.Add( 7000 new Block 7001 { 7002 Id = "ListViewItemQuantityPerUnit", 7003 SortId = 20, 7004 Template = RenderListViewItemQuantityPerUnit() 7005 } 7006 ); 7007 } 7008 7009 listViewPageCustom.RemoveBlockById("ListViewItemFooter"); 7010 var listViewItemInfoContainerRightBlock = listViewPageCustom.GetBlockById("ListViewItemInfoContainerRight"); 7011 if (listViewItemInfoContainerRightBlock != null) 7012 { 7013 //START CUSTOM CODE: Align table left and set blocks to row 7014 listViewItemInfoContainerRightBlock.Design = new Design 7015 { 7016 CssClass = "u-clear u-flex u-flex--row grid--justify-space-between" 7017 }; 7018 //END CUSTOM CODE 7019 listViewItemInfoContainerRightBlock.Add( 7020 new Block 7021 { 7022 Id = "ListViewQuantityPrices", 7023 SortId = 30, 7024 Template = RenderListViewItemPriceTable() 7025 } 7026 ); 7027 //START CUSTOM CODE - Moving unit, qty, price and button 7028 listViewItemInfoContainerRightBlock.Add( 7029 new Block 7030 { 7031 Id = "ListViewItemFooter", 7032 SortId = 50, 7033 SkipRenderBlocksList = true, 7034 Template = RenderListViewItemFooterCustom(), 7035 BlocksList = new List<Block> 7036 { 7037 new Block 7038 { 7039 Id = "ListViewItemPrice", 7040 SortId = 10, 7041 Template = RenderListViewItemPrice() 7042 }, 7043 new Block 7044 { 7045 Id = "ListViewItemActions", 7046 SortId = 20, 7047 Template = RenderListViewItemActionsCustom() 7048 } 7049 } 7050 } 7051 ); //END CUSTOM CODE 7052 } 7053 7054 var listViewAddToCartBlock = listViewPageCustom.GetBlockById("ListViewAddToCart"); 7055 7056 if (listViewAddToCartBlock != null) 7057 { 7058 listViewAddToCartBlock.Template = RenderListViewAddToCartCustom(); 7059 } 7060 7061 listViewPageCustom.GetBlockById("ListViewScripts")?.Add(new Block 7062 { 7063 Id = "ListViewPriceTable", 7064 SortId = 40, 7065 Template = RenderListViewPriceTable() 7066 }); 7067 7068 if (!isB2BListView) 7069 { 7070 listViewPageCustom.GetBlockById("ListViewScripts")?.Add(new Block 7071 { 7072 Id = "ListViewOrderDraftScripts", 7073 SortId = 50, 7074 Template = ListViewOrderDraftScripts() 7075 }); 7076 } 7077 7078 } 7079 7080 @helper RenderListViewAddToCartCustom() 7081 { 7082 @* START CUSTOM CODE *@ 7083 var displayDraftButton = !isB2BListView && Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName")) && Dynamicweb.Rapido.Services.User.IsBuyingAllowed() && Dna.WilsonDaniels.Helpers.GetNewCartDrafts().Any() && GetPageIdByNavigationTag("OrderDraft") != 0; 7084 @* END CUSTOM CODE *@ 7085 7086 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 7087 7088 var addToCartBtn = new AddToCart 7089 { 7090 WrapperCssClass = "buttons-collection--right", 7091 AddButton = new AddToCartButton 7092 { 7093 /*START CUSTOM CODE*/ 7094 Title = isB2BListView ? Translate("Add to cart") : Translate("Add to New Quote"), 7095 /*END CUSTOM CODE*/ 7096 HideTitle = false, 7097 ProductId = "{{productId}}", 7098 VariantId = "{{variantid}}", 7099 UnitId = "{{unitId}}", 7100 ProductInfo = "{{productInfo}}", 7101 BuyForPoints = pointShopOnly, 7102 OnClick = "{{facebookPixelAction}}", 7103 ExtraAttributes = new Dictionary<string, string> 7104 { 7105 { "{{disabledBuyButton}}", "" }, 7106 { "{{outOfStock}}", "" } 7107 } 7108 } 7109 }; 7110 if (!pointShopOnly) 7111 { 7112 addToCartBtn.QuantitySelector = new QuantitySelector 7113 { 7114 Id = "Quantity{{id}}", 7115 CssClass = "u-hidden", //CUSTOM CODE - keeping original qty selector in place but hidden, allows addtocart functionality with separate qty selector 7116 ExtraAttributes = new Dictionary<string, string> 7117 { 7118 { "{{outOfStock}}", "" } 7119 } 7120 }; 7121 } 7122 var listViewUnitSelector = new UnitSelector 7123 { 7124 OptionsContent = "{{#unitOptions}}{{>UnitOption}}{{/unitOptions}}", 7125 Id = "UnitOptions_{{id}}", 7126 SelectedOption = "{{unitName}}", 7127 CssClass = "{{#if hasOnlyOneUnit}}unit-selector--readonly{{/if}} {{hasUnits}}" 7128 }; 7129 7130 <script id="ListViewAddToCartContainer" type="text/x-template"> 7131 @* START CUSTOM CODE *@ 7132 <div class="u-flex u-flex--column"> 7133 <div class="u-flex u-flex--row"> 7134 @Render(listViewUnitSelector) 7135 @if (!pointShopOnly) 7136 { 7137 var listViewQuantitySelector = new QuantitySelector 7138 { 7139 Id = "Quantity{{id}}", 7140 Min = "{{minQuantity}}", 7141 Value = "{{minQuantity}}", 7142 CssClass = "view__selector-custom u-margin-left", 7143 ExtraAttributes = new Dictionary<string, string> 7144 { 7145 {"{{outOfStock}}", ""}, 7146 {"max", "{{maxQuantity}}"} 7147 } 7148 }; 7149 @Render(listViewQuantitySelector) 7150 } 7151 </div> 7152 <div> 7153 @Render(addToCartBtn) 7154 </div> 7155 </div> 7156 @* END CUSTOM CODE *@ 7157 </script> 7158 } 7159 7160 @helper ListViewOrderDraftScripts() 7161 { 7162 <script> 7163 function openOrderDraftModal(el) 7164 { 7165 var cartSelector = document.getElementById('CartSelector'); 7166 document.getElementById('OrderDraftSelectModalTrigger').checked = true; 7167 cartSelector.setAttribute("data-product", el.getAttribute("data-product")); 7168 cartSelector.setAttribute("data-unit", el.getAttribute("data-unit")); 7169 cartSelector.setAttribute("data-quantity", document.getElementById(el.getAttribute("data-quantityinput")).value); 7170 } 7171 7172 function openNewOrderDraftModal(el) 7173 { 7174 var form = document.getElementById('NewDraftForm'); 7175 document.getElementById('NewDraftModalTrigger').checked = true; 7176 form.setAttribute("data-product", el.getAttribute("data-product")); 7177 form.setAttribute("data-unit", el.getAttribute("data-unit")); 7178 form.setAttribute("data-quantity", document.getElementById(el.getAttribute("data-quantityinput")).value); 7179 } 7180 </script> 7181 } 7182 7183 @helper RenderListViewItemActionsCustom() 7184 { 7185 bool showCartButton = listViewSettings.GetBoolean("ShowAddToCartButton"); 7186 bool showViewButton = listViewSettings.GetBoolean("ShowViewButton"); 7187 bool hasVariantSelector = listViewSettings.GetList("Variants") != null && listViewSettings.GetList("Variants").SelectedValue == "selector"; 7188 7189 if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed() && !Dna.WilsonDaniels.Helpers.IsLoginPreventOrdering()) //CUSTOM CODE 7190 { 7191 if (showCartButton) 7192 { 7193 if (!showViewButton || hasVariantSelector) 7194 { 7195 <text>{{#if hideAddToCartButton}}</text> 7196 <div>@RenderListViewItemViewButton()</div> 7197 <text>{{else}}</text> 7198 @RenderListViewItemAddToCart() 7199 <text>{{/if}}</text> 7200 } 7201 else 7202 { 7203 <div>@RenderListViewItemViewButton()</div> 7204 } 7205 } 7206 else if (showViewButton) 7207 { 7208 <div>@RenderListViewItemViewButton()</div> 7209 } 7210 } 7211 else if (showViewButton) 7212 { 7213 <div>@RenderListViewItemViewButton()</div> 7214 } 7215 } 7216 7217 @helper RenderListViewItemQuantityPerUnit() 7218 { 7219 <text> 7220 {{#if quantityPerUnit}} 7221 @*START CUSTOM CODE - conditional on B2B*@ 7222 {{#if isB2B}} 7223 <div class="dw-mod">{{quantityPerUnit}}/{{bottleSize}}</div> 7224 {{else}} 7225 <div class="dw-mod">{{bottleSize}}</div> 7226 {{/if}} 7227 @*END CUSTOM CODE*@ 7228 {{/if}} 7229 </text> 7230 } 7231 7232 @helper RenderListViewItemPriceTable() 7233 { 7234 <text> 7235 {{#unless hidePriceDisallowOrdering}} 7236 {{#if isLiveProductInfoActive}} 7237 <div class="js-handlebars-root js-live-info-container" 7238 data-template="ListViewPriceTableContainer" 7239 data-preloader="minimal" 7240 data-product-id="{{productId}}"> 7241 </div> 7242 {{else}} 7243 {{>ListViewPriceTableContainer}} 7244 {{/if}} 7245 {{/unless}} 7246 </text> 7247 } 7248 7249 @helper RenderListViewPriceTable() 7250 { 7251 var colorStyle = "color:{{cssClass}} !important"; 7252 <script id="ListViewPriceTableContainer" type="text/x-template"> 7253 {{#if ProductPrices}} 7254 <table class="table table--no-top-border u-margin-top--lg dw-mod"> 7255 <thead> 7256 <tr> 7257 <th></th> 7258 <th class="u-ta-center">@Translate("Case price")</th> @*CUSTOM CODE - Helper Added*@ 7259 <th class="u-ta-center">@Translate("Bottle price")</th> @*CUSTOM CODE - Helper Added*@ 7260 </tr> 7261 </thead> 7262 <tbody> 7263 {{#ProductPrices}} 7264 <tr style="@colorStyle"> 7265 <th class="u-ta-center grid--justify-center">{{description}}</th> @*CUSTOM CODE - Helper Added*@ 7266 <td class="u-ta-center grid--justify-center">{{price}}</td> @*CUSTOM CODE - Helper Added*@ 7267 <td class="u-ta-center grid--justify-center">{{bottlePrice}}</td> @*CUSTOM CODE - Helper Added*@ 7268 </tr> 7269 {{/ProductPrices}} 7270 </tbody> 7271 </table> 7272 {{/if}} 7273 </script> 7274 } 7275 7276 @helper RenderListViewItemFavoritesCustom() 7277 { 7278 <div class="favorites u-pull--right {{hasVariants}} dw-mod" {{hasVariants}}> 7279 {{#Favorite}} 7280 {{>FavoriteTemplate}} 7281 {{/Favorite}} 7282 </div> 7283 } 7284 7285 @helper RenderListViewItemFooterCustom() 7286 { 7287 List<Block> subBlocks = listViewPage.GetBlockListById("ListViewItemFooter"); 7288 7289 if (Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 7290 { 7291 <div class="grid__cell-footer u-width--auto u-margin-bottom--auto"> @*CUSTOM CODE - using helpers*@ 7292 <div class="grid__cell"> 7293 <div class="product-list__list-item__price-actions dw-mod"> 7294 @RenderBlockList(subBlocks) 7295 </div> 7296 </div> 7297 </div> 7298 } 7299 else 7300 { 7301 <button type="button" id="CartButton_{{id}}" class="u-hidden"></button> 7302 } 7303 } 7304 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 7305 @using System.Collections.Generic 7306 @using Dynamicweb.Rapido.Blocks 7307 @using Dynamicweb.Rapido.Blocks.Components.General 7308 7309 @{ 7310 var productListFacetsBlocksPageCustom = BlocksPage.GetBlockPage("ProductList"); 7311 7312 if (facetsBlockViewMode == "left" && Pageview.Device.ToString() != "Mobile" && Pageview.Device.ToString() != "Tablet") 7313 { 7314 var facetsBlock = productListFacetsBlocksPageCustom.GetBlockById("Facets"); 7315 if (facetsBlock != null) 7316 { 7317 facetsBlock.Template = RenderProductListFacetsCustom(); 7318 } 7319 } 7320 7321 if (facetsBlockViewMode == "top" || Pageview.Device.ToString() == "Mobile" || Pageview.Device.ToString() == "Tablet") 7322 { 7323 var facetsBlock = productListFacetsBlocksPageCustom.GetBlockById("Facets"); 7324 if (facetsBlock != null) 7325 { 7326 facetsBlock.Template = RenderProductListTopFacetsCustom(); 7327 } 7328 } 7329 7330 var sliderFacetTemplate = new Block 7331 { 7332 Id = "SliderFacet", 7333 SortId = 30, 7334 Template = RenderSliderFacets() 7335 }; 7336 productListFacetsBlocksPageCustom.Add("BottomSnippets", sliderFacetTemplate); 7337 7338 var selectedScoreFilter = new Block 7339 { 7340 Id = "SelectedScoreFilter", 7341 SortId = 70, 7342 Template = RenderSelectedScoreFilter() 7343 }; 7344 productListFacetsBlocksPageCustom.Add("BottomSnippets", selectedScoreFilter); 7345 } 7346 7347 @helper RenderProductListFacetsCustom() { 7348 var facetSettings = Pageview.AreaSettings.GetItem("ProductList").GetItem("Facets"); 7349 string boxDisplay = facetSettings.GetList("BoxDisplay") != null ? facetSettings.GetList("BoxDisplay").SelectedValue : "scroll"; 7350 7351 string facetMoreClass = ( boxDisplay == "view-more" ? "facets-container__list--more" : ""); 7352 7353 @*This is part of a script template *@ 7354 7355 <input type="checkbox" id="CheckFacetGroups" class="js-remember-state u-hidden" data-expand="CheckFacetGroups" /> 7356 <div class="facets-container facets-container--left expandable--collapsed dw-mod" data-trigger="CheckFacetGroups"> 7357 {{#FacetGroups}} 7358 <input type="checkbox" id="OptionsGroup_{{name}}" class="expand-trigger js-remember-state" {{defaultState}} /> 7359 7360 <div class="expand-container facets-container__box dw-mod js-filter"> 7361 <label class="expand-container__btn facets-container__header dw-mod" for="OptionsGroup_{{name}}">{{name}}</label> 7362 <div class="expand-container__content js-facet-container dw-mod" data-input="OptionsGroup_{{name}}"> 7363 <div id="facetList{{name}}" class="facets-container__list @facetMoreClass dw-mod facet-{{queryParameter}}"> 7364 @*START CUSTOM CODE*@ 7365 {{#ifCond queryParameter "===" "Score"}} 7366 {{>Slider}} 7367 {{/ifCond}} 7368 {{#ifCond queryParameter "!==" "Score"}} 7369 <div class="facets-container__search {{showFilter}} dw-mod"> 7370 <input type="text" class="u-full-width u-no-margin" onkeyup="Filter.FilterItems(event)" placeholder="@Translate("Search")" /> 7371 </div> 7372 @*END CUSTOM CODE*@ 7373 {{#FacetOptions}} 7374 {{#ifCond template "===" "Checkboxes"}} 7375 {{>Checkboxes}} 7376 {{/ifCond}} 7377 {{#ifCond template "===" "Range"}} 7378 {{>Checkboxes}} 7379 {{/ifCond}} 7380 {{#ifCond template "===" "Weight"}} 7381 {{>Checkboxes}} 7382 {{/ifCond}} 7383 {{#ifCond template "===" "Tags"}} 7384 {{>Tags}} 7385 {{/ifCond}} 7386 {{#ifCond template "===" "Colors"}} 7387 {{>Colors}} 7388 {{/ifCond}} 7389 {{/FacetOptions}} 7390 @*START CUSTOM CODE*@ 7391 {{/ifCond}} 7392 @*END CUSTOM CODE*@ 7393 <div class="u-hidden js-filter-not-found"> 7394 @Translate("Your search gave 0 results") 7395 </div> 7396 </div> 7397 7398 @if ( boxDisplay == "view-more" ) { 7399 <div class="facets-container__more js-facet-expand"> 7400 @Render(new Button { 7401 Title = "<span class=js-facet-trigger-text>" + Translate("View more") + "</span>", 7402 ButtonType = ButtonType.Button, 7403 ButtonLayout = ButtonLayout.Clean, 7404 CssClass = "facets-container__more-button js-facet-trigger u-flex u-no-margin u-full-width", 7405 OnClick = "Facets.ExpandToggle(this)", 7406 ExtraAttributes = new Dictionary<string, string>{ 7407 {"data-target", "facetList{{name}}"}, 7408 {"data-toggle-text", Translate("Show less")}, 7409 }, 7410 Icon = new Icon { 7411 Prefix = "fal", 7412 Name = "fa-angle-down", 7413 } 7414 }) 7415 </div> 7416 } 7417 </div> 7418 </div> 7419 {{/FacetGroups}} 7420 </div> 7421 <label for="CheckFacetGroups" class="btn btn--primary btn--full u-no-margin dw-mod js-expand-hide facets-container-trigger" data-trigger="CheckFacetGroups">@Translate("Select filters")</label> 7422 <label for="CheckFacetGroups" class="btn btn--primary btn--full u-no-margin dw-mod expandable--collapsed facets-container-trigger" data-trigger="CheckFacetGroups">@Translate("Close filters")</label> 7423 } 7424 7425 @helper RenderProductListTopFacetsCustom() 7426 { 7427 @*This is part of a script template *@ 7428 <input type="checkbox" id="CheckFacetGroups" class="js-remember-state u-hidden" data-expand="CheckFacetGroups" /> 7429 <div class="grid grid--external-bleed dw-mod expandable--collapsed facets-container facets-container--top u-margin-bottom" data-trigger="CheckFacetGroups"> 7430 {{#FacetGroups}} 7431 <div class="grid__col-lg-3 grid__col-md-3 grid__col-sm-4 grid__col-xs-12"> 7432 <input type="checkbox" id="OptionsGroup_{{counter}}" class="dropdown-trigger" /> 7433 <div class="dropdown dw-mod js-filter"> 7434 <label class="dropdown__header dropdown__btn dw-mod" for="OptionsGroup_{{counter}}">{{name}}</label> 7435 <div class="dropdown__content dropdown__content--padding dw-mod facet-{{queryParameter}}"> 7436 @*START CUSTOM CODE*@ 7437 {{#ifCond queryParameter "===" "Score"}} 7438 {{>Slider}} 7439 {{/ifCond}} 7440 {{#ifCond queryParameter "!==" "Score"}} 7441 <div class="u-margin-bottom {{showFilter}}"> 7442 <input type="text" class="u-full-width u-no-margin" onkeyup="Filter.FilterItems(event)" placeholder="@Translate("Search")" /> 7443 </div> 7444 @*END CUSTOM CODE*@ 7445 {{#FacetOptions}} 7446 {{#ifCond template "===" "Checkboxes"}} 7447 {{>Checkboxes}} 7448 {{/ifCond}} 7449 {{#ifCond template "===" "Range"}} 7450 {{>Checkboxes}} 7451 {{/ifCond}} 7452 {{#ifCond template "===" "Weight"}} 7453 {{>Checkboxes}} 7454 {{/ifCond}} 7455 {{#ifCond template "===" "Tags"}} 7456 {{>Tags}} 7457 {{/ifCond}} 7458 {{#ifCond template "===" "Colors"}} 7459 {{>Colors}} 7460 {{/ifCond}} 7461 {{/FacetOptions}} 7462 @*START CUSTOM CODE*@ 7463 {{/ifCond}} 7464 @*END CUSTOM CODE*@ 7465 <div class="u-hidden js-filter-not-found"> 7466 @Translate("Your search gave 0 results") 7467 </div> 7468 </div> 7469 <label class="dropdown-trigger-off" for="OptionsGroup_{{counter}}"></label> 7470 </div> 7471 </div> 7472 {{/FacetGroups}} 7473 </div> 7474 <label for="CheckFacetGroups" class="btn btn--primary btn--full u-margin-bottom--lg dw-mod js-expand-hide facets-container-trigger" data-trigger="CheckFacetGroups">@Translate("Select filters")</label> 7475 <label for="CheckFacetGroups" class="btn btn--primary btn--full u-margin-bottom--lg dw-mod expandable--collapsed facets-container-trigger" data-trigger="CheckFacetGroups">@Translate("Close filters")</label> 7476 } 7477 7478 @helper RenderSliderFacets() 7479 { 7480 <script id="Slider" type="text/x-template"> 7481 <div class="form__field-group u-no-margin dw-mod"> 7482 <div id="ScoreSlider" name="{{queryParameter}}" data-namemin="WineScoreMin" data-namemax="WineScoreMax" data-min-value="{{minValue}}"></div> 7483 </div> 7484 </script> 7485 } 7486 7487 @helper RenderSelectedScoreFilter() 7488 { 7489 <script id="SelectedScoreFilter" type="text/x-template"> 7490 <button type="button" class="btn btn--tag dw-mod" data-check="checked" onclick="ScoreSlider.ResetSlider();" name="{{queryParameter}}" value="[{{value}}]" title="@Translate("Remove filter")"> 7491 {{group}}: {{label}} &nbsp;<i class="fal fa-times"></i> 7492 </button> 7493 </script> 7494 } 7495 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 7496 @using Dynamicweb.Rapido.Blocks 7497 7498 @{ 7499 var productListProductsBlocksPageCustom = BlocksPage.GetBlockPage("ProductList"); 7500 var viewsBlock = productListProductsBlocksPageCustom.GetBlockById("Views"); 7501 7502 if (viewsBlock != null) 7503 { 7504 viewsBlock.Template = RenderProductsCustom(); 7505 } 7506 } 7507 7508 @helper RenderProductsCustom() 7509 { 7510 @*This is part of a script template *@ 7511 7512 <div id="ProductsContainer" data-template="{{listTemplate}}" class="grid product-list grid--external-bleed-x dw-mod grid--align-content-start" data-save-cookie="true"> 7513 @*START CUSTOM CODE*@ 7514 {{#if ProductsContainer}} 7515 {{#ProductsContainer}} 7516 {{> (lookup . 'template') }} 7517 {{/ProductsContainer}} 7518 {{else}} 7519 <div class="grid__col-12"> 7520 <h2 class="u-ta-center">@Translate("Your search gave 0 results")</h2> 7521 </div> 7522 {{/if}} 7523 @*END CUSTOM CODE*@ 7524 </div> 7525 } 7526 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 7527 @using Dynamicweb.Core 7528 @using Dynamicweb.Environment 7529 @using Dynamicweb.Rapido.Blocks; 7530 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce; 7531 @using Dynamicweb.Rapido.Blocks.Components.General; 7532 @if(!Pageview.AreaSettings.GetItem("Custom").GetBoolean("IsB2B")) 7533 { 7534 var blocksPage = BlocksPage.GetBlockPage("ProductList"); 7535 var newDraftModal = new Modal 7536 { 7537 Id = "NewDraft", 7538 Heading = new Heading { Title = Translate("New draft") }, 7539 Width = Pageview.User.GetUsersICanSetAsSecondary().Count == 0 ? ModalWidth.Md : ModalWidth.Lg, 7540 BodyTemplate = RenderNewModalBodyCustom() 7541 }; 7542 7543 newDraftModal.AddActions( 7544 new Button 7545 { 7546 ButtonLayout = ButtonLayout.Secondary, 7547 Title = Translate("Cancel"), 7548 OnClick = "document.getElementById('NewDraftModalTrigger').checked = false;" 7549 }, 7550 new Button 7551 { 7552 Id = "NewDraftFormSubmit",// CUSTOM CODE 7553 ButtonLayout = ButtonLayout.Primary, 7554 Title = Translate("OK"), 7555 OnClick = "Request.AjaxFormSubmit(event, document.getElementById('NewDraftForm'), addToNewCart)" // CUSTOM CODE 7556 } 7557 ); 7558 blocksPage.Add(new Block 7559 { 7560 Id = "NewModalForm", 7561 SortId = 50, 7562 Component = newDraftModal 7563 }); 7564 7565 var selectDraftModal = new Modal 7566 { 7567 Id = "OrderDraftSelect", 7568 Heading = new Heading { Title = Translate("Select Order Request"), Level = 2 }, 7569 BodyTemplate = RenderOrderDraftSelectModalContentCustom(), 7570 Width = ModalWidth.Md 7571 }; 7572 selectDraftModal.AddAction(new Button { Title = Translate("Cancel"), OnClick = "document.getElementById('OrderDraftSelectModalTrigger').checked = false", ButtonLayout = ButtonLayout.Secondary }); 7573 selectDraftModal.AddAction(new Button { Title = Translate("Add"), OnClick = "addToSelectedCart()" }); 7574 7575 blocksPage.Add(new Block 7576 { 7577 Id = "OrderDraft", 7578 SortId = 60, 7579 Component = selectDraftModal 7580 }); 7581 7582 var notificationDraftModal = new Modal 7583 { 7584 Id = "OrderDraftNotification", 7585 Heading = new Heading { Title = Translate("Added to cart"), Level = 2 }, 7586 BodyText = Translate("The product has been added to the selected cart"), 7587 Width = ModalWidth.Md 7588 }; 7589 notificationDraftModal.AddAction(new Button { Title = Translate("View draft"), OnClick = "goToSelectedCart()", ButtonLayout = ButtonLayout.Secondary }); 7590 notificationDraftModal.AddAction(new Button { Title = Translate("Continue shopping"), OnClick = "document.getElementById('OrderDraftNotificationModalTrigger').checked = false" }); 7591 7592 blocksPage.Add(new Block 7593 { 7594 Id = "OrderDraftComplete", 7595 SortId = 70, 7596 Component = notificationDraftModal 7597 }); 7598 7599 blocksPage.Add(new Block 7600 { 7601 Id = "OrderDraftScriptsCustom", 7602 SortId = 80, 7603 Template = RenderOrderDraftScriptsCustom() 7604 }); 7605 } 7606 7607 @helper RenderNewModalBodyCustom() 7608 { 7609 //original helper from Rapido\eCom\CustomerCenter\Blocks\CartList\NewDraftModal.cshtml 7610 var secondaryUsers = Pageview.User.GetUsersICanSetAsSecondary(); 7611 7612 @* START CUSTOM CODE *@ 7613 var redirect = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(GetPageIdByNavigationTag("LatestOrderRequest")); 7614 7615 @Render(new Form()) 7616 <form method="post" id="NewDraftForm" action="/Default.aspx?ID=@Pageview.Page.ID&cartcmd=createnew&redirect=@redirect" onsubmit="document.getElementById('NewDraftFormSubmit').click(); return false;" class="js-filter"> 7617 @* END CUSTOM CODE *@ 7618 <div class="u-w380px"> 7619 @Render(new TextField 7620 { 7621 Id = "NewDraftName", 7622 Label = Translate("Draft name"), 7623 Name = "CartName", 7624 Required = true, 7625 Value = Dna.WilsonDaniels.Helpers.GetCurrentUserAssortmentName() // CUSTOM CODE 7626 }) 7627 </div> 7628 7629 @if (secondaryUsers.Count > 0) 7630 { 7631 <label>@Translate("Customer")</label> 7632 7633 if (secondaryUsers.Count > 4) 7634 { 7635 <div class="u-w380px"> 7636 @Render(new TextField { Placeholder = Translate("Type customer name or number"), OnKeyUp = "Filter.FilterItems(event)" }) 7637 </div> 7638 7639 @Render(new NotificationMessage { Message = Translate("No customers found"), MessageType = NotificationMessageType.Warning, MessageLayout = NotificationMessageLayout.Box, CssClass = "js-filter-not-found u-hidden" }) 7640 } 7641 7642 <div class="u-max-h500px u-overflow-auto"> 7643 @{ 7644 CustomerCenterList table = new CustomerCenterList { }; 7645 7646 foreach (var user in secondaryUsers) 7647 { 7648 CustomerCenterListItem userRow = new CustomerCenterListItem(); 7649 userRow.ExtraAttributes.Add("onmouseover", "mouseOverUserRow('" + user.ID + "')"); 7650 userRow.ExtraAttributes.Add("onmouseout", "mouseOutUserRow('" + user.ID + "')"); 7651 userRow.ExtraAttributes.Add("data-filter-value", user.Name + " " + user.CustomerNumber); 7652 7653 Button signInButton = new Button 7654 { 7655 Title = Translate("Select"), 7656 OnClick = "selectUser('" + user.ID + "', this)", 7657 ButtonLayout = ButtonLayout.Primary, 7658 CssClass = "u-no-margin u-hidden", 7659 Id = "SecondaryUserSelect" + user.ID 7660 }; 7661 7662 Icon userSelectedIcon = new Icon { Name = "fa-check-circle", Prefix = "fal" }; 7663 7664 userRow.AddInfoItem(new CustomerCenterListInfoItem { Title = user.Name }); 7665 userRow.AddInfoItem(new CustomerCenterListInfoItem { Title = user.CustomerNumber }); 7666 userRow.AddInfoItem(new CustomerCenterListInfoItem { Title = user.Email }); 7667 userRow.AddInfoItem(new CustomerCenterListInfoItem { Title = user.Address + ", " + user.Zip + " " + user.City + ", " + user.CountryCode }); 7668 7669 CustomerCenterListInfoItem selector = new CustomerCenterListInfoItem 7670 { 7671 Title = Render(signInButton).ToString() + " <div Id=\"SecondaryUserChecked" + user.ID + "\" class=\"u-hidden\">" + Render(userSelectedIcon).ToString() + "</div>", 7672 Align = CustomerCenterListInfoItemAlignment.Right 7673 }; 7674 selector.ExtraAttributes.Add("height", "70"); 7675 selector.ExtraAttributes.Add("width", "140"); 7676 7677 userRow.AddInfoItem(selector); 7678 7679 table.AddListItem(userRow); 7680 } 7681 } 7682 @Render(table) 7683 </div> 7684 } 7685 7686 @Render(new HiddenField 7687 { 7688 Id = "NewDraftCustomer", 7689 Name = "CartUserId", 7690 Value = Pageview.User.ID.ToString() 7691 }) 7692 </form> 7693 7694 7695 <script> 7696 function mouseOverUserRow(userId) { 7697 var selectedUserId = document.getElementById('NewDraftCustomer').value; 7698 7699 if (userId != selectedUserId) { 7700 document.getElementById("SecondaryUserSelect" + userId).classList.remove('u-hidden'); 7701 } 7702 } 7703 7704 function mouseOutUserRow(userId) { 7705 document.getElementById("SecondaryUserSelect" + userId).classList.add('u-hidden'); 7706 } 7707 7708 function selectUser(userId, clickedButton) { 7709 var allSecondaryUserCheckedIcons = document.querySelectorAll('[id^="SecondaryUserChecked"]'); 7710 7711 for (var icon of allSecondaryUserCheckedIcons) { 7712 icon.classList.add("u-hidden"); 7713 } 7714 7715 clickedButton.classList.add("u-hidden"); 7716 document.getElementById("SecondaryUserChecked" + userId).classList.remove("u-hidden"); 7717 7718 document.getElementById('NewDraftCustomer').value = userId; 7719 } 7720 7721 @* START CUSTOM CODE *@ 7722 @{ 7723 var windowLocation = Dynamicweb.Environment.Helpers.LinkHelper.StripQueryString("newCart,draftproduct,draftunit,draftquantity"); 7724 var newCartId = Dynamicweb.Context.Current.Request.GetString("newCart"); 7725 7726 if (newCartId.IsNotNullOrEmpty()) 7727 { 7728 <text> 7729 let firstLoad = true; 7730 document.getElementById("productList").addEventListener("contentLoaded", function (event) { 7731 if (firstLoad) 7732 { 7733 var cartSelector = document.getElementById("CartSelector"); 7734 if (cartSelector != null){ 7735 cartSelector.value = "@newCartId"; 7736 cartSelector.setAttribute("data-product", QueryArray.getParameterFromCurrentURL("draftproduct")); 7737 cartSelector.setAttribute("data-unit", QueryArray.getParameterFromCurrentURL("draftunit")); 7738 cartSelector.setAttribute("data-quantity", QueryArray.getParameterFromCurrentURL("draftquantity")); 7739 window.history.pushState({}, '', "@Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(windowLocation.Substring(1, windowLocation.Length - 1))"); 7740 addToSelectedCart(); 7741 } 7742 } 7743 firstLoad = false; 7744 }); 7745 </text> 7746 } 7747 } 7748 7749 function addToNewCart(data){ 7750 var form = document.getElementById('NewDraftForm'); 7751 window.location = "@windowLocation" + "&newCart=" + data.cartId + "&" + "draftproduct=" + form.getAttribute("data-product") + "&draftunit=" + form.getAttribute("data-unit") + "&draftquantity=" + form.getAttribute("data-quantity"); 7752 } 7753 7754 @* END CUSTOM CODE *@ 7755 </script> 7756 } 7757 7758 7759 @helper RenderOrderDraftSelectModalContentCustom() { 7760 @* START CUSTOM CODE *@ 7761 var cartsList = Dna.WilsonDaniels.Helpers.GetNewCartDrafts(); 7762 @* END CUSTOM CODE *@ 7763 7764 SelectField cartSelector = new SelectField 7765 { 7766 Id = "CartSelector", 7767 Label = Translate("I want to add this product to"), 7768 // START CUSTOM CODE 7769 ExtraAttributes = new Dictionary<string, string>() 7770 { 7771 {"data-variant", ""} 7772 } 7773 // END CUSTOM CODE 7774 }; 7775 7776 foreach (Dynamicweb.Ecommerce.Orders.Order cart in cartsList) { 7777 string name = !string.IsNullOrEmpty(cart.DisplayName) ? cart.DisplayName : cart.Id; 7778 cartSelector.Options.Add(new SelectFieldOption { Label = name, Value = cart.Id }); 7779 } 7780 7781 @Render(cartSelector) 7782 } 7783 7784 @helper RenderOrderDraftScriptsCustom() 7785 { 7786 var cartCmdUrl = "/Default.aspx?ID=" + Pageview.Page.ID; 7787 int orderDraftPageId = GetPageIdByNavigationTag("DraftDetails"); 7788 7789 <script> 7790 @* START CUSTOM CODE *@ 7791 function addToSelectedCart() { 7792 var cartSelector = document.getElementById("CartSelector"); 7793 var requestUrl = "@cartCmdUrl" + "&cartcmd=Add&Quantity=" + cartSelector.getAttribute("data-quantity") + "&CartId=" + cartSelector.value + "&ProductId=" + cartSelector.getAttribute("data-product") + "&VariantId=" + cartSelector.getAttribute("data-variant") + "&UnitId=" + cartSelector.getAttribute("data-unit"); 7794 7795 @* END CUSTOM CODE *@ 7796 document.getElementById('OrderDraftSelectModalTrigger').checked = false; 7797 7798 var overlayElement = document.createElement('div'); 7799 overlayElement.className = "preloader-overlay"; 7800 overlayElement.setAttribute('id', "CartOverlay"); 7801 var overlayElementIcon = document.createElement('div'); 7802 overlayElementIcon.className = "preloader-overlay__icon dw-mod"; 7803 overlayElementIcon.style.top = window.pageYOffset + "px"; 7804 overlayElement.appendChild(overlayElementIcon); 7805 document.getElementById('content').parentNode.insertBefore(overlayElement, document.getElementById('content')); 7806 7807 Request.Fetch().get( 7808 requestUrl, 7809 function () { 7810 var overlayNode = document.getElementById('CartOverlay'); 7811 overlayNode.parentNode.removeChild(overlayNode); 7812 document.getElementById('OrderDraftNotificationModalTrigger').checked = true; 7813 }, 7814 null, 7815 false 7816 ); 7817 } 7818 7819 function goToSelectedCart() { 7820 window.location = "/Default.aspx?ID=" + "@orderDraftPageId" + "&CartID=" + document.getElementById('CartSelector').value; @* CUSTOM CODE *@ 7821 } 7822 </script> 7823 } 7824 @{ 7825 BlocksPage customBlocksPage = BlocksPage.GetBlockPage("ProductList"); 7826 7827 } 7828 7829 @{ 7830 var customActionsBlock = customBlocksPage.GetBlockById("Actions"); 7831 if (customActionsBlock != null) 7832 { 7833 customActionsBlock.Template = RenderListActionsCustom(); 7834 } 7835 } 7836 7837 @helper RenderListActionsCustom() 7838 { 7839 @*This is part of a script template *@ 7840 7841 bool showSorting = Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableSorting"); 7842 string listId = HttpContext.Current.Request.QueryString.Get("ListID"); 7843 bool isFavoriteList = !string.IsNullOrEmpty(listId); 7844 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; 7845 7846 //START CUSTOM CODE - Standalone Key Message 7847 var userState = (Dynamicweb.Security.UserManagement.User.GetCurrentUser(Dynamicweb.Security.UserManagement.PagePermissionLevels.Frontend)).State; 7848 var messageStates = Pageview.AreaSettings.GetItem("Custom").GetItem("CustomSettings").GetList("PriceKeyStateList").SelectedValue; 7849 var hasStateAlert = userState != null && messageStates.Contains(userState); 7850 var message = Pageview.AreaSettings.GetItem("Custom").GetItem("CustomSettings").GetString("PriceKeyMessage"); 7851 var alertWord = Pageview.AreaSettings.GetItem("Custom").GetItem("CustomSettings").GetString("PriceKeyAlertWord"); 7852 var alertColor = Pageview.AreaSettings.GetItem("Custom").GetItem("CustomSettings").GetValue("PriceKeyColor"); 7853 //END CUSTOM CODE 7854 List<Block> subBlocks = this.productListActionsBlocksPage.GetBlockListById("Views").OrderBy(item => item.SortId).ToList(); 7855 7856 <div class="buttons-collection buttons-collection--right"> 7857 @*START CUSTOM CODE*@ 7858 @if (hasStateAlert) 7859 { 7860 <span>@Translate(message) <span style="color:@alertColor; font-weight: bold">@Translate(alertWord)</span></span> 7861 } 7862 @*END CUSTOM CODE*@ 7863 @if (showSorting) 7864 { 7865 string dropdownCssClass = Pageview.Device.ToString() == "Mobile" ? "u-flex-grow--1" : ""; 7866 7867 <input type="checkbox" id="ProductSort" class="dropdown-trigger"/> 7868 <div class="dropdown u-w150px u-inline-block @dropdownCssClass dw-mod"> 7869 <label class="dropdown__header dropdown__btn dropdown__btn--small dw-mod" for="ProductSort">{{selectedSort}}</label> 7870 <div class="dropdown__content dw-mod"> 7871 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: '', SortOrder: '' }, true);">@Translate("Default")</div> 7872 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'Created', SortOrder: 'DESC'}, true);">@Translate("Newest")</div> 7873 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'NameForSort', SortOrder: 'ASC'}, true);">@Translate("Name A - Z")</div> 7874 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'NameForSort', SortOrder: 'DESC'}, true);">@Translate("Name Z - A")</div> 7875 @if (Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 7876 { 7877 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'Price', SortOrder: 'ASC' }, true);">@Translate("Price low - high")</div> 7878 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'Price', SortOrder: 'DESC' }, true);">@Translate("Price high - low")</div> 7879 } 7880 </div> 7881 <label class="dropdown-trigger-off" for="ProductSort"></label> 7882 </div> 7883 } 7884 7885 @if (subBlocks.Count > 1) 7886 { 7887 <div> 7888 @foreach (Block item in subBlocks) 7889 { 7890 <input type="radio" class="tag-btn-trigger" id="ListViewBtn_@item.Id" name="ViewBtnGroup"> 7891 <label for="ListViewBtn_@item.Id" class="btn btn--tag u-no-margin" onclick="HandlebarsBolt.UpdateTemplate('ProductsContainer', '@item.Id')"><i class="fas fa-@item.Name"></i></label> 7892 } 7893 </div> 7894 } 7895 7896 @if (isFavoriteList && Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 7897 { 7898 string stockValidationUrl = Dna.StockValidation.Product.GetValidationUrl(GetPageIdByNavigationTag("StockValidation")); 7899 Button buyAllButton = new Button 7900 { 7901 ButtonType = ButtonType.Submit, 7902 Title = Translate("Buy all"), 7903 ButtonLayout = ButtonLayout.Secondary, 7904 Icon = new Icon {CssClass = cartIcon}, 7905 CssClass = "buy-all btn--sm dw-mod", 7906 OnClick = "StockValidation.MultiAddToCartValidation(event, '" + stockValidationUrl + "');" 7907 }; 7908 @Render(buyAllButton) 7909 } 7910 </div> 7911 } 7912 7913 7914 @if (productListNavigation.BlocksList.Count == 0) 7915 { 7916 productListNavigation.Design.RenderType = RenderType.Hide; 7917 } 7918 7919 <form name="multiForm" id="multiForm" method="post" onkeypress="return event.keyCode != 13;"> 7920 @* onkeypress is the fix for disabling submit form on Enter key from any field in product list *@ 7921 <input type="hidden" name="CartCmd" id="CartCmd" value="addMulti" /> 7922 @* load getproductinfo input if lazy load price is active and website is not selling with points only *@ 7923 @if (!Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly") && isLiveProductInfoActive) 7924 { 7925 @Render(new HiddenField { Name = "getproductinfo", Value = "true" }) 7926 } 7927 @* The @RenderBlockList base helper is included in Components/GridBuilder.cshtml *@ 7928 @RenderBlockList(productListPage.BlocksRoot.BlocksList) 7929 </form> 7930 7931 @helper RenderPageContainer() 7932 { 7933 List<Block> subBlocks = this.productListPage.GetBlockListById("PageContainer").OrderBy(item => item.SortId).ToList(); 7934 7935 string pageUrl = GetGlobalValue("Global:Pageview.Url.Raw"); 7936 string favoritesParams = !isFavoriteList ? "&DoNotShowVariantsAsSingleProducts=True" : ""; 7937 string updateJsonFeed = "feed=true" + favoritesParams; 7938 string feedFullUrl = pageUrl + "&feed=true"; 7939 feedFullUrl += favoritesParams; 7940 string smallDeviceCss = Pageview.Device.ToString() == "Mobile" ? "" : "u-padding"; 7941 var liveInfoFeed = $"{Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(GetPageIdByNavigationTag("LiveInfoProductFeed"))}?feed=true&getproductinfo=true"; 7942 feedFullUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(feedFullUrl.Replace("/Default", "Default")); // Avoid redirect 7943 7944 <div class="grid grid--align-content-start @smallDeviceCss js-handlebars-root" id="productList" 7945 data-template="ProductContainer" 7946 data-pre-render-template="ProductPreRenderContainer" 7947 data-json-feed="@feedFullUrl" 7948 data-preloader="overlay" 7949 data-update-json-feed="@updateJsonFeed"></div> 7950 <script id="ProductContainer" type="text/x-template"> 7951 {{#each .}} 7952 @RenderBlockList(subBlocks) 7953 {{#if isLiveProductInfoActive}} 7954 {{getLiveProductInfo 'productList' 'js-live-info-container' '@liveInfoFeed' productIds variantIds}} 7955 {{/if}} 7956 {{else}} 7957 <div class="grid__col-12"> 7958 <h2 class="u-ta-center">@Translate("Your search gave 0 results")</h2> 7959 </div> 7960 {{/each}} 7961 </script> 7962 } 7963 7964 @helper RenderProductList() 7965 { 7966 @*This is part of a script template *@ 7967 7968 List<Block> subBlocks = productListPage.GetBlockListById("ProductList").OrderBy(item => item.SortId).ToList(); 7969 string smallDeviceCss = Pageview.Device.ToString() == "Mobile" ? "u-no-padding" : ""; 7970 string columnClass = "auto"; 7971 7972 if (productListPage.GetBlockListById("Navigation").Count == 0) 7973 { 7974 columnClass = "12"; 7975 } 7976 7977 <div class="grid__col-@columnClass @smallDeviceCss"> 7978 @RenderBlockList(subBlocks) 7979 </div> 7980 } 7981 7982 @helper RenderProductListHeader() { 7983 List<Block> subBlocks = this.productListPage.GetBlockListById("ProductListHeader"); 7984 bool enableSeparationLine = productListSettings.GetBoolean("EnableSeparationLine"); 7985 string className = ( enableSeparationLine != null && enableSeparationLine ? "u-border-bottom u-padding-bottom" : "" ); 7986 7987 <div class="grid grid--align-content-start grid--justify-end grid--bleed u-margin-bottom--lg u-padding grid--wrap u-flex-grow--0 dw-mod"> 7988 <div class="grid @className"> 7989 @RenderBlockList(subBlocks) 7990 </div> 7991 </div> 7992 } 7993 7994 @helper RenderProductListTitle() 7995 { 7996 var header = new Heading { Title = "{{{header}}}", CssClass = "u-no-margin product-list__title" }; 7997 7998 if (isFavoriteList) 7999 { 8000 var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star"; 8001 header.Icon = new Icon { Prefix = "fas", Name = "fa-" + selectedFavoriteIcon, LabelPosition = IconLabelPosition.After, CssClass = "product-list__title-icon dw-mod"}; 8002 } 8003 8004 @Render(header) 8005 } 8006 8007 @helper RenderFavoriteListSearch() 8008 { 8009 string pageId = GetGlobalValue("Global:Page.ID"); 8010 string pageUrl = GetGlobalValue("Global:Pageview.Url.Raw"); 8011 string feedFullUrl = pageUrl + "&feed=true"; 8012 string searchPlaceholder = Translate("Search favorite products"); 8013 string searchValue = HttpContext.Current.Request.QueryString.Get("Search") ?? ""; 8014 8015 <div class="typeahead u-color-inherit typeahead--favorites js-typeahead" data-page-size="10" id="FavoritesSearch" data-list-id="@favoriteListId" data-search-feed-id="@pageId&feed=true" data-result-page-id="@pageId" data-live-product-info="@(isLiveProductInfoActive.ToString().ToLowerInvariant())"> 8016 <input type="text" class="typeahead-search-field u-no-margin u-full-width js-typeahead-search-field" placeholder="@searchPlaceholder" value="@searchValue"> 8017 <ul class="dropdown dropdown--absolute-position u-full-width js-handlebars-root js-typeahead-search-content u-min-w220px u-full-width dw-mod" id="FavoritesSearchContent" data-template="SearchProductsTemplate" data-json-feed="@feedFullUrl&ListID=@favoriteListId" data-init-onload="false" data-preloader="minimal"></ul> 8018 <button type="button" class="btn btn--condensed btn--primary u-no-margin dw-mod js-typeahead-enter-btn"><i class="fas fa-search"></i></button> 8019 </div> 8020 }