Error executing template "Designs/Rapido/eCom/Product/Product.cshtml"
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
   at System.ThrowHelper.ThrowKeyNotFoundException()
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Elkotek.Modules.PDfDocuments.DocumentAssets.<>c__DisplayClass0_0.b__0(Object p) in D:\a\1\s\Elkotek\Modules\PDfDocuments\DocumentAssets.cs:line 23
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Elkotek.Modules.PDfDocuments.DocumentAssets.GetDocumentsByProductId(String ProductId) in D:\a\1\s\Elkotek\Modules\PDfDocuments\DocumentAssets.cs:line 21
   at CompiledRazorTemplates.Dynamic.RazorEngine_b11b09e2f3ba4bf8986ae6444c3b5ba3.Execute() in D:\dynamicweb.net\Solutions\Elkotek.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 6110
   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.b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

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