Error executing template "Designs/Rapido/eCom/Product/Product.cshtml"
System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.Convert.ToInt32(String value)
   at CompiledRazorTemplates.Dynamic.RazorEngine_379234b52c4b4be2baf42fba80fe48b0.<RenderMainInfoBuyScripts>b__77_0(TextWriter __razor_helper_writer)
   at CompiledRazorTemplates.Dynamic.RazorEngine_379234b52c4b4be2baf42fba80fe48b0.<RenderMainInfoBuy>b__75_0(TextWriter __razor_helper_writer)
   at RazorEngine.Templating.TemplateWriter.ToString()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_379234b52c4b4be2baf42fba80fe48b0.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer)
   at CompiledRazorTemplates.Dynamic.RazorEngine_379234b52c4b4be2baf42fba80fe48b0.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer)
   at CompiledRazorTemplates.Dynamic.RazorEngine_379234b52c4b4be2baf42fba80fe48b0.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer)
   at CompiledRazorTemplates.Dynamic.RazorEngine_379234b52c4b4be2baf42fba80fe48b0.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer)
   at CompiledRazorTemplates.Dynamic.RazorEngine_379234b52c4b4be2baf42fba80fe48b0.<RenderProductTop>b__119_0(TextWriter __razor_helper_writer)
   at RazorEngine.Templating.TemplateWriter.ToString()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_379234b52c4b4be2baf42fba80fe48b0.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer)
   at CompiledRazorTemplates.Dynamic.RazorEngine_379234b52c4b4be2baf42fba80fe48b0.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer)
   at CompiledRazorTemplates.Dynamic.RazorEngine_379234b52c4b4be2baf42fba80fe48b0.Execute()
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

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