Error executing template "Designs/Rapido/eCom/Productlist/ConfiguratorRender.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_4f7ef9f65dbf486dab0019202e44bf73.b__15_0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\FactorAdman\egholm2019.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Productlist\ConfiguratorRender.cshtml:line 957
   at CompiledRazorTemplates.Dynamic.RazorEngine_4f7ef9f65dbf486dab0019202e44bf73.b__14_0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\FactorAdman\egholm2019.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Productlist\ConfiguratorRender.cshtml:line 900
   at RazorEngine.Templating.TemplateWriter.ToString()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_4f7ef9f65dbf486dab0019202e44bf73.<>c__DisplayClass2_0.b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\FactorAdman\egholm2019.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Productlist\ConfiguratorRender.cshtml:line 169
   at CompiledRazorTemplates.Dynamic.RazorEngine_4f7ef9f65dbf486dab0019202e44bf73.<>c__DisplayClass1_0.b__0(TextWriter __razor_helper_writer) in D:\Dynamicweb.net\Solutions\FactorAdman\egholm2019.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Productlist\ConfiguratorRender.cshtml:line 83
   at CompiledRazorTemplates.Dynamic.RazorEngine_4f7ef9f65dbf486dab0019202e44bf73.Execute() in D:\Dynamicweb.net\Solutions\FactorAdman\egholm2019.cloud.dynamicweb-cms.com\Files\Templates\Designs\Rapido\eCom\Productlist\ConfiguratorRender.cshtml:line 895
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2 @using Dynamicweb.Frontend.Devices 3 @using Dynamicweb.Extensibility 4 @using Dynamicweb.Content 5 @using Dynamicweb.Core 6 @using System 7 @using System.IO 8 @using System.Web 9 @using System.Collections.Generic; 10 @using System.Linq 11 @using System.Text.RegularExpressions 12 @using Dynamicweb.Rapido.Blocks 13 @using Dynamicweb.Ecommerce.Products; 14 15 @functions { 16 BlocksPage productListPage = BlocksPage.GetBlockPage("ProductList"); 17 } 18 19 @{ 20 Block pageContainer = new Block() 21 { 22 Id = "PageContainer", 23 Template = RenderPageContainer(), 24 SkipRenderBlocksList = true 25 }; 26 productListPage.Add(pageContainer); 27 28 Block productListNavigation = new Block() 29 { 30 Id = "Navigation", 31 SortId = 20, 32 Design = new Design 33 { 34 RenderType = RenderType.Column, 35 Size = "0" 36 } 37 }; 38 productListPage.Add("PageContainer", productListNavigation); 39 40 Block productListContainer = new Block() 41 { 42 Id = "ProductList", 43 SortId = 30, 44 Template = RenderProductList(), 45 SkipRenderBlocksList = true 46 }; 47 productListPage.Add("PageContainer", productListContainer); 48 49 Block productListSnippets = new Block() 50 { 51 Id = "BottomSnippets", 52 SortId = 40 53 }; 54 productListPage.Add(productListSnippets); 55 } 56 57 @* This is required for the product list feed to work *@ 58 @GetValue("DoNotRenderProductListTemplate") 59 60 @* Include the required Grid builder (Contains the methods @RenderBlockList and @RenderBlock) *@ 61 @using System.Text.RegularExpressions 62 @using System.Collections.Generic 63 @using System.Reflection 64 @using System.Web.UI.HtmlControls 65 @using Dynamicweb.Rapido.Blocks.Components 66 @using Dynamicweb.Rapido.Blocks.Components.Articles 67 @using Dynamicweb.Rapido.Blocks.Components.Documentation 68 @using Dynamicweb.Rapido.Blocks 69 70 71 @*--- START: Base block renderers ---*@ 72 73 @helper RenderBlockList(List<Block> blocks) 74 { 75 blocks = blocks.OrderBy(item => item.SortId).ToList(); 76 77 foreach (Block item in blocks) 78 { 79 <!-- START: @item.Id --> 80 81 if (item.Design == null) 82 { 83 @RenderBlock(item) 84 } 85 else if (item.Design.RenderType == RenderType.None) { 86 string cssClass = item.Design.CssClass != null ? item.Design.CssClass : ""; 87 88 <div class="@cssClass dw-mod"> 89 @RenderBlock(item) 90 </div> 91 } 92 else if (item.Design.RenderType != RenderType.Hide) 93 { 94 string cssClass = item.Design.CssClass != null ? item.Design.CssClass : ""; 95 96 if (!item.SkipRenderBlocksList) { 97 if (item.Design.RenderType == RenderType.Row) 98 { 99 <div class="grid grid--align-content-start @cssClass dw-mod" id="Block__@item.Id"> 100 @RenderBlock(item) 101 </div> 102 } 103 104 if (item.Design.RenderType == RenderType.Column) 105 { 106 string hidePadding = item.Design.HidePadding ? "u-no-padding" : ""; 107 string size = item.Design.Size ?? "12"; 108 size = Regex.IsMatch(size, @"\d") ? "md-" + item.Design.Size : item.Design.Size; 109 110 <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"> 111 @RenderBlock(item) 112 </div> 113 } 114 115 if (item.Design.RenderType == RenderType.Table) 116 { 117 <table class="table @cssClass dw-mod" id="Block__@item.Id"> 118 @RenderBlock(item) 119 </table> 120 } 121 122 if (item.Design.RenderType == RenderType.TableRow) 123 { 124 <tr class="@cssClass dw-mod" id="Block__@item.Id"> 125 @RenderBlock(item) 126 </tr> 127 } 128 129 if (item.Design.RenderType == RenderType.TableColumn) 130 { 131 <td class="@cssClass dw-mod" id="Block__@item.Id"> 132 @RenderBlock(item) 133 </td> 134 } 135 136 if (item.Design.RenderType == RenderType.CardHeader) 137 { 138 <div class="card-header @cssClass dw-mod"> 139 @RenderBlock(item) 140 </div> 141 } 142 143 if (item.Design.RenderType == RenderType.CardBody) 144 { 145 <div class="card @cssClass dw-mod"> 146 @RenderBlock(item) 147 </div> 148 } 149 150 if (item.Design.RenderType == RenderType.CardFooter) 151 { 152 <div class="card-footer @cssClass dw-mod"> 153 @RenderBlock(item) 154 </div> 155 } 156 } 157 else 158 { 159 @RenderBlock(item) 160 } 161 } 162 163 <!-- END: @item.Id --> 164 } 165 } 166 167 @helper RenderBlock(Block item) 168 { 169 if (item.Template != null) 170 { 171 @BlocksPage.RenderTemplate(item.Template) 172 } 173 174 if (item.Component != null) 175 { 176 string methodName = item.Component.HelperName; 177 dynamic[] methodParameters = new dynamic[1]; 178 methodParameters[0] = item.Component; 179 Type methodType = this.GetType(); 180 MethodInfo generalMethod = methodType.GetMethod(methodName); 181 182 if (generalMethod != null) { 183 @generalMethod.Invoke(this, methodParameters).ToString(); 184 } else { 185 throw new Exception(item.Component.GetType().Name + " method '" + methodName +"' could not be invoked"); 186 } 187 } 188 189 if (item.BlocksList.Count > 0 && !item.SkipRenderBlocksList) 190 { 191 @RenderBlockList(item.BlocksList) 192 } 193 } 194 195 @*--- END: Base block renderers ---*@ 196 197 198 @* Include the Blocks for the page *@ 199 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 200 @using Dynamicweb.Core 201 @using System 202 @using System.Web 203 @using System.Collections.Generic 204 @using Dynamicweb.Rapido.Blocks 205 206 @{ 207 BlocksPage productListProductsBlocksPage = BlocksPage.GetBlockPage("ProductList"); 208 209 Block productsBlock = new Block 210 { 211 Id = "Views", 212 SortId = 30, 213 Template = RenderProducts() 214 }; 215 216 productListProductsBlocksPage.Add("ProductList", productsBlock); 217 } 218 219 @helper RenderProducts() 220 { 221 @*This is part of a script template *@ 222 223 <div id="ProductsContainer" data-template="{{listTemplate}}" class="grid product-list grid--external-bleed-x dw-mod" data-save-cookie="true"> 224 {{#ProductsContainer}} 225 {{> (lookup . 'template') }} 226 {{/ProductsContainer}} 227 </div> 228 } 229 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 230 @using Dynamicweb.Core 231 @using System 232 @using System.Web 233 @using System.Collections.Generic 234 @using Dynamicweb.Rapido.Blocks 235 236 @if (Pageview.AreaSettings.GetItem("ProductList").GetBoolean("EnableGridView")) 237 { 238 BlocksPage productList = BlocksPage.GetBlockPage("ProductList"); 239 240 Block gridViewButton = new Block 241 { 242 Id = "ProductGridItemContainer", 243 Name = "th", 244 SortId = 20 245 }; 246 productList.Add("Views", gridViewButton); 247 248 249 Block gridViewScripts = new Block 250 { 251 Id = "GridViewScripts", 252 SortId = 20, 253 Template = GridView() 254 }; 255 productList.Add("BottomSnippets", gridViewScripts); 256 } 257 258 @helper GridView() 259 { 260 bool onlyPreview = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("OnlyPreviewForAnonymous") && Pageview.User == null; 261 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 262 bool showPrice = !Pageview.AreaSettings.GetItem("ProductList").GetBoolean("HidePrice"); 263 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fas fa-shopping-cart"; 264 string columnsCount = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetList("Columns") != null ? Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetList("Columns").SelectedValue : "4"; 265 bool showCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToCartButton"); 266 bool showViewButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowViewButton"); 267 bool showFavoriteButton = !Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("HideFavoriteButton"); 268 bool showAddToDownloadButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToDownloadButton"); 269 bool showStock = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowStockAndShipping"); 270 bool showNumber = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowProductNumber"); 271 bool showStaticVariants = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowStaticVariants"); 272 string cartButtonText = Translate("Add to cart"); 273 string viewMoreText = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText")) ? Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("ViewMoreText") : "View"; 274 bool useGoogleTagManager = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("GoogleTagManagerID")); 275 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductList").GetBoolean("ShowBothPricesWithWithoutVAT"); 276 bool isPricesWithVATEnabled = Converter.ToBoolean(Pageview.Area.EcomPricesWithVat); 277 string imageZoomOnHover = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("HoverImageZoom") ? "image-hover--zoom" : ""; 278 bool secondaryImage = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetString("HoverAlternatineImage") != null ? Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("HoverAlternatineImage") : false; 279 string footerClasses = showStaticVariants ? "u-min-h120px" : ""; 280 281 <script id="ProductGridItemContainer" type="text/x-template"> 282 {{#.}} 283 <div id="Product{{id}}" data-template="ProductGridItem" data-preloader="overlay" class="grid__col-lg-@columnsCount grid__col-md-@columnsCount grid__col-sm-@columnsCount grid__col-xs-6 product-list__grid-item @imageZoomOnHover dw-mod"> 284 {{#Product}} 285 {{>ProductGridItem}} 286 {{/Product}} 287 </div> 288 {{/.}} 289 </script> 290 291 <script id="ProductGridItem" type="text/x-template"> 292 {{#.}} 293 @if (useGoogleTagManager) 294 { 295 <text>{{{googleEnchantImpression 'Product catalogue' currency googleImpression}}}</text> 296 } 297 <input type="hidden" name="ProductLoopCounter{{id}}" value="{{id}}" /> 298 <input type="hidden" name="ProductID{{id}}" value="{{productId}}" /> 299 300 <div class="grid__cell product-list__grid-item__image dw-mod {{noImage}}"> 301 <img class="grid__cell-img b-lazy @*configurator-image*@" src="/Files/Images/placeholder.gif" 302 data-src="/Admin/Public/GetImage.ashx?width=377&amp;height=316&amp;crop=5&amp;Compression=85&amp;FillCanvas=true&amp;DoNotUpscale=false&amp;image={{image}}" 303 @if (secondaryImage) { <text> 304 {{#if secondaryImage}} 305 data-secondary-image-src="/Admin/Public/GetImage.ashx?width=300&amp;height=300&amp;crop=5&amp;Compression=75&amp;FillCanvas=true&amp;DoNotUpscale=true&amp;image={{secondaryImage}}" 306 {{/if}} 307 </text> } 308 alt="{{name}}" /> 309 {{#StickersContainers}} 310 {{>StickersContainer}} 311 {{/StickersContainers}} 312 @if (showFavoriteButton) 313 { 314 <div class="favorites favorites--for-grid-view u-pull--right {{hasVariants}} dw-mod" {{hasVariants}}> 315 {{#Favorite}} 316 {{>FavoriteTemplate}} 317 {{/Favorite}} 318 </div> 319 } 320 </div> 321 322 <div class="grid__cell product-list__grid-item__price-info {{shortGridInfo}} dw-mod"> 323 <h2 class="u-condensed-text builder__content__card__header" title="{{name}}">{{name}}</h2> 324 <div class="builder__content__card__description">{{{description}}}</div> 325 {{#if TechnicalDocumentLink}} 326 <div style="margin-top:5px;"> 327 <a href="/Files/Files/{{TechnicalDocumentLink}}" target="_blank">@Translate("View Technical Data (pdf)")</a> 328 </div> 329 {{/if}} 330 331 @if (showPrice && !onlyPreview) 332 { 333 if (pointShopOnly) 334 { 335 <text> 336 {{#if havePointPrice}} 337 <div class="price price--product-list dw-mod">{{points}} @Translate("points")</div> 338 {{else}} 339 @Translate("Not available") 340 {{/if}} 341 </text> 342 } 343 else 344 { 345 <div class="price price--product-list dw-mod">{{price}}</div> 346 <div class="before-price {{onSale}} dw-mod">{{discount}}</div> 347 if (showVATPrice) 348 { 349 <div class="vat-price vat-price--product-list u-margin-top dw-mod"> 350 @if (isPricesWithVATEnabled) 351 { 352 <span>@Translate("excl. VAT")</span><span> ({{priceWithoutVAT}})</span> 353 } 354 else 355 { 356 <span>@Translate("incl. VAT")</span><span> ({{priceWithVAT}})</span> 357 } 358 </div> 359 } 360 } 361 } 362 <input type="hidden" value="{{unitId}}" name="Unit{{id}}" id="Unit_{{id}}" /> 363 <input type="hidden" value="{{variantid}}" name="VariantID{{id}}" id="Variant_{{id}}" /> 364 </div> 365 366 <div class="product-list__grid-item__footer @footerClasses dw-mod"> 367 <div class="u-ta-center u-inline-block u-full-width"> 368 <div class="buttons-collection {{hideBuyOptions}}"> 369 <button type="button" id="CartButton_{{id}}" class="js-cart-btn btn btn--secondary builder__content__btn dw-mod builder__content__btn--color-change--green u-full-width builder__mobile__btn {{disabledBuyButton}}" name="submit" data-prodid="{{productId}}" data-variantid="{{variantid}}" data-unitid="{{unitId}}" data-prodinfo="{{productInfo}}" {{#if HasRelatedProducts}} data-hasrelateditems="{{HasRelatedProducts}}" data-relatedproducts="{{SerializedRelatedProducts}}" data-image="{{image}}" {{/if}} data-isbrochure="{{IsBrochure}}" data-name="{{name}}" data-quantity="1" data-id="{{id}}" style="min-height: 42px !important;" 370 onclick="checkProductQuantity(event) {{disabledBuyButton}}"> 371 @cartButtonText 372 </button> 373 <input type="hidden" class="u-w80px u-pull--right use-btn-primary-height" id="Quantity_{{id}}" name="Quantity{{id}}" value="1" min="1"> 374 <input type="hidden" value="{{unitId}}" name="Unit{{id}}" id="Unit_{{id}}" /> 375 </div> 376 </div> 377 378 @if (!onlyPreview && showStock) 379 { 380 <div class="u-margin-top"> 381 <div><span class="stock-icon {{stockState}} u-no-margin dw-mod" title="{{stockText}}"></span> {{stockText}}</div> 382 <div> 383 {{#if deliveryText}} 384 {{deliveryText}} 385 {{else}} 386 - 387 {{/if}} 388 </div> 389 </div> 390 } 391 392 @if (showStaticVariants) 393 { 394 <text> 395 {{#Variants}} 396 {{>StaticVariantsTemplate}} 397 {{/Variants}} 398 399 {{#ifCond variantGroupsCount '>' 1}} 400 <div class="static-variant"> 401 @Translate("More options available") 402 </div> 403 {{/ifCond}} 404 405 {{#ifCond variantGroupsCount '==' 0}} 406 <div class="static-variant"></div> 407 {{/ifCond}} 408 </text> 409 } 410 411 @if (showAddToDownloadButton && Pageview.User != null) 412 { 413 <button type="button" class="btn btn--secondary u-no-margin u-margin-top btn--condensed dw-mod js-add-to-downloads" title="@Translate("Add")" data-product-id="{{productId}}"> 414 <i class="fas fa-plus js-button-icon"></i> 415 <span class="js-button-text">@Translate(viewMoreText)</span> 416 </button> 417 } 418 </div> 419 {{/.}} 420 </script> 421 } 422 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 423 @using Dynamicweb.Core 424 @using System 425 @using System.Web 426 @using System.Collections.Generic 427 @using Dynamicweb.Rapido.Blocks 428 429 @{ 430 BlocksPage productListPromotionsBlocksPage = BlocksPage.GetBlockPage("ProductList"); 431 432 Block productListPromotions = new Block 433 { 434 Id = "Promotions", 435 SortId = 10, 436 Template = RenderProductListPromotions() 437 }; 438 productListPromotionsBlocksPage.Add("PageContainer", productListPromotions); 439 } 440 441 @helper RenderProductListPromotions() 442 { 443 @*This is part of a script template *@ 444 445 string listId = HttpContext.Current.Request.QueryString.Get("ListID"); 446 bool isFavoriteList = !string.IsNullOrEmpty(listId); 447 448 if (!isFavoriteList) 449 { 450 switch (Pageview.AreaSettings.GetItem("ProductList").GetList("PromotionBlockDesign").SelectedValue) 451 { 452 case "OnlyText": 453 <article class="grid__col-12 u-margin-bottom"> 454 <h1>{{groupName}}</h1> 455 {{{groupDescription}}} 456 </article> 457 break; 458 case "TextAndImage": 459 <article class="grid__col-12 u-margin-bottom"> 460 <div class="grid grid--bleed"> 461 <div class="grid__col-md-6"> 462 <h1>{{groupName}}</h1> 463 {{{groupDescription}}} 464 </div> 465 {{#ifCond groupPromotionImage "!==" ""}} 466 <div class="grid__col-md-6"> 467 <img src="/Admin/Public/GetImage.ashx?width=600&crop=5&Compression=75&DoNotUpscale=true&image={{groupPromotionImage}}" alt="{{groupName}}" class="background-image__cover" /> 468 </div> 469 {{/ifCond}} 470 </div> 471 </article> 472 break; 473 case "Banner": 474 <text> 475 {{#ifCond groupPromotionImage "!==" ""}} 476 <article class="grid__col-12 u-margin-bottom"> 477 <div class="u-color-light grid center-container center-container--with-background-image u-padding" style="background-image:url('{{groupPromotionImage}}'); background-size: cover;"> 478 <div class="grid__col-12 u-middle"> 479 <div class="grid__cell"> 480 {{{groupDescription}}} 481 </div> 482 </div> 483 </div> 484 </article> 485 {{/ifCond}} 486 </text> 487 break; 488 } 489 } 490 } 491 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 492 @using Dynamicweb.Core 493 @using System 494 @using System.Web 495 @using System.Collections.Generic 496 @using Dynamicweb.Rapido.Blocks 497 498 @{ 499 BlocksPage productListMenuBlocksPage = BlocksPage.GetBlockPage("ProductList"); 500 501 if (Pageview.Page.PropertyItem["LeftMenu"] != null && Converter.ToString(Pageview.Page.PropertyItem["LeftMenu"]) == "True" && Pageview.Page.NavigationSettings != null && Pageview.Page.NavigationSettings.UseEcomGroups) { 502 Block productListMenuBlock = new Block 503 { 504 Id = "Menu", 505 SortId = 20, 506 Template = RenderProductListMenu() 507 }; 508 509 productListMenuBlocksPage.Add("Navigation", productListMenuBlock); 510 } 511 } 512 513 @helper RenderProductListMenu() 514 { 515 var navigationMarkup = RenderNavigation(new 516 { 517 id = "leftnav", 518 cssclass = "dwnavigation", 519 startLevel = 1, 520 endlevel = 5, 521 template = "LeftNavigation.xslt", 522 mode = "ecom" 523 }); 524 525 <h2 class="u-margin-bottom">@Translate("Product categories")</h2> 526 527 <div class="u-padding-bottom--lg"> 528 @navigationMarkup 529 </div> 530 } 531 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 532 @using Dynamicweb.Core 533 @using System 534 @using System.Web 535 @using System.Collections.Generic 536 @using Dynamicweb.Rapido.Blocks 537 538 @{ 539 BlocksPage productListBottomSnippetsPage = BlocksPage.GetBlockPage("ProductList"); 540 541 Block productListStickers = new Block 542 { 543 Id = "Stickers", 544 SortId = 10, 545 Template = RenderStickersTemplates() 546 }; 547 productListBottomSnippetsPage.Add("BottomSnippets", productListStickers); 548 549 Block productListUnits = new Block 550 { 551 Id = "Units", 552 SortId = 20, 553 Template = RenderUnitTemplates() 554 }; 555 productListBottomSnippetsPage.Add("BottomSnippets", productListUnits); 556 557 Block productListVariants = new Block 558 { 559 Id = "Variants", 560 SortId = 30, 561 Template = RenderVariantTemplates() 562 }; 563 productListBottomSnippetsPage.Add("BottomSnippets", productListVariants); 564 565 Block productListFavorites = new Block 566 { 567 Id = "Favorites", 568 SortId = 40, 569 Template = RenderFavoritesTemplates() 570 }; 571 productListBottomSnippetsPage.Add("BottomSnippets", productListFavorites); 572 573 Block productListPreRender = new Block 574 { 575 Id = "PreRenders", 576 SortId = 50, 577 Template = RenderPreRenderTemplates() 578 }; 579 productListBottomSnippetsPage.Add("BottomSnippets", productListPreRender); 580 581 Block productListInitializers = new Block 582 { 583 Id = "Initializers", 584 SortId = 60, 585 Template = RenderInitializers() 586 }; 587 productListBottomSnippetsPage.Add("BottomSnippets", productListInitializers); 588 } 589 590 @helper RenderStickersTemplates() { 591 <script id="StickersContainer" type="text/x-template"> 592 <div class="stickers-container stickers-container--{{position}} dw-mod"> 593 {{#Stickers}} 594 {{>Sticker}} 595 {{/Stickers}} 596 </div> 597 </script> 598 599 <script id="Sticker" type="text/x-template"> 600 <div class="stickers-container__tag {{className}} dw-mod">{{text}}</div> 601 </script> 602 603 <script id="MiniSticker" type="text/x-template"> 604 <div class="stickers-container__tag stickers-container__tag--micro {{className}} dw-mod">{{text}}</div> 605 </script> 606 } 607 608 @helper RenderUnitTemplates() { 609 <script id="UnitOption" type="text/x-template"> 610 <div class="dropdown__item dw-mod" onclick="HandlebarsBolt.UpdateContent('Product{{id}}', '{{link}}&feed=true&UnitID={{value}}&rid={{id}}')">{{name}}</div> 611 </script> 612 } 613 614 @helper RenderVariantTemplates() { 615 <script id="VariantsTemplate" type="text/x-template"> 616 {{#.}} 617 <div> 618 <div class="u-bold">{{name}}</div> 619 <div> 620 {{#VariantOptions}} 621 {{>VariantOption}} 622 {{/VariantOptions}} 623 </div> 624 </div> 625 {{/.}} 626 </script> 627 628 <script id="VariantOption" type="text/x-template"> 629 {{#if color}} 630 <button type="button" data-variant-id="{{variantId}}" data-variant-group="{{groupId}}" onclick="MatchVariants.SelectThis(event)" class="btn btn--colorbox u-margin-right {{disabled}} {{selected}} js-variant-option" data-check="{{selected}}" {{disabled}} style="background-color: {{color}}"></button> 631 {{else}} 632 {{#if image}} 633 <img data-variant-id="{{variantId}}" data-variant-group="{{groupId}}" src="{{image}}" onclick="MatchVariants.SelectThis(event)" alt="{{name}}" title="{{name}}" class="btn btn--tag {{selected}} js-variant-option" data-check="{{selected}}" /> 634 {{else}} 635 <button type="button" data-variant-id="{{variantId}}" data-variant-group="{{groupId}}" onclick="MatchVariants.SelectThis(event)" class="btn btn--tag {{disabled}} {{selected}} js-variant-option" data-check="{{selected}}" {{disabled}}>{{name}}</button> 636 {{/if}} 637 {{/if}} 638 </script> 639 640 <script id="StaticVariantsTemplate" type="text/x-template"> 641 {{#.}} 642 {{#if isFirstGroup}} 643 <div> 644 {{#VariantOptions}} 645 {{>StaticVariantOption}} 646 {{/VariantOptions}} 647 </div> 648 {{/if}} 649 {{/.}} 650 </script> 651 652 <script id="StaticVariantOption" type="text/x-template"> 653 {{#if color}} 654 <div class="static-variant static-variant--color dw-mod" style="background-color: {{color}}" title="{{name}}"></div> 655 {{else}} 656 <div class="static-variant dw-mod">{{name}} </div> 657 {{/if}} 658 </script> 659 660 <script id="VariantOptionImage" type="text/x-template"> 661 <img data-variant-id="{{variantId}}" data-friends="{{friendsList}}" data-variant-group="{{groupId}}" onclick="MatchVariants.SelectThis(event)" src="/Admin/Public/GetImage.ashx?width=100&amp;height=50&amp;crop=5&amp;Compression=75&amp;image=/Images/{{image}}" alt="{{name}}" title="{{name}}" class="btn btn--tag {{disabled}} {{selected}} js-variant-option" data-check="{{selected}}" {{disabled}} /> 662 </script> 663 } 664 665 @helper RenderFavoritesTemplates() { 666 <script id="FavoriteTemplate" type="text/x-template"> 667 <div class="favorites-list u-ta-left"> 668 <label for="FavoriteTrigger_{{id}}" class="u-no-margin js-favorite-btn"><i class="{{favoriteIcon}} fa-1_5x"></i></label> 669 <input type="checkbox" id="FavoriteTrigger_{{id}}" class="dropdown-trigger" /> 670 <div class="dropdown dropdown--absolute-position"> 671 <div class="dropdown__content dropdown__content--show-left dropdown__content--padding u-w220px dw-mod"> 672 <ul class="list list--clean dw-mod"> 673 {{#FavoriteLists}} 674 {{>FavoriteListItem}} 675 {{/FavoriteLists}} 676 </ul> 677 </div> 678 <label class="dropdown-trigger-off" for="FavoriteTrigger_{{id}}"></label> 679 </div> 680 </div> 681 </script> 682 683 <script id="FavoriteListItem" type="text/x-template"> 684 <li> 685 <a href="{{link}}" class="list__link u-no-underline dw-mod" onclick="Scroll.SavePosition(event); {{facebookPixelAction}}"><i class="{{favoriteIcon}}"></i> {{name}}</a> 686 </li> 687 </script> 688 } 689 690 @helper RenderPreRenderTemplates() { 691 string facetsViewMode = !String.IsNullOrEmpty(Pageview.AreaSettings.GetItem("ProductList").GetString("FacetsViewMode")) ? Pageview.AreaSettings.GetItem("ProductList").GetString("FacetsViewMode").ToLower() : "left"; 692 693 <script id="ProductPreRenderContainer" type="text/x-template"> 694 @if (facetsViewMode == "left" && Pageview.Device.ToString() != "Mobile") 695 { 696 <div class="grid__col-3"> 697 <div class="pre-render-element pre-render-element--xs"></div> 698 <div class="pre-render-element pre-render-element--md"></div> 699 <div class="pre-render-element pre-render-element--md"></div> 700 <div class="pre-render-element pre-render-element--md"></div> 701 </div> 702 } 703 <div class="grid__col-auto"> 704 <div class="pre-render-element pre-render-element--xs"></div> 705 <div class="pre-render-element pre-render-element--lg"></div> 706 <div class="pre-render-element pre-render-element--lg"></div> 707 <div class="pre-render-element pre-render-element--lg"></div> 708 <div class="pre-render-element pre-render-element--lg"></div> 709 </div> 710 </script> 711 } 712 713 @helper RenderInitializers() { 714 <script> 715 document.addEventListener("DOMContentLoaded", function (event) { 716 document.getElementById("productList").addEventListener('contentLoaded', function (e) { 717 if (getTarget(e).id === "productList") { 718 Search.Init(); 719 Facets.Init("selectedFacets", "productList"); 720 } 721 }, false); 722 }); 723 </script> 724 } 725 726 @if (File.Exists(HttpContext.Current.Server.MapPath("/Files/Templates/Designs/Rapido/eCom/ProductList/Blocks/Custom__Blocks.cshtml"))) 727 { 728 <text>@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 729 @using System 730 @using System.Web.UI 731 @using Dynamicweb.Ecommerce.Products; 732 733 @{ 734 BlocksPage customBlocksPage = BlocksPage.GetBlockPage("ProductList"); 735 BlocksPage masterBlocksPage = BlocksPage.GetBlockPage("Master"); 736 737 Block freeReturns = new Block 738 { 739 Id = "freeReturns", 740 SortId = 99, 741 Template = RenderFreeReturns() 742 }; 743 customBlocksPage.Add("PageContainer", freeReturns); 744 } 745 746 @helper RenderFreeReturns() 747 { 748 int optionsPageId = GetPageIdByNavigationTag("OptionsPage"); 749 int attachmentsPageId = GetPageIdByNavigationTag("AttachmentsPage"); 750 int documentsPageId = GetPageIdByNavigationTag("DocumentsPage"); 751 int cartPageId = GetPageIdByNavigationTag("CartPage"); 752 753 int currentPage = Convert.ToInt32(GetGlobalValue("Global:Page.ID")); 754 string nextPage = currentPage.ToString(); 755 756 string modelId = Dynamicweb.Context.Current.Request.QueryString["Model"]; 757 758 bool existingProduct = (Dynamicweb.Context.Current.Request.QueryString["Existing"] != null) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.QueryString["Existing"].ToString().ToLower()) : false; 759 760 string nextPageText = Translate("Continue"); 761 762 if (currentPage == attachmentsPageId) 763 { 764 if (!existingProduct) 765 { 766 if (Pageview.User == null) 767 { 768 nextPage = cartPageId.ToString() + "&Model=" + modelId + "&Existing=" + existingProduct; 769 nextPageText = Translate("Generate proposal - enduser"); 770 } 771 else 772 { 773 nextPage = documentsPageId.ToString() + "&Model=" + modelId + "&Existing=" + existingProduct; 774 nextPageText = Translate("Select documents"); 775 } 776 } 777 else 778 { 779 if (Pageview.User == null) 780 { 781 nextPage = cartPageId.ToString() + "&Model=" + modelId + "&Existing=" + existingProduct; 782 nextPageText = Translate("Generate proposal - enduser"); 783 } 784 else 785 { 786 nextPage = documentsPageId.ToString() + "&Model=" + modelId + "&Existing=" + existingProduct; 787 nextPageText = Translate("Select documents"); 788 } 789 } 790 } 791 792 if (currentPage == optionsPageId) 793 { 794 if (Pageview.User != null) 795 { 796 if (!existingProduct) 797 { 798 nextPage = attachmentsPageId.ToString() + "&Model=" + modelId + "&Existing=" + existingProduct; 799 nextPageText = Translate("Select tools"); 800 } 801 else 802 { 803 nextPage = documentsPageId.ToString() + "&Model=" + modelId + "&Existing=" + existingProduct; 804 nextPageText = Translate("Select documents"); 805 } 806 } 807 else 808 { 809 if (existingProduct != false) 810 { 811 nextPage = cartPageId.ToString() + "&Model=" + modelId + "&Existing=" + existingProduct; 812 nextPageText = Translate("Generate proposal - enduser"); 813 } 814 else 815 { 816 nextPage = attachmentsPageId.ToString() + "&Model=" + modelId + "&Existing=False"; 817 nextPageText = Translate("Select tools"); 818 } 819 } 820 } 821 if (currentPage == documentsPageId) 822 { 823 nextPage = cartPageId.ToString() + "&Model=" + modelId + "&Existing=" + existingProduct; 824 if (Pageview.User == null) 825 { 826 nextPageText = Translate("Generate proposal - enduser"); 827 } 828 else 829 { 830 nextPageText = Translate("Generate proposal - dealer"); 831 } 832 } 833 834 <div class="grid__col-lg-4"> 835 <div class="builder__cart"> 836 @{ 837 Product product = new ProductService().GetProductByNumber(modelId, true); 838 839 if (product != null) 840 { 841 <div class="grid__col-12"> 842 <h2 class="builder__header--fontsize-28 u-mb-0px">@product.Name</h2> 843 </div> 844 } 845 846 <div>&nbsp;</div> 847 <div id="egholmCart"></div> 848 <input value="@Translate("Cart_Remove", "Remove")" id="egholmCartRemoveTranslations" type="hidden"/> 849 @*KR 09222020*@ 850 <input value="@Translate("Total", "Total")" id="egholmCartTotalTranslations" type="hidden"/> 851 <input value="@Translate("Price without VAT", "Price without VAT")" id="egholmCartPriceWithoutVATTranslations" type="hidden"/> 852 @*\KR 09222020*@ 853 } 854 <div class="grid__col-12"></div> 855 <div class="grid__col-12"> 856 <a href="/Default.aspx?ID=@nextPage" class="btn btn--secondary builder__content__btn builder__content__btn--orange builder__content__btn--width100 u-mt-20px">@nextPageText</a> 857 </div> 858 </div> 859 <div class="grid__col-12"> 860 @if ((currentPage == attachmentsPageId || currentPage == documentsPageId) && !existingProduct) 861 { 862 <a href="Default.aspx?ID=@optionsPageId&Model=@modelId&Existing=@existingProduct.ToString()" class="btn btn--secondary builder__content__btn builder__content__btn--grey u-mt-20px">@Translate("Back to Accessories")</a> 863 } 864 @if (currentPage == documentsPageId && !existingProduct) 865 { 866 <a href="Default.aspx?ID=@attachmentsPageId&Model=@modelId&Existing=@existingProduct.ToString()" class="btn btn--secondary builder__content__btn builder__content__btn--grey u-mt-10px">@Translate("Back to Attachments")</a> 867 } 868 <a href="/Default.aspx?ID=@GetPageIdByNavigationTag("CartPage")&cartcmd=emptycart&Redirect=@Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(GetPageIdByNavigationTag("ConfiguratorPage"))" class="btn btn--secondary builder__content__btn builder__content__btn--grey u-mt-10px">@Translate("Clear and restart")</a> 869 870 <!-- 871 <a href="#" onclick="Cart.EmptyCart(event); return false; window.location = '/configurator';" id="restart" name="restart" class="btn btn--secondary builder__content__btn builder__content__btn--grey u-mt-10px">@Translate("Clear and restart")</a> 872 --> 873 874 </div> 875 </div> 876 }</text> 877 } 878 879 @if (productListNavigation.BlocksList.Count < 1) 880 { 881 productListNavigation.Design.RenderType = RenderType.Hide; 882 } 883 <input type="hidden" id="CartOrderlinesFeed" name="CartOrderlinesFeed" value="@GetPageIdByNavigationTag("CartOrderlinesFeed")"/> 884 <input type="hidden" id="CartOrderlinesFeedDOM" name="CartOrderlinesFeedDOM" value="@GetPageIdByNavigationTag("CartOrderlinesFeedDOM")"/> 885 <input type="hidden" id="OptionsPage" name="OptionsPage" value="@GetPageIdByNavigationTag("OptionsPage")"/> 886 <input type="hidden" id="AttachmentsPage" name="AttachmentsPage" value="@GetPageIdByNavigationTag("AttachmentsPage")" /> 887 <input type="hidden" id="PageID" name="PageID" value="@Pageview.Page.ID" /> 888 <input type="hidden" id="DomainUrl" name="DomainUrl" value="@HttpContext.Current.Request.Url.ToString().Substring(0, HttpContext.Current.Request.Url.ToString().IndexOf("/Default.aspx"))"/> 889 <input type="hidden" id="ConfiguratorPath" name="ConfiguratorPath" value="@Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(GetPageIdByNavigationTag("ConfiguratorPage"))"/> 890 <input type="hidden" id="alertTranslation" name="alertTranslation" value="@Translate("already_in_cart", "Already in the cart")"/> 891 <input type="hidden" id="emptyCartTranslation" name="emptyCartTranslation" value="@Translate("empty_configurator", "Your configurator is empty")"/> 892 <form name="multiForm" id="multiForm" method="post"> 893 <input type="hidden" name="CartCmd" id="attachmentCartCmd" value="addMulti"/> 894 @* The @RenderBlockList base helper is included in Components/GridBuilder.cshtml *@ 895 @RenderBlockList(productListPage.BlocksRoot.BlocksList) 896 </form> 897 898 @helper RenderPageContainer() 899 { 900 @RenderPageTop() 901 902 List<Block> subBlocks = this.productListPage.GetBlockListById("PageContainer").OrderBy(item => item.SortId).ToList(); 903 904 string pageUrl = GetGlobalValue("Global:Pageview.Url.Raw"); 905 string listId = HttpContext.Current.Request.QueryString.Get("ListID"); 906 bool isFavoriteList = !string.IsNullOrEmpty(listId); 907 string feedFullUrl = pageUrl + "&feed=true"; 908 feedFullUrl += !isFavoriteList ? "&DoNotShowVariantsAsSingleProducts=True" : ""; 909 string smallDeviceCss = Pageview.Device.ToString() == "Mobile" ? "" : ""; 910 911 <div class="grid grid--align-content-start @smallDeviceCss js-handlebars-root rearrangecart" id="productList" data-template="ProductContainer" data-pre-render-template="ProductPreRenderContainer" data-json-feed="@feedFullUrl" data-preloader="overlay"></div> 912 913 <script id="ProductContainer" type="text/x-template"> 914 {{#each .}} 915 @RenderBlockList(subBlocks) 916 {{else}} 917 <div class="grid__col-12"> 918 <h2 class="u-ta-center">@Translate("Your search gave 0 results")</h2> 919 </div> 920 {{/each}} 921 </script> 922 } 923 924 @helper RenderPageTop() 925 { 926 string modelId = Dynamicweb.Context.Current.Request.QueryString["Model"]; 927 Product product = new ProductService().GetProductByNumber(modelId, true); 928 929 int attachmentsPageId = GetPageIdByNavigationTag("AttachmentsPage"); 930 int accessoriesPageId = GetPageIdByNavigationTag("OptionsPage"); 931 int documentsPageId = GetPageIdByNavigationTag("DocumentsPage"); 932 int currentPage = Convert.ToInt32(GetGlobalValue("Global:Page.ID")); 933 934 string heading = string.Empty; 935 string paragraph = string.Empty; 936 string clientString = string.Empty; 937 string paragraphText = string.Empty; 938 939 if (currentPage == attachmentsPageId) 940 { 941 paragraph = Translate("Now select your attachments for"); 942 } 943 if (currentPage == accessoriesPageId) 944 { 945 paragraph = Translate("Now select your accessories for"); 946 } 947 if (currentPage == documentsPageId) 948 { 949 paragraph = Translate("Now select your documents for"); 950 paragraphText = Translate("Document textarea"); 951 } 952 if (Pageview.User != null) 953 { 954 clientString = Translate(" for client"); 955 } 956 957 <h2>@Translate("Building") @product.Name @clientString</h2> 958 <h4>@paragraph @product.Name</h4> 959 if (!String.IsNullOrEmpty(paragraphText)) 960 { 961 <p>@paragraphText</p> 962 } 963 } 964 965 @helper RenderProductList() 966 { 967 @*This is part of a script template *@ 968 969 List<Block> subBlocks = productListPage.GetBlockListById("ProductList").OrderBy(item => item.SortId).ToList(); 970 971 string pageId = GetGlobalValue("Global:Page.ID"); 972 string pageUrl = GetGlobalValue("Global:Pageview.Url.Raw"); 973 string listId = HttpContext.Current.Request.QueryString.Get("ListID"); 974 bool isFavoriteList = !string.IsNullOrEmpty(listId); 975 string feedFullUrl = pageUrl + "&feed=true"; 976 feedFullUrl += !isFavoriteList ? "&DoNotShowVariantsAsSingleProducts=True" : ""; 977 string smallDeviceCss = Pageview.Device.ToString() == "Mobile" ? "u-no-padding" : ""; 978 979 <div class="grid__col-lg-8 @smallDeviceCss u-no-padding"> 980 @if (isFavoriteList) 981 { 982 string searchPlaceholder = Translate("Search favorite products", "Search favorite products"); 983 string searchValue = HttpContext.Current.Request.QueryString.Get("Search") ?? ""; 984 985 <div class="grid__cell"> 986 <div class="u-pull--left"> 987 <h2 class="u-no-margin"><i class="{{headerIcon}}"></i>{{header}}</h2> 988 </div> 989 <div class="grid__col--bleed grid__col-6 u-pull--right"> 990 <div class="u-margin-bottom"> 991 <div class="typeahead u-color-inherit js-typeahead" data-page-size="10" id="FavoritesSearch" data-list-id="@listId" data-search-feed-id="@pageId&feed=true" data-result-page-id="@pageId"> 992 <input type="text" class="typeahead-search-field u-no-margin u-full-width js-typeahead-search-field" placeholder="@searchPlaceholder" value="@searchValue"> 993 <ul class="dropdown dropdown--absolute-position u-full-width js-handlebars-root js-typeahead-search-content u-min-w220px u-full-width dw-mod" id="FavoritesSearchContent" data-template="SearchProductsTemplate" data-json-feed="@feedFullUrl&ListID=@listId" data-init-onload="false" data-preloader="minimal"></ul> 994 <button type="button" class="btn btn--condensed btn--primary u-no-margin dw-mod js-typeahead-enter-btn"> 995 <i class="fas fa-search"></i> 996 </button> 997 </div> 998 </div> 999 </div> 1000 </div> 1001 } 1002 1003 <div class="grid__cell"> 1004 @RenderBlockList(subBlocks) 1005 </div> 1006 </div> 1007 } 1008 <div class="options-modal" id="options-modal" data-currentlocation="configurator"> 1009 <div class="options-modal-header"> 1010 <span id="options-modal-close" class="options-modal-close">&times;</span> 1011 <div class="options-modal-header-item-name"> 1012 Rotary/mulch mover 1200 1013 </div> 1014 <div class="options-modal-content"> 1015 <p class="text">@Translate("has_options_text", "This item has options - please specify your preferred configuration below.")</p> 1016 <div class="options-container"> 1017 <div class="grid"> 1018 <div class="grid__col-lg-6 grid__col-md-8 u-padding-0"> 1019 <div class="js-options-container"> 1020 1021 </div> 1022 <button class="btn btn--secondary options-modal-btn js-add-options" disabled onclick="configuratorAddPartsToCart(event)">@Translate("add_to_selection", "ADD TO SELECTION")</button> 1023 <button class="btn btn--secondary options-modal-btn js-no-option-please" style="margin-bottom: 0px;" onclick="configuratorSkipOptions(event)">@Translate("no_options_please", "NO OPTIONS PLEASE")</button> 1024 </div> 1025 <div class="grid__col-lg-6 grid__col-md-4 u-padding-0"> 1026 <img class="js-options-modal-content-img" src=""/> 1027 </div> 1028 </div> 1029 </div> 1030 </div> 1031 </div> 1032 </div> 1033 1034 <script> 1035 var modal = document.getElementById("options-modal"); 1036 1037 var btn = document.getElementById("myBtn"); 1038 1039 var span = document.getElementsByClassName("options-modal-close")[0]; 1040 1041 span.onclick = function() { 1042 modal.style.display = "none"; 1043 $("html").css("overflow", "auto"); 1044 } 1045 1046 window.onclick = function(event) { 1047 if (event.target == modal) { 1048 modal.style.display = "none"; 1049 $("html").css("overflow", "auto"); 1050 } 1051 } 1052 </script>