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_cfc62aa7dae04997b07d92b9ee61d197.<RenderMainInfoBuyScripts>b__77_0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Dynamicweb\verktoy.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 3805
   at CompiledRazorTemplates.Dynamic.RazorEngine_cfc62aa7dae04997b07d92b9ee61d197.<RenderMainInfoBuy>b__75_0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Dynamicweb\verktoy.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 3676
   at RazorEngine.Templating.TemplateWriter.ToString()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_cfc62aa7dae04997b07d92b9ee61d197.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Dynamicweb\verktoy.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 208
   at CompiledRazorTemplates.Dynamic.RazorEngine_cfc62aa7dae04997b07d92b9ee61d197.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Dynamicweb\verktoy.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 118
   at CompiledRazorTemplates.Dynamic.RazorEngine_cfc62aa7dae04997b07d92b9ee61d197.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Dynamicweb\verktoy.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 246
   at CompiledRazorTemplates.Dynamic.RazorEngine_cfc62aa7dae04997b07d92b9ee61d197.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Dynamicweb\verktoy.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 146
   at CompiledRazorTemplates.Dynamic.RazorEngine_cfc62aa7dae04997b07d92b9ee61d197.<RenderProductTop>b__119_0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Dynamicweb\verktoy.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 6286
   at RazorEngine.Templating.TemplateWriter.ToString()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_cfc62aa7dae04997b07d92b9ee61d197.<>c__DisplayClass4_0.<RenderBlock>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Dynamicweb\verktoy.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 208
   at CompiledRazorTemplates.Dynamic.RazorEngine_cfc62aa7dae04997b07d92b9ee61d197.<>c__DisplayClass3_0.<RenderBlockList>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\Dynamicweb\verktoy.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 118
   at CompiledRazorTemplates.Dynamic.RazorEngine_cfc62aa7dae04997b07d92b9ee61d197.Execute() in D:\dynamicweb.net\Solutions\Dynamicweb\verktoy.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Product\Product.cshtml:line 6275
   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()) 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 </script> 3866 } 3867 3868 @helper RenderOrderDraftSelectModalContent() 3869 { 3870 var customerId = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUserId(); 3871 var shopId = Pageview.Area.EcomShopId; 3872 var orderType = Dynamicweb.Ecommerce.Orders.OrderType.Order; 3873 var cartsList = (List<Dynamicweb.Ecommerce.Orders.Order>)Dynamicweb.Ecommerce.Services.Orders.GetCustomerOrdersByType(customerId, shopId, orderType, 0, false, "", DateTime.MinValue, false, true); 3874 3875 SelectField cartSelector = new SelectField 3876 { 3877 Id = "CartSelector", 3878 Label = Translate("I want to add this product to") 3879 }; 3880 3881 foreach (Dynamicweb.Ecommerce.Orders.Order cart in cartsList) 3882 { 3883 string name = !string.IsNullOrEmpty(cart.DisplayName) ? cart.DisplayName : cart.Id; 3884 cartSelector.Options.Add(new SelectFieldOption { Label = name, Value = cart.Id }); 3885 } 3886 3887 @Render(cartSelector) 3888 } 3889 3890 @helper RenderOrderDraftScripts() 3891 { 3892 string productId = GetString("Ecom:Product.ID"); 3893 string variantId = !string.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) ? GetString("Ecom:Product.VariantID") : GetString("Ecom:Product.VariantID.Extented"); 3894 string unitId = GetString("Ecom:Product.DefaultUnitID"); 3895 var cartCmdUrl = "/Default.aspx?ID=" + Pageview.Page.ID; 3896 int orderDraftPageId = GetPageIdByNavigationTag("DraftDetails"); 3897 int orderDraftParagraphId = Dynamicweb.Services.Paragraphs.GetParagraphsByPageId(orderDraftPageId).ToList().First().ID; 3898 3899 foreach (LoopItem unitOption in GetLoop("Units")) 3900 { 3901 if (unitOption.GetString("Ecom:VariantOption.Selected") == "SELECTED") 3902 { 3903 unitId = unitOption.GetString("Ecom:VariantOption.ID"); 3904 } 3905 } 3906 3907 <script> 3908 function addToSelectedCart() { 3909 var requestUrl = "@cartCmdUrl" + "&cartcmd=Add&Quantity=1" + "&CartId=" + document.getElementById("CartSelector").value + "&ProductId=@productId" + "&VariantId=@variantId" + "&UnitId=@unitId"; 3910 3911 console.log(requestUrl) 3912 3913 document.getElementById('OrderDraftSelectModalTrigger').checked = false; 3914 3915 var overlayElement = document.createElement('div'); 3916 overlayElement.className = "preloader-overlay"; 3917 overlayElement.setAttribute('id', "CartOverlay"); 3918 var overlayElementIcon = document.createElement('div'); 3919 overlayElementIcon.className = "preloader-overlay__icon dw-mod"; 3920 overlayElementIcon.style.top = window.pageYOffset + "px"; 3921 overlayElement.appendChild(overlayElementIcon); 3922 document.getElementById('content').parentNode.insertBefore(overlayElement, document.getElementById('content')); 3923 3924 Request.Fetch().get( 3925 requestUrl, 3926 function () { 3927 var overlayNode = document.getElementById('CartOverlay'); 3928 overlayNode.parentNode.removeChild(overlayNode); 3929 document.getElementById('OrderDraftNotificationModalTrigger').checked = true; 3930 }, 3931 null, 3932 false 3933 ); 3934 } 3935 3936 function goToSelectedCart() { 3937 window.location = "/Default.aspx?ID=" + "@orderDraftPageId" + "&CartID=" + document.getElementById('CartSelector').value + "&CartCmd=setcart" + "&redirect=false"; 3938 } 3939 </script> 3940 3941 } 3942 3943 @helper RenderGoogleTagManagerScripts() 3944 { 3945 bool useGoogleTagManager = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("GoogleTagManagerID")); 3946 3947 if (useGoogleTagManager) 3948 { 3949 var groupObject = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(GetString("Ecom:Product.PrimaryOrFirstGroupID")); 3950 3951 <script> 3952 // Measure a view of product details. This example assumes the detail view occurs on pageload, 3953 // and also tracks a standard pageview of the details page. 3954 dataLayer.push({ 3955 'event': 'productDetails', 3956 "ecommerce": { 3957 "detail": { 3958 "currencyCode": "@GetString("Ecom:Product.Price.Currency.Code")", 3959 "actionField": {}, // 'detail' actions have an optional list property. 3960 "products": [{ 3961 "name": "@GetString("Ecom:Product.Name")", // Name or ID is required. 3962 "id": "@GetString("Ecom:Product.ID")", 3963 "price": "@(GetDouble("Ecom:Product.Discount.Price.Price") != GetDouble("Ecom:Product.Price.Price") ? GetDouble("Ecom:Product.Discount.Price.Price") : GetDouble("Ecom:Product.Price.Price"))", 3964 "brand": "@GetString("Ecom:Product:Field.brand.Value")", 3965 "category": "@(groupObject != null ? groupObject.Name : "")", 3966 "variant": "@(!string.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) ? GetString("Ecom:Product.VariantID") : GetString("Ecom:Product.VariantID.Extented"))" 3967 }] 3968 } 3969 } 3970 }); 3971 </script> 3972 } 3973 } 3974 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 3975 @using Dynamicweb.Core 3976 @using System 3977 @using System.Web 3978 @using System.Collections.Generic 3979 @using Dynamicweb.Rapido.Blocks 3980 @using Dynamicweb.Rapido.Blocks.Components.General 3981 3982 @functions { 3983 BlocksPage productAssetsPage = BlocksPage.GetBlockPage("Product"); 3984 } 3985 3986 @{ 3987 string productAssetsLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("ProductAssetsLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductAssetsLayout").SelectedValue : "Section"; 3988 productAssetsLayout = productAssetsLayout == "Ribbon" ? "Section" : productAssetsLayout; 3989 3990 if (productAssetsLayout != "hide") 3991 { 3992 Block productAssetsBlock = new Block() 3993 { 3994 Name = productAssetsLayout != "MainInformation" ? Translate("Product assets") : "", 3995 Id = "ProductAssets", 3996 SortId = 10, 3997 Template = RenderProductAssets(productAssetsLayout, downloadDocuments), @*downloadDocuments variable, declared in Product.cshtml and defined in Fields.cshtml*@ 3998 Design = new Design 3999 { 4000 Size = "12", 4001 RenderType = RenderType.Column, 4002 HidePadding = true 4003 } 4004 }; 4005 productAssetsPage.Add(productAssetsLayout, productAssetsBlock); 4006 } 4007 } 4008 4009 @helper RenderProductAssets(string layout, List<LoopItem> documents) 4010 { 4011 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductAssetsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 4012 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductAssetsLayout").SelectedValue == "Ribbon" ? "u-padding--lg" : ""; 4013 string exportPageId = GetPageIdByNavigationTag("ProductExportFeed").ToString(); 4014 4015 //images 4016 4017 HashSet<string> images = new HashSet<string>(); 4018 4019 images.Add(GetProductImage()); 4020 4021 foreach (LoopItem alternativeImage in GetLoop("Ecom:Product.AlternativeImages")) 4022 { 4023 string alt_image = alternativeImage.GetString("Ecom:Product.AlternativeImages.Image"); 4024 4025 if (!string.IsNullOrEmpty(alt_image)) 4026 { 4027 images.Add(alt_image); 4028 } 4029 } 4030 4031 foreach (LoopItem detail in GetLoop("Details")) 4032 { 4033 string detail_image = detail.GetString("Ecom:Product:Detail.Image.Clean"); 4034 4035 if (!string.IsNullOrEmpty(detail_image)) 4036 { 4037 images.Add(detail_image); 4038 } 4039 } 4040 4041 <div class="product__section @ribbonClasses dw-mod"> 4042 <div class="product__description center-container @ribbonSubClasses dw-mod"> 4043 @if (layout == "Section") 4044 { 4045 @Render(new Heading { Title = Translate("Product assets"), Level = 2 }) 4046 } 4047 4048 <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"> 4049 <div class="grid"> 4050 @if (images.Count > 0) 4051 { 4052 <div class="grid__col-md-4 js-checkboxes-list"> 4053 @Render(new CheckboxField { Id = "allImages", OnChange = "selectAll(this)", Label = Translate("Images") + "(" + images.Count + ")" }) 4054 4055 <ul class="panel-list"> 4056 @foreach (string image in images) 4057 { 4058 @RenderProductPanelListItem(image) 4059 } 4060 </ul> 4061 </div> 4062 } 4063 4064 @if (documents.Count > 0) 4065 { 4066 <div class="grid__col-md-4 js-checkboxes-list"> 4067 @Render(new CheckboxField { Id = "allDocuments", OnChange = "selectAll(this)", Label = Translate("Documents") + "(" + documents.Count + ")" }) 4068 4069 <ul class="panel-list"> 4070 @foreach (LoopItem document in documents) 4071 { 4072 string fieldValue; 4073 if (!string.IsNullOrEmpty(document.GetString("Document.FullPath"))) 4074 { 4075 fieldValue = document.GetString("Product.CustomField.Value.Clean"); 4076 @RenderDocument(fieldValue) 4077 } 4078 if (document.GetString("Ecom:Product.CategoryField.TypeID") == "9") 4079 { 4080 fieldValue = document.GetString("Ecom:Product.CategoryField.Value"); 4081 @RenderDocument(fieldValue) 4082 } 4083 if (!string.IsNullOrEmpty(document.GetString("Ecom:Product:Detail.Image.Clean"))) 4084 { 4085 fieldValue = document.GetString("Ecom:Product:Detail.Image.Clean"); 4086 @RenderDocument(fieldValue) 4087 } 4088 } 4089 </ul> 4090 </div> 4091 } 4092 <div class="grid__col-md-4"> 4093 @Render(new HiddenField { Id = "ID", Name = "ID", Value = "532" }) 4094 @Render(new HiddenField { Id = "download", Name = "download", Value = "true" }) 4095 @Render(new HiddenField { Id = "siteUrl", Name = "siteUrl", Value = string.Format("{0}://{1}", GetGlobalValue("Global:Request.Scheme"), GetGlobalValue("Global:Request.Host")) }) 4096 4097 <div class="u-bold u-margin-bottom">@Translate("Export")</div> 4098 4099 @{ 4100 SelectField languageSelect = new SelectField 4101 { 4102 Id = "exportLanguage", 4103 Label = Translate("Language"), 4104 Name = "RequestLanguageId", 4105 CssClass = "u-full-width" 4106 }; 4107 foreach (var lang in Services.Languages.GetLanguages().OrderBy(l => l.Name)) 4108 { 4109 var selected = lang.IsDefault ? true : false; 4110 languageSelect.Options.Add(new SelectFieldOption { Label = lang.Name, Value = lang.LanguageId, Checked = selected }); 4111 } 4112 @Render(languageSelect) 4113 4114 SelectField purposeSelect = new SelectField 4115 { 4116 Id = "purpose", 4117 Label = Translate("Image purpose"), 4118 Name = "purpose", 4119 CssClass = "u-full-width" 4120 }; 4121 purposeSelect.Options.Add(new SelectFieldOption { Label = Translate("Office"), Value = "Office" }); 4122 purposeSelect.Options.Add(new SelectFieldOption { Label = Translate("Original"), Value = "Original" }); 4123 purposeSelect.Options.Add(new SelectFieldOption { Label = Translate("Print"), Value = "Print" }); 4124 purposeSelect.Options.Add(new SelectFieldOption { Label = Translate("Web"), Value = "Web" }); 4125 @Render(purposeSelect) 4126 4127 SelectField formatSelect = new SelectField 4128 { 4129 Id = "exportFormat", 4130 Label = Translate("Export format"), 4131 Name = "format", 4132 CssClass = "u-full-width" 4133 }; 4134 formatSelect.Options.Add(new SelectFieldOption { Label = Translate("Csv"), Value = "csv" }); 4135 formatSelect.Options.Add(new SelectFieldOption { Label = Translate("Json"), Value = "json" }); 4136 formatSelect.Options.Add(new SelectFieldOption { Label = Translate("Xml"), Value = "xml" }); 4137 @Render(formatSelect) 4138 } 4139 4140 @Render(new Button { ButtonType = ButtonType.Submit, ButtonLayout = ButtonLayout.Primary, CssClass = "btn--full u-no-margin", Title = Translate("Download") }) 4141 </div> 4142 </div> 4143 </form> 4144 </div> 4145 </div> 4146 <script> 4147 function selectAll(checkbox) { 4148 checkbox.closest(".js-checkboxes-list").querySelectorAll(".js-checkbox").forEach(function (input) { 4149 input.checked = checkbox.checked; 4150 }); 4151 } 4152 </script> 4153 } 4154 4155 @helper RenderProductPanelListItem(string imageName) 4156 { 4157 <li class="panel-list__item"> 4158 <div class="panel-list__item-check"> 4159 <input id="Image_@imageName" name="Image_@imageName" type="checkbox" class="form__control u-no-margin dw-mod js-checkbox" /> 4160 <label for="Image_@imageName"></label> 4161 </div> 4162 <div class="panel-list__item-image"> 4163 <label for="Image_@imageName" class="u-no-margin"> 4164 @Render(new Image { Path = imageName, Title = Path.GetFileName(imageName), ImageDefault = new ImageSettings { Width = 55, Height = 55, Crop = 5, FillCanvas = true } }) 4165 </label> 4166 </div> 4167 <div class="panel-list__item-name"> 4168 <label for="Image_@imageName" class="u-truncate-text u-w170px" title="@Path.GetFileName(imageName)"> 4169 @Path.GetFileName(imageName) 4170 </label> 4171 </div> 4172 </li> 4173 } 4174 4175 @helper RenderDocument(string fieldValue) 4176 { 4177 <li class="panel-list__item"> 4178 <div class="panel-list__item-check"> 4179 <input id="Document_@fieldValue" name="Document_@fieldValue" type="checkbox" class="form__control u-no-margin js-checkbox dw-mod"> 4180 <label for="Document_@fieldValue"></label> 4181 </div> 4182 <div class="panel-list__item-name"> 4183 <label for="Document_@fieldValue" class="u-truncate-text u-no-margin u-max-w220px" title="@Path.GetFileName(fieldValue)"> 4184 @Path.GetFileName(fieldValue) 4185 </label> 4186 </div> 4187 </li> 4188 } 4189 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 4190 @using Dynamicweb.Core 4191 @using System 4192 @using System.Web 4193 @using System.Collections.Generic 4194 @using Dynamicweb.Rapido.Blocks 4195 @using Dynamicweb.Rapido.Blocks.Components.General 4196 4197 @functions { 4198 BlocksPage productGeneratePDFPage = BlocksPage.GetBlockPage("Product"); 4199 } 4200 4201 @{ 4202 string generatePDFLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("GeneratePDFLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("GeneratePDFLayout").SelectedValue : "Section"; 4203 generatePDFLayout = generatePDFLayout == "Ribbon" ? "Section" : generatePDFLayout; 4204 4205 if (GetPageIdByNavigationTag("ProductPagePDFTemplates") > 0 && generatePDFLayout != "hide") 4206 { 4207 Block generatePDFBlock = new Block() 4208 { 4209 Name = generatePDFLayout != "MainInformation" ? Translate("Generate PDF") : "", 4210 Id = "GeneratePDF", 4211 SortId = 10, 4212 Template = RenderGeneratePDF(generatePDFLayout), 4213 Design = new Design 4214 { 4215 Size = "12", 4216 RenderType = RenderType.Column, 4217 HidePadding = true 4218 } 4219 }; 4220 4221 productGeneratePDFPage.Add(generatePDFLayout, generatePDFBlock); 4222 } 4223 } 4224 4225 @helper RenderGeneratePDF(string layout) 4226 { 4227 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("GeneratePDFLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 4228 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses; 4229 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("GeneratePDFLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 4230 string exportPageId = GetPageIdByNavigationTag("ProductExportFeed").ToString(); 4231 int pdfFolderId = GetPageIdByNavigationTag("ProductPagePDFTemplates"); 4232 4233 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" }; 4234 form.Add(new HiddenField { Name = "siteUrl", Value = string.Format("{0}://{1}", GetGlobalValue("Global:Request.Scheme"), GetGlobalValue("Global:Request.Host")) }); 4235 4236 //Select languages 4237 SelectField languagesList = new SelectField 4238 { 4239 Id = "RequestLanguageID", 4240 Name = "RequestLanguageID", 4241 Label = Translate("Language"), 4242 CssClass = "u-full-width" 4243 }; 4244 4245 foreach (var lang in Services.Languages.GetLanguages().OrderBy(l => l.Name)) 4246 { 4247 languagesList.Options.Add(new SelectFieldOption 4248 { 4249 Label = lang.Name, 4250 Value = lang.LanguageId, 4251 Checked = lang.IsDefault ? true : false 4252 }); 4253 } 4254 form.Add(languagesList); 4255 4256 //Select pages 4257 SelectField pagesList = new SelectField 4258 { 4259 Id = "PDFTemplate", 4260 Name = "ID", 4261 Label = Translate("Generate PDF"), 4262 CssClass = "u-full-width" 4263 }; 4264 4265 foreach (Dynamicweb.Content.Page page in ServiceLocator.Current.GetPageService().GetPagesByParentID(pdfFolderId)) 4266 { 4267 pagesList.Options.Add(new SelectFieldOption 4268 { 4269 Label = page.MenuText, 4270 Value = Converter.ToString(page.ID) 4271 }); 4272 } 4273 form.Add(pagesList); 4274 4275 form.Add(new Button { ButtonType = ButtonType.Submit, Title = Translate("Generate PDF"), CssClass = "btn--full u-no-margin" }); 4276 4277 <div class="product__section @ribbonClasses grid dw-mod"> 4278 <div class="dw-mod grid__col-md-4 @ribbonSubClasses"> 4279 @if (layout == "Section") 4280 { 4281 @Render(new Heading { Title = Translate("Generate PDF"), Level = 2 }) 4282 } 4283 @Render(form) 4284 </div> 4285 </div> 4286 } 4287 4288 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 4289 @using Dynamicweb.Core 4290 @using System 4291 @using System.Web 4292 @using System.Collections.Generic 4293 @using Dynamicweb.Rapido.Blocks 4294 @using Dynamicweb.Rapido.Blocks.Components.General 4295 4296 @functions { 4297 BlocksPage productDescriptionPage = BlocksPage.GetBlockPage("Product"); 4298 } 4299 4300 @{ 4301 string fullDesctiptionLayout = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("FullDescriptionLayout")) ? Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue : "Section"; 4302 fullDesctiptionLayout = fullDesctiptionLayout == "Ribbon" ? "Section" : fullDesctiptionLayout; 4303 4304 if (!string.IsNullOrEmpty(GetString("Ecom:Product.LongDescription")) && fullDesctiptionLayout != "hide") 4305 { 4306 Block detailsDescription = new Block() 4307 { 4308 Name = fullDesctiptionLayout != "MainInformation" ? Translate("Description") : "", 4309 Id = "FullDescription", 4310 SortId = 30, 4311 Template = RenderProductDescription(fullDesctiptionLayout), 4312 Design = new Design 4313 { 4314 Size = "12", 4315 RenderType = RenderType.Column, 4316 HidePadding = true 4317 } 4318 }; 4319 productDescriptionPage.Add(fullDesctiptionLayout, detailsDescription); 4320 } 4321 } 4322 4323 @helper RenderProductDescription(string layout) 4324 { 4325 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 4326 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses; 4327 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("FullDescriptionLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 4328 4329 <div class="product__section @ribbonClasses dw-mod"> 4330 <div class="product__description center-container @ribbonSubClasses dw-mod"> 4331 @if (layout == "Section") { 4332 @Render(new Heading { Title = Translate("Description"), Level = 2 }) 4333 } 4334 @Render(new Text { Content = GetString("Ecom:Product.LongDescription") }) 4335 </div> 4336 </div> 4337 } 4338 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 4339 @using Dynamicweb.Core 4340 @using System 4341 @using System.Web 4342 @using System.Globalization; 4343 @using System.Collections.Generic 4344 @using Dynamicweb.Rapido.Blocks 4345 4346 @functions { 4347 BlocksPage productFieldsPage = BlocksPage.GetBlockPage("Product"); 4348 4349 static string ConvertBytes(long bytes) 4350 { 4351 double size = bytes / 1024; //KB 4352 if (size > 1024) 4353 { 4354 size = (bytes / 1024f) / 1024f; //MB 4355 return string.Format("{0:n1} MB", size); 4356 } 4357 else 4358 { 4359 return string.Format("{0:n0} KB", size); 4360 } 4361 } 4362 4363 static bool isImage(string path) 4364 { 4365 return new List<string> { ".jpg", ".jpeg", ".gif", ".png", ".svg" }.Contains(Path.GetExtension(path).ToLower()); 4366 } 4367 4368 string getIconForFile(string fileName) 4369 { 4370 string ext = Path.GetExtension(fileName); 4371 string icon = ""; 4372 switch (ext.ToLower()) 4373 { 4374 case ".xls": 4375 case ".xlsx": 4376 icon = "fa-file-excel"; 4377 break; 4378 case ".ppt": 4379 case ".pptx": 4380 icon = "fa-file-powerpoint"; 4381 break; 4382 case ".doc": 4383 case ".docx": 4384 icon = "fa-file-word"; 4385 break; 4386 case ".jpg": 4387 case ".jpeg": 4388 case ".png": 4389 case ".gif": 4390 case ".pdf": 4391 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 + "' />"; 4392 default: 4393 icon = "fa-file"; 4394 break; 4395 } 4396 return "<i class='product__document-icon far " + icon + "'></i> "; 4397 } 4398 } 4399 4400 @*downloadDocuments variable, declared in Product.cshtml - this variable also will be used in ProductAssets.cshtml*@ 4401 4402 4403 4404 @{ 4405 var selectedDownloadCategories = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadAssets").SelectedValues; 4406 var downloadsFromAssets = GetLoop("ImageCategories").Where(x => selectedDownloadCategories.Contains(x.GetString("Category.Id"))); 4407 4408 if (string.IsNullOrEmpty(selectedDownloadCategories.ToString())) { 4409 foreach (LoopItem customField in GetLoop("CustomFieldValues")) 4410 { 4411 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") 4412 { 4413 if (!string.IsNullOrEmpty(customField.GetString("Document.FullPath"))) 4414 { 4415 downloadDocuments.Add(customField); 4416 } 4417 } 4418 } 4419 4420 foreach (LoopItem customField in GetLoop("ProductCategories")) 4421 { 4422 foreach (LoopItem field in customField.GetLoop("ProductCategoryFields")) 4423 { 4424 if (!string.IsNullOrEmpty(field.GetString("Ecom:Product.CategoryField.Label")) && !string.IsNullOrEmpty(field.GetString("Ecom:Product.CategoryField.Value"))) 4425 { 4426 if (field.GetString("Ecom:Product.CategoryField.TypeID") == "9") 4427 { 4428 downloadDocuments.Add(field); 4429 } 4430 } 4431 } 4432 } 4433 } else { 4434 foreach (LoopItem category in downloadsFromAssets) { 4435 foreach (LoopItem asset in category.GetLoop("Category.Images")) { 4436 downloadDocuments.Add(asset); 4437 } 4438 } 4439 } 4440 4441 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true; 4442 string detailFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsLayout").SelectedValue : "Section"; 4443 detailFieldsLayout = detailFieldsLayout == "Ribbon" || string.IsNullOrEmpty(detailFieldsLayout) ? "Section" : detailFieldsLayout; 4444 string categoryFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsLayout").SelectedValue : "Section"; 4445 categoryFieldsLayout = categoryFieldsLayout == "Ribbon" || string.IsNullOrEmpty(categoryFieldsLayout) ? "Section" : categoryFieldsLayout; 4446 string displayGroupsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DisplayGroupsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DisplayGroupsLayout").SelectedValue : "Section"; 4447 displayGroupsLayout = displayGroupsLayout == "Ribbon" || string.IsNullOrEmpty(displayGroupsLayout) ? "Section" : displayGroupsLayout; 4448 string downloadsFieldsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsLayout").SelectedValue : "Section"; 4449 downloadsFieldsLayout = downloadsFieldsLayout == "Ribbon" || string.IsNullOrEmpty(downloadsFieldsLayout) ? "Section" : downloadsFieldsLayout; 4450 4451 string detailFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DetailFieldsView").SelectedValue : "grid"; 4452 string categoryFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("CategoryFieldsView").SelectedValue : "grid"; 4453 string downloadsFieldsView = Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsFieldsView") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("DownloadsFieldsView").SelectedValue : "grid"; 4454 4455 if (GetLoop("CustomFieldValues").Count > 0 && detailFieldsLayout != "hide") 4456 { 4457 if (string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductPage").GetString("ProductDetailFields"))) { 4458 Block detailsCustom = new Block() 4459 { 4460 Name = detailFieldsLayout != "MainInformation" ? Translate("Details") : "", 4461 Id = "CustomFields", 4462 SortId = 30, 4463 Design = new Design 4464 { 4465 Size = "12", 4466 RenderType = RenderType.Column, 4467 HidePadding = true 4468 } 4469 }; 4470 4471 detailsCustom.Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Information"), RenderCustomFields(GetLoop("CustomFieldValues"), detailFieldsView)); 4472 productFieldsPage.Add(detailFieldsLayout, detailsCustom); 4473 } else { 4474 var detailFieldsDisplayGroups = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductDetailFields").SelectedValues; 4475 var displayGroups = GetLoop("FieldDisplayGroups").Where(x => detailFieldsDisplayGroups.Contains(x.GetString("Ecom:FieldDisplayGroup.ID"))); 4476 4477 foreach (var group in displayGroups) { 4478 Block detailsCustom = new Block() 4479 { 4480 Name = detailFieldsLayout != "MainInformation" ? group.GetString("Ecom:FieldDisplayGroup.Name") : "", 4481 Id = "DetailFields_" + group.GetString("Ecom:FieldDisplayGroup.ID"), 4482 SortId = 30, 4483 Design = new Design 4484 { 4485 Size = "12", 4486 RenderType = RenderType.Column, 4487 HidePadding = true 4488 } 4489 }; 4490 4491 detailsCustom.Template = RenderProductSection(detailFieldsLayout, detailFieldsView, Translate("Information"), RenderDetailsFields(group.GetLoop("Fields"), detailFieldsView)); 4492 productFieldsPage.Add(detailFieldsLayout, detailsCustom); 4493 } 4494 } 4495 } 4496 4497 if (categoryFieldsLayout != "hide") 4498 { 4499 foreach (LoopItem categoryGroup in GetLoop("ProductCategories")) 4500 { 4501 bool hasFields = categoryGroup.GetLoop("ProductCategoryFields").FirstOrDefault(cf => !string.IsNullOrEmpty(cf.GetString("Ecom:Product.CategoryField.Value"))) != null; 4502 4503 if (collectAllDownloads) 4504 { 4505 int downloadableCount = 0; 4506 foreach (LoopItem field in categoryGroup.GetLoop("ProductCategoryFields")) 4507 { 4508 if (field.GetString("Ecom:Product.CategoryField.TypeID") == "9") 4509 { 4510 downloadableCount++; 4511 } 4512 } 4513 4514 if (downloadableCount == categoryGroup.GetLoop("ProductCategoryFields").Count) 4515 { 4516 hasFields = false; 4517 } 4518 } 4519 4520 if (hasFields) 4521 { 4522 Block detailsCategoryFields = new Block() 4523 { 4524 Name = categoryFieldsLayout != "MainInformation" ? categoryGroup.GetString("Ecom:Product.Category.Name") : "", 4525 Id = ToPascalCase(categoryGroup.GetString("Ecom:Product.Category.Name")), 4526 SortId = 40, 4527 Template = RenderProductSection(categoryFieldsLayout, categoryFieldsView, categoryGroup.GetString("Ecom:Product.Category.Name"), RenderProductCategoryFields(categoryGroup.GetLoop("ProductCategoryFields"), categoryFieldsView)), 4528 Design = new Design 4529 { 4530 Size = "12", 4531 RenderType = RenderType.Column, 4532 HidePadding = true 4533 } 4534 }; 4535 4536 productFieldsPage.Add(categoryFieldsLayout, detailsCategoryFields); 4537 } 4538 } 4539 } 4540 4541 if (displayGroupsLayout != "hide") 4542 { 4543 var detailFieldsDisplayGroups = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductDetailFields").SelectedValues; 4544 var displayGroups = GetLoop("FieldDisplayGroups").Where(x => !detailFieldsDisplayGroups.Contains(x.GetString("Ecom:FieldDisplayGroup.ID"))); 4545 4546 foreach (LoopItem group in displayGroups) 4547 { 4548 int fieldsCount = 0; 4549 4550 foreach (LoopItem field in group.GetLoop("Fields")) 4551 { 4552 if (!string.IsNullOrEmpty(field.GetString("Ecom:FieldDisplayGroup.Field.Name")) && !string.IsNullOrEmpty(field.GetString("Ecom:FieldDisplayGroup.Field.Value"))) 4553 { 4554 fieldsCount++; 4555 } 4556 } 4557 4558 if (fieldsCount != 0) 4559 { 4560 Block displayGroup = new Block() 4561 { 4562 Name = displayGroupsLayout != "MainInformation" ? group.GetString("Ecom:FieldDisplayGroup.Name") : "", 4563 Id = "DisplayGroup_" + group.GetString("Ecom:FieldDisplayGroup.ID"), 4564 SortId = 40, 4565 Template = RenderProductSection(displayGroupsLayout, categoryFieldsView, group.GetString("Ecom:FieldDisplayGroup.Name"), RenderDetailsFields(group.GetLoop("Fields"), categoryFieldsView)), 4566 Design = new Design 4567 { 4568 Size = "12", 4569 RenderType = RenderType.Column, 4570 HidePadding = true 4571 } 4572 }; 4573 productFieldsPage.Add(displayGroupsLayout, displayGroup); 4574 } 4575 } 4576 } 4577 4578 if (downloadDocuments.Count > 0 && downloadsFieldsLayout != "hide" && collectAllDownloads == true) 4579 { 4580 Block detailsDownloads = new Block() 4581 { 4582 Name = downloadsFieldsLayout != "MainInformation" ? Translate("Downloads") : "", 4583 Id = "StandardDownloads", 4584 SortId = 50, 4585 Template = RenderProductSection(downloadsFieldsLayout, downloadsFieldsView, Translate("Downloads"), RenderProductDownloadsFields(downloadDocuments, downloadsFieldsView)), 4586 Design = new Design 4587 { 4588 Size = "12", 4589 RenderType = RenderType.Column, 4590 HidePadding = true 4591 } 4592 }; 4593 4594 productFieldsPage.Add(downloadsFieldsLayout, detailsDownloads); 4595 } 4596 } 4597 4598 @helper RenderCustomFields(List<LoopItem> fieldsLoop, string viewType) 4599 { 4600 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true; 4601 4602 foreach (LoopItem customField in fieldsLoop) 4603 { 4604 string fieldValue = customField.GetString("Product.CustomField.Value.Clean"); 4605 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; 4606 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; 4607 4608 if (customField.GetLoop("Product.CustomField.Options").Count > 0) 4609 { 4610 List<string> accumulatedValues = new List<string> (); 4611 4612 foreach (var option in customField.GetLoop("Product.CustomField.Options")) 4613 { 4614 if (option.GetBoolean("Product.CustomField.Option.IsSelected")) 4615 { 4616 accumulatedValues.Add(option.GetString("Product.CustomField.Option.Name")); 4617 } 4618 } 4619 fieldValue = string.Join(", ", accumulatedValues); 4620 } 4621 4622 if (!string.IsNullOrEmpty(customField.GetString("Product.CustomField.Name")) && !string.IsNullOrEmpty(fieldValue) && customField.GetString("Product.CustomField.Name") != "Custom sticker" && customField.GetString("Product.CustomField.Name") != "RRP") 4623 { 4624 if (string.IsNullOrEmpty(customField.GetString("Document.FullPath"))) 4625 { 4626 @RenderFieldItem(customField.GetString("Product.CustomField.Name"), fieldValue, viewType); 4627 } 4628 else if (collectAllDownloads == false) 4629 { 4630 @RenderFieldItem(customField.GetString("Product.CustomField.Name"), fieldValue, viewType, "download"); 4631 } 4632 } 4633 } 4634 } 4635 4636 @helper RenderProductSection(string layout, string viewType, string name, RazorEngine.Templating.TemplateWriter writer) 4637 { 4638 string ribbonClasses = layout == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : "u-no-padding"; 4639 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses; 4640 string ribbonSubClasses = layout == "Ribbon" ? "center-container--ribbon" : ""; 4641 4642 4643 <div class="product__section @ribbonClasses dw-mod"> 4644 <div class="center-container @ribbonSubClasses dw-mod"> 4645 @if (layout == "Section") 4646 { 4647 @Render(new Heading { Title = name, Level = 2 }) 4648 } 4649 4650 @if (viewType != "table") 4651 { 4652 <div class="grid grid--bleed u-margin-bottom--lg"> 4653 @writer 4654 </div> 4655 } 4656 else 4657 { 4658 string tableWidth = layout != "MainInformation" ? "grid__col-md-6" : "grid__col-md-12"; 4659 4660 <div class="grid grid--external-bleed-x u-margin-bottom--lg"> 4661 <div class="@tableWidth grid__col-sm-12 grid__col-xs-12"> 4662 <table class="table--no-top-border"> 4663 @writer 4664 </table> 4665 </div> 4666 </div> 4667 } 4668 </div> 4669 </div> 4670 } 4671 4672 @helper RenderProductCategoryFields(List<LoopItem> fieldsLoop, string viewType) 4673 { 4674 bool collectAllDownloads = Pageview.AreaSettings.GetItem("ProductPage").GetString("CollectAllDownloads") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("CollectAllDownloads") : true; 4675 4676 foreach (LoopItem categoryField in fieldsLoop) 4677 { 4678 string fieldValue = categoryField.GetString("Ecom:Product.CategoryField.Value"); 4679 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; 4680 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; 4681 4682 if (!string.IsNullOrEmpty(categoryField.GetString("Ecom:Product.CategoryField.Label")) && !string.IsNullOrEmpty(fieldValue)) 4683 { 4684 if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") != "9" || collectAllDownloads == false) 4685 { 4686 if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "15") 4687 { 4688 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), categoryField.GetString("Ecom:Product.CategoryField.OptionLabel"), viewType); 4689 } 4690 else if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "8") 4691 { 4692 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType, "link"); 4693 } 4694 else if (categoryField.GetString("Ecom:Product.CategoryField.TypeID") == "9") 4695 { 4696 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType, "download"); 4697 } 4698 else 4699 { 4700 @RenderFieldItem(categoryField.GetString("Ecom:Product.CategoryField.Label"), fieldValue, viewType); 4701 } 4702 } 4703 } 4704 } 4705 } 4706 4707 @helper RenderDetailsFields(IEnumerable<LoopItem> fields, string viewType) 4708 { 4709 foreach (LoopItem field in fields) 4710 { 4711 string fieldValue = field.GetString("Ecom:FieldDisplayGroup.Field.Value"); 4712 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; 4713 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; 4714 4715 if (!string.IsNullOrEmpty(field.GetString("Ecom:FieldDisplayGroup.Field.Name")) && !string.IsNullOrEmpty(fieldValue)) 4716 { 4717 if (field.GetString("Ecom:FieldDisplayGroup.Field.TypeId") == "15") 4718 { 4719 @RenderFieldItem(field.GetString("Ecom:FieldDisplayGroup.Field.Name"), field.GetString("Ecom:FieldDisplayGroup.Field.OptionLabel"), viewType); 4720 } 4721 else if (field.GetString("Ecom:FieldDisplayGroup.Field.TypeId") == "8") 4722 { 4723 @RenderFieldItem(field.GetString("Ecom:Product.CategoryField.Name"), fieldValue, viewType, "link"); 4724 } 4725 else if (field.GetString("Ecom:FieldDisplayGroup.Field.TypeId") == "9") 4726 { 4727 @RenderFieldItem(field.GetString("Ecom:FieldDisplayGroup.Field.Name"), fieldValue, viewType, "download"); 4728 } 4729 else 4730 { 4731 @RenderFieldItem(field.GetString("Ecom:FieldDisplayGroup.Field.Name"), fieldValue, viewType); 4732 } 4733 } 4734 } 4735 } 4736 4737 @helper RenderProductDownloadsFields(List<LoopItem> fieldsLoop, string viewType) 4738 { 4739 foreach (LoopItem document in fieldsLoop) 4740 { 4741 string fieldValue; 4742 if (!string.IsNullOrEmpty(document.GetString("Document.FullPath"))) 4743 { 4744 fieldValue = document.GetString("Product.CustomField.Value.Clean"); 4745 @RenderFieldItem(fieldValue, document.GetString("Document.FullPath"), viewType, "download") 4746 } 4747 4748 if (document.GetString("Ecom:Product.CategoryField.TypeID") == "9") 4749 { 4750 fieldValue = document.GetString("Ecom:Product.CategoryField.Value"); 4751 @RenderFieldItem(fieldValue, fieldValue, viewType, "download") 4752 } 4753 if (!string.IsNullOrEmpty(document.GetString("Ecom:Product:Detail.Image.Clean"))) 4754 { 4755 fieldValue = document.GetString("Ecom:Product:Detail.Image.Clean"); 4756 @RenderFieldItem("", fieldValue, viewType, "download") 4757 } 4758 } 4759 } 4760 4761 @helper RenderFieldItem(string name, string value, string viewType, string fieldType = "clean") 4762 { 4763 if (viewType != "table") 4764 { 4765 string fieldColumns = viewType == "list" ? "12" : "4"; 4766 <div class="grid__col-md-@fieldColumns grid__col-sm-12 u-margin-bottom"> 4767 <div class="u-bold"> 4768 @name 4769 </div> 4770 <div> 4771 @RenderFieldItemContent(name, value, fieldType) 4772 </div> 4773 </div> 4774 } 4775 else 4776 { 4777 <tr> 4778 <th>@name</th> 4779 <td> 4780 @RenderFieldItemContent(name, value, fieldType) 4781 </td> 4782 </tr> 4783 } 4784 } 4785 4786 @helper RenderFieldItemContent(string name, string value, string fieldType = "clean") 4787 { 4788 if (fieldType == "link") 4789 { 4790 <a target="_blank" rel="noopener" href="@value"> 4791 @if (isImage(value)) 4792 { 4793 @getIconForFile(value) 4794 } 4795 else 4796 { 4797 @value 4798 } 4799 </a> 4800 } 4801 else if (fieldType == "download") 4802 { 4803 FileInfo info = new FileInfo(Dynamicweb.Core.SystemInformation.MapPath(value)); 4804 4805 if (info.Exists) 4806 { 4807 <div class="grid grid--no-wrap"> 4808 <a href="@value" download title="@Translate("Download")" class="product__document dw-mod">@getIconForFile(value)</a> 4809 <div class="product__document-info dw-mod"> 4810 <a href="@value" download title="@Translate("Download")" class="product__document dw-mod">@Path.GetFileName(value)</a> 4811 <small class="u-block u-margin-top">@ConvertBytes(info.Length)</small> 4812 </div> 4813 </div> 4814 } 4815 } 4816 else 4817 { 4818 @value 4819 } 4820 } 4821 4822 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 4823 @using Dynamicweb.Core 4824 @using System.Text.RegularExpressions 4825 @using System 4826 @using System.Web 4827 @using System.Collections.Generic 4828 @using Dynamicweb.Rapido.Blocks 4829 @using Dynamicweb.Rapido.Blocks.Components.General 4830 4831 @functions{ 4832 BlocksPage productVideoPage = BlocksPage.GetBlockPage("Product"); 4833 } 4834 4835 @{ 4836 var selectedVideoCategories = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideoAssets").SelectedValues; 4837 var videosFromAssets = GetLoop("ImageCategories").Where(x => selectedVideoCategories.Contains(x.GetString("Category.Id"))); 4838 4839 string videosLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue : "Section"; 4840 videosLayout = videosLayout == "Ribbon" || string.IsNullOrEmpty(videosLayout) ? "Section" : videosLayout; 4841 4842 int videosCount = 0; 4843 4844 if (videosFromAssets != null) 4845 { 4846 foreach (LoopItem category in videosFromAssets) { 4847 foreach (LoopItem asset in category.GetLoop("Category.Images")) { 4848 videosCount++; 4849 } 4850 } 4851 } else { 4852 foreach (LoopItem detailField in GetLoop("Details")) 4853 { 4854 if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("youtube.com/embed") != -1) 4855 { 4856 videosCount++; 4857 } 4858 if (detailField.GetString("Ecom:Product:Detail.Text").IndexOf("iframe") != -1 && detailField.GetString("Ecom:Product:Detail.Text").IndexOf("vimeo.com") != -1) 4859 { 4860 videosCount++; 4861 } 4862 } 4863 } 4864 4865 if (videosCount > 0 && videosLayout != "hide") 4866 { 4867 Block detailsVideos = new Block() 4868 { 4869 Name = videosLayout != "MainInformation" ? Translate("Videos") : "", 4870 Id = "Videos", 4871 SortId = 60, 4872 Template = RenderProductVideos(videosCount, videosLayout), 4873 Design = new Design 4874 { 4875 Size = "12", 4876 RenderType = RenderType.Column, 4877 HidePadding = true 4878 } 4879 }; 4880 productVideoPage.Add(videosLayout, detailsVideos); 4881 } 4882 } 4883 4884 @helper RenderProductVideos(int videosCount, string layout) { 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 videoColumn = "12"; 4889 videoColumn = videosCount == 2 ? "6" : videoColumn; 4890 videoColumn = videosCount > 2 ? "4" : videoColumn; 4891 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 4892 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses; 4893 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VideosLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 4894 4895 <div class="product__section @ribbonClasses dw-mod"> 4896 <div class="center-container @ribbonSubClasses dw-mod"> 4897 @if (layout == "Section") { 4898 @Render(new Heading { Title = Translate("Videos"), Level = 2 }) 4899 } 4900 4901 <div class="grid u-margin-bottom--lg"> 4902 @if (videosFromAssets != null) { 4903 foreach (LoopItem category in videosFromAssets) { 4904 foreach (LoopItem asset in category.GetLoop("Category.Images")) { 4905 //getting video ID from youtube URL 4906 string videoCode = asset.GetString("Ecom:Product:Detail.Image.Clean"); 4907 Regex regex = new Regex(@".be\/(.[^?]*)"); 4908 Match match = regex.Match(videoCode); 4909 string videoId = ""; 4910 if (match.Success) 4911 { 4912 videoId = match.Groups[1].Value; 4913 } 4914 else 4915 { 4916 regex = new Regex(@"v=([^&]+)"); 4917 match = regex.Match(videoCode); 4918 if (match.Success) 4919 { 4920 videoId = match.Groups[1].Value; 4921 } 4922 } 4923 4924 <div class="grid__col-md-@videoColumn grid__col-lg-@videoColumn"> 4925 <div class="video-wrapper"> 4926 <div class="js-youtube-video" data-video="@videoId" id="ytPlayer@(Guid.NewGuid().ToString("N"))" data-auto-play="False" data-enable-controls="1"></div> 4927 </div> 4928 </div> 4929 } 4930 } 4931 } else { 4932 foreach (LoopItem detailField in GetLoop("Details")) 4933 { 4934 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) 4935 { 4936 <div class="grid__col-md-@videoColumn grid__col-lg-@videoColumn"> 4937 <div class="video-wrapper"> 4938 @detailField.GetString("Ecom:Product:Detail.Text") 4939 </div> 4940 </div> 4941 } 4942 } 4943 } 4944 </div> 4945 </div> 4946 </div> 4947 } 4948 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 4949 @using Dynamicweb.Core 4950 @using System 4951 @using System.Web 4952 @using System.Collections.Generic 4953 @using Dynamicweb.Rapido.Blocks.Components.General 4954 @using Dynamicweb.Rapido.Blocks 4955 @using Dynamicweb.Rapido.Services 4956 4957 4958 @functions{ 4959 BlocksPage productRelatedPage = BlocksPage.GetBlockPage("Product"); 4960 } 4961 4962 @{ 4963 string relatedProductsLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue : "Section"; 4964 relatedProductsLayout = relatedProductsLayout == "Ribbon" || string.IsNullOrEmpty(relatedProductsLayout) ? "Section" : relatedProductsLayout; 4965 bool relatedShowStock = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowStockAndShipping"); 4966 bool showAddToDownloadButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToDownloadButton"); 4967 bool relatedShowPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice"); 4968 bool relatedShowFavoriteButton = !Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("HideFavoriteButton") && Pageview.User != null; 4969 bool relatedPointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 4970 bool relatedShowCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToCartButton"); 4971 bool relatedShowViewButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowViewButton"); 4972 string relatedCartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; 4973 string relatedMoreText = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText")) ? Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText") : "View"; 4974 bool relatedShowNumber = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowProductNumber"); 4975 string relatedImageZoomOnHover = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("HoverImageZoom") ? "image-hover--zoom" : ""; 4976 4977 int relatedProductsPageSize = 4; 4978 4979 if (Pageview.Device.ToString() == "Mobile") 4980 { 4981 relatedProductsPageSize = 1; 4982 } 4983 4984 if (Pageview.Device.ToString() == "Tablet") 4985 { 4986 relatedProductsPageSize = 3; 4987 } 4988 4989 int relatedProductsColumnWidth = 12 / relatedProductsPageSize; 4990 4991 if (relatedProductsLayout != "hide") 4992 { 4993 var i = 0; 4994 foreach (LoopItem relatedGroup in GetLoop("ProductRelatedGroups")) 4995 { 4996 string relatedGroupId = ToPascalCase(relatedGroup.GetString("Ecom:Product:RelatedGroup.Name")); 4997 string baseFeedPageUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + relatedProductsPageSize + "&ProdID=" + GetString("Ecom:Product.ID") + "&feed=true"; 4998 string relatedFeed = baseFeedPageUrl + "&" + relatedGroupId + "=" + GetString("Ecom:Product.ID")+ GetString("Ecom:Product.VariantID") + "&GroupName=" + relatedGroupId; 4999 string relatedGroupName = relatedProductsLayout != "maininformation" ? relatedGroup.GetString("Ecom:Product:RelatedGroup.Name") : ""; 5000 5001 i++; 5002 5003 Block detailsRelated = new Block() 5004 { 5005 Name = relatedGroupName, 5006 Id = relatedGroupId, 5007 SortId = 70 + i, 5008 Template = RenderRelatedProducts(relatedGroupName, relatedGroupId, relatedFeed, relatedProductsLayout), 5009 Design = new Design 5010 { 5011 Size = "12", 5012 RenderType = RenderType.Column, 5013 HidePadding = true 5014 } 5015 }; 5016 5017 productRelatedPage.Add(relatedProductsLayout, detailsRelated); 5018 } 5019 } 5020 } 5021 5022 @helper RenderRelatedProducts(string name, string groupId, string relatedFeedUrl, string layout) 5023 { 5024 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 5025 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses; 5026 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("RelatedProductsLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 5027 5028 <div class="product__section @ribbonClasses dw-mod"> 5029 <div class="center-container @ribbonSubClasses dw-mod"> 5030 @if (layout == "Section") { 5031 @Render(new Heading { Title = name, Level = 2 }) 5032 } 5033 <div class="js-handlebars-root" id="ProductList_@groupId" data-template="ProductContainer" data-pre-render-template="ProductPreRenderContainer" data-json-feed="@relatedFeedUrl" data-preloader="overlay"></div> 5034 </div> 5035 </div> 5036 } 5037 5038 @* Script templates for related products *@ 5039 <script id="ProductPreRenderContainer" type="text/x-template"> 5040 <div class="u-h600px u-full-width"> 5041 <div class="grid"> 5042 <div class="grid__col-12"> 5043 <div class="pre-render-element pre-render-element--md"></div> 5044 </div> 5045 </div> 5046 </div> 5047 </script> 5048 5049 @helper RenderGridViewPriceInfo() 5050 { 5051 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 5052 bool showPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice"); 5053 bool showCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToCartButton"); 5054 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductList").GetBoolean("ShowBothPricesWithWithoutVAT"); 5055 bool isPricesWithVATEnabled = Dynamicweb.Ecommerce.Common.Context.DisplayPricesWithVat; 5056 5057 if (showPrice && Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 5058 { 5059 if (pointShopOnly) 5060 { 5061 <text> 5062 {{#if havePointPrice}} 5063 <div class="price price--product-list dw-mod">{{points}} @Translate("points")</div> 5064 @if (showCartButton) 5065 { 5066 <text> 5067 {{#unless canBePurchasedWithPoints}} 5068 <small class="help-text u-no-margin">@Translate("Not enough points to buy this")</small> 5069 {{/unless}} 5070 </text> 5071 } 5072 {{else}} 5073 @Translate("Not available") 5074 {{/if}} 5075 </text> 5076 } 5077 else 5078 { 5079 <div class="price price--product-list dw-mod">{{price}}</div> 5080 <div class="before-price {{onSale}} dw-mod">{{discount}}</div> 5081 if (showVATPrice) 5082 { 5083 <div class="vat-price vat-price--product-list u-margin-top dw-mod"> 5084 @if (isPricesWithVATEnabled) 5085 { 5086 <span>@Translate("excl. VAT")</span><span> ({{priceWithoutVAT}})</span> 5087 } 5088 else 5089 { 5090 <span>@Translate("incl. VAT")</span><span> ({{priceWithVAT}})</span> 5091 } 5092 </div> 5093 } 5094 <text> 5095 {{#if priceRRP}} 5096 <div><small>@Translate("RRP") {{priceRRP}}</small></div> 5097 {{/if}} 5098 </text> 5099 } 5100 } 5101 } 5102 5103 @helper RenderProductGridItemAddToCart() { 5104 var gridViewSettings = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView"); 5105 var ecommerceSettings = Pageview.AreaSettings.GetItem("Ecommerce"); 5106 5107 bool pointShopOnly = ecommerceSettings.GetBoolean("PointShopOnly"); 5108 bool showCartButton = gridViewSettings.GetBoolean("ShowAddToCartButton"); 5109 bool showViewButton = gridViewSettings.GetBoolean("ShowViewButton"); 5110 string viewMoreText = gridViewSettings.GetString("ViewMoreText"); 5111 viewMoreText = !string.IsNullOrEmpty(viewMoreText) ? viewMoreText : "View"; 5112 string wrapperClass = "buttons-collection--center"; 5113 int columnsCount = gridViewSettings.GetList("Columns") != null ? Converter.ToInt32(gridViewSettings.GetList("Columns").SelectedValue) : 4; 5114 bool hideButtonText = columnsCount >= 4 || Pageview.Device.ToString() == "Mobile" || Pageview.Device.ToString() == "Tablet"; 5115 5116 if (pointShopOnly && columnsCount <= 4) 5117 { 5118 hideButtonText = false; 5119 } 5120 5121 var viewBtn = new Link 5122 { 5123 Href = "{{link}}", 5124 Id = "CartButton_{{id}}", 5125 Title = Translate(viewMoreText), 5126 OnClick = "{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}", 5127 ButtonLayout = ButtonLayout.Secondary, 5128 CssClass = "u-no-margin" 5129 }; 5130 5131 if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 5132 { 5133 var addToCartBtn = new AddToCart 5134 { 5135 WrapperCssClass = wrapperClass, 5136 AddButton = new AddToCartButton 5137 { 5138 ProductId = "{{productId}}", 5139 VariantId = "{{variantid}}", 5140 UnitId = "{{unitId}}", 5141 ProductInfo = "{{productInfo}}", 5142 BuyForPoints = pointShopOnly, 5143 HideTitle = hideButtonText, 5144 OnClick = "{{facebookPixelAction}}", 5145 ExtraAttributes = new Dictionary<string, string> 5146 { 5147 { "{{disabledBuyButton}}", "" } 5148 } 5149 } 5150 }; 5151 5152 if (!pointShopOnly) 5153 { 5154 addToCartBtn.QuantitySelector = new QuantitySelector 5155 { 5156 Id = "Quantity{{id}}" 5157 }; 5158 } 5159 5160 if (showCartButton && Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 5161 { 5162 if (!showViewButton) 5163 { 5164 @Render(addToCartBtn) 5165 } 5166 else 5167 { 5168 <text>{{#if hideAddToCartButton}}</text> 5169 <div>@Render(viewBtn)</div> 5170 <text>{{else}}</text> 5171 @Render(addToCartBtn) 5172 <text>{{/if}}</text> 5173 } 5174 } 5175 else if (showViewButton) 5176 { 5177 <div>@Render(viewBtn)</div> 5178 } 5179 } 5180 else if (showViewButton) 5181 { 5182 <div>@Render(viewBtn)</div> 5183 } 5184 } 5185 5186 <script id="ProductContainer" type="text/x-template"> 5187 {{#.}} 5188 <div class="u-min-h400px u-full-width"> 5189 <div class="grid"> 5190 <div class="grid__col-45px grid__col--bleed-x"> 5191 <div class="grid__cell grid__cell--align-middle-left"> 5192 @{ 5193 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}}')" }; 5194 prevButton.ExtraAttributes.Add("", "{{prevdisabled}}"); 5195 } 5196 @Render(prevButton) 5197 </div> 5198 </div> 5199 <div class="grid__col-auto grid__col--bleed-x"> 5200 <div id="ProductsContainer" data-template="ProductGridItemContainer" class="grid product-list dw-mod" data-save-cookie="true"> 5201 {{#ProductsContainer}} 5202 <div id="Product{{productId}}" class="grid__col-@relatedProductsColumnWidth product-list__grid-item @relatedImageZoomOnHover dw-mod"> 5203 {{#Product}} 5204 <div class="grid__col--auto js-product-scroll-trigger u-no-padding u-full-height" data-params="{{googleImpression}}"> 5205 <div class="grid__cell product-list__grid-item__image dw-mod {{noImage}}"> 5206 <a href="{{link}}" 5207 onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" 5208 class="u-block u-position-relative image-hover__wrapper dw-mod"> 5209 @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" }) 5210 {{#StickersContainers}} 5211 {{>StickersContainer}} 5212 {{/StickersContainers}} 5213 </a> 5214 @if (relatedShowFavoriteButton) 5215 { 5216 <div class="favorites favorites--for-grid-view u-pull--right {{hasVariants}} dw-mod" {{hasVariants}}> 5217 {{#Favorite}} 5218 {{>FavoriteTemplate}} 5219 {{/Favorite}} 5220 </div> 5221 } 5222 </div> 5223 5224 <div class="grid__cell product-list__grid-item__price-info dw-mod"> 5225 <a href="{{link}}" onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" title="{{name}}" class="u-color-inherit"> 5226 @Render(new Heading { Title = "{{name}}", Level = 6, CssClass = "u-condensed-text u-bold" }) 5227 </a> 5228 5229 @if (relatedShowNumber) 5230 { 5231 <div class="item-number dw-mod">{{number}}</div> 5232 } 5233 5234 @RenderGridViewPriceInfo() 5235 </div> 5236 5237 <div class="product-list__grid-item__footer dw-mod"> 5238 @RenderProductGridItemAddToCart() 5239 5240 @if (User.IsStockInfoAllowed() && relatedShowStock) 5241 { 5242 <div class="u-margin-top"> 5243 <div><span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span> {{stockText}}</div> 5244 <div> 5245 {{#if deliveryText}} 5246 {{deliveryText}} 5247 {{else}} 5248 - 5249 {{/if}} 5250 </div> 5251 </div> 5252 } 5253 5254 @if (showAddToDownloadButton && Pageview.User != null) 5255 { 5256 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 } }; 5257 addButton.ExtraAttributes.Add("data-product-id", "{{productId}}"); 5258 @Render(addButton) 5259 } 5260 </div> 5261 </div> 5262 {{/Product}} 5263 </div> 5264 {{/ProductsContainer}} 5265 </div> 5266 </div> 5267 <div class="grid__col-45px grid__col--bleed-x"> 5268 <div class="grid__cell grid__cell--align-middle-right"> 5269 @{ 5270 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}}')" }; 5271 nextButton.ExtraAttributes.Add("", "{{nextdisabled}}"); 5272 } 5273 @Render(nextButton) 5274 </div> 5275 </div> 5276 </div> 5277 </div> 5278 {{/.}} 5279 </script> 5280 5281 <script id="StickersContainer" type="text/x-template"> 5282 <div class="stickers-container stickers-container--{{{convertStickerPositionToClassName Position}}} dw-mod"> 5283 {{#Stickers}} 5284 {{>Sticker}} 5285 {{/Stickers}} 5286 </div> 5287 </script> 5288 5289 <script id="Sticker" type="text/x-template"> 5290 @Render(new Sticker { Title = "{{Title}}", CssClass = "{{CssClass}}" }) 5291 </script> 5292 5293 <script> 5294 @{ 5295 bool relatedUseGoogleTagManager = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("GoogleTagManagerID")); 5296 5297 if (relatedUseGoogleTagManager) 5298 { 5299 <text> 5300 document.addEventListener("DOMContentLoaded", function (event) { 5301 Scroll.AddIsInViewportListener(".js-product-scroll-trigger", function (elem) { 5302 let googleImpression = JSON.parse(elem.getAttribute("data-params")); 5303 googleImpression.list = "Related products"; 5304 googleEnchantImpression(googleImpression); 5305 elem.classList.remove("js-product-scroll-trigger"); 5306 }); 5307 }); 5308 </text> 5309 } 5310 } 5311 </script> 5312 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 5313 @using Dynamicweb.Core 5314 @using System 5315 @using System.Web 5316 @using System.Collections.Generic 5317 @using Dynamicweb.Rapido.Blocks 5318 @using Dynamicweb.Rapido.Blocks.Components.General 5319 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 5320 @using Dynamicweb.Rapido.Services 5321 5322 @functions { 5323 BlocksPage productVariantsListPage = BlocksPage.GetBlockPage("Product"); 5324 Dictionary<string, object> variantListSettings = new Dictionary<string, object> { 5325 { "RenderVariantsAsProducts", false }, 5326 { "RenderVariantGroupsInTable", false }, 5327 { "HideImage", false }, 5328 { "HideProductNumbers", false } 5329 }; 5330 } 5331 5332 @{ 5333 var variantsCount = GetInteger("Ecom:Product.VariantCount"); 5334 string variantsListLayout = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout") != null ? Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue : "Section"; 5335 variantsListLayout = variantsListLayout == "Ribbon" ? "Section" : variantsListLayout; 5336 5337 //family members 5338 bool isFamilyMember = false; 5339 var variantGroups = GetLoop("VariantGroups"); 5340 var variantGroupCount = variantGroups.Count; 5341 if (variantGroupCount == 1) 5342 { 5343 var firstVariantGroup = Dynamicweb.Ecommerce.Services.VariantGroups.GetVariantGroup(Dynamicweb.Ecommerce.Common.Context.LanguageID, variantGroups[0]?.GetString("Ecom:VariantGroup.ID")); 5344 if (firstVariantGroup != null) 5345 { 5346 isFamilyMember = firstVariantGroup.Family; 5347 } 5348 } 5349 if (isFamilyMember) 5350 { 5351 variantListSettings["RenderVariantsAsProducts"] = variantsCount > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderFamilyVariantsAsProducts"); 5352 variantListSettings["RenderVariantGroupsInTable"] = false; 5353 variantListSettings["HideImage"] = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideImageForEachFamilyVariant"); 5354 variantListSettings["HideProductNumbers"] = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideFamilyProductNumbers"); 5355 } 5356 else 5357 { 5358 variantListSettings["RenderVariantsAsProducts"] = variantsCount > 1 && Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantsAsProductList"); 5359 variantListSettings["RenderVariantGroupsInTable"] = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("RenderVariantGroupsInTable"); 5360 variantListSettings["HideImage"] = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideImageForEachVariant"); 5361 variantListSettings["HideProductNumbers"] = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("HideProductNumbers"); 5362 } 5363 5364 if (Converter.ToBoolean(variantListSettings["RenderVariantsAsProducts"]) && variantsListLayout != "hide" && (isFamilyMember || !isFamilyMember)) 5365 { 5366 productVariantsListPage.Add(variantsListLayout, new Block 5367 { 5368 Name = variantsListLayout != "MainInformation" ? Translate("Variants list") : "", 5369 Id = "VariantsList", 5370 SortId = 20, 5371 Template = RenderVariantsProductList(variantsListLayout), 5372 Design = new Design 5373 { 5374 Size = "12", 5375 RenderType = RenderType.Column, 5376 HidePadding = true 5377 } 5378 }); 5379 5380 productVariantsListPage.Add("Section", new Block 5381 { 5382 Id = "VariantListScripts", 5383 SortId = 100, 5384 Template = RenderVariantListScripts(), 5385 Design = new Design {} 5386 }); 5387 } 5388 } 5389 5390 @helper RenderVariantsProductList(string layout) 5391 { 5392 string variantsListPageSize = HttpContext.Current.Request.QueryString.Get("PageSize") ?? "30"; 5393 string variantsFeedUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + variantsListPageSize + "&MainProductID=" + GetString("Ecom:Product.ID") + "&OnlyShowVariants=true&feed=true"; 5394 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 5395 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses; 5396 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 5397 5398 <div class="product__section @ribbonClasses dw-mod"> 5399 <div class="center-container @ribbonSubClasses dw-mod"> 5400 @if (layout == "Section") 5401 { 5402 @Render(new Heading { Title = Translate("Variants"), Level = 2 }) 5403 } 5404 <div class="js-handlebars-root" id="VariantsListRoot" data-template="VariantProductsContainer" data-json-feed="@variantsFeedUrl" data-preloader="minimal"></div> 5405 </div> 5406 </div> 5407 } 5408 5409 @helper RenderVariantListScripts() 5410 { 5411 bool showProductNumberForVariants = !Converter.ToBoolean(variantListSettings["HideProductNumbers"]); 5412 bool showImageForEachVariant = !Converter.ToBoolean(variantListSettings["HideImage"]); 5413 bool variantsPointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 5414 string variantsListPageSize = HttpContext.Current.Request.QueryString.Get("PageSize") ?? "30"; 5415 string variantsFeedUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("ProductsPage") + "&PageSize=" + variantsListPageSize + "&MainProductID=" + GetString("Ecom:Product.ID") + "&OnlyShowVariants=true&feed=true"; 5416 string variantsCartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; 5417 5418 <script id="VariantProductsContainer" type="text/x-template"> 5419 {{#.}} 5420 <div> 5421 <table id="VariantsProductsContainer" class="table u-position-relative dw-mod"> 5422 <thead> 5423 <tr> 5424 @if (showImageForEachVariant) 5425 { 5426 <td width="75">&nbsp;</td> 5427 } 5428 <td>@Translate("Product")</td> 5429 {{#AvailableCustomFields}} 5430 {{>TableFieldNameTemplate}} 5431 {{/AvailableCustomFields}} 5432 @if (Converter.ToBoolean(variantListSettings["RenderVariantGroupsInTable"])) { 5433 foreach (LoopItem variantgroup in GetLoop("VariantGroups")) 5434 { 5435 <td>@variantgroup.GetString("Ecom:VariantGroup.Name")</td> 5436 } 5437 } 5438 <td>&nbsp;</td> 5439 </tr> 5440 </thead> 5441 5442 <tbody id="VariantProductListContainer" data-template="VariantProductItemContainer" data-save-cookie="true"> 5443 {{#ProductsContainer}} 5444 {{>VariantProductItemContainer}} 5445 {{/ProductsContainer}} 5446 </tbody> 5447 </table> 5448 </div> 5449 5450 <div class="grid"> 5451 <div class="grid__col-12 grid__col--bleed-y"> 5452 @{ 5453 Button moreButton = new Button { Id = "LoadMoreButton", ButtonLayout = ButtonLayout.Primary, CssClass = "btn--full {{nextdisabled}}", Title = Translate("Load") + " " + Translate("more"), OnClick = "LoadMore.Next(this)" }; 5454 moreButton.ExtraAttributes.Add("data-current", "{{currentPage}}"); 5455 moreButton.ExtraAttributes.Add("data-page-size", "{{pageSize}}"); 5456 moreButton.ExtraAttributes.Add("data-total", "{{totalPages}}"); 5457 moreButton.ExtraAttributes.Add("data-container", "VariantProductListContainer"); 5458 moreButton.ExtraAttributes.Add("data-feed-url", variantsFeedUrl + "{{loadMoreFeedParams}}"); 5459 moreButton.ExtraAttributes.Add("", "{{nextdisabled}}"); 5460 } 5461 @Render(moreButton) 5462 </div> 5463 </div> 5464 {{/.}} 5465 </script> 5466 5467 <script id="VariantProductItemContainer" type="text/x-template"> 5468 {{#.}} 5469 <tr id="VariantProduct{{id}}" class="js-product" data-template="VariantProductItem" data-preloader="overlay" style="z-index: {{zIndex}}"> 5470 {{#Product}} 5471 {{>VariantProductItem}} 5472 {{/Product}} 5473 </tr> 5474 {{/.}} 5475 </script> 5476 5477 <script id="VariantProductItem" type="text/x-template"> 5478 {{#.}} 5479 @if (showImageForEachVariant) 5480 { 5481 <td width="75"> 5482 <div class="lightbox u-hidden-xxs"> 5483 <a href="{{link}}" onclick="Scroll.SavePosition(event)" title="{{name}}{{#if variantName}}, {{variantName}}{{/if}}"> 5484 <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}}" /> 5485 <div class="u-margin-right {{noImage}}"> 5486 <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}}" /> 5487 </div> 5488 </a> 5489 </div> 5490 </td> 5491 } 5492 5493 <td class="u-va-middle"> 5494 <a href="{{link}}" onclick="Scroll.SavePosition(event)" title="{{name}}{{#if variantName}}, {{variantName}}{{/if}}"> 5495 <h6 class="u-no-margin">{{name}}{{#if variantName}}, {{variantName}}{{/if}}</h6> 5496 </a> 5497 @if (showProductNumberForVariants) 5498 { 5499 <div class="item-number item-number--compressed u-margin-bottom dw-mod"> 5500 <div>{{number}}</div> 5501 </div> 5502 } 5503 @if (User.IsStockInfoAllowed()) 5504 { 5505 <text>{{#if stockText}}</text> 5506 <div class="item-number item-number--compressed dw-mod"> 5507 <span> 5508 <span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span> 5509 <span class="u-margin-right--lg"> {{stockText}}</span> 5510 {{deliveryText}} 5511 </span> 5512 </div> 5513 <text>{{/if}}</text> 5514 } 5515 else 5516 { 5517 <div class="grid__cell-footer stickers-container stickers-container--block dw-mod"> 5518 {{#Stickers}} 5519 {{>MiniSticker}} 5520 {{/Stickers}} 5521 </div> 5522 } 5523 </td> 5524 {{#CustomFields}} 5525 {{>TableFieldValueTemplate}} 5526 {{/CustomFields}} 5527 @if (Converter.ToBoolean(variantListSettings["RenderVariantGroupsInTable"])) 5528 { 5529 <text> 5530 {{#VariantSelectionNames}} 5531 {{>TableFieldNameTemplate}} 5532 {{/VariantSelectionNames}} 5533 </text> 5534 } 5535 <td class="u-va-middle"> 5536 @if (Dynamicweb.Rapido.Services.User.IsPricesAllowed() && !Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 5537 { 5538 <div class="u-hidden-sm"> 5539 <div class="u-full-width u-ta-right u-padding-right"> 5540 <div class="before-price {{onSale}} before-price--micro dw-mod">{{discount}}</div> 5541 <div class="price price--product-list price--micro dw-mod">{{price}}</div> 5542 </div> 5543 </div> 5544 } 5545 5546 <div class="grid grid--align-center grid--justify-end"> 5547 <div class="u-margin-right u-hidden-xs u-hidden-xxs"> 5548 @if (variantsPointShopOnly) 5549 { 5550 <text> 5551 {{#if canBePurchasedWithPoints}} 5552 <div class="price price--product-list price--micro dw-mod">{{points}} @Translate("points")</div> 5553 {{else}} 5554 {{#if havePointPrice}} 5555 <small class="help-text u-no-margin u-margin-top">@Translate("Not enough points to buy this")</small> 5556 {{else}} 5557 <small class="help-text u-no-margin u-margin-top">@Translate("Not available")</small> 5558 {{/if}} 5559 {{/if}} 5560 </text> 5561 } 5562 else if (Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 5563 { 5564 <div class="before-price before-price--micro {{onSale}} dw-mod">{{discount}}</div> 5565 <div class="price price--condensed price--product-list dw-mod">{{price}}</div> 5566 } 5567 </div> 5568 5569 @if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 5570 { 5571 var addToCartBtn = new AddToCart 5572 { 5573 AddButton = new AddToCartButton 5574 { 5575 HideTitle = true, 5576 ProductId = "{{productId}}", 5577 VariantId = "{{variantid}}", 5578 UnitId = "{{unitId}}", 5579 ProductInfo = "{{productInfo}}", 5580 BuyForPoints = variantsPointShopOnly, 5581 OnClick = "{{facebookPixelAction}}" 5582 }, 5583 UnitSelector = new UnitSelector 5584 { 5585 OptionsContent = "{{#unitOptions}}{{>VariantUnitOption}}{{/unitOptions}}", 5586 Id = "UnitOptions_{{id}}", 5587 SelectedOption = "{{unitName}}", 5588 CssClass = "{{hasUnits}}" 5589 } 5590 }; 5591 5592 if (!variantsPointShopOnly) 5593 { 5594 addToCartBtn.QuantitySelector = new QuantitySelector 5595 { 5596 Id = "Quantity_{{id}}" 5597 }; 5598 } 5599 5600 <div class="grid__cell u-flex-grow--0"> 5601 @Render(addToCartBtn) 5602 </div> 5603 } 5604 <div class="favorites u-margin-left dw-mod"> 5605 {{#Favorite}} 5606 {{>FavoriteTemplate}} 5607 {{/Favorite}} 5608 </div> 5609 </div> 5610 </td> 5611 {{/.}} 5612 </script> 5613 5614 <script id="TableFieldNameTemplate" type="text/x-template"> 5615 <td class="u-va-middle">{{name}}</td> 5616 </script> 5617 5618 <script id="TableFieldValueTemplate" type="text/x-template"> 5619 <td class="u-va-middle">{{value}}</td> 5620 </script> 5621 5622 <script id="MiniSticker" type="text/x-template"> 5623 <div class="stickers-container__tag stickers-container__tag--micro {{CssClass}} dw-mod">{{Title}}</div> 5624 </script> 5625 5626 <script id="VariantUnitOption" type="text/x-template"> 5627 <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent(this.closest('.js-product').id, '{{link}}&feed=true&UnitID={{value}}')">{{name}}</div> 5628 </script> 5629 } 5630 5631 5632 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 5633 @using Dynamicweb.Core 5634 @using System 5635 @using System.Web 5636 @using System.Collections.Generic 5637 @using Dynamicweb.Rapido.Blocks 5638 @using Dynamicweb.Rapido.Blocks.Components.General 5639 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 5640 5641 @functions { 5642 BlocksPage productVariantsMatrixPage = BlocksPage.GetBlockPage("Product"); 5643 } 5644 5645 5646 @{ 5647 var matrixLayoutSetting = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsMatrixLayout"); 5648 string variantsMatrixLayout = matrixLayoutSetting != null && !string.IsNullOrEmpty(matrixLayoutSetting.SelectedValue) ? matrixLayoutSetting.SelectedValue : "Section"; 5649 variantsMatrixLayout = variantsMatrixLayout == "Ribbon" ? "Section" : variantsMatrixLayout; 5650 bool renderVariantsAsMatrix = GetInteger("Ecom:Product.VariantCount") > 1 && variantsMatrixLayout.ToLower() != "hide" && Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("EnableVariantMatrix"); 5651 5652 if (renderVariantsAsMatrix) 5653 { 5654 Block variantsMatrix = new Block() 5655 { 5656 Name = Translate("Variants"), 5657 Id = "VariantsMatrix", 5658 SortId = 15, 5659 Template = RenderVariantsMatrixSection(variantsMatrixLayout), 5660 Design = new Design 5661 { 5662 Size = "12", 5663 RenderType = RenderType.Column, 5664 HidePadding = true 5665 } 5666 }; 5667 5668 if (variantsMatrixLayout == "Section") { 5669 productVariantsMatrixPage.Add(variantsMatrix); 5670 } else { 5671 productVariantsMatrixPage.Add(variantsMatrixLayout, variantsMatrix); 5672 } 5673 } 5674 } 5675 5676 @helper RenderVariantsMatrixSection(string layout) 5677 { 5678 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; 5679 string ribbonClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "product__section--ribbon paragraph-container paragraph-container--full-width" : ""; 5680 ribbonClasses = layout == "Tabs" ? "" : ribbonClasses; 5681 string ribbonSubClasses = Pageview.AreaSettings.GetItem("ProductPage").GetList("VariantsListLayout").SelectedValue == "Ribbon" ? "center-container--ribbon" : ""; 5682 5683 List<LoopItem> variantInfos = GetLoop("VariantInfos"); 5684 string productId = GetString("Ecom:Product.ID"); 5685 string pageId = Pageview.Page.ID.ToString(); 5686 5687 5688 <div class="product__section u-no-padding @ribbonClasses dw-mod"> 5689 <div class="center-container @ribbonSubClasses dw-mod"> 5690 @RenderVariantInfoMatrix(variantInfos, productId, pageId, 0, "add") 5691 </div> 5692 </div> 5693 } 5694 5695 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 5696 @using Dynamicweb.Rendering 5697 @using Dynamicweb.Core 5698 @using System 5699 @using System.Web 5700 @using System.Collections.Generic 5701 @using Dynamicweb.Rapido.Blocks 5702 @using Dynamicweb.Rapido.Blocks.Components 5703 @using Dynamicweb.Rapido.Blocks.Components.General 5704 5705 5706 @* Component - Variant Info Matrix. This replaces the old Variant Matrix with a much cleaner approach *@ 5707 5708 @helper RenderVariantInfoMatrix(List<LoopItem> variantInfos, string productId, string pageId, double totalPrice = 0, string actionType = "update") { 5709 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; 5710 bool hideAddToCartButton = Pageview.AreaSettings.GetItem("ProductPage").GetBoolean("hideAddToCartButton"); 5711 5712 string currencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 5713 string countryCode = Pageview.Area.CultureInfo != null ? Pageview.Area.CultureInfo.Name : "en-US"; 5714 5715 int loopCount = 0; 5716 int dimensionsCount = 0; 5717 bool firstRun = true; 5718 List<string> headerLabels = new List<string>(); 5719 5720 //Collect the missing data needed to render matrixes 5721 foreach (var variantInfoFirst in variantInfos) 5722 { 5723 dimensionsCount = 1; 5724 5725 foreach (var variantInfoSecond in variantInfoFirst.GetLoop("VariantInfos")) 5726 { 5727 dimensionsCount = 2; 5728 5729 if (firstRun) { 5730 headerLabels.Add(variantInfoSecond.GetString("OptionName")); 5731 } 5732 5733 foreach (var variantInfoThird in variantInfoSecond.GetLoop("VariantInfos")) 5734 { 5735 dimensionsCount = 3; 5736 } 5737 } 5738 5739 firstRun = false; 5740 } 5741 5742 @*One dimension*@ 5743 if (dimensionsCount == 1) 5744 { 5745 int totalQuantity = 0; 5746 5747 <table cellspacing="0" class="table matrix js-matrix dw-mod"> 5748 <thead class="matrix__head dw-mod"> 5749 <tr> 5750 @foreach (var variantInfoFirst in variantInfos) 5751 { 5752 <td class="u-bold u-ta-center" width="80" > 5753 <div>@variantInfoFirst.GetString("OptionName")</div> 5754 <small>@variantInfoFirst.GetString("VariantId")</small> 5755 </td> 5756 } 5757 <td width="80px" align="right" class="matrix-label-field-right dw-mod">@Translate("Totals")</td> 5758 <td>&nbsp;</td> 5759 </tr> 5760 </thead> 5761 <tbody> 5762 <tr> 5763 @foreach (var variantInfoFirst in variantInfos) 5764 { 5765 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; 5766 5767 loopCount++; 5768 totalQuantity += variantInfoFirst.GetInteger("Quantity"); 5769 5770 <td class="matrix__input-cell dw-mod"> 5771 @if (variantInfoFirst.GetBoolean("IsProduct")) 5772 { 5773 <input type="hidden" name="ProductLoopCounter@(loopCount)" value="@(loopCount)" /> 5774 <input type="hidden" name="ProductID@(loopCount)" value="@productId" /> 5775 <input type="hidden" name="VariantID@(loopCount)" value="@variantInfoFirst.GetString("VariantId")" /> 5776 <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"> 5777 } else { 5778 <div class="matrix__cell-disabled dw-mod"></div> 5779 } 5780 </td> 5781 } 5782 <td class="u-va-middle"> 5783 <div class="u-bold u-ta-right matrix-label-field-right dw-mod" data-row-total="ONE"> 5784 @totalQuantity 5785 </div> 5786 </td> 5787 <td class="u-bold u-va-middle u-ta-right matrix-label-field-right dw-mod"> 5788 <div class="js-total-price" data-currency-code="@currencyCode" data-country-code="@countryCode"></div> 5789 </td> 5790 </tr> 5791 </tbody> 5792 <tfoot> 5793 <tr> 5794 <td colspan="@(variantInfos.Count + 2)">&nbsp;</td> 5795 </tr> 5796 @if (!hideAddToCartButton) 5797 { 5798 <tr> 5799 <td colspan="@(variantInfos.Count + 2)" class="u-ta-right"> 5800 <div class="u-padding--lg"> 5801 @if (actionType == "update") { 5802 @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" }) 5803 } else if (actionType == "justadd") { 5804 @Render(new Button { OnClick = "Matrix.AddToCart(this, '" + pageId + "');", Title = Translate("Add"), ButtonLayout = ButtonLayout.Tertiary, CssClass = "u-no-margin" }) 5805 } else { 5806 @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" }) 5807 } 5808 </div> 5809 </td> 5810 </tr> 5811 } 5812 </tfoot> 5813 </table> 5814 } 5815 5816 @*Two dimensions*@ 5817 if (dimensionsCount == 2) 5818 { 5819 Dictionary<string, int> columnTotals = new Dictionary<string, int>(); 5820 int counter = 0; 5821 int totalProducts = 0; 5822 int totalColumns = 0; 5823 5824 <table class="table matrix js-matrix dw-mod" cellspacing="0"> 5825 <thead class="matrix__head dw-mod"> 5826 <tr> 5827 <td width="160">&nbsp;</td> 5828 @foreach (string label in headerLabels) 5829 { 5830 <td class="u-bold u-ta-center" width="80">@label</td> 5831 } 5832 <td align="right" width="80" class="matrix-label-field-right dw-mod">@Translate("Totals")</td> 5833 <td>&nbsp;</td> 5834 </tr> 5835 </thead> 5836 <tbody> 5837 @foreach (var variantInfoFirst in variantInfos) 5838 { 5839 int totalRowQuantity = 0; 5840 counter += variantInfoFirst.GetInteger("Quantity"); 5841 totalColumns = variantInfoFirst.GetLoop("VariantInfos").Count; 5842 5843 <tr> 5844 <td class="matrix-label-field-left dw-mod"> 5845 <div class="u-pull--left"> 5846 <div>@variantInfoFirst.GetString("OptionName")</div> 5847 <small>@variantInfoFirst.GetString("VariantId")</small> 5848 </div> 5849 5850 @if (!string.IsNullOrEmpty(variantInfoFirst.GetString("Image"))) { 5851 <div class="matrix-option-image u-pull--right dw-mod" onclick="Matrix.ShowOptionImageModal(this)" data-img-src="/files/@variantInfoFirst.GetString("Image")"> 5852 @Render(new Image { 5853 Path = variantInfoFirst.GetString("Image"), 5854 ImageDefault = new ImageSettings { 5855 Width = 28, 5856 Height = 28 5857 }, 5858 ImageMedium = new ImageSettings { 5859 Width = 28, 5860 Height = 28 5861 }, 5862 ImageSmall = new ImageSettings { 5863 Width = 28, 5864 Height = 28 5865 } 5866 }) 5867 </div> 5868 } 5869 </td> 5870 @foreach (var variantInfoSecond in variantInfoFirst.GetLoop("VariantInfos")) 5871 { 5872 loopCount++; 5873 totalRowQuantity += variantInfoSecond.GetInteger("Quantity"); 5874 5875 string optionName = variantInfoSecond.GetString("OptionName"); 5876 int optionQuantity = variantInfoSecond.GetInteger("Quantity"); 5877 if (columnTotals.ContainsKey(optionName)) { 5878 columnTotals[optionName] += optionQuantity; 5879 } else { 5880 columnTotals.Add(optionName, optionQuantity); 5881 } 5882 5883 <td class="matrix__input-cell dw-mod"> 5884 @if (variantInfoSecond.GetBoolean("IsProduct")) { 5885 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; 5886 5887 <input type="hidden" name="ProductLoopCounter@(loopCount)" value="@(loopCount)" /> 5888 <input type="hidden" name="ProductID@(loopCount)" value="@productId" /> 5889 <input type="hidden" name="VariantID@(loopCount)" value="@variantInfoSecond.GetString("VariantId")" /> 5890 <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")"> 5891 } else { 5892 <div class="matrix__cell-disabled dw-mod"></div> 5893 } 5894 </td> 5895 } 5896 <td class="u-va-middle matrix-label-field-right dw-mod"> 5897 <div class="u-bold u-ta-right" data-row-total="@variantInfoFirst.GetString("OptionName")"> 5898 @totalRowQuantity 5899 </div> 5900 </td> 5901 <td>&nbsp;</td> 5902 </tr> 5903 } 5904 </tbody> 5905 <tfoot> 5906 <tr> 5907 <td class="u-bold u-va-middle matrix-label-field-left dw-mod">@Translate("Totals")</td> 5908 @foreach (var item in columnTotals) 5909 { 5910 totalProducts += item.Value; 5911 5912 <td> 5913 <div class="u-bold u-ta-center u-padding--lg" data-column-total="@item.Key"> 5914 @item.Value 5915 </div> 5916 </td> 5917 } 5918 <td class="u-bold u-va-middle u-ta-right matrix-label-field-right dw-mod" align="right"> 5919 <div class="js-total-quantity">@totalProducts</div> 5920 </td> 5921 <td class="u-bold u-va-middle u-ta-right matrix-label-field-right dw-mod"> 5922 <div class="js-total-price" data-currency-code="@currencyCode" data-country-code="@countryCode"></div> 5923 </td> 5924 </tr> 5925 <tr> 5926 <td colspan="@(totalColumns + 4)" class="u-ta-right u-no-padding"> 5927 <div class="u-padding--lg"> 5928 @if (actionType == "update") { 5929 @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" }) 5930 } else { 5931 @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" }) 5932 } 5933 </div> 5934 </td> 5935 </tr> 5936 </tfoot> 5937 </table> 5938 } 5939 5940 5941 Modal optionColorImage = new Modal { 5942 Id = "OptionColorImage", 5943 BodyTemplate = @Render(new Image { Path = "/Files/Images/placeholder.gif", Id = "OptionColorImageElement", DisableImageEngine = true, DisableLazyLoad = true }), 5944 Width = ModalWidth.Full 5945 }; 5946 5947 @Render(optionColorImage) 5948 } 5949 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 5950 @using Dynamicweb.Core 5951 @using System 5952 @using System.Web 5953 @using System.Collections.Generic 5954 @using Dynamicweb.Rapido.Blocks 5955 @functions { 5956 BlocksPage productSnippetsPage = BlocksPage.GetBlockPage("Product"); 5957 } 5958 5959 @{ 5960 Block googleProductSchema = new Block() 5961 { 5962 Id = "GoogleProductSchema", 5963 SortId = 10, 5964 Template = RenderGoogleProductSchema() 5965 }; 5966 5967 productSnippetsPage.Add("Snippets", googleProductSchema); 5968 } 5969 5970 @helper RenderGoogleProductSchema() 5971 { 5972 var siteURL = Dynamicweb.Context.Current.Request.Url.Scheme + "://" + Dynamicweb.Context.Current.Request.Url.Host; 5973 var image = GetProductImage(); 5974 var brand = GetString("Ecom:Product:Field.brand.Value"); 5975 var variantid = !string.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) ? GetString("Ecom:Product.VariantID") : GetString("Ecom:Product.VariantID.Extented"); 5976 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 : "")); 5977 5978 <script type="application/ld+json"> 5979 { 5980 "@@context": "http://schema.org/", 5981 "@@type": "Product", 5982 "name": "@GetString("Ecom:Product.Name")", 5983 @if (!string.IsNullOrEmpty(image)) 5984 { 5985 <text>"image": [ 5986 "@siteURL/Admin/Public/GetImage.ashx?width=400&height=400&crop=0&Compression=75&DoNotUpscale=true&image=@image", 5987 "@siteURL/Admin/Public/GetImage.ashx?width=400&height=300&crop=0&Compression=75&DoNotUpscale=true&image=@image", 5988 "@siteURL/Admin/Public/GetImage.ashx?width=448&height=225&crop=0&Compression=75&DoNotUpscale=true&image=@image" 5989 ],</text> 5990 } 5991 "description": "@GetString("Ecom:Product.ShortDescription")", 5992 "mpn": "925872", 5993 @if (!string.IsNullOrEmpty(brand)) 5994 { 5995 <text>"brand": { 5996 "@@type": "Thing", 5997 "name": "@brand" 5998 },</text> 5999 } 6000 "offers": { 6001 "@@type": "Offer", 6002 "priceCurrency": "@GetString("Ecom:Product.Price.Currency.Code")", 6003 "price": "@GetString("Ecom:Product.Price.Price")", 6004 "availability": "@(GetInteger("Ecom:Product.Stock") > 0 ? "InStock" : "OutOfStock")", 6005 "url": "@url" 6006 } 6007 } 6008 </script> 6009 } 6010 6011 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 6012 6013 @using Dynamicweb.Rapido.Blocks 6014 6015 @functions { 6016 BlocksPage snippetsTemplatesPage = BlocksPage.GetBlockPage("Product"); 6017 } 6018 6019 @{ 6020 snippetsTemplatesPage.Add(new Block { 6021 Id = "FavoritesTemplates", 6022 SortId = 100, 6023 Template = RenderFavoritesTemplates() 6024 }); 6025 } 6026 6027 @helper RenderFavoritesTemplates() 6028 { 6029 var selectedFavoriteIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "star"; 6030 string favoriteIcon = "fas fa-" + selectedFavoriteIcon; 6031 string favoriteOutlineIcon = "fal fa-" + selectedFavoriteIcon; 6032 bool useFacebookPixel = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("FacebookPixelID")); 6033 string currentFavoriteListId = HttpContext.Current.Request.QueryString.Get("ListID"); 6034 6035 <script id="FavoriteTemplate" type="text/x-template"> 6036 <div class="favorites-list u-ta-left js-favorites-list"> 6037 @Render(new Button { 6038 CssClass = "u-no-margin js-favorite-btn", 6039 Icon = new Icon 6040 { 6041 Name = "{{#if isInAnyFavoriteList}}" + favoriteIcon + "{{else}}" + favoriteOutlineIcon + "{{/if}}", 6042 CssClass = "fa-1_5x", 6043 LabelPosition = IconLabelPosition.After 6044 }, 6045 ButtonLayout = ButtonLayout.LinkClean, 6046 ButtonType = ButtonType.Button, 6047 OnClick = "document.getElementById('FavoriteTrigger_{{id}}').checked = true" 6048 }) 6049 <input type="checkbox" id="FavoriteTrigger_{{id}}" class="dropdown-trigger" /> 6050 <div class="dropdown dropdown--position-32px"> 6051 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod"> 6052 <ul class="list list--clean dw-mod"> 6053 {{#FavoriteLists}} 6054 {{>FavoriteListItem}} 6055 {{/FavoriteLists}} 6056 </ul> 6057 </div> 6058 <label class="dropdown-trigger-off" for="FavoriteTrigger_{{id}}"></label> 6059 </div> 6060 </div> 6061 </script> 6062 6063 <script id="FavoriteListItem" type="text/x-template"> 6064 <li> 6065 @{ 6066 var button = new Button { 6067 CssClass = "list__link u-no-underline", 6068 OnClick = "toggleFavAction(this, event)", 6069 Icon = new Icon { Name = "{{#if isInFavoriteList}}" + favoriteIcon + "{{else}}" + favoriteOutlineIcon + "{{/if}}", LabelPosition = IconLabelPosition.After }, 6070 AltText = "{{#if isInFavoriteList}}" + Translate("Remove from") + " {{name}}{{else}}" + Translate("Add to") + " {{name}}{{/if}}", 6071 Title = "{{name}}", 6072 ButtonType = ButtonType.Button, 6073 ButtonLayout = ButtonLayout.LinkClean, 6074 ExtraAttributes = new Dictionary<string, string> 6075 { 6076 { "data-list-id", "{{listId}}" }, 6077 { "data-list-name", "{{name}}" }, 6078 { "data-remove-link", "{{removeLink}}" }, 6079 { "data-add-link", "{{addLink}}" }, 6080 { "data-is-in-list", "{{isInFavoriteList}}" }, 6081 6082 } 6083 }; 6084 if (useFacebookPixel) 6085 { 6086 button.ExtraAttributes.Add("data-facebook-object", "{{facebookPixelAddAction}}"); 6087 } 6088 } 6089 <div class="grid__cell"> 6090 @Render(button) 6091 </div> 6092 </li> 6093 </script> 6094 6095 <script> 6096 @if (!string.IsNullOrEmpty(currentFavoriteListId)) 6097 { 6098 <text> 6099 window.currentFavoriteListId = "@currentFavoriteListId"; 6100 </text> 6101 } 6102 function toggleFavAction(button, event) { 6103 if (button.getAttribute('data-add-link').indexOf('CCCreateNewList') > -1) { 6104 Scroll.SavePosition(event); 6105 @if (useFacebookPixel) 6106 { 6107 <text> 6108 fbq('track', 'AddToWishlist', JSON.parse(button.getAttribute('data-facebook-object'))); 6109 </text> 6110 } 6111 location.href = button.getAttribute('data-add-link'); 6112 return; 6113 } 6114 let isAdd = button.getAttribute('data-is-in-list') == "false"; 6115 Request.Fetch().get( 6116 isAdd ? button.getAttribute('data-add-link') : button.getAttribute('data-remove-link'), 6117 function (result) { 6118 button.querySelector('i').className = isAdd ? '@favoriteIcon u-margin-right--lg' : '@favoriteOutlineIcon u-margin-right--lg'; 6119 button.setAttribute('data-is-in-list', isAdd); 6120 button.setAttribute('title', (!isAdd ? '@Translate("Add to") ' : '@Translate("Remove from") ') + button.getAttribute('data-list-name')) 6121 let favList = button.closest('.js-favorites-list'); 6122 let favBtn = favList.querySelector('.js-favorite-btn i'); 6123 let isInAnyFavoriteList = favList.querySelector('[data-is-in-list=true]') != null; 6124 if (isInAnyFavoriteList) { 6125 favBtn.className = '@favoriteIcon' + ' fa-1_5x'; 6126 } else { 6127 favBtn.className = '@favoriteOutlineIcon' + ' fa-1_5x'; 6128 } 6129 @if (useFacebookPixel) 6130 { 6131 <text> 6132 if (isAdd) { 6133 fbq('track', 'AddToWishlist', JSON.parse(button.getAttribute('data-facebook-object'))); 6134 } 6135 </text> 6136 } 6137 if (window.currentFavoriteListId != null) { //if this page is favorite list 6138 let listId = button.getAttribute("data-list-id"); 6139 if (listId == window.currentFavoriteListId && !isAdd) { 6140 location.reload(); 6141 } 6142 } 6143 }, 6144 function () { 6145 console.error("FavoriteLists: Error in ToggleFavAction request"); 6146 }, 6147 false 6148 ); 6149 } 6150 </script> 6151 } 6152 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 6153 @using Dynamicweb.Core 6154 @using System 6155 @using System.Web 6156 @using System.Collections.Generic 6157 @using Dynamicweb.Rapido.Blocks 6158 6159 @{ 6160 BlocksPage customProductBlocks = BlocksPage.GetBlockPage("Product"); 6161 6162 } 6163 6164 @* // Include custom files *@ 6165 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 6166 @using Dynamicweb.Core 6167 @using System 6168 @using System.Web 6169 @using System.Globalization; 6170 @using System.Collections.Generic 6171 @using Dynamicweb.Rapido.Blocks 6172 @using System.Linq 6173 6174 @functions { 6175 BlocksPage productFieldsPageCustom = BlocksPage.GetBlockPage("Product"); 6176 } 6177 6178 @{ 6179 6180 if (displayGroupsLayout != "hide") 6181 { 6182 var detailFieldsDisplayGroups = Pageview.AreaSettings.GetItem("ProductPage").GetList("ProductDetailFields").SelectedValues; 6183 var displayGroups = GetLoop("FieldDisplayGroups").Where(x => !detailFieldsDisplayGroups.Contains(x.GetString("Ecom:FieldDisplayGroup.ID"))); 6184 6185 foreach (LoopItem group in displayGroups) 6186 { 6187 int fieldsCount = 0; 6188 6189 foreach (LoopItem field in group.GetLoop("Fields")) 6190 { 6191 string fieldValue = field.GetString("Ecom:FieldDisplayGroup.Field.Value"); 6192 List<string> splitValue = new List<string>(fieldValue.Split(' ')); 6193 6194 // 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. 6195 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"))) 6196 { 6197 fieldsCount++; 6198 } 6199 } 6200 6201 if (fieldsCount != 0) 6202 { 6203 Block displayGroupCustom = new Block() 6204 { 6205 Name = displayGroupsLayout != "MainInformation" ? group.GetString("Ecom:FieldDisplayGroup.Name") : "", 6206 Id = "DisplayGroup_" + group.GetString("Ecom:FieldDisplayGroup.ID"), 6207 SortId = 40, 6208 Template = RenderProductSection(displayGroupsLayout, categoryFieldsView, group.GetString("Ecom:FieldDisplayGroup.Name"), RenderDetailsFieldsCustom(group.GetLoop("Fields"), categoryFieldsView)), 6209 Design = new Design 6210 { 6211 Size = "12", 6212 RenderType = RenderType.Column, 6213 HidePadding = true 6214 } 6215 }; 6216 productFieldsPageCustom.ReplaceBlock(displayGroupCustom); 6217 } 6218 else 6219 { 6220 Block displayGroupCustom = new Block() 6221 { 6222 Name = displayGroupsLayout != "MainInformation" ? group.GetString("Ecom:FieldDisplayGroup.Name") : "", 6223 Id = "DisplayGroup_" + group.GetString("Ecom:FieldDisplayGroup.ID"), 6224 SortId = 40, 6225 Design = new Design 6226 { 6227 Size = "12", 6228 RenderType = RenderType.Column, 6229 HidePadding = true 6230 } 6231 }; 6232 6233 productFieldsPageCustom.RemoveBlock(displayGroupCustom); 6234 } 6235 } 6236 } 6237 } 6238 6239 @helper RenderDetailsFieldsCustom(IEnumerable<LoopItem> fields, string viewType) 6240 { 6241 foreach (LoopItem field in fields) 6242 { 6243 string fieldValue = field.GetString("Ecom:FieldDisplayGroup.Field.Value"); 6244 List<string> splitValue = new List<string>(fieldValue.Split(' ')); 6245 6246 fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; 6247 fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; 6248 6249 if (!string.IsNullOrEmpty(field.GetString("Ecom:FieldDisplayGroup.Field.Name")) && !string.IsNullOrEmpty(fieldValue) && !splitValue.Exists(x => x.Equals("0") || x.Equals("0.00"))) 6250 { 6251 if (field.GetString("Ecom:FieldDisplayGroup.Field.TypeId") == "15") 6252 { 6253 @RenderFieldItem(field.GetString("Ecom:FieldDisplayGroup.Field.Name"), field.GetString("Ecom:FieldDisplayGroup.Field.OptionLabel"), viewType); 6254 } 6255 else if (field.GetString("Ecom:FieldDisplayGroup.Field.TypeId") == "8") 6256 { 6257 @RenderFieldItem(field.GetString("Ecom:Product.CategoryField.Name"), fieldValue, viewType, "link"); 6258 } 6259 else if (field.GetString("Ecom:FieldDisplayGroup.Field.TypeId") == "9") 6260 { 6261 @RenderFieldItem(field.GetString("Ecom:FieldDisplayGroup.Field.Name"), fieldValue, viewType, "download"); 6262 } 6263 else 6264 { 6265 @RenderFieldItem(field.GetString("Ecom:FieldDisplayGroup.Field.Name"), fieldValue, viewType); 6266 } 6267 } 6268 } 6269 } 6270 6271 6272 <div class="product__info dw-mod u-margin-bottom--lg js-product"> 6273 <div class="grid grid--align-content-start"> 6274 @* The @RenderBlockList base helper is included in Components/GridBuilder.cshtml *@ 6275 @RenderBlockList(productsPage.BlocksRoot.BlocksList) 6276 </div> 6277 </div> 6278 6279 @helper RenderProductTop() 6280 { 6281 List<Block> subBlocks = productsPage.GetBlockListById("Top").OrderBy(item => item.SortId).ToList(); 6282 6283 <div class="product__top paragraph-container paragraph-container--full-width dw-mod"> 6284 <div class="center-container dw-mod"> 6285 <div class="grid"> 6286 @RenderBlockList(subBlocks) 6287 </div> 6288 </div> 6289 </div> 6290 } 6291 6292 @helper RenderProductMiniTabs() 6293 { 6294 List<Block> subBlocks = productsPage.GetBlockListById("MiniTabs").OrderBy(item => item.SortId).ToList(); 6295 6296 if (subBlocks.Count > 0) 6297 { 6298 <div class="grid__col-12 product__info tabs u-no-padding u-margin-bottom--lg dw-mod"> 6299 @{ 6300 bool firstTab = true; 6301 foreach (Block item in subBlocks) 6302 { 6303 string isChecked = firstTab ? "checked" : ""; 6304 firstTab = false; 6305 6306 <input type="radio" class="tabs__trigger" name="productMiniTabs" id="@item.Id" onchange="bLazy.revalidate()" @isChecked /> 6307 } 6308 } 6309 6310 <div class="tabs__list dw-mod"> 6311 @foreach (Block item in subBlocks) 6312 { 6313 <label for="@item.Id" class="tabs__label dw-mod">@item.Name</label> 6314 } 6315 </div> 6316 6317 <div class="tabs__blocks dw-mod"> 6318 @foreach (Block item in subBlocks) 6319 { 6320 string hidePadding = item.Design.HidePadding ? "u-no-padding" : ""; 6321 6322 if (item.Design.RenderType != RenderType.Hide) 6323 { 6324 <div class="tabs__block u-border dw-mod" id="Block__@item.Id"> 6325 <block class="product__block paragraph-container product__block--bordered dw-mod"> 6326 <div class="center-container dw-mod"> 6327 @RenderBlock(item) 6328 </div> 6329 </block> 6330 </div> 6331 } 6332 } 6333 </div> 6334 </div> 6335 } 6336 } 6337 6338 @helper RenderProductTabs() 6339 { 6340 List<Block> subBlocks = productsPage.GetBlockListById("Tabs").OrderBy(item => item.SortId).ToList(); 6341 6342 if (Pageview.Device.ToString() != "Mobile") { 6343 <div class="grid__col-12 product__info product__info--tabs tabs dw-mod"> 6344 @{ 6345 bool firstTab = true; 6346 foreach (Block item in subBlocks) 6347 { 6348 string isChecked = firstTab ? "checked" : ""; 6349 firstTab = false; 6350 6351 <input type="radio" class="tabs__trigger" name="productTabs" id="@item.Id" onchange="bLazy.revalidate()" @isChecked /> 6352 } 6353 } 6354 6355 <div class="tabs__list dw-mod"> 6356 @foreach (Block item in subBlocks) 6357 { 6358 if (item.Design.RenderType != RenderType.Hide) 6359 { 6360 <label for="@item.Id" class="tabs__label dw-mod">@item.Name</label> 6361 } 6362 } 6363 </div> 6364 6365 <div class="tabs__blocks dw-mod"> 6366 @foreach (Block item in subBlocks) 6367 { 6368 if (item.Design.RenderType != RenderType.Hide) 6369 { 6370 <div class="tabs__block dw-mod" id="Block__@item.Id"> 6371 <section class="product__section paragraph-container paragraph-container--full-width product__section--bordered dw-mod"> 6372 <div class="center-container u-padding--lg dw-mod"> 6373 @RenderBlock(item) 6374 </div> 6375 </section> 6376 </div> 6377 } 6378 } 6379 </div> 6380 </div> 6381 } else { 6382 foreach (Block item in subBlocks) 6383 { 6384 if (item.Design.RenderType != RenderType.Hide) 6385 { 6386 <div class="center-container dw-mod"> 6387 <div class="padding-position-left padding-size-sm"> 6388 @Render(new Heading { Title = item.Name, Level = 2 }) 6389 </div> 6390 6391 @RenderBlock(item) 6392 </div> 6393 } 6394 } 6395 } 6396 }