Error executing template "Designs/Rapido/eCom/Productlist/ProductsRender.cshtml"
System.ArgumentException: An item with the same key has already been added.
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at Dynamicweb.Ecommerce.Products.GroupRelation.GetGroupRelationsByChildId(String childId)
   at Dynamicweb.Ecommerce.Products.Group.get_IsTopGroup()
   at System.Linq.Enumerable.WhereListIterator`1.MoveNext()
   at Dynamicweb.Ecommerce.Products.GroupService.GetToplevelGroups()
   at Dynamicweb.Ecommerce.Products.GroupService.GetToplevelGroups(String languageId)
   at CompiledRazorTemplates.Dynamic.RazorEngine_d5aafc621f094450a6eb0fab7919e410.<LeftSidedNavigation>b__140_0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Flex Media\megatrade.dw9.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 5138
   at RazorEngine.Templating.TemplateWriter.ToString()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_d5aafc621f094450a6eb0fab7919e410.<>c__DisplayClass5_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Flex Media\megatrade.dw9.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 220
   at CompiledRazorTemplates.Dynamic.RazorEngine_d5aafc621f094450a6eb0fab7919e410.<>c__DisplayClass4_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Flex Media\megatrade.dw9.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 130
   at CompiledRazorTemplates.Dynamic.RazorEngine_d5aafc621f094450a6eb0fab7919e410.<>c__DisplayClass5_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Flex Media\megatrade.dw9.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 253
   at CompiledRazorTemplates.Dynamic.RazorEngine_d5aafc621f094450a6eb0fab7919e410.<>c__DisplayClass4_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Flex Media\megatrade.dw9.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 158
   at CompiledRazorTemplates.Dynamic.RazorEngine_d5aafc621f094450a6eb0fab7919e410.<RenderPageContainer>b__163_0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Flex Media\megatrade.dw9.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 6284
   at RazorEngine.Templating.TemplateWriter.ToString()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_d5aafc621f094450a6eb0fab7919e410.<>c__DisplayClass5_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Flex Media\megatrade.dw9.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 220
   at CompiledRazorTemplates.Dynamic.RazorEngine_d5aafc621f094450a6eb0fab7919e410.<>c__DisplayClass4_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Flex Media\megatrade.dw9.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 130
   at CompiledRazorTemplates.Dynamic.RazorEngine_d5aafc621f094450a6eb0fab7919e410.Execute() in D:\dynamicweb.net\Solutions\Flex Media\megatrade.dw9.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Productlist\ProductsRender.cshtml:line 6268
   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 15 @functions { 16 BlocksPage productListPage = BlocksPage.GetBlockPage("ProductList"); 17 Dynamicweb.Frontend.ItemViewModel productListSettings = null; 18 19 string favoriteListId = HttpContext.Current.Request.QueryString.Get("ListID"); 20 bool isFavoriteList = !string.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("ListID")); 21 } 22 23 @{ 24 productListSettings = Pageview.AreaSettings.GetItem("ProductList"); 25 26 27 Block pageContainer = new Block() 28 { 29 Id = "PageContainer", 30 Template = RenderPageContainer(), 31 SkipRenderBlocksList = true, 32 BlocksList = new List<Block> { 33 new Block 34 { 35 Id = "ProductListHeader", 36 SortId = 10, 37 Template = RenderProductListHeader(), 38 SkipRenderBlocksList = true, 39 BlocksList = new List<Block> { 40 new Block 41 { 42 Id = "ProductListTitle", 43 SortId = 10, 44 Design = new Design 45 { 46 CssClass = isFavoriteList ? "grid__col-xs-12 grid__col-md-4" : "grid__col-xs-12 grid__col-md-6" 47 }, 48 Template = RenderProductListTitle() 49 } 50 } 51 } 52 } 53 }; 54 productListPage.Add(pageContainer); 55 56 Block productListNavigation = new Block() 57 { 58 Id = "Navigation", 59 SortId = 20, 60 Design = new Design 61 { 62 RenderType = RenderType.Column, 63 Size = "3", 64 CssClass = "grid__col-12 grid__col-md-8" 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 else if (!string.IsNullOrEmpty(settings.Title)) 347 { 348 string cleanTitle = Regex.Replace(settings.Title, "<.*?>", String.Empty); 349 cleanTitle = cleanTitle.Replace("&nbsp;", " "); 350 attributes.Add("title", cleanTitle); 351 } 352 353 var onClickEvents = new List<string>(); 354 if (!string.IsNullOrEmpty(settings.OnClick)) 355 { 356 onClickEvents.Add(settings.OnClick); 357 } 358 if (!string.IsNullOrEmpty(settings.Href)) 359 { 360 onClickEvents.Add("location.href='" + settings.Href + "'"); 361 } 362 if (onClickEvents.Count > 0) 363 { 364 attributes.Add("onClick", string.Join(";", onClickEvents)); 365 } 366 367 if (settings.ButtonLayout != ButtonLayout.None) 368 { 369 classList.Add("btn"); 370 string btnLayout = Enum.GetName(typeof(ButtonLayout), settings.ButtonLayout).ToLower(); 371 if (btnLayout == "linkclean") 372 { 373 btnLayout = "link-clean"; //fix 374 } 375 classList.Add("btn--" + btnLayout); 376 } 377 378 if (settings.Icon == null) 379 { 380 settings.Icon = new Icon(); 381 } 382 383 settings.Icon.CssClass += Enum.GetName(typeof(ButtonLayout), settings.ButtonLayout).ToLower() != "linkclean" ? " u-flex--align-center" : ""; 384 settings.Icon.Label = settings.Title; 385 386 attributes.Add("type", Enum.GetName(typeof(ButtonType), settings.ButtonType).ToLower()); 387 388 <button class="@string.Join(" ", classList) dw-mod" @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@Render(settings.Icon)</button> 389 } 390 } 391 392 @helper RenderConfirmDialog(Button settings) 393 { 394 Modal confirmDialog = new Modal { 395 Id = settings.Id, 396 Width = ModalWidth.Sm, 397 Heading = new Heading 398 { 399 Level = 2, 400 Title = settings.ConfirmTitle 401 }, 402 BodyText = settings.ConfirmText 403 }; 404 405 confirmDialog.AddAction(new Button { Title = Translate("Cancel"), ButtonLayout = ButtonLayout.Secondary, OnClick = "document.getElementById('" + settings.Id + "ModalTrigger').checked = false"}); 406 confirmDialog.AddAction(new Button { Title = Translate("OK"), ButtonLayout = ButtonLayout.Primary, OnClick = "document.getElementById('" + settings.Id + "ModalTrigger').checked = false;" + settings.OnClick }); 407 408 @Render(confirmDialog) 409 } 410 @using Dynamicweb.Rapido.Blocks.Components.General 411 @using Dynamicweb.Rapido.Blocks.Components 412 @using Dynamicweb.Core 413 414 @helper RenderDashboard(Dashboard settings) 415 { 416 var widgets = settings.GetWidgets(); 417 418 if (!string.IsNullOrEmpty(settings.WidgetsBaseBackgroundColor)) 419 { 420 //set bg color for them 421 422 System.Drawing.Color color = System.Drawing.ColorTranslator.FromHtml(settings.WidgetsBaseBackgroundColor); 423 int r = Convert.ToInt16(color.R); 424 int g = Convert.ToInt16(color.G); 425 int b = Convert.ToInt16(color.B); 426 427 var count = widgets.Length; 428 var max = Math.Max(r, Math.Max(g, b)); 429 double step = 255.0 / (max * count); 430 var i = 0; 431 foreach (var widget in widgets) 432 { 433 i++; 434 435 var shade = "rgb(" + Converter.ToString(r * step * i).Replace(",", ".") + ", " + Converter.ToString(g * step * i).Replace(",", ".") + ", " + Converter.ToString(b * step * i).Replace(",", ".") + ")"; 436 widget.BackgroundColor = shade; 437 } 438 } 439 440 <div class="dashboard @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 441 @foreach (var widget in widgets) 442 { 443 <div class="dashboard__widget"> 444 @Render(widget) 445 </div> 446 } 447 </div> 448 } 449 @using Dynamicweb.Rapido.Blocks.Components.General 450 @using Dynamicweb.Rapido.Blocks.Components 451 452 @helper RenderDashboardWidgetLink(DashboardWidgetLink settings) 453 { 454 if (!string.IsNullOrEmpty(settings.Link)) 455 { 456 var backgroundStyles = ""; 457 if (!string.IsNullOrEmpty(settings.BackgroundColor)) 458 { 459 backgroundStyles = "style=\"background-color:" + settings.BackgroundColor + "\""; 460 } 461 462 <a href="@settings.Link" class="widget widget--link @settings.CssClass dw-mod" @backgroundStyles title="@settings.Title" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 463 <div class="u-center-middle u-color-light"> 464 @if (settings.Icon != null) 465 { 466 settings.Icon.CssClass += "widget__icon"; 467 @Render(settings.Icon) 468 } 469 <div class="widget__title">@settings.Title</div> 470 </div> 471 </a> 472 } 473 } 474 @using Dynamicweb.Rapido.Blocks.Components.General 475 @using Dynamicweb.Rapido.Blocks.Components 476 477 @helper RenderDashboardWidgetCounter(DashboardWidgetCounter settings) 478 { 479 var backgroundStyles = ""; 480 if (!string.IsNullOrEmpty(settings.BackgroundColor)) 481 { 482 backgroundStyles = "style='background-color:" + settings.BackgroundColor + "'"; 483 } 484 485 <div class="widget @settings.CssClass dw-mod" @backgroundStyles @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 486 <div class="u-center-middle u-color-light"> 487 @if (settings.Icon != null) 488 { 489 settings.Icon.CssClass += "widget__icon"; 490 @Render(settings.Icon) 491 } 492 <div class="widget__counter">@settings.Count</div> 493 <div class="widget__title">@settings.Title</div> 494 </div> 495 </div> 496 } 497 @using System.Reflection 498 @using Dynamicweb.Rapido.Blocks.Components.General 499 @using Dynamicweb.Rapido.Blocks.Components 500 @using Dynamicweb.Core 501 502 @* Component *@ 503 504 @helper RenderLink(Link settings) 505 { 506 if (settings != null && !string.IsNullOrEmpty(settings.Href) && (!string.IsNullOrEmpty(settings.Title) || settings.Icon != null)) 507 { 508 Dictionary<string, string> attributes = new Dictionary<string, string>(); 509 List<string> classList = settings.CssClass != null ? settings.CssClass.Split(' ').ToList() : new List<string>(); 510 if (settings.Disabled) 511 { 512 attributes.Add("disabled", "true"); 513 classList.Add("disabled"); 514 } 515 516 if (!string.IsNullOrEmpty(settings.AltText)) 517 { 518 attributes.Add("title", settings.AltText); 519 } 520 else if (!string.IsNullOrEmpty(settings.Title)) 521 { 522 attributes.Add("title", settings.Title); 523 } 524 525 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 526 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 527 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onClick", settings.OnClick); } 528 attributes.Add("href", settings.Href); 529 530 if (settings.ButtonLayout != ButtonLayout.None) 531 { 532 classList.Add("btn"); 533 string btnLayout = Enum.GetName(typeof(ButtonLayout), settings.ButtonLayout).ToLower(); 534 if (btnLayout == "linkclean") 535 { 536 btnLayout = "link-clean"; //fix 537 } 538 classList.Add("btn--" + btnLayout); 539 } 540 541 if (settings.Icon == null) 542 { 543 settings.Icon = new Icon(); 544 } 545 settings.Icon.Label = settings.Title; 546 547 if (settings.Target == LinkTargetType.Blank && settings.Rel == LinkRelType.None) 548 { 549 settings.Rel = LinkRelType.Noopener; 550 } 551 if (settings.Target != LinkTargetType.None) 552 { 553 attributes.Add("target", "_" + Enum.GetName(typeof(LinkTargetType), settings.Target).ToLower()); 554 } 555 if (settings.Download) 556 { 557 attributes.Add("download", "true"); 558 } 559 if (settings.Rel != LinkRelType.None) 560 { 561 attributes.Add("rel", Enum.GetName(typeof(LinkRelType), settings.Rel).ToLower()); 562 } 563 564 <a class="@string.Join(" ", classList) dw-mod" @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@Render(settings.Icon)</a> 565 } 566 } 567 @using System.Reflection 568 @using Dynamicweb.Rapido.Blocks.Components 569 @using Dynamicweb.Rapido.Blocks.Components.General 570 @using Dynamicweb.Rapido.Blocks 571 572 573 @* Component *@ 574 575 @helper RenderRating(Rating settings) 576 { 577 if (settings.Score > 0) 578 { 579 int rating = settings.Score; 580 string iconType = "fa-star"; 581 582 switch (settings.Type.ToString()) { 583 case "Stars": 584 iconType = "fa-star"; 585 break; 586 case "Hearts": 587 iconType = "fa-heart"; 588 break; 589 case "Lemons": 590 iconType = "fa-lemon"; 591 break; 592 case "Bombs": 593 iconType = "fa-bomb"; 594 break; 595 } 596 597 <div class="u-ta-right"> 598 @for (int i = 0; i < settings.OutOf; i++) 599 { 600 <i class="@(rating > i ? "fas" : "far") @iconType"></i> 601 } 602 </div> 603 } 604 } 605 @using System.Reflection 606 @using Dynamicweb.Rapido.Blocks.Components.General 607 @using Dynamicweb.Rapido.Blocks.Components 608 609 610 @* Component *@ 611 612 @helper RenderSelectFieldOption(SelectFieldOption settings) 613 { 614 Dictionary<string, string> attributes = new Dictionary<string, string>(); 615 if (settings.Checked) { attributes.Add("selected", "true"); } 616 if (settings.Disabled) { attributes.Add("disabled", "true"); } 617 if (settings.Value != null) { attributes.Add("value", settings.Value); } 618 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 619 620 <option @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@settings.Label</option> 621 } 622 @using System.Reflection 623 @using Dynamicweb.Rapido.Blocks.Components.General 624 @using Dynamicweb.Rapido.Blocks.Components 625 626 627 @* Component *@ 628 629 @helper RenderNavigation(Navigation settings) { 630 @RenderNavigation(new 631 { 632 id = settings.Id, 633 cssclass = settings.CssClass, 634 startLevel = settings.StartLevel, 635 endlevel = settings.EndLevel, 636 expandmode = settings.Expandmode, 637 sitemapmode = settings.SitemapMode, 638 template = settings.Template 639 }) 640 } 641 @using Dynamicweb.Rapido.Blocks.Components.General 642 @using Dynamicweb.Rapido.Blocks.Components 643 644 645 @* Component *@ 646 647 @helper RenderBreadcrumbNavigation(BreadcrumbNavigation settings) { 648 settings.Id = String.IsNullOrEmpty(settings.Id) ? "breadcrumb" : settings.Id; 649 settings.Template = String.IsNullOrEmpty(settings.Template) ? "Breadcrumb_All.xslt" : settings.Template; 650 settings.StartLevel = settings.StartLevel == 0 ? 1 : settings.StartLevel; 651 settings.EndLevel = settings.EndLevel == 10 ? 1 : settings.EndLevel; 652 settings.Expandmode = String.IsNullOrEmpty(settings.Expandmode) ? "all" : settings.Expandmode; 653 settings.SitemapMode = true; 654 655 @RenderNavigation(settings) 656 } 657 @using Dynamicweb.Rapido.Blocks.Components.General 658 @using Dynamicweb.Rapido.Blocks.Components 659 660 661 @* Component *@ 662 663 @helper RenderLeftNavigation(LeftNavigation settings) { 664 settings.Id = String.IsNullOrEmpty(settings.Id) ? "breadcrumb" : settings.Id; 665 settings.Template = String.IsNullOrEmpty(settings.Template) ? "Breadcrumb.xslt" : settings.Template; 666 settings.StartLevel = settings.StartLevel == 0 ? 1 : settings.StartLevel; 667 settings.EndLevel = settings.EndLevel == 10 ? 1 : settings.EndLevel; 668 settings.Expandmode = String.IsNullOrEmpty(settings.Expandmode) ? "all" : settings.Expandmode; 669 670 <div class="grid__cell"> 671 @RenderNavigation(settings) 672 </div> 673 } 674 @using System.Reflection 675 @using Dynamicweb.Rapido.Blocks.Components.General 676 @using Dynamicweb.Core 677 678 @* Component *@ 679 680 @helper RenderHeading(Heading settings) 681 { 682 if (settings != null && !string.IsNullOrEmpty(settings.Title)) 683 { 684 string color = settings.Color != null ? "style=\"color: " + settings.Color + "\"" : ""; 685 string tagName = settings.Level != 0 ? "h" + settings.Level.ToString() : "div"; 686 687 @("<" + tagName + " class=\"" + settings.CssClass + " dw-mod\" " + color + ">") 688 if (!string.IsNullOrEmpty(settings.Link)) 689 { 690 @Render(new Link { Href = settings.Link, Icon = settings.Icon, Title = settings.Title, ButtonLayout = ButtonLayout.None }) 691 } 692 else 693 { 694 if (settings.Icon == null) 695 { 696 settings.Icon = new Icon(); 697 } 698 settings.Icon.Label = settings.Title; 699 @Render(settings.Icon) 700 } 701 @("</" + tagName + ">"); 702 } 703 } 704 @using Dynamicweb.Rapido.Blocks.Components 705 @using Dynamicweb.Rapido.Blocks.Components.General 706 @using Dynamicweb.Rapido.Blocks 707 708 709 @* Component *@ 710 711 @helper RenderImage(Image settings) 712 { 713 if (settings.FilterPrimary != ImageFilter.None || settings.FilterSecondary != ImageFilter.None) 714 { 715 Dictionary<string, string> optionalAttributes = new Dictionary<string, string>(); 716 if (!string.IsNullOrEmpty(settings.FilterColor)) { optionalAttributes.Add("style", "background-color: " + settings.FilterColor); } 717 718 if (settings.Caption != null) 719 { 720 @:<div> 721 } 722 723 var primaryFilterClass = settings.FilterPrimary.ToString().ToLower(); 724 var secondaryFilterClass = settings.FilterSecondary.ToString().ToLower(); 725 726 <div class="image-filter image-filter--@primaryFilterClass u-position-relative dw-mod" @ComponentMethods.AddAttributes(optionalAttributes)> 727 <div class="image-filter image-filter--@secondaryFilterClass dw-mod"> 728 @if (settings.Link != null) 729 { 730 <a href="@settings.Link"> 731 @RenderTheImage(settings) 732 </a> 733 } 734 else 735 { 736 @RenderTheImage(settings) 737 } 738 </div> 739 </div> 740 741 if (settings.Caption != null) 742 { 743 <span class="image-caption dw-mod">@settings.Caption</span> 744 @:</div> 745 } 746 } 747 else 748 { 749 if (settings.Caption != null) 750 { 751 @:<div> 752 } 753 if (!string.IsNullOrEmpty(settings.Link)) 754 { 755 <a href="@settings.Link"> 756 @RenderTheImage(settings) 757 </a> 758 } 759 else 760 { 761 @RenderTheImage(settings) 762 } 763 764 if (settings.Caption != null) 765 { 766 <span class="image-caption dw-mod">@settings.Caption</span> 767 @:</div> 768 } 769 } 770 } 771 772 @helper RenderTheImage(Image settings) 773 { 774 if (settings != null) 775 { 776 string alternativeImage = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("AlternativeImage")) ? Pageview.AreaSettings.GetItem("Settings").GetFile("AlternativeImage").PathUrlEncoded : "/Images/missing_image.jpg"; 777 string placeholderImage = "/Files/Images/placeholder.gif"; 778 string imageEngine = "/Admin/Public/GetImage.ashx?"; 779 780 string imageStyle = ""; 781 782 switch (settings.Style) 783 { 784 case ImageStyle.Ball: 785 imageStyle = "grid__cell-img--ball"; 786 break; 787 788 case ImageStyle.Triangle: 789 imageStyle = "grid__cell-img--triangle"; 790 break; 791 } 792 793 if (settings.Style == ImageStyle.Ball || settings.Style == ImageStyle.Circle || settings.Style == ImageStyle.Triangle) 794 { 795 settings.ImageDefault.Crop = settings.ImageDefault.Crop == 5 ? settings.ImageDefault.Crop = 0 : settings.ImageDefault.Crop; 796 797 if (settings.ImageDefault != null) 798 { 799 settings.ImageDefault.Height = settings.ImageDefault.Width; 800 } 801 if (settings.ImageMedium != null) 802 { 803 settings.ImageMedium.Height = settings.ImageMedium.Width; 804 } 805 if (settings.ImageSmall != null) 806 { 807 settings.ImageSmall.Height = settings.ImageSmall.Width; 808 } 809 } 810 811 string defaultImage = imageEngine; 812 string imageSmall = ""; 813 string imageMedium = ""; 814 815 if (settings.DisableImageEngine) 816 { 817 defaultImage = settings.Path; 818 } 819 else 820 { 821 if (settings.ImageDefault != null) 822 { 823 defaultImage += Dynamicweb.Rapido.Services.Images.GetImagePathFromSettings(settings.ImageDefault); 824 825 if (settings.Path.GetType() != typeof(string)) 826 { 827 defaultImage += settings.Path != null ? "Image=" + settings.Path.PathUrlEncoded : ""; 828 defaultImage += settings.Path != null ? "&" + settings.Path.GetFocalPointParameters() : ""; 829 } 830 else 831 { 832 defaultImage += settings.Path != null ? "Image=" + settings.Path : ""; 833 } 834 835 defaultImage += "&Format=WebP&AlternativeImage=" + alternativeImage; 836 } 837 838 if (settings.ImageSmall != null) 839 { 840 imageSmall = "data-src-small=\"" + imageEngine; 841 imageSmall += Dynamicweb.Rapido.Services.Images.GetImagePathFromSettings(settings.ImageSmall); 842 843 if (settings.Path.GetType() != typeof(string)) 844 { 845 imageSmall += settings.Path != null ? "Image=" + settings.Path.PathUrlEncoded : ""; 846 imageSmall += settings.Path != null ? "&" + settings.Path.GetFocalPointParameters() : ""; 847 } 848 else 849 { 850 imageSmall += settings.Path != null ? "Image=" + settings.Path : ""; 851 } 852 853 imageSmall += "&Format=WebP&alternativeImage=" + alternativeImage; 854 855 imageSmall += "\""; 856 } 857 858 if (settings.ImageMedium != null) 859 { 860 imageMedium = "data-src-medium=\"" + imageEngine; 861 imageMedium += Dynamicweb.Rapido.Services.Images.GetImagePathFromSettings(settings.ImageMedium); 862 863 if (settings.Path.GetType() != typeof(string)) 864 { 865 imageMedium += settings.Path != null ? "Image=" + settings.Path.PathUrlEncoded : ""; 866 imageMedium += settings.Path != null ? "&" + settings.Path.GetFocalPointParameters() : ""; 867 } 868 else 869 { 870 imageMedium += settings.Path != null ? "Image=" + settings.Path : ""; 871 } 872 873 imageMedium += "&Format=WebP&alternativeImage=" + alternativeImage; 874 875 imageMedium += "\""; 876 } 877 } 878 879 Dictionary<string, string> optionalAttributes = new Dictionary<string, string>(); 880 if (!string.IsNullOrEmpty(settings.OnClick)) { optionalAttributes.Add("onclick", settings.OnClick); } 881 if (!string.IsNullOrEmpty(settings.Title)) 882 { 883 optionalAttributes.Add("alt", settings.Title); 884 optionalAttributes.Add("title", settings.Title); 885 } 886 887 if (settings.DisableLazyLoad) 888 { 889 <img id="@settings.Id" class="@imageStyle @settings.CssClass dw-mod" src="@defaultImage" @ComponentMethods.AddAttributes(optionalAttributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes) /> 890 } 891 else 892 { 893 <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) /> 894 } 895 } 896 } 897 @using System.Reflection 898 @using Dynamicweb.Rapido.Blocks.Components.General 899 @using Dynamicweb.Rapido.Blocks.Components 900 901 @* Component *@ 902 903 @helper RenderFileField(FileField settings) 904 { 905 var attributes = new Dictionary<string, string>(); 906 if (string.IsNullOrEmpty(settings.Id)) 907 { 908 settings.Id = Guid.NewGuid().ToString("N"); 909 } 910 911 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 912 if (settings.Disabled) { attributes.Add("disabled", "true"); } 913 if (settings.Required) { attributes.Add("required", "true"); } 914 if (settings.Multiple) { attributes.Add("multiple", "true"); } 915 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 916 if (string.IsNullOrEmpty(settings.ChooseFileText)) 917 { 918 settings.ChooseFileText = Translate("Choose file"); 919 } 920 if (string.IsNullOrEmpty(settings.NoFilesChosenText)) 921 { 922 settings.NoFilesChosenText = Translate("No files chosen..."); 923 } 924 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 925 926 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 927 928 string setValueToFakeInput = "FileUpload.setValueToFakeInput(this)"; 929 attributes.Add("onchange", setValueToFakeInput + (!string.IsNullOrEmpty(settings.OnChange) ? settings.OnChange : "")); 930 931 attributes.Add("type", "file"); 932 if (settings.Value != null) { attributes.Add("value", settings.Value); } 933 settings.CssClass = "u-full-width " + settings.CssClass; 934 935 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 936 937 <div class="form__field-group u-full-width @settings.WrapperCssClass dw-mod"> 938 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null ) 939 { 940 <div class="u-full-width"> 941 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> } 942 @if (settings.Link != null) { 943 <div class="u-pull--right"> 944 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; } 945 @Render(settings.Link) 946 </div> 947 } 948 </div> 949 950 } 951 952 @if (!string.IsNullOrEmpty(settings.HelpText)) 953 { 954 <small class="form__help-text">@settings.HelpText</small> 955 } 956 957 <div class="form__field-combi file-input u-no-margin dw-mod"> 958 <input @ComponentMethods.AddAttributes(resultAttributes) class="file-input__real-input" data-no-files-text="@settings.NoFilesChosenText" data-many-files-text="@Translate("files")" /> 959 <label for="@settings.Id" class="file-input__btn btn--secondary btn dw-mod">@settings.ChooseFileText</label> 960 <label for="@settings.Id" class="@settings.CssClass file-input__fake-input js-fake-input dw-mod">@settings.NoFilesChosenText</label> 961 @if (settings.UploadButton != null) 962 { 963 settings.UploadButton.CssClass += " btn--condensed u-no-margin"; 964 @Render(settings.UploadButton) 965 } 966 </div> 967 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 968 </div> 969 } 970 @using System.Reflection 971 @using Dynamicweb.Rapido.Blocks.Components.General 972 @using Dynamicweb.Rapido.Blocks.Components 973 @using Dynamicweb.Core 974 @using System.Linq 975 976 @* Component *@ 977 978 @helper RenderDateTimeField(DateTimeField settings) 979 { 980 if (string.IsNullOrEmpty(settings.Id)) 981 { 982 settings.Id = Guid.NewGuid().ToString("N"); 983 } 984 985 var textField = new TextField { 986 Name = settings.Name, 987 Id = settings.Id, 988 Label = settings.Label, 989 HelpText = settings.HelpText, 990 Value = settings.Value, 991 Disabled = settings.Disabled, 992 Required = settings.Required, 993 ErrorMessage = settings.ErrorMessage, 994 CssClass = settings.CssClass, 995 WrapperCssClass = settings.WrapperCssClass, 996 OnChange = settings.OnChange, 997 OnClick = settings.OnClick, 998 Link = settings.Link, 999 ExtraAttributes = settings.ExtraAttributes, 1000 // 1001 Placeholder = settings.Placeholder 1002 }; 1003 1004 @Render(textField) 1005 1006 List<string> jsAttributes = new List<string>(); 1007 1008 jsAttributes.Add("mode: '" + Enum.GetName(typeof(DateTimeFieldMode), settings.Mode).ToLower() + "'"); 1009 1010 if (!string.IsNullOrEmpty(settings.DateFormat)) 1011 { 1012 jsAttributes.Add("dateFormat: '" + settings.DateFormat + "'"); 1013 } 1014 if (!string.IsNullOrEmpty(settings.MinDate)) 1015 { 1016 jsAttributes.Add("minDate: '" + settings.MinDate + "'"); 1017 } 1018 if (!string.IsNullOrEmpty(settings.MaxDate)) 1019 { 1020 jsAttributes.Add("maxDate: '" + settings.MaxDate + "'"); 1021 } 1022 if (settings.IsInline) 1023 { 1024 jsAttributes.Add("inline: " + Converter.ToString(settings.IsInline).ToLower()); 1025 } 1026 if (settings.EnableTime) 1027 { 1028 jsAttributes.Add("enableTime: " + Converter.ToString(settings.EnableTime).ToLower()); 1029 } 1030 if (settings.EnableWeekNumbers) 1031 { 1032 jsAttributes.Add("weekNumbers: " + Converter.ToString(settings.EnableWeekNumbers).ToLower()); 1033 } 1034 1035 jsAttributes.AddRange(settings.GetFlatPickrOptions().Select(x => x.Key + ": " + x.Value)); 1036 1037 <script> 1038 document.addEventListener("DOMContentLoaded", function () { 1039 flatpickr("#@textField.Id", { 1040 @string.Join(",", jsAttributes) 1041 }); 1042 }); 1043 </script> 1044 } 1045 @using System.Reflection 1046 @using Dynamicweb.Rapido.Blocks.Components.General 1047 @using Dynamicweb.Rapido.Blocks.Components 1048 1049 @* Component *@ 1050 1051 @helper RenderTextField(TextField settings) 1052 { 1053 var attributes = new Dictionary<string, string>(); 1054 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id)) 1055 { 1056 settings.Id = Guid.NewGuid().ToString("N"); 1057 } 1058 1059 /*base settings*/ 1060 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1061 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1062 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1063 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1064 if (settings.Required) { attributes.Add("required", "true"); } 1065 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1066 /*end*/ 1067 1068 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); } 1069 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); } 1070 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); } 1071 if (settings.ReadOnly) { attributes.Add("readonly", "true"); } 1072 if (settings.MaxLength != 0) { attributes.Add("maxlength", settings.MaxLength.ToString()); } 1073 if (!string.IsNullOrEmpty(settings.Placeholder)) { attributes.Add("placeholder", settings.Placeholder); } 1074 attributes.Add("type", Enum.GetName(typeof(TextFieldType), settings.Type).ToLower()); 1075 if (settings.Type == TextFieldType.Password) { attributes.Add("autocomplete", "off"); }; 1076 if (settings.Value != null) { attributes.Add("value", settings.Value); } 1077 1078 settings.CssClass = "u-full-width " + settings.CssClass; 1079 1080 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1081 1082 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1083 1084 string noMargin = "u-no-margin"; 1085 if (!settings.ReadOnly) { 1086 noMargin = ""; 1087 } 1088 1089 <div class="form__field-group u-full-width @noMargin @settings.WrapperCssClass dw-mod"> 1090 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null ) 1091 { 1092 <div class="u-full-width"> 1093 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> } 1094 @if (settings.Link != null) { 1095 settings.Link.ButtonLayout = ButtonLayout.LinkClean; 1096 1097 <div class="u-pull--right"> 1098 @Render(settings.Link) 1099 </div> 1100 } 1101 </div> 1102 1103 } 1104 1105 @if (!string.IsNullOrEmpty(settings.HelpText)) 1106 { 1107 <small class="form__help-text">@settings.HelpText</small> 1108 } 1109 1110 @if (settings.ActionButton != null) 1111 { 1112 settings.ActionButton.CssClass += " btn--condensed u-no-margin"; 1113 <div class="form__field-combi u-no-margin dw-mod"> 1114 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1115 @Render(settings.ActionButton) 1116 </div> 1117 } 1118 else 1119 { 1120 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1121 } 1122 1123 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1124 </div> 1125 } 1126 @using System.Reflection 1127 @using Dynamicweb.Rapido.Blocks.Components.General 1128 @using Dynamicweb.Rapido.Blocks.Components 1129 1130 @* Component *@ 1131 1132 @helper RenderNumberField(NumberField settings) 1133 { 1134 var attributes = new Dictionary<string, string>(); 1135 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id)) 1136 { 1137 settings.Id = Guid.NewGuid().ToString("N"); 1138 } 1139 1140 /*base settings*/ 1141 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1142 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1143 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1144 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1145 if (settings.Required) { attributes.Add("required", "true"); } 1146 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1147 /*end*/ 1148 1149 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); } 1150 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); } 1151 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); } 1152 if (settings.ReadOnly) { attributes.Add("readonly", "true"); } 1153 if (settings.Max != null) { attributes.Add("max", settings.Max.ToString()); } 1154 if (settings.Min != null) { attributes.Add("min", settings.Min.ToString()); } 1155 if (settings.Step != 0) { attributes.Add("step", settings.Step.ToString()); } 1156 if (settings.Value != null && !string.IsNullOrEmpty(settings.Value.ToString())) { attributes.Add("value", settings.Value.ToString()); } 1157 attributes.Add("type", "number"); 1158 1159 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1160 1161 <div class="form__field-group u-full-width @settings.WrapperCssClass dw-mod"> 1162 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null ) 1163 { 1164 <div class="u-full-width"> 1165 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> } 1166 @if (settings.Link != null) { 1167 <div class="u-pull--right"> 1168 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; } 1169 @Render(settings.Link) 1170 </div> 1171 } 1172 </div> 1173 1174 } 1175 1176 @if (!string.IsNullOrEmpty(settings.HelpText)) 1177 { 1178 <small class="form__help-text">@settings.HelpText</small> 1179 } 1180 1181 @if (settings.ActionButton != null) 1182 { 1183 settings.ActionButton.CssClass += " btn--condensed u-no-margin"; 1184 <div class="form__field-combi u-no-margin dw-mod"> 1185 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1186 @Render(settings.ActionButton) 1187 </div> 1188 } 1189 else 1190 { 1191 <div class="form__field-combi u-no-margin dw-mod"> 1192 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1193 </div> 1194 } 1195 1196 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1197 </div> 1198 } 1199 @using System.Reflection 1200 @using Dynamicweb.Rapido.Blocks.Components.General 1201 @using Dynamicweb.Rapido.Blocks.Components 1202 1203 1204 @* Component *@ 1205 1206 @helper RenderTextareaField(TextareaField settings) 1207 { 1208 Dictionary<string, string> attributes = new Dictionary<string, string>(); 1209 string id = settings.Id; 1210 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(id)) 1211 { 1212 id = Guid.NewGuid().ToString("N"); 1213 } 1214 1215 if (!string.IsNullOrEmpty(id)) { attributes.Add("id", id); } 1216 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1217 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); } 1218 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); } 1219 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); } 1220 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1221 if (!string.IsNullOrEmpty(settings.Placeholder)) { attributes.Add("placeholder", settings.Placeholder); } 1222 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1223 if (settings.Required) { attributes.Add("required", "true"); } 1224 if (settings.ReadOnly) { attributes.Add("readonly", "true"); } 1225 if (settings.MaxLength != 0) { attributes.Add("maxlength", settings.MaxLength.ToString()); } 1226 if (settings.Rows != 0) { attributes.Add("rows", settings.Rows.ToString()); } 1227 attributes.Add("name", settings.Name); 1228 1229 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1230 1231 <div class="form__field-group @settings.WrapperCssClass dw-mod"> 1232 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null ) 1233 { 1234 <div class="u-full-width"> 1235 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> } 1236 @if (settings.Link != null) { 1237 <div class="u-pull--right"> 1238 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; } 1239 @Render(settings.Link) 1240 </div> 1241 } 1242 </div> 1243 } 1244 1245 @if (!string.IsNullOrEmpty(settings.HelpText)) 1246 { 1247 <small class="form__help-text">@settings.HelpText</small> 1248 } 1249 1250 <textarea class="u-full-width @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@settings.Value</textarea> 1251 1252 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1253 </div> 1254 } 1255 @using System.Reflection 1256 @using Dynamicweb.Rapido.Blocks.Components.General 1257 @using Dynamicweb.Rapido.Blocks.Components 1258 1259 1260 @* Component *@ 1261 1262 @helper RenderHiddenField(HiddenField settings) { 1263 var attributes = new Dictionary<string, string>(); 1264 attributes.Add("type", "hidden"); 1265 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1266 if (settings.Value != null) { attributes.Add("value", settings.Value); } 1267 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1268 1269 <input @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)/> 1270 } 1271 @using System.Reflection 1272 @using Dynamicweb.Rapido.Blocks.Components.General 1273 @using Dynamicweb.Rapido.Blocks.Components 1274 1275 @* Component *@ 1276 1277 @helper RenderCheckboxField(CheckboxField settings) 1278 { 1279 var attributes = new Dictionary<string, string>(); 1280 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id)) 1281 { 1282 settings.Id = Guid.NewGuid().ToString("N"); 1283 } 1284 1285 /*base settings*/ 1286 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1287 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1288 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1289 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1290 if (settings.Required) { attributes.Add("required", "true"); } 1291 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1292 /*end*/ 1293 1294 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1295 1296 attributes.Add("type", "checkbox"); 1297 if (settings.Checked) { attributes.Add("checked", "true"); } 1298 settings.CssClass = "form__control " + settings.CssClass; 1299 if (settings.Value != null) { attributes.Add("value", settings.Value); } 1300 1301 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1302 1303 <div class="form__field-group @settings.WrapperCssClass dw-mod"> 1304 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1305 @if (!string.IsNullOrEmpty(settings.Label)) 1306 { 1307 <label for="@settings.Id" class="dw-mod">@settings.Label</label> 1308 } 1309 1310 @if (settings.Link != null) { 1311 <span> 1312 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; } 1313 @Render(settings.Link) 1314 </span> 1315 } 1316 1317 @if (!string.IsNullOrEmpty(settings.HelpText)) 1318 { 1319 <small class="form__help-text checkbox-help dw-mod">@settings.HelpText</small> 1320 } 1321 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1322 </div> 1323 } 1324 @using System.Reflection 1325 @using Dynamicweb.Rapido.Blocks.Components.General 1326 @using Dynamicweb.Rapido.Blocks.Components 1327 1328 1329 @* Component *@ 1330 1331 @helper RenderCheckboxListField(CheckboxListField settings) 1332 { 1333 <div class="form__field-group @settings.WrapperCssClass u-margin-bottom dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 1334 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null ) 1335 { 1336 <div class="u-full-width"> 1337 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> } 1338 @if (settings.Link != null) { 1339 <div class="u-pull--right"> 1340 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; } 1341 @Render(settings.Link) 1342 </div> 1343 } 1344 </div> 1345 1346 } 1347 1348 <div class="u-pull--left"> 1349 @if (!string.IsNullOrEmpty(settings.HelpText)) 1350 { 1351 <small class="form__help-text">@settings.HelpText</small> 1352 } 1353 1354 @foreach (var item in settings.Options) 1355 { 1356 if (settings.Required) 1357 { 1358 item.Required = true; 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 1386 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1387 </div> 1388 1389 </div> 1390 } 1391 @using Dynamicweb.Rapido.Blocks.Components.General 1392 1393 @* Component *@ 1394 1395 @helper RenderSearch(Search settings) 1396 { 1397 var searchValue = HttpContext.Current.Request.QueryString.Get(settings.SearchParameter) ?? ""; 1398 var groupValue = HttpContext.Current.Request.QueryString.Get(settings.GroupsParameter) ?? ""; 1399 1400 if (string.IsNullOrEmpty(settings.Id)) 1401 { 1402 settings.Id = Guid.NewGuid().ToString("N"); 1403 } 1404 1405 var resultAttributes = new Dictionary<string, string>(); 1406 1407 if (settings.PageSize != 0) 1408 { 1409 resultAttributes.Add("data-page-size", settings.PageSize.ToString()); 1410 } 1411 if (!string.IsNullOrEmpty(settings.GroupItemsFeedUrl)) 1412 { 1413 resultAttributes.Add("data-groups-feed-url", settings.GroupItemsFeedUrl); 1414 if (!string.IsNullOrEmpty(groupValue)) 1415 { 1416 resultAttributes.Add("data-selected-group", groupValue); 1417 } 1418 if (!string.IsNullOrEmpty(settings.GroupsParameter)) 1419 { 1420 resultAttributes.Add("data-groups-parameter", settings.GroupsParameter); 1421 } 1422 } 1423 resultAttributes.Add("data-force-init", "true"); 1424 if (settings.GoToFirstSearchResultOnEnter) 1425 { 1426 resultAttributes.Add("data-go-to-first-search-result-on-enter", settings.GoToFirstSearchResultOnEnter.ToString().ToLower()); 1427 } 1428 if (!string.IsNullOrEmpty(settings.SearchParameter)) 1429 { 1430 resultAttributes.Add("data-search-parameter", settings.SearchParameter); 1431 } 1432 resultAttributes.Add("data-search-feed-url", settings.SearchData.SearchFeedUrl); 1433 resultAttributes.Add("data-results-template-id", settings.SearchData.ResultsTemplateId); 1434 1435 if (settings.SecondSearchData != null) 1436 { 1437 resultAttributes.Add("data-second-search-feed-url", settings.SecondSearchData.SearchFeedUrl); 1438 resultAttributes.Add("data-second-results-template-id", settings.SecondSearchData.ResultsTemplateId); 1439 } 1440 if (!string.IsNullOrEmpty(settings.ResultsPageUrl)) 1441 { 1442 resultAttributes.Add("data-results-page-url", settings.ResultsPageUrl); 1443 } 1444 1445 resultAttributes = resultAttributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1446 1447 string searchFieldCss = (settings.SearchButton == null) ? "search--with-icon" : ""; 1448 1449 <div class="search @settings.CssClass @searchFieldCss js-search-data-source dw-mod" id="@settings.Id" @ComponentMethods.AddAttributes(resultAttributes)> 1450 @if (!string.IsNullOrEmpty(settings.GroupItemsFeedUrl)) 1451 { 1452 <button type="button" class="search__groups-btn dw-mod js-search-groups-btn">@Translate("All")</button> 1453 <ul class="dropdown dropdown--absolute-position dw-mod search__groups-results js-search-groups-list"></ul> 1454 } 1455 1456 <input type="text" class="search__field dw-mod js-search-field" placeholder="@settings.Placeholder" value="@searchValue"> 1457 1458 <div class="dropdown dropdown--absolute-position search__results dw-mod js-search-results @(settings.SecondSearchData != null ? "search__results--combined" : "")"> 1459 @if (settings.SecondSearchData != null) 1460 { 1461 <div class="search__column search__column--products dw-mod"> 1462 <div class="search__column-header dw-mod">@Translate("Products")</div> 1463 <ul class="search__results-list dw-mod js-search-results-list" id="@(settings.Id)_ResultsList"></ul> 1464 @if (!string.IsNullOrEmpty(settings.SearchData.ResultsPageUrl)) 1465 { 1466 @Render(new Link { 1467 Title = Translate("View all"), 1468 CssClass = "js-view-all-button u-margin", 1469 Href = settings.SearchData.ResultsPageUrl 1470 }); 1471 } 1472 </div> 1473 <div class="search__column search__column--pages dw-mod"> 1474 <div class="search__column-header">@Translate("Pages")</div> 1475 <ul class="search__results-list dw-mod js-search-results-second-list" id="@(settings.Id)_SecondResultsList"></ul> 1476 @if (!string.IsNullOrEmpty(settings.SecondSearchData.ResultsPageUrl)) 1477 { 1478 @Render(new Link 1479 { 1480 Title = Translate("View all"), 1481 CssClass = "js-view-all-button u-margin", 1482 Href = settings.SecondSearchData.ResultsPageUrl 1483 }); 1484 } 1485 </div> 1486 } 1487 else 1488 { 1489 <div class="search__column search__column--only dw-mod"> 1490 <ul class="search__results-list dw-mod js-search-results-list" id="@(settings.Id)_ResultsList"></ul> 1491 @if (!string.IsNullOrEmpty(settings.SearchData.ResultsPageUrl)) 1492 { 1493 @Render(new Link { 1494 Title = Translate("View all"), 1495 CssClass = "js-view-all-button u-margin", 1496 Href = settings.SearchData.ResultsPageUrl 1497 }); 1498 } 1499 </div> 1500 } 1501 </div> 1502 1503 @if (settings.SearchButton != null) 1504 { 1505 settings.SearchButton.CssClass += " search__btn js-search-btn"; 1506 if (settings.RenderDefaultSearchIcon) 1507 { 1508 settings.SearchButton.Icon = new Icon { Name = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SearchIcon").SelectedValue }; 1509 } 1510 @Render(settings.SearchButton); 1511 } 1512 </div> 1513 } 1514 @using System.Reflection 1515 @using Dynamicweb.Rapido.Blocks.Components.General 1516 @using Dynamicweb.Rapido.Blocks.Components 1517 1518 1519 @* Component *@ 1520 1521 @helper RenderSelectField(SelectField settings) 1522 { 1523 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id)) 1524 { 1525 settings.Id = Guid.NewGuid().ToString("N"); 1526 } 1527 1528 <div class="form__field-group u-full-width @settings.WrapperCssClass dw-mod"> 1529 @if (!string.IsNullOrEmpty(settings.Label) || settings.Link != null ) 1530 { 1531 <div class="u-full-width"> 1532 @if (!string.IsNullOrEmpty(settings.Label)) { <label for="@settings.Id" class="u-pull--left">@settings.Label</label> } 1533 @if (settings.Link != null) { 1534 <div class="u-pull--right"> 1535 @{ settings.Link.ButtonLayout = ButtonLayout.LinkClean; } 1536 @Render(settings.Link) 1537 </div> 1538 } 1539 </div> 1540 } 1541 1542 @if (!string.IsNullOrEmpty(settings.HelpText)) 1543 { 1544 <small class="form__help-text">@settings.HelpText</small> 1545 } 1546 1547 @if (settings.ActionButton != null) 1548 { 1549 settings.ActionButton.CssClass += " btn--condensed u-no-margin"; 1550 <div class="form__field-combi u-no-margin dw-mod"> 1551 @RenderSelectBase(settings) 1552 @Render(settings.ActionButton) 1553 </div> 1554 } 1555 else 1556 { 1557 @RenderSelectBase(settings) 1558 } 1559 1560 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1561 </div> 1562 } 1563 1564 @helper RenderSelectBase(SelectField settings) 1565 { 1566 var attributes = new Dictionary<string, string>(); 1567 1568 /*base settings*/ 1569 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1570 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1571 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1572 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1573 if (settings.Required) { attributes.Add("required", "true"); } 1574 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1575 /*end*/ 1576 1577 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1578 1579 <select @ComponentMethods.AddAttributes(resultAttributes) class="u-full-width @settings.CssClass dw-mod"> 1580 @if (settings.Default != null) 1581 { 1582 @Render(settings.Default) 1583 } 1584 1585 @foreach (var item in settings.Options) 1586 { 1587 if (settings.Value != null) { 1588 item.Checked = item.Value == settings.Value; 1589 } 1590 @Render(item) 1591 } 1592 </select> 1593 } 1594 @using System.Reflection 1595 @using Dynamicweb.Rapido.Blocks.Components.General 1596 @using Dynamicweb.Rapido.Blocks.Components 1597 1598 @* Component *@ 1599 1600 @helper RenderRadioButtonField(RadioButtonField settings) 1601 { 1602 var attributes = new Dictionary<string, string>(); 1603 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id)) 1604 { 1605 settings.Id = Guid.NewGuid().ToString("N"); 1606 } 1607 1608 /*base settings*/ 1609 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1610 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1611 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1612 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1613 if (settings.Required) { attributes.Add("required", "true"); } 1614 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1615 /*end*/ 1616 1617 attributes.Add("type", "radio"); 1618 if (settings.Checked) { attributes.Add("checked", "true"); } 1619 settings.CssClass = "form__control " + settings.CssClass; 1620 if (settings.Value != null) { attributes.Add("value", settings.Value); } 1621 1622 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1623 1624 <div class="form__field-group @settings.WrapperCssClass dw-mod"> 1625 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1626 @if (!string.IsNullOrEmpty(settings.Label)) 1627 { 1628 <label for="@settings.Id" class="dw-mod">@settings.Label</label> 1629 } 1630 @if (!string.IsNullOrEmpty(settings.HelpText)) 1631 { 1632 <small class="form__help-text">@settings.HelpText</small> 1633 } 1634 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1635 </div> 1636 } 1637 @using System.Reflection 1638 @using Dynamicweb.Rapido.Blocks.Components.General 1639 @using Dynamicweb.Rapido.Blocks.Components 1640 1641 1642 @* Component *@ 1643 1644 @helper RenderRadioButtonListField(RadioButtonListField settings) 1645 { 1646 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1647 1648 <div class="form__field-group @settings.WrapperCssClass u-margin-bottom dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 1649 @if (!string.IsNullOrEmpty(settings.Label)) 1650 { 1651 <label>@settings.Label</label> 1652 } 1653 @if (!string.IsNullOrEmpty(settings.HelpText)) 1654 { 1655 <small class="form__help-text">@settings.HelpText</small> 1656 } 1657 1658 @foreach (var item in settings.Options) 1659 { 1660 if (settings.Required) 1661 { 1662 item.Required = true; 1663 } 1664 if (settings.Disabled) 1665 { 1666 item.Disabled = true; 1667 } 1668 if (!string.IsNullOrEmpty(settings.Name)) 1669 { 1670 item.Name = settings.Name; 1671 } 1672 if (settings.Value != null && settings.Value == item.Value) 1673 { 1674 item.Checked = true; 1675 } 1676 if (!string.IsNullOrEmpty(settings.OnClick)) 1677 { 1678 item.OnClick += settings.OnClick; 1679 } 1680 if (!string.IsNullOrEmpty(settings.OnChange)) 1681 { 1682 item.OnChange += settings.OnChange; 1683 } 1684 if (!string.IsNullOrEmpty(settings.CssClass)) 1685 { 1686 item.CssClass += settings.CssClass; 1687 } 1688 @Render(item) 1689 } 1690 1691 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1692 </div> 1693 } 1694 @using System.Reflection 1695 @using Dynamicweb.Rapido.Blocks.Components.General 1696 @using Dynamicweb.Rapido.Blocks.Components 1697 1698 1699 @* Component *@ 1700 1701 @helper RenderNotificationMessage(NotificationMessage settings) 1702 { 1703 if (!string.IsNullOrEmpty(settings.Message)) 1704 { 1705 var attributes = new Dictionary<string, string>(); 1706 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1707 1708 string messageTypeClass = Enum.GetName(typeof(NotificationMessageType), settings.MessageType).ToLower(); 1709 string messageLayoutClass = Enum.GetName(typeof(NotificationMessageLayout), settings.MessageLayout).ToLower(); 1710 string minHeightClass = settings.Icon != null ? "u-min-h70px" : ""; 1711 1712 <div class="notification-message-@messageTypeClass notification-message-@messageLayoutClass @messageLayoutClass @minHeightClass @settings.CssClass u-full-width dw-mod" @ComponentMethods.AddAttributes(attributes)> 1713 @if (settings.Icon != null) { 1714 settings.Icon.Label = !string.IsNullOrEmpty(settings.Icon.Label) ? settings.Message + settings.Icon.Label : settings.Message; 1715 @Render(settings.Icon) 1716 } else { 1717 @settings.Message 1718 } 1719 </div> 1720 } 1721 } 1722 @using Dynamicweb.Rapido.Blocks.Components.General 1723 1724 1725 @* Component *@ 1726 1727 @helper RenderHandlebarsRoot(HandlebarsRoot settings) { 1728 string preRender = !String.IsNullOrEmpty(settings.PreRenderScriptTemplate) ? "data-pre-render-template=\"" + settings.PreRenderScriptTemplate + "\"" : ""; 1729 1730 <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> 1731 @if (settings.SubBlocks != null) { 1732 @RenderBlockList(settings.SubBlocks) 1733 } 1734 </div> 1735 } 1736 @using System.Reflection 1737 @using Dynamicweb.Rapido.Blocks.Components.General 1738 @using Dynamicweb.Rapido.Blocks.Components 1739 @using System.Text.RegularExpressions 1740 1741 1742 @* Component *@ 1743 1744 @helper RenderSticker(Sticker settings) { 1745 if (!String.IsNullOrEmpty(settings.Title)) { 1746 string size = settings.Size.ToString() != "None" ? "" + "stickers-container__tag--" + settings.Size.ToString().ToLower() : ""; 1747 string style = settings.Style.ToString() != "None" ? "" + "stickers-container__tag--" + settings.Style.ToString().ToLower() : ""; 1748 1749 Dictionary<String, String> optionalAttributes = new Dictionary<string, string>(); 1750 if (!String.IsNullOrEmpty(settings.Color) || !String.IsNullOrEmpty(settings.BackgroundColor)) { 1751 string styleTag = !String.IsNullOrEmpty(settings.Color) ? "color: " + settings.Color + "; " : ""; 1752 styleTag += !String.IsNullOrEmpty(settings.BackgroundColor) ? "background-color: " + settings.BackgroundColor + "; " : ""; 1753 optionalAttributes.Add("style", styleTag); 1754 } 1755 1756 <div class="stickers-container__tag @size @style @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(optionalAttributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@settings.Title</div> 1757 } 1758 } 1759 1760 @using System.Reflection 1761 @using Dynamicweb.Rapido.Blocks.Components.General 1762 @using Dynamicweb.Rapido.Blocks.Components 1763 1764 1765 @* Component *@ 1766 1767 @helper RenderStickersCollection(StickersCollection settings) 1768 { 1769 if (settings.Stickers.Count > 0) 1770 { 1771 string position = "stickers-container--" + Regex.Replace(settings.Position.ToString(), "([a-z])([A-Z])", "$1-$2").ToLower(); 1772 1773 <div class="stickers-container @position @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 1774 @foreach (Sticker sticker in settings.Stickers) 1775 { 1776 @Render(sticker) 1777 } 1778 </div> 1779 } 1780 } 1781 1782 @using Dynamicweb.Rapido.Blocks.Components.General 1783 1784 1785 @* Component *@ 1786 1787 @helper RenderForm(Form settings) { 1788 if (settings != null) 1789 { 1790 Dictionary<string, string> optionalAttributes = new Dictionary<string, string>(); 1791 if (!string.IsNullOrEmpty(settings.Action)) { optionalAttributes.Add("action", settings.Action); }; 1792 if (!string.IsNullOrEmpty(settings.Name)) { optionalAttributes.Add("name", settings.Name); }; 1793 if (!string.IsNullOrEmpty(settings.OnSubmit)) { optionalAttributes.Add("onsubmit", settings.OnSubmit); }; 1794 var enctypes = new Dictionary<string, string> 1795 { 1796 { "multipart", "multipart/form-data" }, 1797 { "text", "text/plain" }, 1798 { "application", "application/x-www-form-urlencoded" } 1799 }; 1800 if (settings.Enctype != FormEnctype.none) { optionalAttributes.Add("enctype", enctypes[Enum.GetName(typeof(FormEnctype), settings.Enctype).ToLower()]); }; 1801 optionalAttributes.Add("method", settings.Method.ToString()); 1802 1803 if (!string.IsNullOrEmpty(settings.FormStartMarkup)) 1804 { 1805 @settings.FormStartMarkup 1806 } 1807 else 1808 { 1809 @:<form class="@settings.CssClass u-no-margin dw-mod" @ComponentMethods.AddAttributes(optionalAttributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 1810 } 1811 1812 foreach (var field in settings.GetFields()) 1813 { 1814 @Render(field) 1815 } 1816 1817 @:</form> 1818 } 1819 } 1820 @using System.Reflection 1821 @using Dynamicweb.Rapido.Blocks.Components.General 1822 @using Dynamicweb.Rapido.Blocks.Components 1823 1824 1825 @* Component *@ 1826 1827 @helper RenderText(Text settings) 1828 { 1829 @settings.Content 1830 } 1831 @using System.Reflection 1832 @using Dynamicweb.Rapido.Blocks.Components.General 1833 @using Dynamicweb.Rapido.Blocks.Components 1834 1835 1836 @* Component *@ 1837 1838 @helper RenderContentModule(ContentModule settings) { 1839 if (!string.IsNullOrEmpty(settings.Content)) 1840 { 1841 @settings.Content 1842 } 1843 } 1844 @using System.Reflection 1845 @using Dynamicweb.Rapido.Blocks.Components.General 1846 @using Dynamicweb.Rapido.Blocks.Components 1847 1848 1849 @* Component *@ 1850 1851 @helper RenderModal(Modal settings) { 1852 if (settings != null) 1853 { 1854 string modalId = !string.IsNullOrEmpty(settings.Id) ? settings.Id : Guid.NewGuid().ToString("N"); 1855 1856 string onchange = !string.IsNullOrEmpty(settings.OnClose) ? "onchange=\"if(!this.checked){" + settings.OnClose + "}\"" : ""; 1857 1858 <input type="checkbox" id="@(modalId)ModalTrigger" class="modal-trigger" @onchange /> 1859 1860 <div class="modal-container"> 1861 @if (!settings.DisableDarkOverlay) 1862 { 1863 <label for="@(modalId)ModalTrigger" id="@(modalId)ModalOverlay" class="modal-overlay"></label> 1864 } 1865 <div class="modal modal--@settings.Width.ToString().ToLower() modal-height--@settings.Height.ToString().ToLower()" id="@(modalId)Modal"> 1866 @if (settings.Heading != null) 1867 { 1868 if (!string.IsNullOrEmpty(settings.Heading.Title)) 1869 { 1870 <div class="modal__header"> 1871 @Render(settings.Heading) 1872 </div> 1873 } 1874 } 1875 <div class="modal__body @(settings.Width.ToString().ToLower() == "full" ? "modal__body--full" : "")"> 1876 @if (!string.IsNullOrEmpty(settings.BodyText)) 1877 { 1878 @settings.BodyText 1879 } 1880 @if (settings.BodyTemplate != null) 1881 { 1882 @settings.BodyTemplate 1883 } 1884 @{ 1885 var actions = settings.GetActions(); 1886 } 1887 </div> 1888 @if (actions.Length > 0) 1889 { 1890 <div class="modal__footer"> 1891 @foreach (var action in actions) 1892 { 1893 if (Pageview.Device.ToString() != "Mobile") { 1894 action.CssClass += " u-no-margin"; 1895 } else { 1896 action.CssClass += " u-full-width u-margin-bottom"; 1897 } 1898 1899 @Render(action) 1900 } 1901 </div> 1902 } 1903 <label class="modal__close-btn" for="@(modalId)ModalTrigger"></label> 1904 </div> 1905 </div> 1906 } 1907 } 1908 @using Dynamicweb.Rapido.Blocks.Components.General 1909 1910 @* Component *@ 1911 1912 @helper RenderMediaListItem(MediaListItem settings) 1913 { 1914 <div class="media-list-item @settings.CssClass dw-mod" @(!string.IsNullOrEmpty(settings.Id) ? "id=\"" + settings.Id + "\"" : "")> 1915 @if (!string.IsNullOrEmpty(settings.Label)) 1916 { 1917 if (!string.IsNullOrEmpty(settings.Link)) 1918 { 1919 @Render(new Link 1920 { 1921 Href = settings.Link, 1922 CssClass = "media-list-item__sticker dw-mod", 1923 ButtonLayout = ButtonLayout.None, 1924 Title = settings.Label, 1925 OnClick = !string.IsNullOrEmpty(settings.OnClick) ? settings.OnClick : "" 1926 }) 1927 } 1928 else if (!string.IsNullOrEmpty(settings.OnClick)) 1929 { 1930 <span class="media-list-item__sticker dw-mod" onclick="@(settings.OnClick)"> 1931 <span class="u-uppercase">@settings.Label</span> 1932 </span> 1933 } 1934 else 1935 { 1936 <span class="media-list-item__sticker media-list-item__sticker--no-link dw-mod"> 1937 <span class="u-uppercase">@settings.Label</span> 1938 </span> 1939 } 1940 } 1941 <div class="media-list-item__wrap"> 1942 <div class="media-list-item__info dw-mod"> 1943 <div class="media-list-item__header dw-mod"> 1944 @if (!string.IsNullOrEmpty(settings.Title)) 1945 { 1946 if (!string.IsNullOrEmpty(settings.Link)) 1947 { 1948 @Render(new Link 1949 { 1950 Href = settings.Link, 1951 CssClass = "media-list-item__name dw-mod", 1952 ButtonLayout = ButtonLayout.None, 1953 Title = settings.Title, 1954 OnClick = !string.IsNullOrEmpty(settings.OnClick) ? settings.OnClick : "" 1955 }) 1956 } 1957 else if (!string.IsNullOrEmpty(settings.OnClick)) 1958 { 1959 <span class="media-list-item__name dw-mod" onclick="@(settings.OnClick)">@settings.Title</span> 1960 } 1961 else 1962 { 1963 <span class="media-list-item__name media-list-item__name--no-link dw-mod">@settings.Title</span> 1964 } 1965 } 1966 1967 @if (!string.IsNullOrEmpty(settings.Status)) 1968 { 1969 <div class="media-list-item__state dw-mod">@settings.Status</div> 1970 } 1971 </div> 1972 @{ 1973 settings.InfoTable.CssClass += " media-list-item__parameters-table"; 1974 } 1975 1976 @Render(settings.InfoTable) 1977 </div> 1978 <div class="media-list-item__actions dw-mod"> 1979 <div class="media-list-item__actions-list dw-mod"> 1980 @{ 1981 var actions = settings.GetActions(); 1982 1983 foreach (ButtonBase action in actions) 1984 { 1985 action.ButtonLayout = ButtonLayout.None; 1986 action.CssClass += " media-list-item__action link"; 1987 1988 @Render(action) 1989 } 1990 } 1991 </div> 1992 1993 @if (settings.SelectButton != null && !string.IsNullOrEmpty(settings.SelectButton.Title)) 1994 { 1995 settings.SelectButton.CssClass += " u-no-margin"; 1996 1997 <div class="media-list-item__action-button"> 1998 @Render(settings.SelectButton) 1999 </div> 2000 } 2001 </div> 2002 </div> 2003 </div> 2004 } 2005 @using Dynamicweb.Rapido.Blocks.Components.General 2006 @using Dynamicweb.Rapido.Blocks.Components 2007 2008 @helper RenderTable(Table settings) 2009 { 2010 Dictionary<string, string> attributes = new Dictionary<string, string>(); 2011 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 2012 2013 var enumToClasses = new Dictionary<TableDesign, string> 2014 { 2015 { TableDesign.Clean, "table--clean" }, 2016 { TableDesign.Bordered, "table--bordered" }, 2017 { TableDesign.Striped, "table--striped" }, 2018 { TableDesign.Hover, "table--hover" }, 2019 { TableDesign.Compact, "table--compact" }, 2020 { TableDesign.Condensed, "table--condensed" }, 2021 { TableDesign.NoTopBorder, "table--no-top-border" } 2022 }; 2023 string tableDesignClass = ""; 2024 if (settings.Design != TableDesign.None) 2025 { 2026 tableDesignClass = enumToClasses[settings.Design]; 2027 } 2028 2029 if (!string.IsNullOrEmpty(settings.CssClass) || settings.Design != TableDesign.None) { attributes.Add("class", "table " + tableDesignClass + " " + settings.CssClass + " dw-mod"); } 2030 2031 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.Last().Value); 2032 2033 <table @ComponentMethods.AddAttributes(resultAttributes)> 2034 @if (settings.Header != null) 2035 { 2036 <thead> 2037 @Render(settings.Header) 2038 </thead> 2039 } 2040 <tbody> 2041 @foreach (var row in settings.Rows) 2042 { 2043 @Render(row) 2044 } 2045 </tbody> 2046 @if (settings.Footer != null) 2047 { 2048 <tfoot> 2049 @Render(settings.Footer) 2050 </tfoot> 2051 } 2052 </table> 2053 } 2054 @using Dynamicweb.Rapido.Blocks.Components.General 2055 @using Dynamicweb.Rapido.Blocks.Components 2056 2057 @helper RenderTableRow(TableRow settings) 2058 { 2059 Dictionary<string, string> attributes = new Dictionary<string, string>(); 2060 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 2061 2062 var enumToClasses = new Dictionary<TableRowDesign, string> 2063 { 2064 { TableRowDesign.NoBorder, "table__row--no-border" }, 2065 { TableRowDesign.Border, "table__row--border" }, 2066 { TableRowDesign.TopBorder, "table__row--top-line" }, 2067 { TableRowDesign.BottomBorder, "table__row--bottom-line" }, 2068 { TableRowDesign.Solid, "table__row--solid" } 2069 }; 2070 2071 string tableRowDesignClass = ""; 2072 if (settings.Design != TableRowDesign.None) 2073 { 2074 tableRowDesignClass = enumToClasses[settings.Design]; 2075 } 2076 2077 if (!string.IsNullOrEmpty(settings.CssClass) || settings.Design != TableRowDesign.None) { attributes.Add("class", "table__row " + tableRowDesignClass + " " + settings.CssClass + " dw-mod"); } 2078 2079 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.Last().Value); 2080 2081 <tr @ComponentMethods.AddAttributes(resultAttributes)> 2082 @foreach (var cell in settings.Cells) 2083 { 2084 if (settings.IsHeaderRow) 2085 { 2086 cell.IsHeader = true; 2087 } 2088 @Render(cell) 2089 } 2090 </tr> 2091 } 2092 @using Dynamicweb.Rapido.Blocks.Components.General 2093 @using Dynamicweb.Rapido.Blocks.Components 2094 @using Dynamicweb.Core 2095 2096 @helper RenderTableCell(TableCell settings) 2097 { 2098 Dictionary<string, string> attributes = new Dictionary<string, string>(); 2099 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 2100 if (settings.Colspan != 0) { attributes.Add("colspan", Converter.ToString(settings.Colspan)); } 2101 if (settings.Rowspan != 0) { attributes.Add("rowspan", Converter.ToString(settings.Rowspan)); } 2102 if (!string.IsNullOrEmpty(settings.CssClass)) { attributes.Add("class", settings.CssClass + " dw-mod"); } 2103 2104 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.Last().Value); 2105 2106 string tagName = settings.IsHeader ? "th" : "td"; 2107 2108 @("<" + tagName + " " + ComponentMethods.AddAttributes(resultAttributes) + ">") 2109 @settings.Content 2110 @("</" + tagName + ">"); 2111 } 2112 @using System.Linq 2113 @using Dynamicweb.Rapido.Blocks.Components.General 2114 2115 @* Component *@ 2116 2117 @helper RenderPagination(Dynamicweb.Rapido.Blocks.Components.General.Pagination settings) 2118 { 2119 var pageNumberQueryStringName = Dynamicweb.Rapido.Services.Pagination.GetPageNumberQueryStringName(settings); // Get the proper 'page number' query string parameter 2120 var queryParameters = Dynamicweb.Rapido.Services.Url.GetQueryParameters(pageNumberQueryStringName); // Get the NameValueCollection from the querystring 2121 2122 if (settings.NumberOfPages > 1) 2123 { 2124 string url = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + "/Default.aspx"; 2125 string ariaLabel = !string.IsNullOrWhiteSpace(settings.AriaLabel) ? settings.AriaLabel : Translate("Page navigation"); 2126 Dictionary<string, int> startAndEndPageNumber = Dynamicweb.Rapido.Services.Pagination.GetStartAndEndPageNumber(settings); 2127 2128 <div class="pager u-margin-top dw-mod @settings.CssClass" aria-label="@ariaLabel"> 2129 @if (settings.ShowPagingInfo) 2130 { 2131 <div class="pager__info dw-mod"> 2132 @Translate("Page") @settings.CurrentPageNumber @Translate("of") @settings.NumberOfPages 2133 </div> 2134 } 2135 <ul class="pager__list dw-mod"> 2136 @if (!string.IsNullOrWhiteSpace(settings.FirstPageUrl) && settings.ShowFirstAndLastControls) 2137 { 2138 @Render(new PaginationItem { Link = settings.FirstPageUrl, Icon = settings.FirstIcon }) 2139 } 2140 @if (!string.IsNullOrWhiteSpace(settings.PreviousPageUrl) && settings.ShowNextAndPrevControls) 2141 { 2142 @Render(new PaginationItem { Link = settings.PreviousPageUrl, Icon = settings.PrevIcon }) 2143 } 2144 @if (settings.GetPages().Any()) 2145 { 2146 foreach (var page in settings.GetPages()) 2147 { 2148 @Render(page) 2149 } 2150 } 2151 else 2152 { 2153 for (var page = startAndEndPageNumber["StartPage"]; page <= startAndEndPageNumber["EndPage"]; page++) 2154 { 2155 queryParameters = Dynamicweb.Rapido.Services.Url.UpdateQueryStringParameter(queryParameters, pageNumberQueryStringName, page.ToString()); 2156 @Render(new PaginationItem { Label = page.ToString(), Link = Dynamicweb.Rapido.Services.Url.BuildUri(url, queryParameters).PathAndQuery, IsActive = (settings.CurrentPageNumber == page) }); 2157 } 2158 } 2159 @if (!string.IsNullOrWhiteSpace(settings.NextPageUrl) && settings.ShowNextAndPrevControls) 2160 { 2161 @Render(new PaginationItem { Link = settings.NextPageUrl, Icon = settings.NextIcon }) 2162 } 2163 @if (!string.IsNullOrWhiteSpace(settings.LastPageUrl) && settings.ShowFirstAndLastControls) 2164 { 2165 @Render(new PaginationItem { Link = settings.LastPageUrl, Icon = settings.LastIcon }) 2166 } 2167 </ul> 2168 </div> 2169 } 2170 } 2171 2172 @helper RenderPaginationItem(PaginationItem settings) 2173 { 2174 if (settings.Icon == null) 2175 { 2176 settings.Icon = new Icon(); 2177 } 2178 2179 settings.Icon.Label = settings.Label; 2180 <li class="pager__btn dw-mod"> 2181 @if (settings.IsActive) 2182 { 2183 <span class="pager__num pager__num--current dw-mod"> 2184 @Render(settings.Icon) 2185 </span> 2186 } 2187 else 2188 { 2189 <a href="@settings.Link" class="pager__num dw-mod"> 2190 @Render(settings.Icon) 2191 </a> 2192 } 2193 </li> 2194 } 2195 2196 2197 @using Dynamicweb.Rapido.Blocks.Components.General 2198 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 2199 2200 2201 @using Dynamicweb.Rapido.Blocks.Components 2202 @using Dynamicweb.Rapido.Blocks.Components.General 2203 @using Dynamicweb.Rapido.Blocks 2204 @using System.IO 2205 2206 2207 @using Dynamicweb.Rapido.Blocks.Components.General 2208 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 2209 2210 2211 @* Component *@ 2212 2213 @helper RenderVariantMatrix(VariantMatrix settings) { 2214 if (settings != null) 2215 { 2216 int productLoopCounter = 0; 2217 int groupCount = 0; 2218 List<VariantOption> firstDimension = new List<VariantOption>(); 2219 List<VariantOption> secondDimension = new List<VariantOption>(); 2220 List<VariantOption> thirdDimension = new List<VariantOption>(); 2221 2222 foreach (VariantGroup variantGroup in settings.GetVariantGroups()) 2223 { 2224 foreach (VariantOption variantOptions in variantGroup.GetVariantOptions()) 2225 { 2226 if (groupCount == 0) { 2227 firstDimension.Add(variantOptions); 2228 } 2229 if (groupCount == 1) 2230 { 2231 secondDimension.Add(variantOptions); 2232 } 2233 if (groupCount == 2) 2234 { 2235 thirdDimension.Add(variantOptions); 2236 } 2237 } 2238 groupCount++; 2239 } 2240 2241 int rowCount = 0; 2242 int columnCount = 0; 2243 2244 <script> 2245 var variantsCollection = []; 2246 </script> 2247 2248 <table class="table table--compact js-variants-matrix dw-mod" id="VariantMatrixTable_@settings.ProductId"> 2249 @if (groupCount == 1) 2250 { 2251 <tbody> 2252 @foreach (VariantOption firstVariantOption in firstDimension) 2253 { 2254 var variantId = firstVariantOption.Id; 2255 <tr> 2256 <td class="u-bold"> 2257 @firstVariantOption.Name 2258 </td> 2259 <td> 2260 @RenderVariantMatrixQuantityField(variantId, settings, productLoopCounter, rowCount, columnCount) 2261 </td> 2262 </tr> 2263 productLoopCounter++; 2264 } 2265 2266 <tr> 2267 <td>&nbsp;</td> 2268 <td> 2269 <div class="qty-field js-total-qty-column-@columnCount dw-mod">0</div> 2270 </td> 2271 </tr> 2272 </tbody> 2273 } 2274 @if (groupCount == 2) 2275 { 2276 <thead> 2277 <tr> 2278 <td>&nbsp;</td> 2279 @foreach (VariantOption variant in secondDimension) 2280 { 2281 <td>@variant.Name</td> 2282 } 2283 </tr> 2284 </thead> 2285 <tbody> 2286 @foreach (VariantOption firstVariantOption in firstDimension) 2287 { 2288 string variantId = ""; 2289 columnCount = 0; 2290 2291 <tr> 2292 <td class="u-min-w120px">@firstVariantOption.Name</td> 2293 2294 @foreach (VariantOption secondVariantOption in secondDimension) 2295 { 2296 variantId = firstVariantOption.Id + "." + secondVariantOption.Id; 2297 <td> 2298 @RenderVariantMatrixQuantityField(variantId, settings, productLoopCounter, rowCount, columnCount) 2299 </td> 2300 2301 columnCount++; 2302 2303 productLoopCounter++; 2304 } 2305 2306 <td> 2307 <div class="qty-field js-total-qty-row-@rowCount dw-mod">0</div> 2308 </td> 2309 </tr> 2310 2311 rowCount++; 2312 } 2313 2314 @{ 2315 columnCount = 0; 2316 } 2317 2318 <tr> 2319 <td>&nbsp;</td> 2320 @foreach (VariantOption secondVariantOption in secondDimension) 2321 { 2322 <td> 2323 <div class="qty-field js-total-qty-column-@columnCount dw-mod">0</div> 2324 </td> 2325 2326 columnCount++; 2327 } 2328 <td>&nbsp;</td> 2329 </tr> 2330 </tbody> 2331 } 2332 @if (groupCount == 3) 2333 { 2334 <thead> 2335 <tr> 2336 <td>&nbsp;</td> 2337 @foreach (VariantOption thirdVariantOption in thirdDimension) 2338 { 2339 <td>@thirdVariantOption.Name</td> 2340 } 2341 </tr> 2342 </thead> 2343 <tbody> 2344 @foreach (VariantOption firstVariantOption in firstDimension) 2345 { 2346 int colspan = (thirdDimension.Count + 1); 2347 2348 <tr> 2349 <td colspan="@colspan" class="u-color-light-gray--bg u-bold">@firstVariantOption.Name</td> 2350 </tr> 2351 2352 foreach (VariantOption secondVariantOption in secondDimension) 2353 { 2354 string variantId = ""; 2355 columnCount = 0; 2356 2357 <tr> 2358 <td class="u-min-w120px">@secondVariantOption.Name</td> 2359 2360 @foreach (VariantOption thirdVariantOption in thirdDimension) 2361 { 2362 variantId = firstVariantOption.Id + "." + secondVariantOption.Id + "." + thirdVariantOption.Id; 2363 2364 <td> 2365 @RenderVariantMatrixQuantityField(variantId, settings, productLoopCounter, rowCount, columnCount) 2366 </td> 2367 2368 columnCount++; 2369 productLoopCounter++; 2370 } 2371 2372 <td> 2373 <div class="qty-field js-total-qty-row-@rowCount dw-mod">0</div> 2374 </td> 2375 </tr> 2376 rowCount++; 2377 } 2378 } 2379 2380 @{ 2381 columnCount = 0; 2382 } 2383 2384 <tr> 2385 <td>&nbsp;</td> 2386 @foreach (VariantOption thirdVariantOption in thirdDimension) 2387 { 2388 <td> 2389 <div class="qty-field js-total-qty-column-@columnCount dw-mod">0</div> 2390 </td> 2391 2392 columnCount++; 2393 } 2394 <td>&nbsp;</td> 2395 </tr> 2396 </tbody> 2397 } 2398 </table> 2399 2400 <script> 2401 document.addEventListener("DOMContentLoaded", function (event) { 2402 MatrixUpdateQuantity("@settings.ProductId"); 2403 }); 2404 2405 MatrixUpdateQuantity = function (productId) { 2406 var currentMatrix = document.getElementById("VariantMatrixTable_" + productId); 2407 var allQtyFields = currentMatrix.getElementsByClassName("js-qty"); 2408 2409 var qtyRowArr = []; 2410 var qtyColumnArr = []; 2411 2412 var totalQty = 0; 2413 2414 for (var i = 0; i < allQtyFields.length; i++) { 2415 qtyRowArr[allQtyFields[i].getAttribute("data-qty-row-group")] = 0; 2416 qtyColumnArr[allQtyFields[i].getAttribute("data-qty-column-group")] = 0; 2417 } 2418 2419 for (var i = 0; i < allQtyFields.length; i++) { 2420 qtyRowArr[allQtyFields[i].getAttribute("data-qty-row-group")] += parseFloat(allQtyFields[i].value); 2421 qtyColumnArr[allQtyFields[i].getAttribute("data-qty-column-group")] += parseFloat(allQtyFields[i].value); 2422 totalQty += parseFloat(allQtyFields[i].value); 2423 } 2424 2425 //Update row counters 2426 for (var i = 0; i < qtyRowArr.length; i++) { 2427 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-row-" + i)[0]; 2428 2429 if (qtyRowArr[i] != undefined && qtyCounter != null) { 2430 var currentCount = qtyCounter.innerHTML; 2431 qtyCounter.innerHTML = qtyRowArr[i]; 2432 2433 if (currentCount != qtyCounter.innerHTML) { 2434 qtyCounter.classList.add("qty-field--active"); 2435 } 2436 } 2437 2438 } 2439 2440 //Update column counters 2441 for (var i = 0; i < qtyColumnArr.length; i++) { 2442 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-column-" + i)[0]; 2443 2444 if (qtyColumnArr[i] != undefined && qtyCounter != null) { 2445 var currentCount = qtyCounter.innerHTML; 2446 qtyCounter.innerHTML = qtyColumnArr[i]; 2447 2448 if (currentCount != qtyCounter.innerHTML) { 2449 qtyCounter.classList.add("qty-field--active"); 2450 } 2451 } 2452 } 2453 2454 if (document.getElementById("TotalQtyCount_" + productId)) { 2455 document.getElementById("TotalQtyCount_" + productId).innerHTML = totalQty; 2456 } 2457 2458 //Clean up animations 2459 setTimeout(function () { 2460 for (var i = 0; i < qtyRowArr.length; i++) { 2461 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-row-" + i)[0]; 2462 if (qtyCounter != null) { 2463 qtyCounter.classList.remove("qty-field--active"); 2464 } 2465 } 2466 for (var i = 0; i < qtyColumnArr.length; i++) { 2467 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-column-" + i)[0]; 2468 if (qtyCounter != null) { 2469 qtyCounter.classList.remove("qty-field--active"); 2470 } 2471 } 2472 }, 1000); 2473 } 2474 </script> 2475 } 2476 } 2477 2478 @helper RenderVariantMatrixQuantityField(string variantId, VariantMatrix settings, int productLoopCounter, int rowCount, int columnCount) 2479 { 2480 string loopCount = productLoopCounter.ToString(); 2481 2482 bool combinationFound = false; 2483 double stock = 0; 2484 double quantityValue = 0; 2485 string note = ""; 2486 2487 VariantProduct variantProduct = null; 2488 2489 if (settings.GetVariantProducts().TryGetValue(variantId, out variantProduct)) 2490 { 2491 stock = variantProduct.Stock; 2492 quantityValue = variantProduct.Quantity; 2493 combinationFound = true; 2494 } 2495 2496 if (combinationFound) 2497 { 2498 <input type="hidden" name="ProductLoopCounter@(loopCount)" value="@loopCount" /> 2499 <input type="hidden" name="ProductID@(loopCount)" value="@settings.ProductId" /> 2500 <input type="hidden" name="VariantID@(loopCount)" value="@variantId" /> 2501 <input type="hidden" name="CurrentNote@(loopCount)" id="CurrentNote_@(settings.ProductId)_@variantId" value="@note" /> 2502 <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"> 2503 2504 if (stock != 0) 2505 { 2506 <small>@Translate("Stock") @stock</small> 2507 } 2508 2509 <script> 2510 var variants = '{ "ProductId" :' + '"@settings.ProductId"' + ', "VariantId": ' + '"@variantId"' +'}'; 2511 variantsCollection.push(variants); 2512 document.getElementById("Quantity_@(settings.ProductId)_@variantId").closest(".js-variants-matrix").setAttribute("data-variants-collection", "[" + variantsCollection + "]" ); 2513 </script> 2514 } 2515 else 2516 { 2517 <div class="use-btn-height" style="background-color: #a8a8a8"></div> 2518 } 2519 } 2520 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 2521 2522 @* Component *@ 2523 2524 @helper RenderAddToCart(AddToCart settings) 2525 { 2526 //set Id for quantity selector to get it's value from button 2527 if (settings.QuantitySelector != null) 2528 { 2529 if (string.IsNullOrEmpty(settings.QuantitySelector.Id)) 2530 { 2531 settings.QuantitySelector.Id = Guid.NewGuid().ToString("N"); 2532 } 2533 2534 settings.AddButton.QuantitySelectorId = settings.QuantitySelector.Id; 2535 2536 if (settings.Disabled) 2537 { 2538 settings.QuantitySelector.Disabled = true; 2539 } 2540 2541 if (string.IsNullOrEmpty(settings.QuantitySelector.Name)) 2542 { 2543 settings.QuantitySelector.Name = settings.QuantitySelector.Id; 2544 } 2545 } 2546 2547 if (settings.Disabled) 2548 { 2549 settings.AddButton.Disabled = true; 2550 } 2551 2552 settings.AddButton.CssClass += " btn--condensed"; 2553 2554 //unitsSelector 2555 if (settings.UnitSelector != null) 2556 { 2557 if (settings.Disabled) 2558 { 2559 settings.QuantitySelector.Disabled = true; 2560 } 2561 } 2562 2563 <div class="buttons-collection @settings.WrapperCssClass" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 2564 @if (settings.UnitSelector != null) 2565 { 2566 @Render(settings.UnitSelector) 2567 } 2568 @if (settings.QuantitySelector != null) 2569 { 2570 @Render(settings.QuantitySelector) 2571 } 2572 @Render(settings.AddButton) 2573 </div> 2574 } 2575 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 2576 2577 @* Component *@ 2578 2579 @helper RenderAddToCartButton(AddToCartButton settings) 2580 { 2581 if (!settings.HideTitle) 2582 { 2583 if (string.IsNullOrEmpty(settings.Title)) 2584 { 2585 if (settings.BuyForPoints) 2586 { 2587 settings.Title = Translate("Buy with points"); 2588 } 2589 else 2590 { 2591 settings.Title = Translate("Add to cart"); 2592 } 2593 } 2594 } 2595 else 2596 { 2597 settings.Title = ""; 2598 } 2599 2600 if (settings.Icon == null) 2601 { 2602 settings.Icon = new Icon(); 2603 settings.Icon.LabelPosition = Dynamicweb.Rapido.Blocks.Components.General.IconLabelPosition.After; 2604 } 2605 2606 if (string.IsNullOrEmpty(settings.Icon.Name)) 2607 { 2608 settings.Icon.Name = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue; 2609 } 2610 2611 settings.OnClick = "Cart.AddToCart(event, { " + 2612 "id: '" + settings.ProductId + "'," + 2613 (!string.IsNullOrEmpty(settings.VariantId) ? "variantId: '" + settings.VariantId + "'," : "") + 2614 (!string.IsNullOrEmpty(settings.UnitId) ? "unitId: '" + settings.UnitId + "'," : "") + 2615 (settings.BuyForPoints ? "buyForPoints: true," : "") + 2616 (!string.IsNullOrEmpty(settings.ProductInfo) ? "productInfo: " + settings.ProductInfo + "," : "") + 2617 "quantity: " + (string.IsNullOrEmpty(settings.QuantitySelectorId) ? "1" : "parseFloat(document.getElementById('" + settings.QuantitySelectorId + "').value)") + 2618 "});" + settings.OnClick; 2619 2620 @RenderButton(settings) 2621 } 2622 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 2623 2624 @* Component *@ 2625 2626 @helper RenderUnitSelector(UnitSelector settings) 2627 { 2628 if (string.IsNullOrEmpty(settings.Id)) 2629 { 2630 settings.Id = Guid.NewGuid().ToString("N"); 2631 } 2632 var disabledClass = settings.Disabled ? "disabled" : ""; 2633 2634 <input type="checkbox" id="@settings.Id" class="dropdown-trigger" /> 2635 <div class="dropdown unit-selector @settings.CssClass @disabledClass dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 2636 <label class="dropdown__header dropdown__btn dropdown__btn--unit-selector dw-mod" for="@settings.Id">@settings.SelectedOption</label> 2637 <div class="dropdown__content dw-mod"> 2638 @settings.OptionsContent 2639 </div> 2640 <label class="dropdown-trigger-off" for="@settings.Id"></label> 2641 </div> 2642 } 2643 @using System.Reflection 2644 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 2645 2646 @* Component *@ 2647 2648 @helper RenderQuantitySelector(QuantitySelector settings) 2649 { 2650 var attributes = new Dictionary<string, string>(); 2651 2652 /*base settings*/ 2653 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 2654 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 2655 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 2656 if (settings.Disabled) { attributes.Add("disabled", "true"); } 2657 if (settings.Required) { attributes.Add("required", "true"); } 2658 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 2659 /*end*/ 2660 2661 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); } 2662 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); } 2663 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); } 2664 if (settings.ReadOnly) { attributes.Add("readonly", "true"); } 2665 if (settings.Max != null) { attributes.Add("max", settings.Max.ToString()); } 2666 if (settings.Min == null) { settings.Min = 1; } 2667 attributes.Add("min", settings.Min.ToString()); 2668 if (settings.Step != null && !string.IsNullOrEmpty(settings.Step.ToString())) { attributes.Add("step", settings.Step.ToString()); } 2669 if (settings.Value == null) { settings.Value = 1; } 2670 attributes.Add("value", settings.Value.ToString()); 2671 attributes.Add("type", "number"); 2672 2673 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 2674 2675 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 2676 } 2677 @using Dynamicweb.Rapido.Blocks.Components 2678 2679 @using Dynamicweb.Frontend 2680 @using Dynamicweb.Frontend.Devices 2681 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 2682 @using Dynamicweb.Rapido.Blocks.Components.General 2683 @using System.Collections.Generic; 2684 2685 @* Component *@ 2686 2687 @helper RenderCustomerCenterList(CustomerCenterList settings) 2688 { 2689 bool isTouchDevice = Pageview.Device.ToString() == "Mobile" || Pageview.Device.ToString() == "Tablet" ? true : false; 2690 string hideActions = isTouchDevice ? "u-block" : ""; 2691 2692 <table class="table data-list dw-mod"> 2693 @if (settings.GetHeaders().Length > 0) { 2694 <thead> 2695 <tr class="u-bold"> 2696 @foreach (CustomerCenterListHeaderItem header in settings.GetHeaders()) 2697 { 2698 var attributes = new Dictionary<string, string>(); 2699 if (!string.IsNullOrEmpty(header.Id)) { attributes.Add("id", header.Id); } 2700 if (!string.IsNullOrEmpty(header.CssClass)) { attributes.Add("class", header.CssClass); } 2701 attributes.Add("align", header.Align.ToString()); 2702 attributes = attributes.Concat(header.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 2703 2704 <td @ComponentMethods.AddAttributes(attributes)>@header.Title</td> 2705 } 2706 </tr> 2707 </thead> 2708 } 2709 @foreach (CustomerCenterListItem listItem in settings.GetItems()) 2710 { 2711 int columnCount = 0; 2712 int totalColumns = listItem.GetInfoItems().Length; 2713 string rowHasActions = listItem.GetActions().Length > 0 ? "data-list__item--has-actions" : ""; 2714 listItem.Id = !string.IsNullOrEmpty(listItem.Id) ? listItem.Id : Guid.NewGuid().ToString("N"); 2715 2716 var attributes = new Dictionary<string, string>(); 2717 if (!string.IsNullOrEmpty(listItem.Title)) { attributes.Add("title", listItem.Title); }; 2718 2719 attributes = attributes.Concat(listItem.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 2720 <tbody class="data-list__item @rowHasActions @listItem.CssClass dw-mod" @ComponentMethods.AddAttributes(attributes)> 2721 <tr> 2722 @if (!string.IsNullOrEmpty(listItem.Title) || !string.IsNullOrEmpty(listItem.Description)) { 2723 string onClick = !string.IsNullOrEmpty(listItem.OnClick) ? "onclick=\"" + listItem.OnClick + "\"" : ""; 2724 2725 <td rowspan="2" @onClick class="data-list__main-item dw-mod"> 2726 @if (!string.IsNullOrEmpty(listItem.Title)) { 2727 <div class="u-bold">@listItem.Title</div> 2728 } 2729 @if (!string.IsNullOrEmpty(listItem.Description)) { 2730 <div>@listItem.Description</div> 2731 } 2732 </td> 2733 } 2734 2735 @foreach (CustomerCenterListInfoItem infoItem in listItem.GetInfoItems()) 2736 { 2737 var infoAttributes = new Dictionary<string, string>(); 2738 if (!string.IsNullOrEmpty(infoItem.Id)) { infoAttributes.Add("id", infoItem.Id); }; 2739 if (!string.IsNullOrEmpty(infoItem.OnClick)) { infoAttributes.Add("onclick", infoItem.OnClick); }; 2740 infoAttributes.Add("align", infoItem.Align.ToString()); 2741 2742 infoAttributes = infoAttributes.Concat(infoItem.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 2743 string columnClick = columnCount < (totalColumns-1) && !string.IsNullOrEmpty(listItem.OnClick) ? "onclick=\"" + listItem.OnClick + "\"" : ""; 2744 2745 <td @ComponentMethods.AddAttributes(infoAttributes) @columnClick class="data-list__info-item dw-mod"> 2746 @if (!string.IsNullOrEmpty(infoItem.Title)) { 2747 <div>@infoItem.Title</div> 2748 } 2749 @if (!string.IsNullOrEmpty(infoItem.Subtitle)) { 2750 <div><small>@infoItem.Subtitle</small></div> 2751 } 2752 </td> 2753 2754 columnCount++; 2755 } 2756 </tr> 2757 <tr> 2758 <td colspan="7" align="right" class="u-va-bottom u-no-border"> 2759 <div class="data-list__actions @hideActions dw-mod" id="ActionsMenu_@listItem.Id"> 2760 @foreach (ButtonBase action in listItem.GetActions()) 2761 { 2762 action.ButtonLayout = ButtonLayout.LinkClean; 2763 action.Icon.CssClass += " u-full-height"; 2764 action.CssClass += " data-list__action-button link"; 2765 2766 @Render(action) 2767 } 2768 </div> 2769 </td> 2770 </tr> 2771 </tbody> 2772 } 2773 </table> 2774 } 2775 2776 @* Include the Blocks for the page *@ 2777 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2778 @using Dynamicweb.Core 2779 @using System 2780 @using System.Web 2781 @using System.Collections.Generic 2782 @using Dynamicweb.Rapido.Blocks 2783 2784 @{ 2785 BlocksPage productListProductsBlocksPage = BlocksPage.GetBlockPage("ProductList"); 2786 2787 Block productsBlock = new Block 2788 { 2789 Id = "Views", 2790 SortId = 30, 2791 Template = RenderProducts() 2792 }; 2793 2794 productListProductsBlocksPage.Add("ProductList", productsBlock); 2795 } 2796 2797 @helper RenderProducts() 2798 { 2799 @*This is part of a script template *@ 2800 2801 <div id="ProductsContainer" data-template="{{listTemplate}}" class="grid product-list grid--external-bleed-x dw-mod grid--align-content-start" data-save-cookie="true" style="padding-left: .5em;"> 2802 {{#ProductsContainer}} 2803 {{> (lookup . 'template') }} 2804 {{/ProductsContainer}} 2805 </div> 2806 } 2807 2808 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2809 @using Dynamicweb.Core 2810 @using System 2811 @using System.Web 2812 @using System.Collections.Generic 2813 @using Dynamicweb.Rapido.Blocks 2814 @using Dynamicweb.Rapido.Services 2815 2816 @functions { 2817 BlocksPage listViewPage = BlocksPage.GetBlockPage("ProductList"); 2818 Dynamicweb.Frontend.ItemViewModel listViewSettings = null; 2819 } 2820 2821 @if (Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableListView")) 2822 { 2823 listViewSettings = Pageview.AreaSettings.GetItem("ProductList").GetItem("ListView"); 2824 2825 listViewPage.Add("Views", new Block 2826 { 2827 Id = "ProductItemContainer", 2828 Name = "th-list", 2829 SortId = 10 2830 }); 2831 2832 Block listViewScripts = new Block 2833 { 2834 Id = "ListViewScripts", 2835 SortId = 20, 2836 Template = ListView(), 2837 BlocksList = new List<Block> { 2838 new Block 2839 { 2840 Id = "ListViewItem", 2841 SortId = 10, 2842 Template = RenderListViewItem(), 2843 SkipRenderBlocksList = true, 2844 BlocksList = new List<Block> { 2845 new Block 2846 { 2847 Id = "ListViewItemHiddenProperties", 2848 SortId = 10, 2849 Template = RenderListViewItemHiddenProperties() 2850 }, 2851 new Block 2852 { 2853 Id = "ListViewItemLeft", 2854 SortId = 10, 2855 SkipRenderBlocksList = true, 2856 Template = RenderListViewItemLeft(), 2857 BlocksList = new List<Block> { 2858 new Block 2859 { 2860 Id = "ListViewItemImage", 2861 SortId = 10, 2862 Template = RenderListViewItemImage() 2863 }, 2864 new Block 2865 { 2866 Id = "ListViewItemStickers", 2867 SortId = 20, 2868 Template = RenderListViewItemStickers() 2869 } 2870 } 2871 }, 2872 new Block 2873 { 2874 Id = "ListViewItemRight", 2875 SortId = 20, 2876 Design = new Design 2877 { 2878 RenderType = RenderType.Column, 2879 Size = "auto", 2880 CssClass = "product-list__list-item__right" 2881 }, 2882 BlocksList = new List<Block> { 2883 new Block 2884 { 2885 Id = "ListViewItemInfoContainer", 2886 SortId = 10, 2887 Design = new Design 2888 { 2889 RenderType = RenderType.None 2890 }, 2891 BlocksList = new List<Block> { 2892 new Block { 2893 Id = "ListViewItemInfoContainerLeft", 2894 SortId = 10, 2895 Design = new Design 2896 { 2897 CssClass = "u-pull--left" 2898 }, 2899 BlocksList = new List<Block> { 2900 new Block 2901 { 2902 Id = "ListViewItemTitle", 2903 SortId = 10, 2904 Template = RenderListViewItemTitle() 2905 } 2906 } 2907 }, 2908 new Block { 2909 Id = "ListViewItemInfoContainerRight", 2910 SortId = 20, 2911 Design = new Design 2912 { 2913 CssClass = "u-pull--right" 2914 } 2915 } 2916 } 2917 }, 2918 new Block 2919 { 2920 Id = "ListViewItemDescription", 2921 SortId = 20, 2922 Template = RenderListViewItemDescription() 2923 }, 2924 new Block 2925 { 2926 Id = "ListViewItemSignIn", 2927 SortId = 40, 2928 Template = RenderListViewItemSignIn() 2929 }, 2930 new Block 2931 { 2932 Id = "ListViewItemFooter", 2933 SortId = 50, 2934 SkipRenderBlocksList = true, 2935 Template = RenderListViewItemFooter(), 2936 BlocksList = new List<Block> { 2937 new Block 2938 { 2939 Id = "ListViewItemActions", 2940 SortId = 20, 2941 Template = RenderListViewItemActions() 2942 } 2943 } 2944 } 2945 } 2946 } 2947 } 2948 } 2949 } 2950 }; 2951 listViewPage.Add("BottomSnippets", listViewScripts); 2952 2953 //number 2954 bool listViewShowNumber = listViewSettings.GetBoolean("ShowProductNumber"); 2955 2956 if (listViewShowNumber) 2957 { 2958 listViewPage.Add("ListViewItemInfoContainerLeft", new Block 2959 { 2960 Id = "ListViewItemNumber", 2961 SortId = 20, 2962 Template = RenderListViewItemNumber() 2963 }); 2964 } 2965 2966 //stock 2967 bool listViewShowStock = listViewSettings.GetBoolean("ShowStockAndShipping"); 2968 if (User.IsStockInfoAllowed() && listViewShowStock) 2969 { 2970 listViewPage.Add("ListViewItemInfoContainerLeft", new Block 2971 { 2972 Id = "ListViewItemStock", 2973 SortId = 30, 2974 Template = RenderListViewItemStock() 2975 }); 2976 } 2977 2978 //favorites 2979 bool listViewShowFavoriteButton = !listViewSettings.GetBoolean("HideFavoriteButton"); 2980 2981 if (listViewShowFavoriteButton) 2982 { 2983 listViewPage.Add("ListViewItemInfoContainerRight", new Block 2984 { 2985 Id = "ListViewItemFavorites", 2986 SortId = 10, 2987 Template = RenderListViewItemFavorites() 2988 }); 2989 } 2990 2991 //variant selector 2992 bool listViewShowCartButton = listViewSettings.GetBoolean("ShowAddToCartButton"); 2993 bool listViewShowVariantSelector = listViewSettings.GetList("Variants").SelectedValue == "selector"; 2994 if (listViewShowCartButton && listViewShowVariantSelector) 2995 { 2996 listViewPage.Add("ListViewItemRight", new Block 2997 { 2998 Id = "ListViewItemVariantSelector", 2999 SortId = 30, 3000 Template = RenderListViewItemVariantSelector() 3001 }); 3002 } 3003 3004 //static variants 3005 bool listViewShowStaticVariants = listViewSettings.GetList("Variants").SelectedValue == "static"; 3006 3007 if (listViewShowStaticVariants) 3008 { 3009 listViewPage.Add("ListViewItemRight", new Block 3010 { 3011 Id = "ListViewItemStaticVariants", 3012 SortId = 40, 3013 Template = RenderListViewItemStaticVariants() 3014 }); 3015 } 3016 3017 //download button 3018 bool listViewShowAddToDownloadButton = listViewSettings.GetBoolean("ShowAddToDownloadButton"); 3019 if (listViewShowAddToDownloadButton && Pageview.User != null) 3020 { 3021 listViewPage.Add("ListViewItemRight", new Block 3022 { 3023 Id = "ListViewItemDownloadButton", 3024 SortId = 60, 3025 Template = RenderListViewItemDownloadButton() 3026 }); 3027 } 3028 3029 //price 3030 bool listViewShowPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice"); 3031 if (listViewShowPrice && Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 3032 { 3033 listViewPage.Add("ListViewItemFooter", new Block 3034 { 3035 Id = "ListViewItemPrice", 3036 SortId = 10, 3037 Template = RenderListViewItemPrice() 3038 }); 3039 } 3040 3041 3042 } 3043 3044 @helper ListView() 3045 { 3046 <script id="ProductItemContainer" type="text/x-template"> 3047 {{#.}} 3048 <div id="Product{{id}}" class="grid__col-12 js-product dw-mod" data-template="ListViewItem" data-preloader="overlay"> 3049 {{#Product}} 3050 {{>ListViewItem}} 3051 {{/Product}} 3052 </div> 3053 {{/.}} 3054 </script> 3055 } 3056 3057 @helper RenderListViewItem() 3058 { 3059 List<Block> subBlocks = listViewPage.GetBlockListById("ListViewItem"); 3060 3061 <script id="ListViewItem" type="text/x-template"> 3062 {{#.}} 3063 <div class="grid product-list__list-item dw-mod js-product-scroll-trigger" data-params="{{googleImpression}}"> 3064 @RenderBlockList(subBlocks) 3065 </div> 3066 {{/.}} 3067 </script> 3068 3069 } 3070 3071 @helper RenderListViewItemHiddenProperties() 3072 { 3073 <input type="hidden" name="ProductLoopCounter{{id}}" value="{{id}}" /> 3074 <input type="hidden" name="ProductID{{id}}" value="{{productId}}" /> 3075 <input type="hidden" name="VariantID{{id}}" value="{{variantid}}" id="Variant_{{id}}" /> 3076 <input type="hidden" name="UnitID{{id}}" value="{{unitId}}" id="Unit_{{id}}" /> 3077 3078 <input type="hidden" name="Quantity{{id}}" value="1" id="Quantity_{{id}}" /> 3079 3080 } 3081 3082 @helper RenderListViewItemLeft() 3083 { 3084 List<Block> subBlocks = listViewPage.GetBlockListById("ListViewItemLeft"); 3085 3086 string imageZoomOnHover = listViewSettings.GetBoolean("HoverImageZoom") ? "image-hover--zoom" : ""; 3087 3088 <div class="grid__col-md-4 {{noImage}} product-list__list-item__left u-no-padding u-color-light--bg dw-mod @imageZoomOnHover"> 3089 <div class="grid__cell"> 3090 @RenderBlockList(subBlocks) 3091 </div> 3092 </div> 3093 } 3094 3095 @helper RenderListViewItemImage() 3096 { 3097 bool secondaryImage = listViewSettings.GetString("HoverAlternatineImage") != null ? listViewSettings.GetBoolean("HoverAlternatineImage") : false; 3098 3099 <a t=l1 href="{{link}}" 3100 onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" 3101 title="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}" 3102 class="u-position-relative u-block image-hover__wrapper dw-mod"> 3103 <img class="grid__cell-img grid__cell-img--centered b-lazy" src="/Files/Images/placeholder.gif" 3104 data-src="/Admin/Public/GetImage.ashx?width=300&amp;height=300&amp;crop=5&amp;Format=WebP&amp;Compression=75&amp;DoNotUpscale=true&amp;FillCanvas=true&amp;image={{image}}" 3105 @if (secondaryImage) { <text> 3106 {{#if secondaryImage}} 3107 data-secondary-image-src="/Admin/Public/GetImage.ashx?width=300&amp;height=300&amp;crop=5&amp;Format=WebP&amp;Compression=75&amp;FillCanvas=true&amp;DoNotUpscale=true&amp;image={{secondaryImage}}" 3108 {{/if}} 3109 </text> } 3110 alt="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}" /> 3111 </a> 3112 } 3113 3114 @helper RenderListViewItemStickers() 3115 { 3116 <text> 3117 {{#StickersContainers}} 3118 {{>StickersContainer}} 3119 {{/StickersContainers}} 3120 </text> 3121 } 3122 3123 @helper RenderListViewItemTitle() 3124 { 3125 <a t=l2 href="{{link}}" onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" title="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}"> 3126 <h2 class="u-no-margin">{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}</h2> 3127 </a> 3128 // <a href="{{link}}" target="_blank"><h2 class="u-no-margin">{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}</h2></a> 3129 } 3130 3131 @helper RenderListViewItemNumber() 3132 { 3133 <div class="item-number dw-mod">{{number}}</div> 3134 } 3135 3136 @helper RenderListViewItemStock() 3137 { 3138 <text>{{#if stockText}}</text> 3139 <div> 3140 <span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span> 3141 <span class="u-margin-right--lg"> {{stockText}}</span> 3142 {{deliveryText}} 3143 </div> 3144 <text>{{/if}}</text> 3145 } 3146 3147 @helper RenderListViewItemSignIn() 3148 { 3149 if (!Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName"))) 3150 { 3151 int createAccountPageId = GetPageIdByNavigationTag("CreateAccount"); 3152 string createAccountUrl = "/Default.aspx?ID=" + createAccountPageId; 3153 <div class="u-flex grid--wrap u-full-width"> 3154 <div class="u-flex u-full-width u-align-right grid--align-baseline"> 3155 <a> 3156 <label style="display: inline-block;" for="SignInModalTrigger" class="sign-in-modal-trigger-button dw-mod" onclick="setTimeout(function() { document.getElementById('LoginUsername').focus() }, 10)">@Translate("Sign in")</label> 3157 </a> 3158 <p class="m-y-0 m-x-1 dw-mod"> 3159 @Translate("or") 3160 </p> 3161 <a class="u-no-margin btn btn--primary dw-mod" title="Create account" href="@createAccountUrl">@Translate("Create account")</a> 3162 </div> 3163 <div class="u-flex u-full-width u-align-right m-y-1 dw-mod"> 3164 <p class="u-ta-left">@Translate("Megatrade produktlist desc")</p> 3165 </div> 3166 </div> 3167 } 3168 3169 } 3170 3171 @helper RenderListViewItemFavorites() 3172 { 3173 <div class="favorites u-pull--right {{hasVariants}} dw-mod" {{hasVariants}}> 3174 {{#Favorite}} 3175 {{>FavoriteTemplate}} 3176 {{/Favorite}} 3177 </div> 3178 } 3179 3180 @helper RenderListViewItemDescription() 3181 { 3182 <div class="u-margin-top u-margin-bottom"> 3183 {{{description}}} 3184 </div> 3185 } 3186 3187 @helper RenderListViewItemVariantSelector() 3188 { 3189 string pageId = GetGlobalValue("Global:Page.ID"); 3190 var ecommerceSettings = Pageview.AreaSettings.GetItem("Ecommerce"); 3191 string variantsLayout = ecommerceSettings.GetString("VariantsLayout") != null ? ecommerceSettings.GetList("VariantsLayout").SelectedValue : "buttons"; 3192 3193 <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}}"> 3194 {{#Variants}} 3195 @if (variantsLayout == "buttons") 3196 { 3197 <text>{{>VariantsTemplate}}</text> 3198 } 3199 else 3200 { 3201 <text>{{>DropdownVariantsTemplate}}</text> 3202 } 3203 {{/Variants}} 3204 </div> 3205 <small class="js-help-text help-text {{hideViewMore}} {{hideHelpText}}">@Translate("Please select variant!")</small> 3206 } 3207 3208 @helper RenderListViewItemStaticVariants() 3209 { 3210 string variantsSize = listViewSettings.GetList("StaticVariantsDisplay") != null ? listViewSettings.GetList("StaticVariantsDisplay").SelectedValue : "sm"; 3211 3212 <text> 3213 {{#Variants}} 3214 @if (variantsSize == "lg") 3215 { 3216 <text> 3217 {{>StaticVariantsLgTemplate}} 3218 </text> 3219 } 3220 else 3221 { 3222 <text> 3223 {{>StaticVariantsTemplate}} 3224 </text> 3225 } 3226 {{/Variants}} 3227 3228 {{#ifCond variantGroupsCount '>' 1}} 3229 <div class="static-variant"> 3230 @Translate("More options available") 3231 </div> 3232 {{/ifCond}} 3233 </text> 3234 } 3235 3236 @helper RenderListViewItemFooter() 3237 { 3238 List<Block> subBlocks = listViewPage.GetBlockListById("ListViewItemFooter"); 3239 3240 if (Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 3241 { 3242 <div class="grid__cell-footer"> 3243 <div class="grid__cell"> 3244 <div class="product-list__list-item__price-actions dw-mod"> 3245 @RenderBlockList(subBlocks) 3246 </div> 3247 </div> 3248 </div> 3249 } 3250 else 3251 { 3252 <button type="button" id="CartButton_{{id}}" class="u-hidden"></button> 3253 } 3254 } 3255 3256 @helper RenderListViewItemPrice() 3257 { 3258 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 3259 bool showCartButton = listViewSettings.GetBoolean("ShowAddToCartButton"); 3260 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductList").GetBoolean("ShowBothPricesWithWithoutVAT"); 3261 bool isPricesWithVATEnabled = Dynamicweb.Ecommerce.Common.Context.DisplayPricesWithVat; 3262 3263 <div class="u-margin-bottom"> 3264 @if (pointShopOnly) 3265 { 3266 <text> 3267 {{#if havePointPrice}} 3268 <div class="price price--product-list dw-mod">{{points}} @Translate("points")</div> 3269 @if (showCartButton) 3270 { 3271 <text> 3272 {{#unless canBePurchasedWithPoints}} 3273 <small class="help-text u-no-margin">@Translate("Not enough points to buy this")</small> 3274 {{/unless}} 3275 </text> 3276 } 3277 {{else}} 3278 @Translate("Not available") 3279 {{/if}} 3280 </text> 3281 3282 } 3283 else 3284 { 3285 <text> 3286 {{#if priceDouble}} 3287 <div class="price price--product-list dw-mod">@Translate("FraPris", "fra") {{price}}</div> 3288 {{else}} 3289 <div class="price price--product-list dw-mod">@Translate("PriceNotAvaliable", "Prisen kommer snart")</div> 3290 {{/if}} 3291 </text> 3292 <div class="before-price {{onSale}} dw-mod">{{discount}}</div> 3293 if (showVATPrice) 3294 { 3295 <div class="vat-price vat-price--product-list u-margin-top dw-mod"> 3296 @if (isPricesWithVATEnabled) 3297 { 3298 <span>@Translate("excl. VAT")</span><span> ({{priceWithoutVAT}})</span> 3299 } 3300 else 3301 { 3302 <span>@Translate("incl. VAT")</span><span> ({{priceWithVAT}})</span> 3303 } 3304 </div> 3305 } 3306 <text> 3307 {{#if priceRRP}} 3308 <div><small>@Translate("RRP") {{priceRRP}}</small></div> 3309 {{/if}} 3310 </text> 3311 } 3312 </div> 3313 } 3314 3315 @helper RenderListViewItemViewButton() 3316 { 3317 string viewMoreText = listViewSettings.GetString("ViewMoreText"); 3318 viewMoreText = !string.IsNullOrEmpty(viewMoreText) ? viewMoreText : "View"; 3319 3320 @Render(new Link 3321 { 3322 Href = "{{link}}", 3323 Id = "CartButton_{{id}}", 3324 Title = Translate(viewMoreText), 3325 OnClick = "{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}", 3326 ButtonLayout = ButtonLayout.Secondary, 3327 CssClass = "u-no-margin" 3328 }); 3329 } 3330 3331 @helper RenderListViewItemAddToCart() 3332 { 3333 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 3334 3335 var addToCartBtn = new AddToCart 3336 { 3337 WrapperCssClass = "buttons-collection--right", 3338 AddButton = new AddToCartButton 3339 { 3340 HideTitle = false, 3341 ProductId = "{{productId}}", 3342 VariantId = "{{variantid}}", 3343 UnitId = "{{unitId}}", 3344 ProductInfo = "{{productInfo}}", 3345 BuyForPoints = pointShopOnly, 3346 OnClick = "{{facebookPixelAction}}", 3347 ExtraAttributes = new Dictionary<string, string> 3348 { 3349 { "{{disabledBuyButton}}", "" } 3350 } 3351 } 3352 }; 3353 3354 if (!pointShopOnly) 3355 { 3356 addToCartBtn.QuantitySelector = new QuantitySelector 3357 { 3358 Id = "Quantity{{id}}" 3359 }; 3360 } 3361 3362 addToCartBtn.UnitSelector = new UnitSelector 3363 { 3364 OptionsContent = "{{#unitOptions}}{{>UnitOption}}{{/unitOptions}}", 3365 Id = "UnitOptions_{{id}}", 3366 SelectedOption = "{{unitName}}", 3367 CssClass = "{{#if hasOnlyOneUnit}}unit-selector--readonly{{/if}} {{hasUnits}}" 3368 }; 3369 3370 @Render(addToCartBtn) 3371 } 3372 3373 @helper RenderListViewItemActions() 3374 { 3375 bool showCartButton = listViewSettings.GetBoolean("ShowAddToCartButton"); 3376 bool showViewButton = listViewSettings.GetBoolean("ShowViewButton"); 3377 bool hasVariantSelector = listViewSettings.GetList("Variants") != null && listViewSettings.GetList("Variants").SelectedValue == "selector"; 3378 3379 if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 3380 { 3381 if (showCartButton) 3382 { 3383 if (!showViewButton || hasVariantSelector) 3384 { 3385 <text>{{#if hideAddToCartButton}}</text> 3386 <div>@RenderListViewItemViewButton()</div> 3387 <text>{{else}}</text> 3388 @RenderListViewItemAddToCart() 3389 <text>{{/if}}</text> 3390 } 3391 else 3392 { 3393 <div>@RenderListViewItemViewButton()</div> 3394 } 3395 } 3396 else if (showViewButton) 3397 { 3398 <div>@RenderListViewItemViewButton()</div> 3399 } 3400 } 3401 else if (showViewButton) 3402 { 3403 <div>@RenderListViewItemViewButton()</div> 3404 } 3405 } 3406 3407 @helper RenderListViewItemDownloadButton() 3408 { 3409 <div class="grid__cell-footer u-margin-top"> 3410 <div class="grid__cell"> 3411 <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}}"> 3412 <i class="fas fa-plus js-button-icon"></i> 3413 <span class="js-button-text">@Translate("Add")</span> 3414 </button> 3415 </div> 3416 </div> 3417 } 3418 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 3419 @using Dynamicweb.Core 3420 @using System 3421 @using System.Web 3422 @using System.Collections.Generic 3423 @using Dynamicweb.Rapido.Blocks 3424 @using Dynamicweb.Rapido.Blocks.Components 3425 @using Dynamicweb.Rapido.Blocks.Components.General 3426 @using Dynamicweb.Rapido.Services 3427 3428 @functions { 3429 BlocksPage gridViewPage = BlocksPage.GetBlockPage("ProductList"); 3430 Dynamicweb.Frontend.ItemViewModel gridViewSettings = null; 3431 } 3432 3433 @if (Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableGridView")) 3434 { 3435 gridViewSettings = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView"); 3436 3437 BlocksPage gridViewPage = BlocksPage.GetBlockPage("ProductList"); 3438 3439 gridViewPage.Add("Views", new Block 3440 { 3441 Id = "ProductGridItemContainer", 3442 Name = "th", 3443 SortId = 20 3444 }); 3445 3446 Block gridViewScripts = new Block 3447 { 3448 Id = "GridViewScripts", 3449 SortId = 20, 3450 Template = GridView(), 3451 BlocksList = new List<Block> { 3452 new Block 3453 { 3454 Id = "GridViewItem", 3455 SortId = 10, 3456 Template = RenderGridViewItem(), 3457 SkipRenderBlocksList = true, 3458 BlocksList = new List<Block> { 3459 new Block 3460 { 3461 Id = "GridViewItemHiddenProperties", 3462 SortId = 10, 3463 Template = RenderGridViewItemHiddenProperties() 3464 }, 3465 new Block 3466 { 3467 Id = "GridViewItemImageContainer", 3468 SortId = 20, 3469 SkipRenderBlocksList = true, 3470 Template = RenderGridViewItemImageContainer(), 3471 BlocksList = new List<Block> { 3472 new Block 3473 { 3474 Id = "GridViewItemImage", 3475 SortId = 10, 3476 Template = RenderGridViewItemImage() 3477 }, 3478 new Block 3479 { 3480 Id = "GridViewItemStickers", 3481 SortId = 20, 3482 Template = RenderGridViewItemStickers() 3483 } 3484 } 3485 }, 3486 new Block 3487 { 3488 Id = "GridViewItemInfoContainer", 3489 SortId = 30, 3490 SkipRenderBlocksList = true, 3491 Template = RenderGridViewItemInfoContainer(), 3492 BlocksList = new List<Block> { 3493 new Block 3494 { 3495 Id = "GridViewItemTitle", 3496 SortId = 10, 3497 Template = RenderGridViewItemTitle() 3498 } 3499 } 3500 }, 3501 new Block 3502 { 3503 Id = "GridViewItemFooter", 3504 SortId = 40, 3505 SkipRenderBlocksList = true, 3506 Template = RenderGridViewItemFooter(), 3507 BlocksList = new List<Block> { 3508 new Block 3509 { 3510 Id = "GridViewItemActions", 3511 SortId = 10, 3512 Template = RenderGridViewItemActions() 3513 } 3514 } 3515 } 3516 } 3517 } 3518 } 3519 }; 3520 gridViewPage.Add("BottomSnippets", gridViewScripts); 3521 3522 //favorites 3523 bool gridViewShowFavoriteButton = !gridViewSettings.GetBoolean("HideFavoriteButton"); 3524 3525 if (gridViewShowFavoriteButton) 3526 { 3527 gridViewPage.Add("GridViewItemImageContainer", new Block 3528 { 3529 Id = "GridViewItemFavorites", 3530 SortId = 30, 3531 Template = RenderGridViewItemFavorites() 3532 }); 3533 } 3534 3535 //number 3536 bool gridViewShowNumber = gridViewSettings.GetBoolean("ShowProductNumber"); 3537 3538 if (gridViewShowNumber) 3539 { 3540 gridViewPage.Add("GridViewItemInfoContainer", new Block 3541 { 3542 Id = "GridViewItemNumber", 3543 SortId = 20, 3544 Template = RenderGridViewItemNumber() 3545 }); 3546 } 3547 3548 //price 3549 bool gridViewShowPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice"); 3550 if (gridViewShowPrice && Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 3551 { 3552 gridViewPage.Add("GridViewItemInfoContainer", new Block 3553 { 3554 Id = "GridViewItemPrice", 3555 SortId = 30, 3556 Template = RenderGridViewItemPrice() 3557 }); 3558 } 3559 3560 //stock 3561 bool gridViewShowStock = gridViewSettings.GetBoolean("ShowStockAndShipping"); 3562 3563 if (User.IsStockInfoAllowed() && gridViewShowStock) 3564 { 3565 gridViewPage.Add("GridViewItemFooter", new Block 3566 { 3567 Id = "GridViewItemStockAndDelivery", 3568 SortId = 20, 3569 Template = RenderGridViewItemStockAndDelivery() 3570 }); 3571 } 3572 3573 //static variants 3574 bool gridViewShowStaticVariants = gridViewSettings.GetBoolean("ShowStaticVariants"); 3575 3576 if (gridViewShowStaticVariants) 3577 { 3578 gridViewPage.Add("GridViewItemFooter", new Block 3579 { 3580 Id = "GridViewItemStaticVariants", 3581 SortId = 30, 3582 Template = RenderGridViewItemStaticVariants() 3583 }); 3584 } 3585 3586 //download button 3587 bool gridViewShowAddToDownloadButton = gridViewSettings.GetBoolean("ShowAddToDownloadButton"); 3588 3589 if (gridViewShowAddToDownloadButton && Pageview.User != null) 3590 { 3591 gridViewPage.Add("GridViewItemFooter", new Block 3592 { 3593 Id = "GridViewItemDownloadButton", 3594 SortId = 40, 3595 Template = RenderGridViewItemDownloadButton() 3596 }); 3597 } 3598 } 3599 3600 @helper GridView() 3601 { 3602 int columnsCount = gridViewSettings.GetList("Columns") != null ? Converter.ToInt32(gridViewSettings.GetList("Columns").SelectedValue) : 3; 3603 string imageZoomOnHover = gridViewSettings.GetBoolean("HoverImageZoom") ? "image-hover--zoom" : ""; 3604 3605 <script id="ProductGridItemContainer" type="text/x-template"> 3606 {{#.}} 3607 <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"> 3608 {{#Product}} 3609 {{>GridViewItem}} 3610 {{/Product}} 3611 </div> 3612 {{/.}} 3613 </script> 3614 } 3615 3616 @helper RenderGridViewItem() 3617 { 3618 List<Block> subBlocks = gridViewPage.GetBlockListById("GridViewItem"); 3619 3620 <script id="GridViewItem" type="text/x-template"> 3621 {{#.}} 3622 <div class="grid__col--auto js-product-scroll-trigger u-no-padding u-full-height" data-params="{{googleImpression}}"> 3623 @RenderBlockList(subBlocks) 3624 </div> 3625 {{/.}} 3626 </script> 3627 } 3628 3629 @helper RenderGridViewItemHiddenProperties() 3630 { 3631 <input type="hidden" name="ProductLoopCounter{{id}}" value="{{id}}" /> 3632 <input type="hidden" name="ProductID{{id}}" value="{{productId}}" /> 3633 <input type="hidden" name="VariantID{{id}}" value="{{variantid}}" id="Variant_{{id}}" /> 3634 <input type="hidden" name="UnitID{{id}}" value="{{unitId}}" id="Unit_{{id}}" /> 3635 <input type="hidden" name="Quantity{{id}}" value="1" id="Quantity_{{id}}" /> 3636 } 3637 3638 @helper RenderGridViewItemImageContainer() 3639 { 3640 List<Block> subBlocks = gridViewPage.GetBlockListById("GridViewItemImageContainer"); 3641 3642 <div class="grid__cell product-list__grid-item__image dw-mod {{noImage}}"> 3643 @RenderBlockList(subBlocks) 3644 </div> 3645 } 3646 3647 @helper RenderGridViewItemImage() 3648 { 3649 bool secondaryImage = gridViewSettings.GetString("HoverAlternatineImage") != null ? gridViewSettings.GetBoolean("HoverAlternatineImage") : false; 3650 3651 <a t=g1 href="{{link}}" 3652 onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" 3653 title="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}" 3654 class="u-block u-position-relative image-hover__wrapper dw-mod"> 3655 <img class="grid__cell-img grid__cell-img--centered u-padding b-lazy" src="/Files/Images/placeholder.gif" 3656 data-src="/Admin/Public/GetImage.ashx?width=300&amp;height=300&amp;crop=5&amp;Format=WebP&amp;Compression=75&amp;FillCanvas=true&amp;DoNotUpscale=true&amp;image={{image}}" 3657 @if (secondaryImage) { <text> 3658 {{#if secondaryImage}} 3659 data-secondary-image-src="/Admin/Public/GetImage.ashx?width=300&amp;height=300&amp;crop=5&amp;Format=WebP&amp;Compression=75&amp;FillCanvas=true&amp;DoNotUpscale=true&amp;image={{secondaryImage}}" 3660 {{/if}} 3661 </text> } 3662 alt="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}" /> 3663 </a> 3664 } 3665 3666 @helper RenderGridViewItemStickers() 3667 { 3668 <text> 3669 {{#StickersContainers}} 3670 {{>StickersContainer}} 3671 {{/StickersContainers}} 3672 </text> 3673 } 3674 3675 @helper RenderGridViewItemFavorites() 3676 { 3677 <div class="favorites favorites--for-grid-view u-pull--right {{hasVariants}} dw-mod" {{hasVariants}}> 3678 {{#Favorite}} 3679 {{>FavoriteTemplate}} 3680 {{/Favorite}} 3681 </div> 3682 } 3683 3684 @helper RenderGridViewItemInfoContainer() 3685 { 3686 List<Block> subBlocks = gridViewPage.GetBlockListById("GridViewItemInfoContainer"); 3687 3688 <div class="grid__cell product-list__grid-item__price-info dw-mod"> 3689 @RenderBlockList(subBlocks) 3690 </div> 3691 } 3692 3693 @helper RenderGridViewItemTitle() 3694 { 3695 <a t=g2 href="{{link}}" class="u-color-inherit" onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" title="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}"> 3696 <h6 class="u-condensed-text u-bold">{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}</h6> 3697 </a> 3698 } 3699 3700 @helper RenderGridViewItemNumber() 3701 { 3702 <div class="item-number dw-mod">{{number}}</div> 3703 } 3704 3705 @helper RenderGridViewItemPrice() 3706 { 3707 int columnsCount = gridViewSettings.GetList("Columns") != null ? Converter.ToInt32(gridViewSettings.GetList("Columns").SelectedValue) : 4; 3708 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 3709 bool showCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToCartButton"); 3710 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductList").GetBoolean("ShowBothPricesWithWithoutVAT"); 3711 bool isPricesWithVATEnabled = Dynamicweb.Ecommerce.Common.Context.DisplayPricesWithVat; 3712 3713 if (pointShopOnly) 3714 { 3715 <text> 3716 {{#if havePointPrice}} 3717 <div class="price price--product-list dw-mod">{{points}} @Translate("points")</div> 3718 @if (showCartButton) 3719 { 3720 <text> 3721 {{#unless canBePurchasedWithPoints}} 3722 <small class="help-text u-no-margin">@Translate("Not enough points to buy this")</small> 3723 {{/unless}} 3724 </text> 3725 } 3726 {{else}} 3727 @Translate("Not available") 3728 {{/if}} 3729 </text> 3730 3731 } 3732 else 3733 { 3734 <text> 3735 {{#if priceDouble}} 3736 <div class="price price--product-list dw-mod">@Translate("FraPris", "fra") {{price}}</div> 3737 {{else}} 3738 <div class="price price--product-list dw-mod">@Translate("PriceNotAvaliable", "Prisen kommer snart")</div> 3739 {{/if}} 3740 </text> 3741 <div class="before-price {{onSale}} dw-mod">{{discount}}</div> 3742 if (showVATPrice) 3743 { 3744 <div class="vat-price vat-price--product-list u-margin-top dw-mod"> 3745 @if (columnsCount <= 4) 3746 { 3747 if (isPricesWithVATEnabled) 3748 { 3749 <span>@Translate("excl. VAT")</span><span> ({{priceWithoutVAT}})</span> 3750 } 3751 else 3752 { 3753 <span>@Translate("incl. VAT")</span><span> ({{priceWithVAT}})</span> 3754 } 3755 } 3756 else 3757 { 3758 if (isPricesWithVATEnabled) 3759 { 3760 <div>@Translate("excl. VAT")</div><div>({{priceWithoutVAT}})</div> 3761 } 3762 else 3763 { 3764 <div>@Translate("incl. VAT")</div><div>({{priceWithVAT}})</div> 3765 } 3766 } 3767 </div> 3768 } 3769 <text> 3770 {{#if priceRRP}} 3771 <div><small>@Translate("RRP") {{priceRRP}}</small></div> 3772 {{/if}} 3773 </text> 3774 } 3775 } 3776 3777 @helper RenderGridViewItemFooter() 3778 { 3779 List<Block> subBlocks = gridViewPage.GetBlockListById("GridViewItemFooter"); 3780 bool showStaticVariants = gridViewSettings.GetBoolean("ShowStaticVariants"); 3781 3782 <div class="product-list__grid-item__footer dw-mod"> 3783 @RenderBlockList(subBlocks) 3784 </div> 3785 } 3786 3787 @helper RenderGridViewItemViewButton() 3788 { 3789 string viewMoreText = gridViewSettings.GetString("ViewMoreText"); 3790 viewMoreText = !string.IsNullOrEmpty(viewMoreText) ? viewMoreText : "View"; 3791 3792 @Render(new Link 3793 { 3794 Href = "{{link}}", 3795 Id = "CartButton_{{id}}", 3796 Title = Translate(viewMoreText), 3797 OnClick = "{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}", 3798 ButtonLayout = ButtonLayout.Secondary, 3799 CssClass = "u-no-margin" 3800 }); 3801 } 3802 3803 @helper RenderGridViewItemAddToCart() 3804 { 3805 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 3806 string wrapperClass = "buttons-collection--center"; 3807 int columnsCount = gridViewSettings.GetList("Columns") != null ? Converter.ToInt32(gridViewSettings.GetList("Columns").SelectedValue) : 4; 3808 bool hideButtonText = columnsCount >= 4 || Pageview.Device.ToString() == "Mobile" || Pageview.Device.ToString() == "Tablet"; 3809 3810 if (pointShopOnly && columnsCount <= 4) 3811 { 3812 hideButtonText = false; 3813 } 3814 3815 var addToCartBtn = new AddToCart 3816 { 3817 WrapperCssClass = wrapperClass, 3818 AddButton = new AddToCartButton 3819 { 3820 HideTitle = hideButtonText, 3821 ProductId = "{{productId}}", 3822 VariantId = "{{variantid}}", 3823 UnitId = "{{unitId}}", 3824 ProductInfo = "{{productInfo}}", 3825 BuyForPoints = pointShopOnly, 3826 OnClick = "{{facebookPixelAction}}", 3827 ExtraAttributes = new Dictionary<string, string> 3828 { 3829 { "{{disabledBuyButton}}", "" } 3830 } 3831 } 3832 }; 3833 3834 if (!pointShopOnly) 3835 { 3836 addToCartBtn.QuantitySelector = new QuantitySelector 3837 { 3838 Id = "Quantity{{id}}" 3839 }; 3840 } 3841 3842 @Render(addToCartBtn) 3843 } 3844 3845 @helper RenderGridViewItemActions() 3846 { 3847 bool showCartButton = gridViewSettings.GetBoolean("ShowAddToCartButton"); 3848 bool showViewButton = gridViewSettings.GetBoolean("ShowViewButton"); 3849 3850 if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 3851 { 3852 if (showCartButton) 3853 { 3854 if (!showViewButton) 3855 { 3856 <text>{{#if hideAddToCartButton}}</text> 3857 <div>@RenderGridViewItemViewButton()</div> 3858 <text>{{else}}</text> 3859 @RenderGridViewItemAddToCart() 3860 <text>{{/if}}</text> 3861 } 3862 else 3863 { 3864 @RenderGridViewItemAddToCart() 3865 } 3866 } 3867 else if (showViewButton) 3868 { 3869 <div>@RenderGridViewItemViewButton()</div> 3870 } 3871 } 3872 else if (showViewButton) 3873 { 3874 <div>@RenderGridViewItemViewButton()</div> 3875 } 3876 } 3877 3878 @helper RenderGridViewItemStockAndDelivery() 3879 { 3880 <text>{{#if stockText}}</text> 3881 <div class="u-margin-top"> 3882 <div><span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span> {{stockText}}</div> 3883 <div> 3884 {{#if deliveryText}} 3885 {{deliveryText}} 3886 {{else}} 3887 - 3888 {{/if}} 3889 </div> 3890 </div> 3891 <text>{{/if}}</text> 3892 } 3893 3894 @helper RenderGridViewItemStaticVariants() 3895 { 3896 string variantsSize = gridViewSettings.GetList("StaticVariantsDisplay") != null ? gridViewSettings.GetList("StaticVariantsDisplay").SelectedValue : "sm"; 3897 3898 <text> 3899 {{#Variants}} 3900 @if (variantsSize == "lg") 3901 { 3902 <text> 3903 {{>StaticVariantsLgTemplate}} 3904 </text> 3905 } 3906 else 3907 { 3908 <text> 3909 {{>StaticVariantsTemplate}} 3910 </text> 3911 } 3912 {{/Variants}} 3913 3914 {{#ifCond variantGroupsCount '>' 1}} 3915 <div class="static-variant"> 3916 @Translate("More options available") 3917 </div> 3918 {{/ifCond}} 3919 3920 {{#ifCond variantGroupsCount '==' 0}} 3921 <div class="static-variant"></div> 3922 {{/ifCond}} 3923 </text> 3924 } 3925 3926 @helper RenderGridViewItemDownloadButton() 3927 { 3928 <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}}"> 3929 @Render(new Icon { Prefix = "fas", Name = "fa-plus", CssClass = "js-button-icon" }) 3930 <span class="js-button-text">@Translate("Add")</span> 3931 </button> 3932 } 3933 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 3934 @using Dynamicweb.Core 3935 @using System 3936 @using System.Web 3937 @using System.Collections.Generic 3938 @using Dynamicweb.Rapido.Blocks 3939 @using Dynamicweb.Rapido.Blocks.Components 3940 @using Dynamicweb.Rapido.Blocks.Components.General 3941 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 3942 @using Dynamicweb.Rapido.Services 3943 3944 @functions { 3945 BlocksPage detailsViewPage = BlocksPage.GetBlockPage("ProductList"); 3946 Dynamicweb.Frontend.ItemViewModel detailsViewSettings = null; 3947 3948 /* this function need because in details view we have specipfic situation 3949 * when price need to be placed between unit selector and quantity selector 3950 */ 3951 3952 UnitSelector getUnitsSelector() 3953 { 3954 return new UnitSelector 3955 { 3956 OptionsContent = "{{#unitOptions}}{{>UnitOption}}{{/unitOptions}}", 3957 Id = "UnitOptions_{{id}}", 3958 SelectedOption = "{{unitName}}", 3959 CssClass = "product-list__details-units-selector {{#if hasOnlyOneUnit}}unit-selector--readonly{{/if}} {{hasUnits}}" 3960 }; 3961 } 3962 } 3963 3964 @if (Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableDetailsView")) 3965 { 3966 detailsViewSettings = Pageview.AreaSettings.GetItem("ProductList").GetItem("DetailsView"); 3967 3968 detailsViewPage.Add("Views", new Block 3969 { 3970 Id = "ProductDetailsItemContainer", 3971 Name = "list", 3972 SortId = 30 3973 }); 3974 3975 Block detailsViewScripts = new Block 3976 { 3977 Id = "DetailsViewScripts", 3978 SortId = 30, 3979 Template = DetailsView(), 3980 BlocksList = new List<Block> 3981 { 3982 new Block 3983 { 3984 Id = "DetailsViewItem", 3985 SortId = 10, 3986 Template = RenderDetailsViewItem(), 3987 SkipRenderBlocksList = true, 3988 BlocksList = new List<Block> { 3989 new Block 3990 { 3991 Id = "DetailsViewItemHiddenProperties", 3992 SortId = 10, 3993 Template = RenderDetailsViewItemHiddenProperties() 3994 }, 3995 new Block 3996 { 3997 Id = "DetailsViewItemLeft", 3998 SortId = 10, 3999 Design = new Design 4000 { 4001 CssClass = "product-list__details-item__left product__list--width grid__cell dw-mod" 4002 }, 4003 BlocksList = new List<Block> { 4004 new Block 4005 { 4006 Id = "DetailsViewItemInfoContainer", 4007 SortId = 20, 4008 Design = new Design 4009 { 4010 CssClass = "product-list__details-info dw-mod" 4011 }, 4012 BlocksList = new List<Block> { 4013 new Block 4014 { 4015 Id = "DetailsViewItemTitle", 4016 SortId = 10, 4017 Template = RenderDetailsViewItemTitle() 4018 }, 4019 new Block 4020 { 4021 Id = "DetailsViewItemStickers", 4022 SortId = 50, 4023 Template = RenderDetailsViewItemStickers() 4024 } 4025 } 4026 } 4027 } 4028 }, 4029 new Block 4030 { 4031 Id = "DetailsViewItemRight", 4032 SortId = 20, 4033 Design = new Design 4034 { 4035 CssClass = "product-list__details-item__right grid__cell dw-mod" 4036 }, 4037 BlocksList = new List<Block> { 4038 new Block { 4039 Id = "DetailsViewItemRightBottom", 4040 SortId = 20, 4041 Design = new Design 4042 { 4043 CssClass = "u-flex product-list__details-right-bottom-section dw-mod" 4044 }, 4045 BlocksList = new List<Block> { 4046 new Block 4047 { 4048 Id = "DetailsViewItemActions", 4049 SortId = 30, 4050 Template = RenderDetailsViewItemActions() 4051 } 4052 } 4053 } 4054 } 4055 } 4056 } 4057 } 4058 } 4059 }; 4060 detailsViewPage.Add("BottomSnippets", detailsViewScripts); 4061 4062 //image 4063 bool detailsViewShowImage = detailsViewSettings.GetBoolean("ShowImage"); 4064 4065 if (detailsViewShowImage) 4066 { 4067 detailsViewPage.Add("DetailsViewItemLeft", new Block 4068 { 4069 Id = "DetailsViewItemImage", 4070 SortId = 10, 4071 Template = RenderDetailsViewItemImage() 4072 }); 4073 } 4074 4075 //number 4076 bool detailsViewShowNumber = detailsViewSettings.GetBoolean("ShowProductNumber"); 4077 4078 if (detailsViewShowNumber) 4079 { 4080 detailsViewPage.Add("DetailsViewItemInfoContainer", new Block 4081 { 4082 Id = "ProductDetailsItemNumber", 4083 SortId = 30, 4084 Template = RenderDetailsViewItemNumber() 4085 }); 4086 } 4087 4088 //static variants 4089 bool detailsViewShowStaticVariants = detailsViewSettings.GetBoolean("ShowStaticVariants"); 4090 4091 if (detailsViewShowStaticVariants) 4092 { 4093 detailsViewPage.Add("DetailsViewItemInfoContainer", new Block 4094 { 4095 Id = "DetailsViewItemStaticVariants", 4096 SortId = 30, 4097 Template = RenderDetailsViewItemStaticVariants() 4098 }); 4099 } 4100 4101 //stock 4102 bool detailsViewShowStock = detailsViewSettings.GetBoolean("ShowStockAndShipping"); 4103 4104 if (User.IsStockInfoAllowed() && detailsViewShowStock) 4105 { 4106 detailsViewPage.Add("DetailsViewItemInfoContainer", new Block 4107 { 4108 Id = "DetailsViewItemStock", 4109 SortId = 40, 4110 Template = RenderDetailsViewItemStock() 4111 }); 4112 } 4113 4114 //price 4115 bool detailsViewShowPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice"); 4116 if (detailsViewShowPrice && Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 4117 { 4118 var separatedUnitSelector = getUnitsSelector(); 4119 separatedUnitSelector.CssClass += " product-list__details-units-selector--separated"; 4120 4121 detailsViewPage.Add("DetailsViewItemRightBottom", new Block 4122 { 4123 Id = "DetailsViewUnitSelector", 4124 SortId = 10, 4125 Component = separatedUnitSelector 4126 }); 4127 4128 detailsViewPage.Add("DetailsViewItemRightBottom", new Block 4129 { 4130 Id = "ProductDetailsItemPrice", 4131 SortId = 20, 4132 Template = RenderDetailsViewItemPrice() 4133 }); 4134 } 4135 4136 //favorites 4137 bool detailsViewShowFavoriteButton = !detailsViewSettings.GetBoolean("HideFavoriteButton"); 4138 4139 if (detailsViewShowFavoriteButton && Pageview.User != null) 4140 { 4141 detailsViewPage.Add("DetailsViewItemRightBottom", new Block 4142 { 4143 Id = "DetailsViewItemFavorites", 4144 SortId = 40, 4145 Template = RenderDetailsViewItemFavorites() 4146 }); 4147 } 4148 4149 //download button 4150 bool detailsViewShowAddToDownloadButton = detailsViewSettings.GetBoolean("ShowAddToDownloadButton"); 4151 4152 if (detailsViewShowAddToDownloadButton && Pageview.User != null) 4153 { 4154 detailsViewPage.Add("DetailsViewItemRightBottom", new Block 4155 { 4156 Id = "DetailsViewItemDownloadButton", 4157 SortId = 20, 4158 Template = RenderDetailsViewItemDownloadButton() 4159 }); 4160 } 4161 } 4162 4163 @helper DetailsView() 4164 { 4165 <script id="ProductDetailsItemContainer" type="text/x-template"> 4166 {{#.}} 4167 <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}}"> 4168 {{#Product}} 4169 {{>DetailsViewItem}} 4170 {{/Product}} 4171 </div> 4172 {{/.}} 4173 </script> 4174 } 4175 4176 @helper RenderDetailsViewItem() 4177 { 4178 List<Block> subBlocks = detailsViewPage.GetBlockListById("DetailsViewItem"); 4179 4180 <script id="DetailsViewItem" type="text/x-template"> 4181 {{#.}} 4182 <div class="product-list__details-item grid__col-12 dw-mod js-product-scroll-trigger" data-params="{{googleImpression}}"> 4183 @RenderBlockList(subBlocks) 4184 </div> 4185 {{/.}} 4186 </script> 4187 } 4188 4189 @helper RenderDetailsViewItemHiddenProperties() 4190 { 4191 <input type="hidden" name="ProductLoopCounter{{id}}" value="{{id}}" /> 4192 <input type="hidden" name="ProductID{{id}}" value="{{productId}}" /> 4193 <input type="hidden" name="VariantID{{id}}" value="{{variantid}}" id="Variant_{{id}}" /> 4194 <input type="hidden" name="UnitID{{id}}" value="{{unitId}}" id="Unit_{{id}}" /> 4195 <input type="hidden" name="Quantity{{id}}" value="1" id="Quantity_{{id}}" /> 4196 } 4197 4198 @helper RenderDetailsViewItemImage() 4199 { 4200 <div class="lightbox"> 4201 <a t=d1 href="{{link}}" onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" title="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}"> 4202 <img class="lightbox__image {{noImage}}" src="/Admin/Public/GetImage.ashx?width=220&amp;height=220&amp;crop=5&amp;Compression=75&amp;image={{image}}" alt="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}" /> 4203 <div class="u-margin-right {{noImage}}"> 4204 <img class="b-lazy product-list__details-image" src="/Files/Images/placeholder.gif" 4205 data-src="/Admin/Public/GetImage.ashx?width=75&amp;height=55&amp;crop=5&Format=WebP&FillCanvas=true&amp;Compression=75&amp;image={{image}}" 4206 alt="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}" /> 4207 </div> 4208 </a> 4209 </div> 4210 } 4211 4212 @helper RenderDetailsViewItemTitle() 4213 { 4214 <a t=d2 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"> 4215 <h6 class="u-no-margin u-bold">{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}</h6> 4216 </a> 4217 } 4218 4219 @helper RenderDetailsViewItemNumber() 4220 { 4221 <div class="item-number item-number--compressed dw-mod"> 4222 <div class="item-number dw-mod">{{number}}</div> 4223 </div> 4224 } 4225 4226 @helper RenderDetailsViewItemStaticVariants() 4227 { 4228 string variantsSize = detailsViewSettings.GetList("StaticVariantsDisplay") != null ? detailsViewSettings.GetList("StaticVariantsDisplay").SelectedValue : "sm"; 4229 4230 <text> 4231 <span> 4232 {{#Variants}} 4233 @if (variantsSize == "lg") 4234 { 4235 <text> 4236 {{>StaticVariantsLgTemplate}} 4237 </text> 4238 } 4239 else 4240 { 4241 <text> 4242 {{>StaticVariantsTemplate}} 4243 </text> 4244 } 4245 {{/Variants}} 4246 </span> 4247 4248 {{#ifCond variantGroupsCount '>' 1}} 4249 <div class="static-variant"> 4250 @Translate("More options available") 4251 </div> 4252 {{/ifCond}} 4253 </text> 4254 } 4255 4256 @helper RenderDetailsViewItemStock() 4257 { 4258 <text>{{#if stockText}}</text> 4259 <div class="item-number item-number--compressed dw-mod"> 4260 <span> 4261 <span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span> 4262 <span class="u-margin-right--lg"> {{stockText}}</span> 4263 {{deliveryText}} 4264 </span> 4265 </div> 4266 <text>{{/if}}</text> 4267 } 4268 4269 @helper RenderDetailsViewItemStickers() 4270 { 4271 <div class="grid__cell-footer stickers-container stickers-container--row u-margin-top dw-mod"> 4272 {{#StickersContainers}} 4273 {{#Stickers}} 4274 {{>MiniSticker}} 4275 {{/Stickers}} 4276 {{/StickersContainers}} 4277 </div> 4278 } 4279 4280 @helper RenderDetailsViewItemPrice() 4281 { 4282 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 4283 bool showCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("DetailsView").GetBoolean("ShowAddToCartButton"); 4284 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductList").GetBoolean("ShowBothPricesWithWithoutVAT"); 4285 bool isPricesWithVATEnabled = Dynamicweb.Ecommerce.Common.Context.DisplayPricesWithVat; 4286 4287 <div class="product-list__details-price"> 4288 @if (pointShopOnly) 4289 { 4290 <text> 4291 {{#if havePointPrice}} 4292 <div class="price price--product-list price--micro dw-mod">{{points}} @Translate("points")</div> 4293 @if (showCartButton) 4294 { 4295 <text> 4296 {{#unless canBePurchasedWithPoints}} 4297 <small class="help-text u-no-margin">@Translate("Not enough points to buy this")</small> 4298 {{/unless}} 4299 </text> 4300 } 4301 {{else}} 4302 @Translate("Not available") 4303 {{/if}} 4304 </text> 4305 4306 } 4307 else 4308 { 4309 <text> 4310 {{#if priceDouble}} 4311 <div class="price price--product-list price--micro dw-mod">@Translate("FraPris", "fra") {{price}}</div> 4312 {{else}} 4313 <div class="price price--product-list price--micro dw-mod">@Translate("PriceNotAvaliable", "Prisen kommer snart")</div> 4314 {{/if}} 4315 </text> 4316 4317 <div class="before-price {{onSale}} before-price--micro dw-mod">{{discount}}</div> 4318 if (showVATPrice) 4319 { 4320 <div class="vat-price vat-price--product-list u-margin-top dw-mod"> 4321 @if (isPricesWithVATEnabled) 4322 { 4323 <span>@Translate("excl. VAT")</span><span> ({{priceWithoutVAT}})</span> 4324 } 4325 else 4326 { 4327 <span>@Translate("incl. VAT")</span><span> ({{priceWithVAT}})</span> 4328 } 4329 </div> 4330 } 4331 <text> 4332 {{#if priceRRP}} 4333 <div><small>@Translate("RRP") {{priceRRP}}</small></div> 4334 {{/if}} 4335 </text> 4336 } 4337 </div> 4338 } 4339 4340 @helper RenderDetailsViewItemFavorites() 4341 { 4342 <div class="favorites product-list__details-favorites {{hasVariants}} dw-mod" {{hasVariants}}> 4343 {{#Favorite}} 4344 {{>FavoriteTemplate}} 4345 {{/Favorite}} 4346 </div> 4347 } 4348 4349 @helper RenderDetailsViewItemViewButton() 4350 { 4351 string viewMoreText = detailsViewSettings.GetString("ViewMoreText"); 4352 viewMoreText = !string.IsNullOrEmpty(viewMoreText) ? viewMoreText : "View"; 4353 4354 <div class="product-list__details-actions"> 4355 @Render(new Link 4356 { 4357 Href = "{{link}}", 4358 Id = "CartButton_{{id}}", 4359 Title = Translate(viewMoreText), 4360 OnClick = "{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}", 4361 ButtonLayout = ButtonLayout.Secondary, 4362 CssClass = "u-no-margin" 4363 }) 4364 </div> 4365 } 4366 4367 @helper RenderDetailsViewItemSignInButton() 4368 { 4369 if (!Dynamicweb.Core.Converter.ToBoolean(GetGlobalValue("Global:Extranet.UserName"))) 4370 { 4371 int createAccountPageId = GetPageIdByNavigationTag("CreateAccount"); 4372 string createAccountUrl = "/Default.aspx?ID=" + createAccountPageId; 4373 4374 <div class="u-flex grid--wrap u-full-width"> 4375 <div class="u-flex u-full-width u-align-right grid--align-baseline"> 4376 <a> 4377 <label style="display: inline-block;" for="SignInModalTrigger" class="sign-in-modal-trigger-button dw-mod" onclick="setTimeout(function() { document.getElementById('LoginUsername').focus() }, 10)">@Translate("Megatrade produktlist sign in")</label> 4378 </a> 4379 <p class="m-y-0 m-x-1 dw-mod">@Translate("or")</p> 4380 <a class="u-no-margin btn btn--primary dw-mod" title="Create account" href="@createAccountUrl">@Translate("Megatrade produktlist create account")</a> 4381 </div> 4382 <div class="u-flex u-full-width u-align-right m-y-1 dw-mod"> 4383 <p class="u-ta-left">@Translate("Megatrade produktlist desc")</p> 4384 </div> 4385 </div> 4386 } 4387 } 4388 4389 @helper RenderDetailsViewItemAddToCart() 4390 { 4391 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 4392 bool showPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice"); 4393 4394 var addToCartBtn = new AddToCart 4395 { 4396 AddButton = new AddToCartButton 4397 { 4398 HideTitle = true, 4399 ProductId = "{{productId}}", 4400 VariantId = "{{variantid}}", 4401 UnitId = "{{unitId}}", 4402 ProductInfo = "{{productInfo}}", 4403 BuyForPoints = pointShopOnly, 4404 OnClick = "{{facebookPixelAction}}", 4405 ExtraAttributes = new Dictionary<string, string> 4406 { 4407 { "{{disabledBuyButton}}", "" } 4408 } 4409 } 4410 }; 4411 4412 if (!pointShopOnly) 4413 { 4414 addToCartBtn.QuantitySelector = new QuantitySelector 4415 { 4416 Id = "Quantity{{id}}" 4417 }; 4418 } 4419 4420 if (!showPrice) 4421 { 4422 addToCartBtn.UnitSelector = getUnitsSelector(); 4423 } 4424 4425 <div class="product-list__details-actions"> 4426 @Render(addToCartBtn) 4427 </div> 4428 } 4429 4430 @helper RenderDetailsViewItemActions() 4431 { 4432 bool showCartButton = detailsViewSettings.GetBoolean("ShowAddToCartButton"); 4433 bool showViewButton = detailsViewSettings.GetBoolean("ShowViewButton"); 4434 4435 if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 4436 { 4437 if (showCartButton) 4438 { 4439 if (!showViewButton) 4440 { 4441 @RenderDetailsViewItemAddToCart() 4442 } 4443 else 4444 { 4445 <text>{{#if hideAddToCartButton}}</text> 4446 @RenderDetailsViewItemViewButton() 4447 <text>{{else}}</text> 4448 @RenderDetailsViewItemAddToCart() 4449 <text>{{/if}}</text> 4450 } 4451 } 4452 else if (showViewButton) 4453 { 4454 @RenderDetailsViewItemViewButton() 4455 } 4456 } 4457 else 4458 { 4459 @RenderDetailsViewItemSignInButton() 4460 } 4461 } 4462 4463 @helper RenderDetailsViewItemDownloadButton() 4464 { 4465 <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}}"> 4466 @Render(new Icon { Prefix = "fas", Name = "fa-plus", CssClass = "js-button-icon" }) 4467 </button> 4468 } 4469 4470 4471 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 4472 @using Dynamicweb.Core 4473 @using System 4474 @using System.Web 4475 @using System.Collections.Generic 4476 @using Dynamicweb.Rapido.Blocks 4477 @using Dynamicweb.Rapido.Blocks.Components 4478 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 4479 @using Dynamicweb.Rapido.Blocks.Components.General 4480 @using Dynamicweb.Rapido.Services 4481 @using System.Web.Helpers 4482 4483 @functions { 4484 BlocksPage tilesView = BlocksPage.GetBlockPage("ProductList"); 4485 Dynamicweb.Frontend.ItemViewModel tilesViewSettings = null; 4486 } 4487 4488 @{ 4489 var settings = Pageview.AreaSettings.GetItem("ProductList"); 4490 var enableTiles = settings.GetBoolean("EnableTilesView"); 4491 4492 if ( enableTiles ) { 4493 tilesViewSettings = settings.GetItem("TilesView"); 4494 BlocksPage tilesView = BlocksPage.GetBlockPage("ProductList"); 4495 4496 Block tiles = new Block { 4497 Id = "ProductTilesViewContainer", 4498 Name ="grip-horizontal", 4499 SortId = 50, 4500 }; 4501 4502 tilesView.Add("Views", tiles); 4503 4504 4505 Block tilesViewScripts = new Block { 4506 Id = "TilesViewScripts", 4507 SortId = 20, 4508 Template = TilesView(), 4509 BlocksList = new List<Block> { 4510 new Block { 4511 Id = "TilesViewItem", 4512 SortId = 10, 4513 Template = RenderTilesViewItem(), 4514 SkipRenderBlocksList = true, 4515 BlocksList = new List<Block> { 4516 new Block { 4517 Id = "TilesViewItemHiddenProperties", 4518 SortId = 10, 4519 Template = RenderTilesViewItemHiddenProperties() 4520 }, 4521 new Block { 4522 Id = "TilesViewItemImageContainer", 4523 SortId = 20, 4524 Template = RenderTilesViewItemImageContainer(), 4525 SkipRenderBlocksList = true, 4526 BlocksList = new List<Block> { 4527 new Block { 4528 Id = "TilesViewItemImage", 4529 SortId = 10, 4530 Template = RenderTilesViewItemImage(), 4531 }, 4532 new Block 4533 { 4534 Id = "TilesViewItemStickers", 4535 SortId = 20, 4536 Template = RenderTilesViewItemStickers() 4537 }, 4538 new Block { 4539 Id = "TilesViewItemFavorites", 4540 SortId = 20, 4541 Template = RenderTilesViewItemFavorites() 4542 }, 4543 }, 4544 }, 4545 new Block { 4546 Id = "TilesViewItemContentContainer", 4547 SortId = 30, 4548 Template = RenderTilesViewItemContentContainer(), 4549 SkipRenderBlocksList = true, 4550 BlocksList = new List<Block> { 4551 new Block { 4552 Id = "TilesViewItemContent", 4553 SortId = 30, 4554 Template = RenderTilesViewItemContent(), 4555 SkipRenderBlocksList = true, 4556 BlocksList = new List<Block> { 4557 new Block { 4558 Id = "TilesViewItemHeader", 4559 SortId = 10, 4560 Template = RenderTilesViewItemHeader(), 4561 SkipRenderBlocksList = true, 4562 BlocksList = new List<Block> { 4563 new Block { 4564 Id = "TilesViewItemTitle", 4565 SortId = 10, 4566 Template = RenderTilesViewItemTitle(), 4567 }, 4568 new Block { 4569 Id = "TilesViewItemNumber", 4570 SortId = 20, 4571 Template = RenderTilesViewItemNumber(), 4572 }, 4573 } 4574 }, 4575 new Block { 4576 Id = "TilesViewItemPrice", 4577 SortId = 30, 4578 Template = RenderTilesViewItemPrice(), 4579 }, 4580 } 4581 }, 4582 new Block { 4583 Id = "TilesViewItemFooter", 4584 SortId = 40, 4585 Template = RenderTilesViewItemFooter(), 4586 SkipRenderBlocksList = true 4587 } 4588 } 4589 } 4590 } 4591 } 4592 } 4593 }; 4594 tilesView.Add("BottomSnippets", tilesViewScripts); 4595 4596 if (tilesViewSettings.GetBoolean("ShowStaticVariants")) { 4597 Block staticVariants = new Block { 4598 Id = "TilesViewItemVariants", 4599 SortId = 10, 4600 Template = RenderTilesViewItemVariants(), 4601 }; 4602 tilesView.Add("TilesViewItemContentContainer", staticVariants); 4603 } 4604 4605 //download button 4606 bool tilesViewShowAddToDownloadButton = tilesViewSettings.GetBoolean("ShowAddToDownloadButton"); 4607 4608 if (tilesViewShowAddToDownloadButton && Pageview.User != null) 4609 { 4610 tilesView.Add("TilesViewItemFooter", new Block 4611 { 4612 Id = "TilesViewItemDownloadButton", 4613 SortId = 20, 4614 Template = RenderTilesViewItemDownloadButton() 4615 }); 4616 } 4617 } 4618 } 4619 4620 @helper TilesView() { 4621 int columnsCount = tilesViewSettings.GetList("Columns") != null ? Converter.ToInt32(tilesViewSettings.GetList("Columns").SelectedValue) : 3; 4622 4623 <script id="ProductTilesViewContainer" type="text/x-template"> 4624 {{#.}} 4625 <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"> 4626 {{#Product}} 4627 {{>TilesViewItem}} 4628 {{/Product}} 4629 </div> 4630 {{/.}} 4631 </script> 4632 } 4633 4634 4635 @helper RenderTilesViewItem() { 4636 List<Block> subBlocks = tilesView.GetBlockListById("TilesViewItem"); 4637 bool showShadow = tilesViewSettings.GetBoolean("HoverShowShadow"); 4638 string addShadow = ( showShadow != null && showShadow ) ? "product-list--shadow" : ""; 4639 4640 <script id="TilesViewItem" type="text/x-template"> 4641 {{#.}} 4642 <div class="grid__col--auto js-product-scroll-trigger u-no-padding u-full-height @addShadow" data-params="{{googleImpression}}"> 4643 @RenderBlockList(subBlocks) 4644 </div> 4645 {{/.}} 4646 </script> 4647 } 4648 4649 4650 @helper RenderTilesViewItemContentContainer() { 4651 List<Block> subBlocks = tilesView.GetBlockListById("TilesViewItemContentContainer"); 4652 4653 <text> 4654 {{#.}} 4655 <div class="grid__cell product-list__tiles-item__price-info u-padding--lg u-flex u-flex--column dw-mod"> 4656 @RenderBlockList(subBlocks) 4657 </div> 4658 {{/.}} 4659 </text> 4660 } 4661 4662 4663 4664 @helper RenderTilesViewItemVariants() { 4665 string variantsSize = tilesViewSettings.GetList("StaticVariantsDisplay") != null ? tilesViewSettings.GetList("StaticVariantsDisplay").SelectedValue : "sm"; 4666 4667 <text> 4668 {{#Variants}} 4669 @if ( variantsSize == "lg" ) { 4670 <text> 4671 {{>StaticVariantsLgTemplate}} 4672 </text> 4673 } else { 4674 <text> 4675 {{>StaticVariantsTemplate}} 4676 </text> 4677 } 4678 {{/Variants}} 4679 4680 {{#ifCond variantGroupsCount '==' 0}} 4681 <div class="static-variant"></div> 4682 {{/ifCond}} 4683 </text> 4684 } 4685 4686 @helper RenderTilesViewItemFavorites() { 4687 bool showFavoriteButton = !tilesViewSettings.GetBoolean("HideFavoriteButton"); 4688 4689 if ( !showFavoriteButton ) { 4690 return; 4691 } 4692 4693 <div class="favorites favorites--for-tiles-view u-pull--right {{hasVariants}} dw-mod" {{hasVariants}}> 4694 {{#Favorite}} 4695 {{>FavoriteTemplate}} 4696 {{/Favorite}} 4697 </div> 4698 } 4699 4700 @helper RenderTilesViewItemImageContainer() { 4701 List<Block> subBlocks = tilesView.GetBlockListById("TilesViewItemImageContainer"); 4702 4703 <div class="grid__cell dw-mod {{noImage}}"> 4704 @RenderBlockList(subBlocks) 4705 </div> 4706 } 4707 4708 @helper RenderTilesViewItemStickers() 4709 { 4710 <text> 4711 {{#StickersContainers}} 4712 {{>StickersContainer}} 4713 {{/StickersContainers}} 4714 </text> 4715 } 4716 4717 @helper RenderTilesViewItemImage() { 4718 string imageZoomOnHover = tilesViewSettings.GetBoolean("HoverImageZoom") ? "image-hover--zoom" : ""; 4719 bool secondaryImage = tilesViewSettings.GetString("HoverAlternativeImage") != null ? tilesViewSettings.GetBoolean("HoverAlternativeImage") : false; 4720 4721 <a t=t1 href="{{link}}" 4722 onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" 4723 title="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}" 4724 class="product-list__tiles-item__image u-block u-position-relative image-hover__wrapper @imageZoomOnHover dw-mod"> 4725 <img class="grid__cell-img u-middle-horizontal b-lazy" src="/Files/Images/placeholder.gif" 4726 data-src="/Admin/Public/GetImage.ashx?width=450&amp;height=450&amp;crop=5&amp;Format=WebP&amp;Compression=75&amp;FillCanvas=true&amp;DoNotUpscale=true&amp;image={{image}}" 4727 @if (secondaryImage) { 4728 <text> 4729 {{#if secondaryImage}} 4730 data-secondary-image-src="/Admin/Public/GetImage.ashx?width=450&amp;height=450&amp;crop=5&amp;Format=WebP&amp;Compression=75&amp;FillCanvas=true&amp;DoNotUpscale=true&amp;image={{secondaryImage}}" 4731 {{/if}} 4732 </text> 4733 } 4734 alt="{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}" /> 4735 </a> 4736 } 4737 4738 4739 @helper RenderTilesViewItemHiddenProperties() { 4740 <input type="hidden" name="ProductLoopCounter{{id}}" value="{{id}}" /> 4741 <input type="hidden" name="ProductID{{id}}" value="{{productId}}" /> 4742 <input type="hidden" name="VariantID{{id}}" value="{{variantid}}" id="Variant_{{id}}" /> 4743 <input type="hidden" name="UnitID{{id}}" value="{{unitId}}" id="Unit_{{id}}" /> 4744 <input type="hidden" name="Quantity{{id}}" value="1" id="Quantity_{{id}}" /> 4745 } 4746 4747 4748 @helper RenderTilesViewItemContent() { 4749 List<Block> subBlocks = tilesView.GetBlockListById("TilesViewItemContent"); 4750 4751 <div class="grid__cell dw-mod"> 4752 @RenderBlockList(subBlocks) 4753 </div> 4754 } 4755 4756 4757 @helper RenderTilesViewItemHeader() { 4758 List<Block> subBlocks = tilesView.GetBlockListById("TilesViewItemHeader"); 4759 4760 <div class="u-flex u-justify-content--between u-margin-bottom dw-mod"> 4761 @RenderBlockList(subBlocks) 4762 </div> 4763 } 4764 4765 4766 @helper RenderTilesViewItemTitle() { 4767 <a t=t2 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}}"> 4768 <h6 class="u-bold u-capitalize">{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}</h6> 4769 </a> 4770 } 4771 4772 4773 @helper RenderTilesViewItemNumber() { 4774 bool showNumber = tilesViewSettings.GetBoolean("ShowProductNumber"); 4775 4776 if ( !showNumber ) { 4777 return; 4778 } 4779 4780 <div class="item-number u-margin-left--lg dw-mod">{{number}}</div> 4781 } 4782 4783 4784 @helper RenderTilesViewItemPrice() { 4785 <div class="price__wrapper u-flex u-flex--wrap u-justify-content--between"> 4786 <div class="price__inner u-margin-right"> 4787 <div class="price price--product-list u-bold dw-mod">{{price}}</div> 4788 <div class="before-price {{onSale}} dw-mod">{{discount}}</div> 4789 </div> 4790 4791 {{#if priceRRP}} 4792 <div class="price--rrp dw-mod">{{priceRRP}}</div> 4793 {{/if}} 4794 </div> 4795 } 4796 4797 4798 @helper RenderTilesViewItemFooter() { 4799 List<Block> subBlocks = tilesView.GetBlockListById("TilesViewItemFooter"); 4800 4801 <div class="product-list__tiles-item__footer u-margin-top--auto dw-mod"> 4802 @RenderBlockList(subBlocks) 4803 </div> 4804 } 4805 4806 @helper RenderTilesViewItemDownloadButton() { 4807 <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}}"> 4808 @Render(new Icon { Prefix = "fas", Name = "fa-plus", CssClass = "js-button-icon" }) 4809 <span class="js-button-text">@Translate("Add")</span> 4810 </button> 4811 } 4812 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 4813 @using Dynamicweb.Core 4814 @using System 4815 @using System.Web 4816 @using System.Collections.Generic 4817 @using Dynamicweb.Rapido.Blocks 4818 4819 @{ 4820 BlocksPage productListCustomSeoBlocksPage = BlocksPage.GetBlockPage("ProductList"); 4821 4822 Block productListCustomSeo = new Block 4823 { 4824 Id = "CustomSeo", 4825 SortId = 30, 4826 Template = RenderProductListCustomSeo() 4827 }; 4828 productListCustomSeoBlocksPage.Add("PageContainer", productListCustomSeo); 4829 } 4830 4831 @helper RenderProductListCustomSeo() 4832 { 4833 @*This is part of a script template *@ 4834 4835 string listId = HttpContext.Current.Request.QueryString.Get("ListID"); 4836 bool isFavoriteList = !string.IsNullOrEmpty(listId); 4837 string smallDeviceCss = Pageview.Device.ToString() == "Mobile" ? "u-no-padding" : ""; 4838 4839 4840 <article class="grid__col-12 u-margin-bottom"> 4841 {{#if groupCustomSeoText}} 4842 {{{groupCustomSeoText}}} 4843 {{/if}} 4844 </article> 4845 } 4846 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 4847 @using Dynamicweb.Core 4848 @using System 4849 @using System.Web 4850 @using System.Collections.Generic 4851 @using Dynamicweb.Rapido.Blocks 4852 4853 @{ 4854 BlocksPage productListPromotionsBlocksPage = BlocksPage.GetBlockPage("ProductList"); 4855 4856 Block productListPromotions = new Block 4857 { 4858 Id = "Promotions", 4859 SortId = 10, 4860 Template = RenderProductListPromotions() 4861 }; 4862 productListPromotionsBlocksPage.Add("PageContainer", productListPromotions); 4863 } 4864 4865 @helper RenderProductListPromotions() 4866 { 4867 @*This is part of a script template *@ 4868 4869 string listId = HttpContext.Current.Request.QueryString.Get("ListID"); 4870 bool isFavoriteList = !string.IsNullOrEmpty(listId); 4871 string smallDeviceCss = Pageview.Device.ToString() == "Mobile" ? "u-no-padding" : ""; 4872 4873 if (!isFavoriteList) 4874 { 4875 switch (Pageview.AreaSettings.GetItem("ProductList").GetList("PromotionBlockDesign").SelectedValue) 4876 { 4877 case "OnlyText": 4878 <article class="grid__col-12 u-margin-bottom @smallDeviceCss"> 4879 <h1>{{groupName}}</h1> 4880 {{{groupDescription}}} 4881 @*{{#ifCond groupPromotionLink "!==" ""}} 4882 <div> 4883 <a href="{{groupPromotionLink}}" class="btn btn--primary">{{groupPromotionLinkText}}</a> 4884 </div> 4885 {{/ifCond}}*@ 4886 </article> 4887 break; 4888 case "TextAndImage": 4889 <article class="grid__col-12 u-margin-bottom @smallDeviceCss"> 4890 <div class="grid grid--bleed"> 4891 <div class="grid__col-md-6"> 4892 <h1>{{groupName}}</h1> 4893 {{{groupDescription}}} 4894 {{#ifCond groupPromotionLink "!==" ""}} 4895 <div> 4896 <a href="{{groupPromotionLink}}" class="btn btn--primary">{{groupPromotionLinkText}}</a> 4897 </div> 4898 {{/ifCond}} 4899 </div> 4900 {{#ifCond groupPromotionImage "!==" ""}} 4901 <div class="grid__col-md-6"> 4902 <img src="/Admin/Public/GetImage.ashx?width=600&crop=5&Compression=75&DoNotUpscale=true&image={{groupPromotionImage}}" alt="{{groupName}}" class="background-image__cover" /> 4903 </div> 4904 {{/ifCond}} 4905 </div> 4906 </article> 4907 break; 4908 case "Banner": 4909 <text> 4910 {{#ifCond groupPromotionImage "!==" ""}} 4911 <article class="grid__col-12 u-margin-bottom @smallDeviceCss"> 4912 <div class="u-color-light grid center-container center-container--with-background-image grid__col--bg" style="background-image:url('{{groupPromotionImage}}');"> 4913 <div class="grid__col-12 u-middle"> 4914 <div class="grid__cell"> 4915 {{{groupDescription}}} 4916 {{#ifCond groupPromotionLink "!==" ""}} 4917 <div> 4918 <a href="{{groupPromotionLink}}" class="btn btn--primary">{{groupPromotionLinkText}}</a> 4919 </div> 4920 {{/ifCond}} 4921 </div> 4922 </div> 4923 </div> 4924 </article> 4925 {{/ifCond}} 4926 </text> 4927 break; 4928 } 4929 } 4930 } 4931 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 4932 @using Dynamicweb.Core 4933 @using System 4934 @using System.Web 4935 @using System.Collections.Generic 4936 @using Dynamicweb.Rapido.Blocks 4937 4938 @{ 4939 BlocksPage productListMenuBlocksPage = BlocksPage.GetBlockPage("ProductList"); 4940 4941 if (Pageview.Device.ToString() != "Mobile" && Pageview.Device.ToString() != "Tablet" && 4942 Converter.ToString(Pageview.Page.PropertyItem["LeftMenu"]) == "True" && 4943 Pageview.Page.NavigationSettings != null && 4944 Pageview.Page.NavigationSettings.UseEcomGroups) { 4945 4946 Block productListMenuBlock = new Block 4947 { 4948 Id = "Menu", 4949 SortId = 20, 4950 Template = RenderProductListMenu() 4951 }; 4952 4953 productListMenuBlocksPage.Add("Navigation", productListMenuBlock); 4954 } 4955 } 4956 4957 @helper RenderProductListMenu() 4958 { 4959 var navigationMarkup = RenderNavigation(new 4960 { 4961 id = "leftnav", 4962 cssclass = "dwnavigation", 4963 startLevel = 1, 4964 endlevel = 5, 4965 template = "LeftNavigation.xslt", 4966 mode = "ecom" 4967 }); 4968 4969 <h2 class="u-margin-bottom">@Translate("Product categories")</h2> 4970 4971 <div class="u-padding-bottom--lg"> 4972 @navigationMarkup 4973 </div> 4974 } 4975 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 4976 @using System.Collections.Generic 4977 @using Dynamicweb 4978 @using Dynamicweb.Frontend 4979 @using Dynamicweb.Frontend.Devices 4980 @using Dynamicweb.Extensibility 4981 @using Dynamicweb.Content 4982 @using Dynamicweb.Security 4983 @using Dynamicweb.Core 4984 @using System.IO 4985 @using Dynamicweb.Rapido.Blocks 4986 @using System.Net 4987 @using System 4988 @using System.Web 4989 @using Dynamicweb.Frontend.Navigation 4990 @using Dynamicweb.Rapido.Blocks.Components.General 4991 @using Dynamicweb.Rapido.Blocks.Components 4992 @using megatrade.website.CustomModules.Extensions 4993 4994 @functions 4995 { 4996 string GetTopLevelGroupName(Dynamicweb.Ecommerce.Products.Group group) 4997 { 4998 if (group == null) return string.Empty; 4999 5000 var topLevelGroupName = group.Name; 5001 5002 if (group.ParentGroups.Any()) 5003 { 5004 topLevelGroupName = GetTopLevelGroupName(group.ParentGroups.FirstOrDefault()); 5005 } 5006 5007 return topLevelGroupName; 5008 } 5009 } 5010 5011 @{ 5012 BlocksPage productListFacetsBlocksPage = BlocksPage.GetBlockPage("ProductList"); 5013 string facetsBlockViewMode = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductList").GetString("FacetsViewMode")) ? Pageview.AreaSettings.GetItem("ProductList").GetString("FacetsViewMode").ToLower() : "left"; 5014 5015 if (facetsBlockViewMode == "left" && Pageview.Device.ToString() != "Mobile" && Pageview.Device.ToString() != "Tablet") 5016 { 5017 Block facetsBlock = new Block 5018 { 5019 Id = "Facets", 5020 SortId = 30, 5021 Template = RenderProductListFacets() 5022 }; 5023 productListFacetsBlocksPage.Add("Navigation", facetsBlock); 5024 } 5025 5026 if (facetsBlockViewMode == "top" || Pageview.Device.ToString() == "Mobile" || Pageview.Device.ToString() == "Tablet") 5027 { 5028 Block facetsBlock = new Block 5029 { 5030 Id = "Facets", 5031 SortId = 10, 5032 Template = RenderProductListTopFacets() 5033 }; 5034 productListFacetsBlocksPage.Add("ProductList", facetsBlock); 5035 } 5036 5037 Block facetSelections = new Block 5038 { 5039 Id = "FacetSelections", 5040 SortId = 20, 5041 Template = RenderFacetSelections() 5042 }; 5043 productListFacetsBlocksPage.Add("ProductList", facetSelections); 5044 5045 Block checkboxFacetTemplate = new Block 5046 { 5047 Id = "CheckboxFacet", 5048 SortId = 30, 5049 Template = RenderCheckboxFacets() 5050 }; 5051 productListFacetsBlocksPage.Add("BottomSnippets", checkboxFacetTemplate); 5052 5053 Block rangeFacetTemplate = new Block 5054 { 5055 Id = "RangeFacet", 5056 SortId = 40, 5057 Template = RenderRangeFacets() 5058 }; 5059 productListFacetsBlocksPage.Add("BottomSnippets", rangeFacetTemplate); 5060 5061 Block tagsFacetTemplate = new Block 5062 { 5063 Id = "TagsFacet", 5064 SortId = 50, 5065 Template = RenderTagsFacets() 5066 }; 5067 productListFacetsBlocksPage.Add("BottomSnippets", tagsFacetTemplate); 5068 5069 Block colorsFacetTemplate = new Block 5070 { 5071 Id = "ColorFacet", 5072 SortId = 60, 5073 Template = RenderColorFacets() 5074 }; 5075 productListFacetsBlocksPage.Add("BottomSnippets", colorsFacetTemplate); 5076 5077 Block selectedFilter = new Block 5078 { 5079 Id = "SelectedFilter", 5080 SortId = 70, 5081 Template = RenderSelectedFilter() 5082 }; 5083 productListFacetsBlocksPage.Add("BottomSnippets", selectedFilter); 5084 5085 Block customRangeSelectedFilter = new Block 5086 { 5087 Id = "CustomRangeSelectedFilter", 5088 SortId = 80, 5089 Template = RenderCustomRangeSelectedFilter() 5090 }; 5091 productListFacetsBlocksPage.Add("BottomSnippets", customRangeSelectedFilter); 5092 5093 Block selectedColorFilter = new Block 5094 { 5095 Id = "SelectedColorFilter", 5096 SortId = 90, 5097 Template = RenderSelectedColorFilter() 5098 }; 5099 productListFacetsBlocksPage.Add("BottomSnippets", selectedColorFilter); 5100 5101 Block resetFilters = new Block 5102 { 5103 Id = "ResetFilters", 5104 SortId = 100, 5105 Template = RenderResetFilters() 5106 }; 5107 5108 productListFacetsBlocksPage.Add("BottomSnippets", resetFilters); 5109 5110 Block rangeScript = new Block 5111 { 5112 Id = "RangeScript", 5113 SortId = 110, 5114 Template = RenderRangeScript() 5115 }; 5116 5117 productListFacetsBlocksPage.Add("BottomSnippets", rangeScript); 5118 5119 Block leftSidedNavigation = new Block 5120 { 5121 Id = "LeftSidedNavigation", 5122 SortId = 1, 5123 Template = LeftSidedNavigation() 5124 }; 5125 5126 productListFacetsBlocksPage.Add("Navigation", leftSidedNavigation); 5127 } 5128 5129 @helper LeftSidedNavigation() 5130 { 5131 var enableLeftSidedNavigation = Converter.ToString(Pageview.Page.PropertyItem["ShowLeftNavigation"]); 5132 5133 if (enableLeftSidedNavigation == "True") 5134 { 5135 var pageId = Pageview.ID; 5136 string languageId = Pageview.Area.EcomLanguageId; 5137 5138 var topLevelGroups = Dynamicweb.Ecommerce.Services.ProductGroups.GetToplevelGroups(languageId); 5139 5140 var groupId = System.Web.HttpContext.Current.Request.QueryString.Get("groupid"); 5141 5142 if (string.IsNullOrEmpty(groupId)) 5143 { 5144 return; 5145 } 5146 5147 var renderedGroup = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(groupId); 5148 5149 if (renderedGroup == null) 5150 { 5151 return; 5152 } 5153 5154 var parentGroup = renderedGroup.ParentGroups.FirstOrDefault(); 5155 var topLevelGroupName = renderedGroup.GetTopLevelGroupName(); 5156 5157 var groupList = new Dynamicweb.Ecommerce.Products.GroupCollection(); 5158 5159 if (parentGroup != null) 5160 { 5161 if (renderedGroup.HasChildGroups) 5162 { 5163 groupList = parentGroup.GetSubgroups(languageId); 5164 } 5165 else 5166 { 5167 var parentParentGroup = parentGroup.ParentGroups.FirstOrDefault(); 5168 if (parentParentGroup != null) 5169 { 5170 groupList = parentParentGroup.GetSubgroups(languageId); 5171 } 5172 } 5173 var friendlyParentUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl($"Default.aspx?ID={pageId}&GroupID={parentGroup.Id}"); 5174 @*Link to parent group*@ 5175 @*<a href="@friendlyParentUrl">@Translate("Back to", "Back to") @parentGroup.Name</a>*@ 5176 } 5177 else 5178 { 5179 groupList = renderedGroup.GetSubgroups(languageId); 5180 } 5181 5182 <h2>@topLevelGroupName</h2> 5183 <div class="u-full-width leftsided-navigation-productlist-container"> 5184 <ul class="dw-mod"> 5185 @foreach (var group in groupList) 5186 { 5187 5188 if (group.NavigationShowInMenu) 5189 { 5190 bool activeParent = false; 5191 5192 if (group.Subgroups.Any(x => x == renderedGroup)) 5193 { 5194 activeParent = true; 5195 } 5196 var isActive = group == renderedGroup; 5197 var friendlyGroupUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl($"Default.aspx?ID={pageId}&GroupID={group.Id}"); 5198 5199 //Niveau 2 i navigationen 5200 <li class="menu-left__item dw-mod @(activeParent ? "menu-left-item-container" : "")"> 5201 <a class="first-menu-link-left menu-left__link dw-mod @(isActive ? "active" : "not-active") u-no-padding-left u-no-padding-bottom" href="@friendlyGroupUrl">@group.Name</a> 5202 5203 @if ((isActive && group.HasChildGroups) || (parentGroup == group && group.HasChildGroups)) 5204 { 5205 <ul class="menu-left dw-mod"> 5206 @foreach (var subgroup in group.GetSubgroups()) 5207 { 5208 if (subgroup.NavigationShowInMenu) 5209 { 5210 isActive = subgroup == renderedGroup; 5211 var subgroupFriendlyUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl($"Default.aspx?ID={pageId}&GroupID={subgroup.Id}"); 5212 <li class="menu-left__item dw-mod"> 5213 <a class="menu-left__link submenu-left-link dw-mod @(isActive ? "active" : "not-active-sublink") u-no-padding-y" data-is-active="@(isActive ? "active" : "false")" id="@subgroup.Id" href="@subgroupFriendlyUrl"><small>- @subgroup.Name</small></a> 5214 </li> 5215 } 5216 } 5217 </ul> 5218 } 5219 </li> 5220 } 5221 } 5222 </ul> 5223 </div> 5224 5225 } 5226 5227 5228 @*var navigationSettings = new NavigationSettings(); 5229 navigationSettings.StartLevel = 2; 5230 navigationSettings.StopLevel = 5; 5231 navigationSettings.ExpandMode = ExpandMode.All; 5232 5233 if (!string.IsNullOrEmpty(GetString("NavigationRoot"))) 5234 { 5235 int rootPageId = Convert.ToInt32(GetString("NavigationRoot").Substring(GetString("NavigationRoot").LastIndexOf('=') + 1)); 5236 navigationSettings.RootPageId = rootPageId; 5237 } 5238 5239 5240 5241 <div class="u-full-width leftsided-navigation-productlist-container"> 5242 @Navigation.RenderNavigation("Navigation/LeftNavigationExpandable.cshtml", navigationSettings) 5243 </div>*@ 5244 5245 } 5246 5247 5248 @helper RenderFacetSelections() 5249 { 5250 @*This is part of a script template *@ 5251 <text> 5252 <div class="buttons-collection u-margin-bottom" id="selectedFacets" style="padding-left: .5em;"> 5253 {{#if FacetSelections}} 5254 {{#FacetSelections}} 5255 {{>(lookup . 'template')}} 5256 {{/FacetSelections}} 5257 {{/if}} 5258 {{>CustomRangeSelectedFilter}} 5259 </div> 5260 </text> 5261 } 5262 5263 @helper RenderProductListFacets() 5264 { 5265 var facetSettings = Pageview.AreaSettings.GetItem("ProductList").GetItem("Facets"); 5266 string boxDisplay = facetSettings.GetList("BoxDisplay") != null ? facetSettings.GetList("BoxDisplay").SelectedValue : "scroll"; 5267 5268 string facetMoreClass = (boxDisplay == "view-more" ? "facets-container__list--more" : ""); 5269 5270 @*This is part of a script template *@ 5271 5272 <input type="checkbox" id="CheckFacetGroups" class="js-remember-state u-hidden" data-expand="CheckFacetGroups" /> 5273 <div class="facets-container facets-container--left expandable--collapsed dw-mod" data-trigger="CheckFacetGroups"> 5274 {{#FacetGroups}} 5275 5276 {{#ifCond type "===" "Range"}} 5277 {{#ifCond minValue "!==" maxValue}} 5278 <input type="checkbox" id="OptionsGroup_{{name}}" class="expand-trigger js-remember-state" {{defaultState}} /> 5279 5280 <div class="expand-container facets-container__box dw-mod js-filter"> 5281 <label class="expand-container__btn facets-container__header dw-mod" for="OptionsGroup_{{name}}">{{name}}</label> 5282 <div class="expand-container__content js-facet-container dw-mod" data-input="OptionsGroup_{{name}}"> 5283 <div id="facetList{{name}}" class="facets-container__list @facetMoreClass dw-mod"> 5284 {{>Ranges}} 5285 <div class="u-hidden js-filter-not-found"> 5286 @Translate("Your search gave 0 results") 5287 </div> 5288 </div> 5289 5290 @if (boxDisplay == "view-more") 5291 { 5292 <div class="facets-container__more js-facet-expand"> 5293 @Render(new Button 5294 { 5295 Title = "<span class=js-facet-trigger-text>" + Translate("View more") + "</span>", 5296 ButtonType = ButtonType.Button, 5297 ButtonLayout = ButtonLayout.Clean, 5298 CssClass = "facets-container__more-button js-facet-trigger u-flex u-no-margin u-full-width", 5299 OnClick = "Facets.ExpandToggle(this)", 5300 ExtraAttributes = new Dictionary<string, string>{ 5301 {"data-target", "facetList{{name}}"}, 5302 {"data-toggle-text", Translate("Show less")}, 5303 }, 5304 Icon = new Icon 5305 { 5306 Prefix = "fal", 5307 Name = "fa-angle-down", 5308 } 5309 }) 5310 </div> 5311 } 5312 </div> 5313 </div> 5314 {{/ifCond}} 5315 {{else}} 5316 5317 <input type="checkbox" id="OptionsGroup_{{name}}" class="expand-trigger js-remember-state" {{defaultState}} /> 5318 5319 <div class="expand-container facets-container__box dw-mod js-filter"> 5320 <label class="expand-container__btn facets-container__header dw-mod" for="OptionsGroup_{{name}}">{{name}}</label> 5321 <div class="expand-container__content js-facet-container dw-mod" data-input="OptionsGroup_{{name}}"> 5322 <div class="facets-container__search {{showFilter}} dw-mod"> 5323 <input type="text" class="u-full-width u-no-margin" onkeyup="Filter.FilterItems(event)" placeholder="@Translate("Search")" /> 5324 </div> 5325 <div id="facetList{{name}}" class="facets-container__list @facetMoreClass dw-mod"> 5326 {{#FacetOptions}} 5327 {{#ifCond template "===" "Checkboxes"}} 5328 {{>Checkboxes}} 5329 {{/ifCond}} 5330 {{#ifCond template "===" "Weight"}} 5331 {{>Checkboxes}} 5332 {{/ifCond}} 5333 {{#ifCond template "===" "Tags"}} 5334 {{>Tags}} 5335 {{/ifCond}} 5336 {{#ifCond template "===" "Colors"}} 5337 {{>Colors}} 5338 {{/ifCond}} 5339 {{/FacetOptions}} 5340 {{#ifCond type "===" "Range"}} 5341 {{>Ranges}} 5342 {{/ifCond}} 5343 5344 <div class="u-hidden js-filter-not-found"> 5345 @Translate("Your search gave 0 results") 5346 </div> 5347 </div> 5348 5349 @if (boxDisplay == "view-more") 5350 { 5351 <div class="facets-container__more js-facet-expand"> 5352 @Render(new Button 5353 { 5354 Title = "<span class=js-facet-trigger-text>" + Translate("View more") + "</span>", 5355 ButtonType = ButtonType.Button, 5356 ButtonLayout = ButtonLayout.Clean, 5357 CssClass = "facets-container__more-button js-facet-trigger u-flex u-no-margin u-full-width", 5358 OnClick = "Facets.ExpandToggle(this)", 5359 ExtraAttributes = new Dictionary<string, string>{ 5360 {"data-target", "facetList{{name}}"}, 5361 {"data-toggle-text", Translate("Show less")}, 5362 }, 5363 Icon = new Icon 5364 { 5365 Prefix = "fal", 5366 Name = "fa-angle-down", 5367 } 5368 }) 5369 </div> 5370 } 5371 </div> 5372 </div> 5373 {{/ifCond}} 5374 {{/FacetGroups}} 5375 </div> 5376 <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> 5377 <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> 5378 } 5379 5380 @helper RenderProductListTopFacets() 5381 { 5382 @*This is part of a script template *@ 5383 <input type="checkbox" id="CheckFacetGroups" class="js-remember-state u-hidden" data-expand="CheckFacetGroups" /> 5384 <div class="grid grid--external-bleed dw-mod expandable--collapsed facets-container facets-container--top u-margin-bottom" data-trigger="CheckFacetGroups"> 5385 @if (Pageview.Device.ToString() == "Mobile") 5386 { 5387 string dropdownCssClass = Pageview.Device.ToString() == "Mobile" ? "u-flex-grow--1" : ""; 5388 5389 <div class="grid__col-lg-3 grid__col-md-3 grid__col-sm-4 grid__col-xs-12"> 5390 <input type="checkbox" id="ProductSort" class="dropdown-trigger" /> 5391 <div class="dropdown u-inline-block @dropdownCssClass dw-mod"> 5392 <label class="dropdown__header dropdown__btn dropdown__btn--small dw-mod" for="ProductSort">{{selectedSort}}</label> 5393 <div class="dropdown__content dw-mod"> 5394 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: '', SortOrder: '' }, true);">@Translate("Default")</div> 5395 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'Created', SortOrder: 'DESC'}, true);">@Translate("Newest")</div> 5396 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'NameForSort', SortOrder: 'ASC'}, true);">@Translate("Name A - Z")</div> 5397 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'NameForSort', SortOrder: 'DESC'}, true);">@Translate("Name Z - A")</div> 5398 @if (Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 5399 { 5400 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'Price', SortOrder: 'ASC' }, true);">@Translate("Price low - high")</div> 5401 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'Price', SortOrder: 'DESC' }, true);">@Translate("Price high - low")</div> 5402 } 5403 </div> 5404 <label class="dropdown-trigger-off" for="ProductSort"></label> 5405 </div> 5406 </div> 5407 } 5408 5409 {{#FacetGroups}} 5410 5411 {{#ifCond type "===" "Range"}} 5412 {{#ifCond minValue "!==" maxValue}} 5413 <div class="grid__col-lg-3 grid__col-md-3 grid__col-sm-4 grid__col-xs-12"> 5414 <input type="checkbox" id="OptionsGroup_{{counter}}" class="dropdown-trigger" /> 5415 <div class="dropdown dw-mod js-filter"> 5416 <label class="dropdown__header dropdown__btn dw-mod" for="OptionsGroup_{{counter}}">{{name}}</label> 5417 <div class="dropdown__content dropdown__content--padding dw-mod"> 5418 <div class="u-margin-bottom {{showFilter}}"> 5419 <input type="text" class="u-full-width u-no-margin" onkeyup="Filter.FilterItems(event)" placeholder="@Translate("Search")" /> 5420 </div> 5421 {{>Ranges}} 5422 <div class="u-hidden js-filter-not-found"> 5423 @Translate("Your search gave 0 results") 5424 </div> 5425 </div> 5426 <label class="dropdown-trigger-off" for="OptionsGroup_{{counter}}"></label> 5427 </div> 5428 </div> 5429 {{/ifCond}} 5430 {{else}} 5431 <div class="grid__col-lg-3 grid__col-md-3 grid__col-sm-4 grid__col-xs-12"> 5432 <input type="checkbox" id="OptionsGroup_{{counter}}" class="dropdown-trigger" /> 5433 <div class="dropdown dw-mod js-filter"> 5434 <label class="dropdown__header dropdown__btn dw-mod" for="OptionsGroup_{{counter}}">{{name}}</label> 5435 <div class="dropdown__content dropdown__content--padding dw-mod"> 5436 <div class="u-margin-bottom {{showFilter}}"> 5437 <input type="text" class="u-full-width u-no-margin" onkeyup="Filter.FilterItems(event)" placeholder="@Translate("Search")" /> 5438 </div> 5439 {{#FacetOptions}} 5440 {{#ifCond template "===" "Checkboxes"}} 5441 {{>Checkboxes}} 5442 {{/ifCond}} 5443 {{#ifCond template "===" "Weight"}} 5444 {{>Checkboxes}} 5445 {{/ifCond}} 5446 {{#ifCond template "===" "Tags"}} 5447 {{>Tags}} 5448 {{/ifCond}} 5449 {{#ifCond template "===" "Colors"}} 5450 {{>Colors}} 5451 {{/ifCond}} 5452 {{/FacetOptions}} 5453 <div class="u-hidden js-filter-not-found"> 5454 @Translate("Your search gave 0 results") 5455 </div> 5456 </div> 5457 <label class="dropdown-trigger-off" for="OptionsGroup_{{counter}}"></label> 5458 </div> 5459 </div> 5460 {{/ifCond}} 5461 {{/FacetGroups}} 5462 </div> 5463 <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> 5464 <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> 5465 } 5466 5467 @helper RenderCheckboxFacets() 5468 { 5469 <script id="Checkboxes" type="text/x-template"> 5470 <div class="form__field-group u-no-margin dw-mod"> 5471 <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}}> 5472 <label class="{{disabled}} checkbox-facet dw-mod" data-filter-value="{{label}}" for="{{queryParameter}}{{value}}"> 5473 <span class="checkbox-facet__label dw-mod">{{label}}</span> 5474 <span class="checkbox-facet__count dw-mod">({{count}})</span> 5475 </label> 5476 </div> 5477 </script> 5478 } 5479 5480 @helper RenderRangeFacets() 5481 { 5482 <script id="Ranges" type="text/x-template"> 5483 <div id="{{name}}_range-slider" class="range-slider__wrapper dw-mod"> 5484 <div class="range-slider__range-number dw-mod"> 5485 <div class="range-slider__field dw-mod"> 5486 <span>Min</span> 5487 {{#if queryParameterMinValue}} 5488 <input id="{{name}}_min" class="range-slider__input-min dw-mod" type="number" name="{{name}}_min" value="{{queryParameterMinValue}}" step="any" /> 5489 {{else}} 5490 {{#ifCond minValue "<" maxValue}} 5491 <input id="{{name}}_min" class="range-slider__input-min dw-mod" type="number" name="{{name}}_min" value="{{minValue}}" step="any" /> 5492 {{/ifCond}} 5493 {{/if}} 5494 </div> 5495 <div class="range-slider__field dw-mod"> 5496 <span>Max</span> 5497 {{#if queryParameterMaxValue}} 5498 <input id="{{name}}_max" class="range-slider__input-max dw-mod" type="number" name="{{name}}_max" value="{{queryParameterMaxValue}}" step="any" /> 5499 {{else}} 5500 {{#ifCond minValue "<" maxValue}} 5501 <input id="{{name}}_max" class="range-slider__input-max dw-mod" type="number" name="{{name}}_max" value="{{maxValue}}" step="any" /> 5502 {{/ifCond}} 5503 {{/if}} 5504 </div> 5505 </div> 5506 5507 <div class="range-slider__slider dw-mod"> 5508 <div class="range-slider__progress dw-mod"></div> 5509 </div> 5510 5511 <div class="range-slider__range-input dw-mod"> 5512 5513 {{#ifCond minValue ">" 0}} 5514 {{#if queryParameterMinValue}} 5515 <input class="range-slider__range-min dw-mod" type="{{type}}" name="" value="{{queryParameterMinValue}}" min="0" max="{{maxValue}}" step="1" /> 5516 {{else}} 5517 {{#ifCond minValue "<" maxValue}} 5518 <input class="range-slider__range-min dw-mod" type="{{type}}" name="" value="{{minValue}}" min="0" max="{{maxValue}}" step="1" /> 5519 {{/ifCond}} 5520 {{/if}} 5521 {{#if queryParameterMaxValue}} 5522 <input class="range-slider__range-max dw-mod" type="{{type}}" name="" value="{{queryParameterMaxValue}}" min="0" max="{{maxValue}}" step="1" /> 5523 {{else}} 5524 {{#ifCond minValue "<" maxValue}} 5525 <input class="range-slider__range-max dw-mod" type="{{type}}" name="" value="{{maxValue}}" min="0" max="{{maxValue}}" step="1" /> 5526 {{/ifCond}} 5527 {{/if}} 5528 {{else}} 5529 {{#if queryParameterMinValue}} 5530 <input class="range-slider__range-min dw-mod" type="{{type}}" name="" value="{{queryParameterMinValue}}" min="{{minValue}}" max="{{maxValue}}" step="1" /> 5531 {{else}} 5532 {{#ifCond minValue "<" maxValue}} 5533 <input class="range-slider__range-min dw-mod" type="{{type}}" name="" value="{{minValue}}" min="{{minValue}}" max="{{maxValue}}" step="1" /> 5534 {{/ifCond}} 5535 {{/if}} 5536 {{#if queryParameterMaxValue}} 5537 <input class="range-slider__range-max dw-mod" type="{{type}}" name="" value="{{queryParameterMaxValue}}" min="{{minValue}}" max="{{maxValue}}" step="1" /> 5538 {{else}} 5539 {{#ifCond minValue "<" maxValue}} 5540 <input class="range-slider__range-max dw-mod" type="{{type}}" name="" value="{{maxValue}}" min="{{minValue}}" max="{{maxValue}}" step="1" /> 5541 {{/ifCond}} 5542 {{/if}} 5543 {{/ifCond}} 5544 5545 </div> 5546 5547 <div class="btn btn--tertiary range-slider__submit-btn dw-mod" onclick="rangeSlider('{{name}}')">@Translate("Range slider button")</div> 5548 </div> 5549 </script> 5550 } 5551 5552 @helper RenderTagsFacets() 5553 { 5554 <script id="Tags" type="text/x-template"> 5555 <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}}> 5556 {{label}} <span class="facets-group__counter dw-mod">({{count}})</span> 5557 </button> 5558 </script> 5559 } 5560 5561 @helper RenderColorFacets() 5562 { 5563 <script id="Colors" type="text/x-template"> 5564 <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> 5565 </script> 5566 } 5567 5568 @helper RenderSelectedFilter() 5569 { 5570 <script id="SelectedFilter" type="text/x-template"> 5571 <button id="{{queryParameter}}_removeFilter" type="button" class="btn btn--tag dw-mod" data-check="checked" onclick="Facets.UpdateFacets(this);" name="{{queryParameter}}" value="[{{value}}]" title="@Translate("Remove filter")"> 5572 {{group}}: {{label}} &nbsp;<i class="fal fa-times"></i> 5573 </button> 5574 </script> 5575 } 5576 5577 @helper RenderCustomRangeSelectedFilter() 5578 { 5579 <script id="CustomRangeSelectedFilter" type="text/x-template"> 5580 {{#FacetGroups}} 5581 {{#if selected}} 5582 {{#ifCond type "===" "Range"}} 5583 <button id="{{name}}_removeFilter" type="button" class="btn btn--tag dw-mod" data-check="checked" onclick="removeRangeSlider(this);" name="{{name}}" title="@Translate("Remove filter")"> 5584 {{name}}: {{queryParameterMinValue}} - {{queryParameterMaxValue}} &nbsp;<i class="fal fa-times"></i> 5585 </button> 5586 {{/ifCond}} 5587 {{/if}} 5588 {{/FacetGroups}} 5589 </script> 5590 } 5591 5592 @helper RenderSelectedColorFilter() 5593 { 5594 <script id="SelectedColorFilter" type="text/x-template"> 5595 <button type="button" class="btn btn--tag dw-mod" data-check="checked" onclick="Facets.UpdateFacets(this);" name="{{queryParameter}}" value="[{{value}}]" title="@Translate("Remove filter")"> 5596 {{group}}: <div class="btn__colorbox dw-mod" style="background-color: {{value}}"></div> <i class="fas fa-times"></i> 5597 </button> 5598 </script> 5599 } 5600 5601 @helper RenderResetFilters() 5602 { 5603 <script id="ResetFilters" type="text/x-template"> 5604 <button type="button" class="btn btn--tag" onclick="Facets.ResetFacets();"> 5605 @Translate("Reset all filters") &nbsp;<i class="fal fa-redo"></i> 5606 </button> 5607 </script> 5608 } 5609 5610 @helper RenderRangeScript() 5611 { 5612 <script id="RangeSlider" type="text/javascript"> 5613 5614 function removeRangeSlider(para) { 5615 var name = para.getAttribute("name"); 5616 let url = new URL(window.location.href); 5617 url.searchParams.delete(name); 5618 window.location.href = url.toString(); 5619 } 5620 5621 function rangeSlider(para) { 5622 let currentUrl = window.location.href; 5623 let min = document.getElementById(para + "_min").value, 5624 max = document.getElementById(para + "_max").value; 5625 if (currentUrl.includes(encodeURIComponent(para)) || currentUrl.includes(para)) { 5626 let newParam = new URL(window.location.href); 5627 newParam.searchParams.set(para, min + ',' + max); 5628 window.location.href = newParam.toString(); 5629 } else { 5630 if (currentUrl.includes("?")) { 5631 window.location.href = window.location.href + "&" + encodeURIComponent(para) + "=" + min + "," + max; 5632 } else { 5633 window.location.href = window.location.href + "?" + encodeURIComponent(para) + "=" + min + "," + max; 5634 } 5635 } 5636 } 5637 window.onload = (event) => { 5638 const wrappers = document.getElementsByClassName("range-slider__wrapper"); 5639 if (wrappers) { 5640 for (var i = 0; i < wrappers.length; i++) { 5641 rangeSliderPos(wrappers[i]); 5642 } 5643 } 5644 } 5645 window.setInterval(function () { 5646 const wrappers = document.getElementsByClassName("range-slider__wrapper"); 5647 if (wrappers) { 5648 for (var i = 0; i < wrappers.length; i++) { 5649 rangeSliderPos(wrappers[i]); 5650 } 5651 } 5652 }, 2000); 5653 5654 function rangeSliderPos(element) { 5655 let rangeInput = element.querySelectorAll(".range-slider__range-input input"), 5656 rangeNumber = element.querySelectorAll(".range-slider__range-number input"), 5657 progress = element.querySelector(".range-slider__slider .range-slider__progress"); 5658 let minFirstVal = parseInt(rangeNumber[0].value), 5659 maxFirstVal = parseInt(rangeNumber[1].value); 5660 5661 if (rangeInput[0].min < 0) { 5662 progress.style.left = ((minFirstVal - rangeInput[0].min) / (rangeInput[0].max - rangeInput[0].min)) * 100 + "%"; 5663 progress.style.right = 100 - ((maxFirstVal - rangeInput[1].min) / (rangeInput[1].max - rangeInput[1].min)) * 100 + "%"; 5664 } else { 5665 progress.style.left = (minFirstVal / rangeInput[0].max) * 100 + "%"; 5666 progress.style.right = 100 - (maxFirstVal / rangeInput[1].max) * 100 + "%"; 5667 } 5668 5669 let gap = 1; 5670 5671 rangeNumber.forEach(input => { 5672 input.addEventListener("input", e => { 5673 let minVal = parseInt(rangeNumber[0].value), 5674 maxVal = parseInt(rangeNumber[1].value); 5675 if ((maxVal - minVal >= gap) && maxVal <= maxFirstVal) { 5676 if (e.target.className === "range-slider__input-min dw-mod") { 5677 rangeInput[0].value = minVal; 5678 if (rangeInput[0].min < 0) { 5679 progress.style.left = ((minVal - rangeInput[0].min) / (rangeInput[0].max - rangeInput[0].min)) * 100 + "%"; 5680 } else { 5681 progress.style.left = (minVal / rangeInput[0].max) * 100 + "%"; 5682 } 5683 } else { 5684 rangeInput[1].value = maxVal; 5685 if (rangeInput[0].min < 0) { 5686 progress.style.right = 100 - ((maxVal - rangeInput[1].min) / (rangeInput[1].max - rangeInput[1].min)) * 100 + "%"; 5687 } else { 5688 progress.style.right = 100 - (maxVal / rangeInput[1].max) * 100 + "%"; 5689 } 5690 } 5691 } 5692 }) 5693 }) 5694 5695 rangeInput.forEach(input => { 5696 input.addEventListener("input", e => { 5697 let minVal = parseInt(rangeInput[0].value), 5698 maxVal = parseInt(rangeInput[1].value); 5699 if ((maxVal - minVal) < gap) { 5700 if (e.target.className === "range-slider__range-min dw-mod") { 5701 rangeInput[0].value = maxVal - gap; 5702 } else { 5703 rangeInput[1].value = minVal + gap; 5704 } 5705 } else { 5706 rangeNumber[0].value = minVal; 5707 rangeNumber[1].value = maxVal; 5708 if (rangeInput[0].min < 0) { 5709 progress.style.left = ((minVal - rangeInput[0].min) / (rangeInput[0].max - rangeInput[0].min)) * 100 + "%"; 5710 progress.style.right = 100 - ((maxVal - rangeInput[1].min) / (rangeInput[1].max - rangeInput[1].min)) * 100 + "%"; 5711 } else { 5712 progress.style.left = (minVal / rangeInput[0].max) * 100 + "%"; 5713 progress.style.right = 100 - (maxVal / rangeInput[1].max) * 100 + "%"; 5714 } 5715 5716 } 5717 }) 5718 }) 5719 } 5720 5721 </script> 5722 } 5723 5724 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 5725 @using Dynamicweb.Core 5726 @using System 5727 @using System.Web 5728 @using System.Collections.Generic 5729 @using Dynamicweb.Rapido.Blocks 5730 5731 @{ 5732 BlocksPage productListMoreBlocksPage = BlocksPage.GetBlockPage("ProductList"); 5733 5734 Block moreBlock = new Block 5735 { 5736 Id = "More", 5737 SortId = 40, 5738 Template = RenderListMore() 5739 }; 5740 5741 productListMoreBlocksPage.Add("ProductList", moreBlock); 5742 } 5743 5744 @helper RenderListMore() 5745 { 5746 @*This is part of a script template *@ 5747 string groupID = HttpContext.Current.Request.QueryString.Get("groupid"); 5748 string listId = HttpContext.Current.Request.QueryString.Get("ListID"); 5749 bool isFavoriteList = !string.IsNullOrEmpty(listId); 5750 string moreFeedFullUrl = GetGlobalValue("Global:Pageview.Url.Raw") + "&feed=true"; 5751 moreFeedFullUrl += !isFavoriteList ? "&DoNotShowVariantsAsSingleProducts=True" : ""; 5752 string columnCss = Pageview.Device.ToString() == "Mobile" ? "grid__col--bleed" : "u-no-padding"; 5753 <text> 5754 {{#if ProductsContainer}} 5755 <div class="grid"> 5756 <div class="grid__col-12 @columnCss"> 5757 <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> 5758 <button type="button" class="btn btn--clean" onclick="window.scroll(0, 0)">@Translate("Return to top")</button> 5759 </div> 5760 </div> 5761 {{/if}} 5762 </text> 5763 } 5764 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 5765 @using Dynamicweb.Core 5766 @using System 5767 @using System.Web 5768 @using System.Collections.Generic 5769 @using Dynamicweb.Rapido.Blocks 5770 @using Dynamicweb.Rapido.Blocks.Components 5771 @using Dynamicweb.Rapido.Blocks.Components.General 5772 5773 @{ 5774 BlocksPage productListBottomSnippetsPage = BlocksPage.GetBlockPage("ProductList"); 5775 5776 Block productListStickers = new Block 5777 { 5778 Id = "Stickers", 5779 SortId = 10, 5780 Template = RenderStickersTemplates() 5781 }; 5782 productListBottomSnippetsPage.Add("BottomSnippets", productListStickers); 5783 5784 Block productListUnits = new Block 5785 { 5786 Id = "Units", 5787 SortId = 20, 5788 Template = RenderUnitTemplates() 5789 }; 5790 productListBottomSnippetsPage.Add("BottomSnippets", productListUnits); 5791 5792 Block productListVariants = new Block 5793 { 5794 Id = "Variants", 5795 SortId = 30, 5796 Template = RenderVariantTemplates() 5797 }; 5798 productListBottomSnippetsPage.Add("BottomSnippets", productListVariants); 5799 5800 Block productListFavorites = new Block 5801 { 5802 Id = "Favorites", 5803 SortId = 40, 5804 Template = RenderFavoritesTemplates() 5805 }; 5806 productListBottomSnippetsPage.Add("BottomSnippets", productListFavorites); 5807 5808 Block productListPreRender = new Block 5809 { 5810 Id = "PreRenders", 5811 SortId = 50, 5812 Template = RenderPreRenderTemplates() 5813 }; 5814 productListBottomSnippetsPage.Add("BottomSnippets", productListPreRender); 5815 5816 Block productListInitializers = new Block 5817 { 5818 Id = "Initializers", 5819 SortId = 60, 5820 Template = RenderInitializers() 5821 }; 5822 productListBottomSnippetsPage.Add("BottomSnippets", productListInitializers); 5823 } 5824 5825 5826 @helper RenderFavoritesTemplates() 5827 { 5828 var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star"; 5829 string favoriteIcon = "fas fa-" + selectedFavoriteIcon; 5830 string favoriteOutlineIcon = "fal fa-" + selectedFavoriteIcon; 5831 bool useFacebookPixel = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("FacebookPixelID")); 5832 string currentFavoriteListId = HttpContext.Current.Request.QueryString.Get("ListID"); 5833 5834 <script id="FavoriteTemplate" type="text/x-template"> 5835 <div class="favorites-list u-ta-left js-favorites-list"> 5836 @Render(new Button { 5837 CssClass = "u-no-margin js-favorite-btn", 5838 Icon = new Icon 5839 { 5840 Name = "{{#if isInAnyFavoriteList}}" + favoriteIcon + "{{else}}" + favoriteOutlineIcon + "{{/if}}", 5841 CssClass = "fa-1_5x", 5842 LabelPosition = IconLabelPosition.After 5843 }, 5844 ButtonLayout = ButtonLayout.LinkClean, 5845 ButtonType = ButtonType.Button, 5846 OnClick = "document.getElementById('FavoriteTrigger_{{id}}').checked = true" 5847 }) 5848 <input type="checkbox" id="FavoriteTrigger_{{id}}" class="dropdown-trigger" /> 5849 <div class="dropdown dropdown--position-32px"> 5850 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod"> 5851 <ul class="list list--clean dw-mod"> 5852 {{#FavoriteLists}} 5853 {{>FavoriteListItem}} 5854 {{/FavoriteLists}} 5855 </ul> 5856 </div> 5857 <label class="dropdown-trigger-off" for="FavoriteTrigger_{{id}}"></label> 5858 </div> 5859 </div> 5860 </script> 5861 5862 <script id="FavoriteListItem" type="text/x-template"> 5863 <li> 5864 @{ 5865 var button = new Button { 5866 CssClass = "list__link u-no-underline", 5867 OnClick = "toggleFavAction(this, event)", 5868 Icon = new Icon { Name = "{{#if isInFavoriteList}}" + favoriteIcon + "{{else}}" + favoriteOutlineIcon + "{{/if}}", LabelPosition = IconLabelPosition.After }, 5869 AltText = "{{#if isInFavoriteList}}" + Translate("Remove from") + " {{name}}{{else}}" + Translate("Add to") + " {{name}}{{/if}}", 5870 Title = "{{name}}", 5871 ButtonType = ButtonType.Button, 5872 ButtonLayout = ButtonLayout.LinkClean, 5873 ExtraAttributes = new Dictionary<string, string> 5874 { 5875 { "data-list-id", "{{listId}}" }, 5876 { "data-list-name", "{{name}}" }, 5877 { "data-remove-link", "{{removeLink}}" }, 5878 { "data-add-link", "{{addLink}}" }, 5879 { "data-is-in-list", "{{isInFavoriteList}}" }, 5880 5881 } 5882 }; 5883 if (useFacebookPixel) 5884 { 5885 button.ExtraAttributes.Add("data-facebook-object", "{{facebookPixelAddAction}}"); 5886 } 5887 } 5888 @Render(button) 5889 </li> 5890 </script> 5891 5892 <script> 5893 @if (!string.IsNullOrEmpty(currentFavoriteListId)) 5894 { 5895 <text> 5896 window.currentFavoriteListId = "@currentFavoriteListId"; 5897 </text> 5898 } 5899 function toggleFavAction(button, event) { 5900 if (button.getAttribute('data-add-link').indexOf('CCCreateNewList') > -1) { 5901 Scroll.SavePosition(event); 5902 @if (useFacebookPixel) 5903 { 5904 <text> 5905 fbq('track', 'AddToWishlist', JSON.parse(button.getAttribute('data-facebook-object'))); 5906 </text> 5907 } 5908 location.href = button.getAttribute('data-add-link'); 5909 return; 5910 } 5911 let isAdd = button.getAttribute('data-is-in-list') == "false"; 5912 Request.Fetch().get( 5913 isAdd ? button.getAttribute('data-add-link') : button.getAttribute('data-remove-link'), 5914 function (result) { 5915 button.querySelector('i').className = isAdd ? '@favoriteIcon u-margin-right--lg' : '@favoriteOutlineIcon u-margin-right--lg'; 5916 button.setAttribute('data-is-in-list', isAdd); 5917 button.setAttribute('title', (!isAdd ? '@Translate("Add to") ' : '@Translate("Remove from") ') + button.getAttribute('data-list-name')) 5918 let favList = button.closest('.js-favorites-list'); 5919 let favBtn = favList.querySelector('.js-favorite-btn i'); 5920 let isInAnyFavoriteList = favList.querySelector('[data-is-in-list=true]') != null; 5921 if (isInAnyFavoriteList) { 5922 favBtn.className = '@favoriteIcon' + ' fa-1_5x'; 5923 } else { 5924 favBtn.className = '@favoriteOutlineIcon' + ' fa-1_5x'; 5925 } 5926 @if (useFacebookPixel) 5927 { 5928 <text> 5929 if (isAdd) { 5930 fbq('track', 'AddToWishlist', JSON.parse(button.getAttribute('data-facebook-object'))); 5931 } 5932 </text> 5933 } 5934 if (window.currentFavoriteListId != null) { //if this page is favorite list 5935 let listId = button.getAttribute("data-list-id"); 5936 if (listId == window.currentFavoriteListId && !isAdd) { 5937 location.reload(); 5938 } 5939 } 5940 }, 5941 function () { 5942 console.error("FavoriteLists: Error in ToggleFavAction request"); 5943 }, 5944 false 5945 ); 5946 } 5947 </script> 5948 } 5949 5950 @helper RenderStickersTemplates() 5951 { 5952 <script id="StickersContainer" type="text/x-template"> 5953 <div class="stickers-container stickers-container--{{{convertStickerPositionToClassName Position}}} dw-mod"> 5954 {{#Stickers}} 5955 {{>Sticker}} 5956 {{/Stickers}} 5957 </div> 5958 </script> 5959 5960 <script id="Sticker" type="text/x-template"> 5961 <div class="stickers-container__tag {{CssClass}} dw-mod">{{Title}}</div> 5962 </script> 5963 5964 <script id="MiniSticker" type="text/x-template"> 5965 <div class="stickers-container__tag stickers-container__tag--micro {{CssClass}} dw-mod">{{Title}}</div> 5966 </script> 5967 } 5968 5969 @helper RenderUnitTemplates() 5970 { 5971 <script id="UnitOption" type="text/x-template"> 5972 <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent(this.closest('.js-product').id, '{{link}}&feed=true&UnitID={{value}}')">{{name}}</div> 5973 </script> 5974 } 5975 5976 @helper RenderVariantTemplates() { 5977 <script id="VariantsTemplate" type="text/x-template"> 5978 {{#.}} 5979 <div> 5980 <div> 5981 {{#VariantOptions}} 5982 {{>VariantOption}} 5983 {{/VariantOptions}} 5984 </div> 5985 </div> 5986 {{/.}} 5987 </script> 5988 5989 <script id="VariantOption" type="text/x-template"> 5990 {{#if color}} 5991 <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> 5992 {{else}} 5993 {{#if image}} 5994 <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}}" /> 5995 {{else}} 5996 <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> 5997 {{/if}} 5998 {{/if}} 5999 </script> 6000 6001 <script id="DropdownVariantsTemplate" type="text/x-template"> 6002 {{#.}} 6003 <div> 6004 <div class="u-bold">{{name}}</div> 6005 <select id="VariantSelector_{{id}}" class="u-full-width dw-mod" name="VariantSelector_{{id}}" onchange="MatchVariants.SelectOnChange(event)" > 6006 <option>@Translate("Choose")</option> 6007 {{#VariantOptions}} 6008 {{>DropdownVariantOption}} 6009 {{/VariantOptions}} 6010 </select> 6011 </div> 6012 {{/.}} 6013 </script> 6014 6015 <script id="DropdownVariantOption" type="text/x-template"> 6016 <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> 6017 </script> 6018 6019 <script id="StaticVariantsTemplate" type="text/x-template"> 6020 {{#.}} 6021 {{#if isFirstGroup}} 6022 <div> 6023 {{#VariantOptions}} 6024 {{>StaticVariantOption}} 6025 {{/VariantOptions}} 6026 </div> 6027 {{/if}} 6028 {{/.}} 6029 </script> 6030 6031 <script id="StaticVariantOption" type="text/x-template"> 6032 {{#if color}} 6033 <div class="static-variant static-variant--color dw-mod" style="background-color: {{color}}" title="{{name}}"></div> 6034 {{else}} 6035 <div class="static-variant dw-mod">{{name}} </div> 6036 {{/if}} 6037 </script> 6038 6039 6040 <script id="StaticVariantsLgTemplate" type="text/x-template"> 6041 {{#.}} 6042 {{#if isFirstGroup}} 6043 <div class="padding-size-xs"> 6044 {{#VariantOptions}} 6045 {{>StaticVariantLgOption}} 6046 {{/VariantOptions}} 6047 </div> 6048 {{/if}} 6049 {{/.}} 6050 </script> 6051 6052 <script id="StaticVariantLgOption" type="text/x-template"> 6053 {{#if color}} 6054 <div class="static-variant static-variant--color static-variant--color--lg dw-mod" style="background-color: {{color}}" title="{{name}}"></div> 6055 {{else}} 6056 <div class="static-variant dw-mod">{{name}} </div> 6057 {{/if}} 6058 </script> 6059 6060 <script id="VariantOptionImage" type="text/x-template"> 6061 <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}} /> 6062 </script> 6063 } 6064 6065 @helper RenderPreRenderTemplates() { 6066 string facetsViewMode = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductList").GetString("FacetsViewMode")) ? Pageview.AreaSettings.GetItem("ProductList").GetString("FacetsViewMode").ToLower() : "left"; 6067 6068 <script id="ProductPreRenderContainer" type="text/x-template"> 6069 @if (facetsViewMode == "left" && Pageview.Device.ToString() != "Mobile") 6070 { 6071 <div class="grid__col-3"> 6072 <div class="pre-render-element pre-render-element--xs"></div> 6073 <div class="pre-render-element pre-render-element--md"></div> 6074 <div class="pre-render-element pre-render-element--md"></div> 6075 <div class="pre-render-element pre-render-element--md"></div> 6076 </div> 6077 } 6078 <div class="grid__col-auto"> 6079 <div class="pre-render-element pre-render-element--xs"></div> 6080 <div class="pre-render-element pre-render-element--lg"></div> 6081 <div class="pre-render-element pre-render-element--lg"></div> 6082 <div class="pre-render-element pre-render-element--lg"></div> 6083 <div class="pre-render-element pre-render-element--lg"></div> 6084 </div> 6085 </script> 6086 } 6087 6088 @helper RenderInitializers() { 6089 <script> 6090 document.addEventListener("DOMContentLoaded", function (event) { 6091 document.getElementById("productList").addEventListener('contentLoaded', function (e) { 6092 if (getTarget(e).id === "productList") { 6093 Search.Init(); 6094 Facets.Init("selectedFacets", "productList"); 6095 } 6096 }, false); 6097 6098 @{ 6099 bool useGoogleTagManager = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("GoogleTagManagerID")); 6100 6101 if (useGoogleTagManager) 6102 { 6103 <text> 6104 Scroll.AddIsInViewportListener(".js-product-scroll-trigger", function (elem) { 6105 let googleImpression = JSON.parse(elem.getAttribute("data-params")); 6106 googleEnchantImpression(googleImpression); 6107 elem.classList.remove("js-product-scroll-trigger"); 6108 }); 6109 </text> 6110 } 6111 } 6112 6113 }); 6114 </script> 6115 } 6116 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 6117 @using Dynamicweb.Core 6118 @using System 6119 @using System.Web 6120 @using System.Linq 6121 @using System.Collections.Generic 6122 @using Dynamicweb.Rapido.Blocks 6123 @using Dynamicweb.Rapido.Services 6124 6125 @functions { 6126 BlocksPage productListActionsBlocksPage = BlocksPage.GetBlockPage("ProductList"); 6127 } 6128 6129 @{ 6130 string actionsFavoriteListId = HttpContext.Current.Request.QueryString.Get("ListID"); 6131 bool actionsIsFavoriteList = !string.IsNullOrEmpty(actionsFavoriteListId); 6132 string actionsColumnSize = actionsIsFavoriteList ? "4" : "6"; 6133 6134 productListActionsBlocksPage.Add("ProductListHeader", new Block 6135 { 6136 Id = "Actions", 6137 SortId = 30, 6138 Template = RenderListActions(), 6139 Design = new Design 6140 { 6141 CssClass = "grid__col-" + actionsColumnSize + " grid--align-self-center" 6142 } 6143 }); 6144 6145 productListActionsBlocksPage.Add("BottomSnippets", new Block() { 6146 Id = "ListViewSelectListener", 6147 Template = RenderListViewSelectListener() 6148 }); 6149 6150 } 6151 6152 @helper RenderListActions() 6153 { 6154 @*This is part of a script template *@ 6155 6156 bool showSorting = Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableSorting"); 6157 string listId = HttpContext.Current.Request.QueryString.Get("ListID"); 6158 bool isFavoriteList = !string.IsNullOrEmpty(listId); 6159 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; 6160 6161 List<Block> subBlocks = this.productListActionsBlocksPage.GetBlockListById("Views").OrderBy(item => item.SortId).ToList(); 6162 6163 <div class="buttons-collection buttons-collection--right"> 6164 @if (showSorting && Pageview.Device.ToString() != "Mobile") 6165 { 6166 string dropdownCssClass = Pageview.Device.ToString() == "Mobile" ? "u-flex-grow--1" : ""; 6167 6168 <input type="checkbox" id="ProductSort" class="dropdown-trigger" /> 6169 <div class="dropdown u-w150px u-inline-block @dropdownCssClass dw-mod"> 6170 <label class="dropdown__header dropdown__btn dropdown__btn--small dw-mod" for="ProductSort">{{selectedSort}}</label> 6171 <div class="dropdown__content dw-mod"> 6172 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: '', SortOrder: '' }, true);">@Translate("Default")</div> 6173 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'Created', SortOrder: 'DESC'}, true);">@Translate("Newest")</div> 6174 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'NameForSort', SortOrder: 'ASC'}, true);">@Translate("Name A - Z")</div> 6175 <div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'NameForSort', SortOrder: 'DESC'}, true);">@Translate("Name Z - A")</div> 6176 @if (Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 6177 { 6178 @*<div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'Price', SortOrder: 'ASC' }, true);">@Translate("Price low - high")</div>*@ 6179 @*<div class="dropdown__item" onclick="HandlebarsBolt.UpdateQueryParameters('productList', { SortBy: 'Price', SortOrder: 'DESC' }, true);">@Translate("Price high - low")</div>*@ 6180 } 6181 </div> 6182 <label class="dropdown-trigger-off" for="ProductSort"></label> 6183 </div> 6184 } 6185 6186 @if (subBlocks.Count > 1 && Pageview.Device.ToString() != "Mobile") 6187 { 6188 <div> 6189 @foreach (Block item in subBlocks) 6190 { 6191 <input type="radio" class="tag-btn-trigger" id="ListViewBtn_@item.Id" name="ViewBtnGroup"> 6192 <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> 6193 } 6194 </div> 6195 } 6196 6197 @if (isFavoriteList && Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 6198 { 6199 if (Pageview.Device.ToString() != "Mobile") 6200 { 6201 <button type="submit" class="btn btn--secondary btn--sm dw-mod">@Translate("Buy all") <i class="@cartIcon"></i></button> 6202 } 6203 else 6204 { 6205 <button type="submit" class="btn btn--secondary btn--full btn--sm dw-mod">@Translate("Buy all") <i class="@cartIcon"></i></button> 6206 } 6207 } 6208 </div> 6209 } 6210 6211 @helper RenderListViewSelectListener() 6212 { 6213 /* the same block code placed in ProductListFeed.cshtml */ 6214 Dictionary<string, bool> views = new Dictionary<string, bool>() 6215 { 6216 { "ProductItemContainer", Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableListView") }, 6217 { "ProductGridItemContainer", Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableGridView") }, 6218 { "ProductDetailsItemContainer", Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableDetailsView") }, 6219 { "ProductTilesViewContainer", Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableTilesView") } 6220 }; 6221 6222 string defaultView = Pageview.AreaSettings.GetItem("ProductList").GetList("DefaultListView") != null ? Pageview.AreaSettings.GetItem("ProductList").GetList("DefaultListView").SelectedValue : ""; 6223 6224 if (string.IsNullOrEmpty(defaultView) || !views[defaultView]) 6225 { 6226 defaultView = views.FirstOrDefault(x => x.Value).Key ?? "ProductItemContainer"; 6227 } 6228 6229 <script> 6230 let defaultTemplate = '@defaultView'; 6231 let container = 'productList'; 6232 let cookieName = 'ProductsContainerTemplate'; 6233 6234 document.addEventListener('DOMContentLoaded', function (event) { 6235 document.getElementById(container).addEventListener('contentLoaded', function () { 6236 let selectedMode = RememberState.GetCookie(cookieName); 6237 let element = document.getElementById('ListViewBtn_' + (selectedMode ? selectedMode : defaultTemplate)); 6238 if (element != null) { 6239 element.checked = true; 6240 } 6241 }, false); 6242 }); 6243 </script> 6244 } 6245 6246 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 6247 @using Dynamicweb.Core 6248 @using System 6249 @using System.Web 6250 @using System.Collections.Generic 6251 @using Dynamicweb.Rapido.Blocks 6252 6253 @{ 6254 BlocksPage customBlocksPage = BlocksPage.GetBlockPage("ProductList"); 6255 6256 } 6257 6258 6259 @if (productListNavigation.BlocksList.Count == 0) 6260 { 6261 productListNavigation.Design.RenderType = RenderType.Hide; 6262 } 6263 6264 <form name="multiForm" id="multiForm" method="post" onkeypress="return event.keyCode != 13;"> 6265 @* onkeypress is the fix for disabling submit form on Enter key from any field in product list *@ 6266 <input type="hidden" name="CartCmd" id="CartCmd" value="addMulti" /> 6267 @* The @RenderBlockList base helper is included in Components/GridBuilder.cshtml *@ 6268 @RenderBlockList(productListPage.BlocksRoot.BlocksList) 6269 </form> 6270 6271 @helper RenderPageContainer() 6272 { 6273 List<Block> subBlocks = this.productListPage.GetBlockListById("PageContainer").OrderBy(item => item.SortId).ToList(); 6274 6275 string pageUrl = GetGlobalValue("Global:Pageview.Url.Raw"); 6276 string feedFullUrl = pageUrl + "&feed=true"; 6277 feedFullUrl += !isFavoriteList ? "&DoNotShowVariantsAsSingleProducts=True" : ""; 6278 string smallDeviceCss = Pageview.Device.ToString() == "Mobile" ? "grid__col-12" : "u-padding"; 6279 6280 <div class="grid grid--align-content-start @smallDeviceCss js-handlebars-root" id="productList" data-template="ProductContainer" data-pre-render-template="ProductPreRenderContainer" data-json-feed="@feedFullUrl" data-preloader="overlay"></div> 6281 6282 <script id="ProductContainer" type="text/x-template"> 6283 {{#each .}} 6284 @RenderBlockList(subBlocks) 6285 {{else}} 6286 <div class="grid__col-12"> 6287 <h2 class="u-ta-center">@Translate("Your search gave 0 results")</h2> 6288 </div> 6289 {{/each}} 6290 </script> 6291 } 6292 6293 @helper RenderProductList() 6294 { 6295 @*This is part of a script template *@ 6296 6297 List<Block> subBlocks = productListPage.GetBlockListById("ProductList").OrderBy(item => item.SortId).ToList(); 6298 string smallDeviceCss = Pageview.Device.ToString() == "Mobile" ? "u-no-padding" : ""; 6299 string columnClass = "12"; 6300 6301 if (productListPage.GetBlockListById("Navigation").Count == 0) 6302 { 6303 columnClass = "12"; 6304 } 6305 6306 <div class="grid__col-@columnClass grid__col-md-9 @smallDeviceCss"> 6307 @RenderBlockList(subBlocks) 6308 </div> 6309 } 6310 6311 @helper RenderProductListHeader() 6312 { 6313 List<Block> subBlocks = this.productListPage.GetBlockListById("ProductListHeader"); 6314 bool enableSeparationLine = productListSettings.GetBoolean("EnableSeparationLine"); 6315 string className = (enableSeparationLine != null && enableSeparationLine ? "u-border-bottom u-padding-bottom" : ""); 6316 6317 <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"> 6318 <div class="grid @className"> 6319 @RenderBlockList(subBlocks) 6320 </div> 6321 </div> 6322 } 6323 6324 @helper RenderProductListTitle() 6325 { 6326 var header = new Heading { Title = "{{{header}}}", CssClass = "u-no-margin productlist-results-headline dw-mod" }; 6327 6328 if (isFavoriteList) 6329 { 6330 var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star"; 6331 header.Icon = new Icon { Prefix = "fas", Name = "fa-" + selectedFavoriteIcon, LabelPosition = IconLabelPosition.After }; 6332 } 6333 6334 @Render(header) 6335 } 6336 6337 @helper RenderFavoriteListSearch() 6338 { 6339 string pageId = GetGlobalValue("Global:Page.ID"); 6340 string pageUrl = GetGlobalValue("Global:Pageview.Url.Raw"); 6341 string feedFullUrl = pageUrl + "&feed=true"; 6342 string searchPlaceholder = Translate("Search favorite products"); 6343 string searchValue = HttpContext.Current.Request.QueryString.Get("Search") ?? ""; 6344 6345 <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"> 6346 <input type="text" class="typeahead-search-field u-no-margin u-full-width js-typeahead-search-field" placeholder="@searchPlaceholder" value="@searchValue"> 6347 <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> 6348 <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> 6349 </div> 6350 }