Error executing template "Designs/Tapas/eCom/Productlist/productlist_Default.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_084e85d6ec5c4c93ac3e51166daf62f9.<>c__DisplayClass16_0.<RenderGroupLevelFilter>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\millarco.live\Files\Templates\Designs\Tapas\eCom\Productlist\productlist_Default.cshtml:line 1141
   at CompiledRazorTemplates.Dynamic.RazorEngine_084e85d6ec5c4c93ac3e51166daf62f9.<>c__DisplayClass16_0.<RenderGroupLevelFilter>b__0(TextWriter __razor_helper_writer) in D:\dynamicweb.net\Solutions\millarco.live\Files\Templates\Designs\Tapas\eCom\Productlist\productlist_Default.cshtml:line 1173
   at CompiledRazorTemplates.Dynamic.RazorEngine_084e85d6ec5c4c93ac3e51166daf62f9.Execute() in D:\dynamicweb.net\Solutions\millarco.live\Files\Templates\Designs\Tapas\eCom\Productlist\productlist_Default.cshtml:line 679
   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 RazorTemplateBase<RazorTemplateModel<Template>> 2 @using Dynamicweb.Rendering; 3 @using Dynamicweb.Environment; 4 5 @inherits RazorTemplateBase<RazorTemplateModel<Template>> 6 @using Dynamicweb.Rendering; 7 @using System.Text.RegularExpressions; 8 9 10 11 @helper renderProduct(bool showShopFunctionsAlternativeIfNotLoggedIn, LoopItem product, bool renderAs4Cols = false, bool boxShadow = false) 12 { 13 14 string productID = product.GetString("Ecom:Product.ID"); 15 string productNumber = product.GetString("Ecom:Product.Number"); 16 string mainProductID = product.GetString("Ecom:Product:Field.FirstwebMainProductID"); 17 string PrimaryProductPageId = Firstweb.Custom.CustomCode.Tapas.Context.AreaPages.GetPageId("productcatalog"); 18 19 string productLink = product.GetString("Ecom:Product.Link.Clean"); 20 21 if (!String.IsNullOrEmpty(PrimaryProductPageId)) 22 { 23 productLink = "/Default.aspx?id=" + PrimaryProductPageId + "&productid=" + productID; 24 } 25 26 string languageId = product.GetString("Ecom:Product.LanguageID"); 27 string variantId = product.GetString("Ecom:Product.VariantID"); 28 29 string productName = product.GetString("Ecom:Product.Name"); 30 string productShortDescription = product.GetString("Ecom:Product.ShortDescription"); 31 32 string nettoPrice = product.GetString("Firstweb:ErpPriceInfo.NettoPriceFormatted"); 33 int bruttoPrice = product.GetInteger("Firstweb:ErpPriceInfo.BruttoAmountFormattedNoSymbol"); 34 35 string availableAmount = product.GetString("Firstweb:ErpStockInfo.StockQuantity"); 36 string stockColor = product.GetString("Firstweb:ErpStockInfo.StockColor"); 37 bool priceAndStockFound = product.GetBoolean("Firstweb:ErpPriceInfo.PriceAndStockFound"); 38 bool priceFound = product.GetBoolean("Firstweb:ErpPriceInfo.PriceFound"); 39 bool hasQuantityPrices = product.GetBoolean("Firstweb:ErpPriceInfo.HasQuantityPrices"); 40 string RRPrice = product.GetString("Firstweb:ErpPriceInfo:Prices.RRPFormatted"); 41 string OutletPrice = product.GetString("Firstweb:ErpPriceInfo.NettoPriceFormatted"); 42 43 int productPackagingQuantity = product.GetInteger("Firstweb:ErpPriceInfo:ExtraInfos.PackagingSize"); 44 int defaultQuantity = productPackagingQuantity > 0 ? productPackagingQuantity : 1; 45 46 47 bool hasVariants = (product.GetLoop("VariantCombinations").Count() > 0); 48 49 //Images 50 List<Dynamicweb.Ecommerce.Products.Detail> productImages = Firstweb.Custom.CustomCode.Frontend.Helpers.ProductImages.GetProductImages(languageId, productID, variantId); 51 Dynamicweb.Ecommerce.Products.Detail primaryProductImage = productImages.FirstOrDefault(x=>x.IsDefault); //Tag you can use instead: product.GetString("Ecom:Product.ImageDefault.Clean"); 52 //check for valid default image 53 if (primaryProductImage == null) 54 { 55 primaryProductImage = new Dynamicweb.Ecommerce.Products.Detail { Value = "" }; 56 } 57 else if (primaryProductImage.Value == null) 58 { 59 primaryProductImage.Value = ""; 60 } 61 62 //Sorted: first by imagegroup then by sortorder 63 //@foreach (var productImage in productImages) 64 //{ 65 //productImage.Value; //This is the imagepath eks. /Images/products/R12155_10_2.jpg 66 //productImage.IsDefault; //If the image is default or not. 67 //} 68 69 string primaryProductImageUrl = "/admin/public/getimage.ashx?image=" + primaryProductImage.Value + "&altFmImage_path=/Files/Images/ecom/Products/no-image.jpg&width=350&height=250&Compression=90&Crop=5"; 70 if (String.IsNullOrEmpty(primaryProductImage.Value)) 71 { 72 primaryProductImageUrl = "/admin/public/getimage.ashx?image=/Files/Images/ecom/Products/no-image.jpg&width=250&height=150&Compression=90&Crop=5"; 73 } 74 75 //Other packagings 76 var otherPackagingProducts = Firstweb.Custom.CustomCode.Frontend.Helpers.OtherPackagingProducts.GetOtherPackagingProducts(mainProductID, false).Where(i => i.Id != productID); 77 var showOtherPackagingProducts = otherPackagingProducts.Count() > 0; 78 79 80 //Customer product number 81 //string customerProductNumber = Firstweb.Custom.CustomCode.Frontend.Helpers.CustomerProductNumbers.GetCustomerProductNumber(productID); 82 83 //OrderTemplate 84 int productInFavoritLists = product.GetInteger("Firstweb:Ecom:Product:OrderTemplate.InTemplates.Count"); 85 86 string orderLineId = product.GetString("Firstweb:OrderTemplate:Line.ID"); 87 string orderTemplateId = product.GetString("Firstweb:OrderTemplate:Line.OrderTemplateID"); 88 int orderLineQuantity = product.GetInteger("Firstweb:OrderTemplate:Line.Quantity"); 89 90 bool inFavourite = productInFavoritLists > 0 ? true : false; 91 string inFavouriteBoolJS = inFavourite.ToString().ToLower(); 92 93 bool isOrderTemplate = !String.IsNullOrEmpty(orderLineId); 94 95 string productPriceCacheKey = productNumber; //orderLineId != "" ? orderLineId : productNumber; 96 97 98 99 100 string stock = ""; 101 102 string addBorderCss = isOrderTemplate ? "border-1" : ""; 103 104 105 if (!priceAndStockFound) 106 { 107 stock = "asyncLoad"; 108 } 109 else 110 { 111 stock = availableAmount; 112 } 113 114 string WidthClass = renderAs4Cols ? "col-md-4 col-lg-3" : "col-md-4"; 115 bool ShowShopFunctions = Firstweb.Custom.CustomCode.Tapas.Context.Current.ShopFunctionsVisibility.ShowShopFunctions(); 116 string BrandLogo = "/admin/public/getimage.ashx?image=" + product.GetString("Ecom:Product:Field.FirstwebBrandLogo.Value.FullPath") + "&height=25&crop=5"; 117 string BrandName = product.GetString("Ecom:Product:Field.FirstwebBrand.Value.Clean"); 118 string AddingToCartText = Translate("Product.AddingToCart", "Tilføjer produkt"); 119 string PickListText = Translate("Ordertemplate.SelectList", "Vælg en liste"); 120 bool IsOutletShop = Firstweb.Custom.CustomCode.Frontend.Helpers.Millarco.IsOutletShop(); 121 string boxShadowCss = ""; 122 if (boxShadow) 123 { 124 boxShadowCss = "box-shadow:0 2px 10px 0.5px #edebeb;"; 125 } 126 127 128 <!-- ko viewModel: 'ProductViewModel'--> 129 <!-- ko initValue: {observable: ProductId, value:'@productID'}--><!-- /ko--> 130 <div class="col-xs-12 col-sm-6 @WidthClass price xs-m-t-2 xs-m-b-2 asyncLoad" data-productid="@productNumber" data-productkey="@productPriceCacheKey" data-test="@PrimaryProductPageId"> 131 <div class="product-list-item bg-white" style="@boxShadowCss"> 132 <a href="@productLink"> 133 <div class="brand-image"> 134 @if (!String.IsNullOrEmpty(product.GetString("Ecom:Product:Field.FirstwebBrandLogo.Value.FullPath"))) 135 { 136 <img src="@BrandLogo" alt="@BrandName" /> 137 } 138 </div> 139 <div class="product-image"> 140 <img src="@primaryProductImageUrl" alt="@productName" /> 141 </div> 142 <div class="product-info"> 143 <p class="product-number">@Translate("Product.NumberShort", "Varenr.") @productNumber</p> 144 <p class="product-name">@productName</p> 145 </div> 146 @if (ShowShopFunctions && !IsOutletShop) 147 { 148 <p class="product-price"> 149 <span class="wave"> 150 <span class="dot"></span> 151 <span class="dot"></span> 152 <span class="dot"></span> 153 </span> 154 <span class="price-load-async"></span> 155 </p> 156 <p class="unit-price">@Translate("Product.PricePer", "Pris pr.") <span class="js-unit-size"></span> @Translate("Product.Unit", "stk.")</p> 157 } 158 else if (IsOutletShop) 159 { 160 <p class="product-price"> 161 @nettoPrice 162 </p> 163 } 164 else if (ShowShopFunctions) 165 { 166 <p class="product-price"> 167 @RRPrice 168 </p> 169 } 170 </a> 171 @if (ShowShopFunctions) 172 { 173 <div class="add-to-cart-area"> 174 @if (isOrderTemplate) 175 { 176 <!-- ko initValue: {observable: Quantity, value:@orderLineQuantity}--><!-- /ko--> 177 } 178 else 179 { 180 <!-- ko initValue: {observable: Quantity, value:@defaultQuantity}--><!-- /ko--> 181 } 182 <input class="product-quantity js-product-quantity hide" type="number" name="quantity" data-bind="value: Quantity" /> 183 <div class="btn btn-primary green js-product-buy-btn hide" 184 data-bind="click: function() { $parent.addItemToCart(ProductId(), Quantity(), '', '', '@AddingToCartText') }" 185 data-productid="@productID"> 186 @Translate("Product.AddToCart", "TILFØJ TIL KURV") 187 </div> 188 <div class="not-in-stock-indicator js-not-in-stock-indicator width-100 is-centered hide"> 189 <p>@Translate("Product.NotInStock", "Ikke p&aring; lager")</p> 190 </div> 191 @if (!isOrderTemplate) 192 { 193 <div class="favorite-list-icon" data-toggle="modal" data-target="#modal-@productID" data-bind="with: OrderTemplateViewModel"> 194 <i class="fas fa-heart" data-bind=" 195 oninit: function() { IsInFavoriteList('@inFavourite'.toLowerCase()) }, 196 css : { showFavorite : ShowOrderTemplateDialog, showNewList : OrderTemplateShowNewList, active: IsInFavoriteList() == 'true' }, 197 visible: $root.User().IsLoggedIn(), 198 click: ToggleOrderTemplateDialog"> 199 </i> 200 </div> 201 <div class="modal fade" id="modal-@productID" tabindex="-1" role="dialog" data-bind="with: OrderTemplateViewModel"> 202 <!-- ko initValue: {observable: OrderTemplateRelationCount, value:'@productInFavoritLists'}--><!-- /ko--> 203 <!-- ko initValue: {observable: ShowInFavourite, value: @inFavouriteBoolJS}--><!-- /ko--> 204 <!-- ko initValue: {observable: ModalSelector, value: '#modal-@productID'}--><!-- /ko--> 205 <div class="modal-dialog" role="document"> 206 <div class="modal-content fav-list"> 207 208 <p class="favlist-header">@Translate("Ordertemplate.AddToExistingList", "Tilføj til eksisterende favoritliste")</p> 209 210 <div class="existing-lists"> 211 212 <select class="favField select-fix" 213 data-bind="options: OrderTemplateList, 214 optionsCaption: '@PickListText', 215 optionsText: function(item) { return item.Value.Name() + ' (' + item.Value.Count() + ')' }, 216 value: OrderTemplateSelectedList"></select> 217 218 <input class="product-quantity" type="number" name="quantity" data-bind="textInput: OrderTemplateQuantity" /> 219 220 <div class="btn btn-primary" 221 data-bind="click: function() { 222 OrderTemplateShowNewList() 223 ? CreateNewOrderTemplateList('@productID') 224 : AddProductToOrderTemplate('@productID' , OrderTemplateQuantity()) 225 }"> 226 @Translate("Ordertemplate.AddToList", "Tilføj") 227 </div> 228 229 </div> 230 231 <p class="or-text">@Translate("Ordertemplate.OrNewList", "eller...")</p> 232 233 <p class="favlist-header">@Translate("Ordertemplate.AddToNewList", "Tilføj til ny favoritliste")</p> 234 235 <form id="EditForm-@productID" 236 name="EditForm"> 237 <label class="xs-m-b-1" for="name">@Translate("Ordertemplate.ListName", "Favoritliste navn")</label> 238 <div class="new-list"> 239 <input type="text" 240 name="name" 241 _id="name" 242 data-bind="textInput: OrderTemplateNewListName" 243 autofocus 244 autocomplete="off" /> 245 246 <input class="product-quantity" type="number" name="quantity" data-bind="textInput: OrderTemplateNewListQuantity" /> 247 248 <button type="submit" 249 class="btn btn-primary" 250 _id="btnSave" 251 data-bind="click: function() { CreateNewOrderTemplateList('@productID', OrderTemplateNewListQuantity()) }"> 252 @Translate("Ordertemplate.SaveToNewList", "Tilføj til ny favoritliste") 253 </button> 254 </div> 255 </form> 256 257 </div> 258 </div> 259 </div> 260 } 261 else 262 { 263 <div class="favorite-list-icon" data-bind="with: OrderTemplateViewModel"> 264 <!-- ko initValue: {observable: OrderTemplateId, value:'@orderTemplateId'}--><!-- /ko--> 265 <!-- ko initValue: {observable: OrderTemplateLineId, value:'@orderLineId'}--><!-- /ko--> 266 <i class="fas fa-times" 267 data-bind=" 268 oninit: function() { IsInFavoriteList('@inFavourite'.toLowerCase()) }, 269 css: { showFavorite: ShowOrderTemplateDialog, showNewList: OrderTemplateShowNewList, active: IsInFavoriteList() == 'true' }, 270 click: DeleteOrderTemplateLine"> 271 </i> 272 </div> 273 } 274 </div> 275 } 276 @if (ShowShopFunctions && !IsOutletShop) 277 { 278 <p class="stock-indicator js-stock-indicator"> 279 <span class="stock-load-async"></span> 280 <span class="stock-name js-stock-name">@Translate("Product.StockStatus", "Lagerstatus")</span> 281 <span class="stock-name js-in-stock-again hide">@Translate("Product.StockExpectedAgaing", "P&aring; lager: ")<span class="js-stock-date"></span></span> 282 </p> 283 } 284 @if (IsOutletShop) 285 { 286 <div class="bg-secondary regular-rrp"> 287 <p class="xs-m-b-0"> 288 @Translate("Product.NormalRRP", "Normal butikspris: ") @RRPrice 289 </p> 290 </div> 291 } 292 </div> 293 294 </div> 295 <!-- /ko--> 296 } 297 298 299 300 301 302 @helper renderRelatedProduct(LoopItem repatedProduct) 303 { 304 string productID = repatedProduct.GetString("Ecom:Product.ID"); 305 string productNumber = repatedProduct.GetString("Ecom:Product.Number"); 306 string mainProductID = GetString("Ecom:Product:Field.FirstwebMainProductID"); 307 308 string productName = repatedProduct.GetString("Ecom:Product.Name"); 309 string productDescription = GetString("Ecom:Product.LongDescription"); 310 string productShortDescription = GetString("Ecom:Product.ShortDescription"); 311 312 string nettoPrice = repatedProduct.GetString("Firstweb:ErpPriceInfo.NettoPriceFormatted"); 313 int bruttoPrice = repatedProduct.GetInteger("Firstweb:ErpPriceInfo.BruttoAmountFormattedNoSymbol"); 314 315 int productPackagingQuantity = repatedProduct.GetInteger("Ecom:Product:Field.FirstwebNoPerColli"); 316 int defaultQuantity = productPackagingQuantity > 0 ? productPackagingQuantity : 1; 317 318 string languageId = repatedProduct.GetString("Ecom:Product.LanguageID"); 319 string variantId = repatedProduct.GetString("Ecom:Product.VariantID"); 320 321 int productInFavoritLists = GetInteger("Firstweb:Ecom:Product:OrderTemplate.InTemplates.Count"); 322 323 List<Dynamicweb.Ecommerce.Products.Detail> productImages = Firstweb.Custom.CustomCode.Frontend.Helpers.ProductImages.GetProductImages(languageId, productID, variantId); 324 Dynamicweb.Ecommerce.Products.Detail primaryProductImage = productImages.FirstOrDefault(x=>x.IsDefault); //Tag you can use instead: product.GetString("Ecom:Product.ImageDefault.Clean"); 325 //check for valid default image 326 if (primaryProductImage == null) 327 { 328 primaryProductImage = new Dynamicweb.Ecommerce.Products.Detail { Value = "" }; 329 } 330 else if (primaryProductImage.Value == null) 331 { 332 primaryProductImage.Value = ""; 333 } 334 335 string primaryProductImageUrl = "/admin/public/getimage.ashx?image=" + primaryProductImage.Value + "&altFmImage_path=/Files/Images/ecom/Products/no-image.jpg&width=300&height=300&Compression=90&Crop=5"; 336 337 //Sorted: first by imagegroup then by sortorder 338 //@foreach (var productImage in productImages) 339 //{ 340 //productImage.Value; //This is the imagepath eks. /Images/products/R12155_10_2.jpg 341 //productImage.IsDefault; //If the image is default or not. 342 //} 343 344 <li> 345 <article class="xs-p-2 lg-p-1 rounded-5 border-1 border-color-default"> 346 <div class="row is-flex xs-is-flex-column sm-is-flex-col md-is-flex-col"> 347 348 <div class="col-md-12 md-is-flex lg-p-r-0"> 349 <section class="col-md-3 col-lg-3 xs-p-0 md-p-l-0 md-p-r-1 lg-p-r-1 lg-p-l-0"> 350 <img class="img-responsive xs-auto-margin sm-auto-margin" src="@primaryProductImageUrl" /> 351 </section> 352 353 <section class="col-md-9 col-lg-7 xs-m-t-2 sm-m-t-2 md-m-t-0 xs-p-0 md-p-r-0 md-p-l-1 lg-p-r-0 lg-p-l-0"> 354 <header class="xs-m-b-1"> 355 <h2 data-bind="text: name" 356 class="h2 tertiary-font xs-m-t-0"> 357 @productName 358 </h2> 359 </header> 360 361 <section class="xs-m-b-1 clearfix"> 362 <span class="pull-left font-size-small"> 363 @Translate("Product.NumberShort", "Varenr."): <span>@productNumber</span> 364 </span> 365 </section> 366 367 <section class="word-break"> 368 <p class="font-size-small"> 369 @productShortDescription 370 </p> 371 </section> 372 </section> 373 </div> 374 375 <section class="col-md-9 col-md-offset-3 col-lg-5 col-lg-offset-0 sm-m-t-1 lg-m-t-0 md-p-l-2 376 lg-p-l-0 is-flex is-flex-col sm-is-flex-row sm-is-flex-wrap sm-flex-justify-space-between 377 md-is-flex-row md-is-flex-wrap md-flex-justify-space-between lg-flex-grow-2 lg-flex-justify-space-between"> 378 379 <div class="is-flex xs-m-t-1 sm-m-t-0 is-flex-col lg-m-b-auto"> 380 381 </div> 382 383 <div class="is-flex is-flex-col md-m-b-1 lg-m-b-0"> 384 <h4 class="h4 tertiary-font font-size-16px xs-m-b-1 sm-m-t-0 md-text-right lg-text-right"> 385 @nettoPrice 386 </h4> 387 388 <section class="xs-m-b-1 clearfix is-flex xs-flex-space-between lg-is-row-reverse"> 389 <div class="pull-right margin-left-1 xs-order-1 sm-order-1 md-order-1 xs-is-self-end sm-is-self-end md-is-self-end lg-m-t-0"> 390 @renderQuantityBox(defaultQuantity) 391 </div> 392 393 <div class="is-flex is-flex-col is-centered xs-margin-right-auto sm-m-r-1 md-m-r-1 font-size-small line-height-base md-text-right lg-text-right"> 394 <span>@Translate("Product.Packaging", "Forpakning"): </span> 395 <span> @productPackagingQuantity</span> 396 </div> 397 </section> 398 </div> 399 400 <section class="t-align-right clearfix sm-width-100 md-width-100"> 401 <button _data-bind="click: handleAddProductToCart" 402 class="btn btn-primary btn-xs tertiary-font lg-p-l-1 lg-p-r-1 xs-width-100 sm-width-100 md-width-100"> 403 @Translate("Product.AddToCart", "Tilføj til kurv") 404 </button> 405 </section> 406 </section> 407 408 </div> 409 </article> 410 </li> 411 412 413 414 } 415 416 @helper renderProductBuyBox(bool showShopFunctionsAlternativeIfNotLoggedIn, string productName, string productId, string price, int productPackagingQuantity, int quantity, string stockColor) 417 { 418 419 420 <article class="product-packaging border-bottom-1"> 421 <section class="row md-is-flex lg-is-flex md-is-flex-center lg-is-flex-center"> 422 <section class="packaging-section col-md-4 col-lg-5"> 423 <h4 class="h4 xs-m-t-0 xs-m-b-0 tertiary-font v-align-mid">@productName</h4> 424 </section> 425 426 427 428 @if (Firstweb.Custom.CustomCode.Tapas.Context.Current.ShopFunctionsVisibility.ShowShopFunctions()) 429 { 430 <section class="packaging-section md-p-l-0 xs-col-12 col-md-2 col-lg-2 tertiary-font"> 431 <span>@price</span> 432 433 434 </section> 435 <div class="stock md-is-self-end lg-is-self-end lg-order-0" > 436 @Translate("Product.StockStatus", "Lagerstatus"): <div class="stock-load-async @stockColor"></div> 437 438 </div> 439 <section class="packaging-section md-p-l-0 lg-p-r-8p packaging-section--alt xs-col-12 col-md-4 col-lg-3"> 440 <ul class="list-unstyled lg-m-l-auto lg-p-r-24p xs-m-b-0"> 441 <li> 442 <h5 class="h5 xs-m-b-0 xs-m-t-0 line-height-16px"> 443 <span>@Translate("Product.Packaging", "Forpakning"): </span> 444 <span> @productPackagingQuantity</span> 445 </h5> 446 </li> 447 </ul> 448 449 @renderQuantityBox(quantity) 450 451 </section> 452 453 <section class="packaging-section md-p-l-0 packaging-section--buy xs-col-12 col-md-2 col-lg-2 t-align-right"> 454 <button class="btn btn-primary btn-xs tertiary-font lg-p-l-1 lg-p-r-1 xs-width-100 sm-width-100 margin-bottom-4px" 455 _data-bind="click: handleAddProductToCart"> 456 @Translate("Product.AddToCart", "Tilføj til kurv") 457 </button> 458 </section> 459 460 } 461 else if (showShopFunctionsAlternativeIfNotLoggedIn) 462 { 463 var replaceWith = Firstweb.Custom.CustomCode.Tapas.Context.Current.ShopFunctionsVisibility.ReplaceWith(); 464 465 <section> 466 467 @if (replaceWith == "LOGIN") 468 { 469 <text>@renderLogin()</text> 470 } 471 else if (replaceWith == "RESELLER") 472 { 473 <text>@renderResellerLink()</text> 474 } 475 </section> 476 } 477 478 </section> 479 </article> 480 } 481 482 483 @helper renderInstantSearchProduct(LoopItem product) 484 { 485 string productID = product.GetString("Ecom:Product.ID"); 486 string productNumber = product.GetString("Ecom:Product.Number"); 487 string mainProductID = product.GetString("Ecom:Product:Field.FirstwebMainProductID"); 488 489 string productLink = product.GetString("Ecom:Product.Link.Clean"); 490 491 string productName = product.GetString("Ecom:Product.Name"); 492 string productShortDescription = product.GetString("Ecom:Product.ShortDescription"); 493 494 int productPackagingQuantity = product.GetInteger("Firstweb:ErpPriceInfo:ExtraInfos.PackagingSize"); 495 int defaultQuantity = productPackagingQuantity > 0 ? productPackagingQuantity : 1; 496 497 string languageId = product.GetString("Ecom:Product.LanguageID"); 498 string variantId = product.GetString("Ecom:Product.VariantID"); 499 500 bool hasVariants = (product.GetLoop("VariantCombinations").Count() > 0); 501 502 //Images 503 List<Dynamicweb.Ecommerce.Products.Detail> productImages = Firstweb.Custom.CustomCode.Frontend.Helpers.ProductImages.GetProductImages(languageId, productID, variantId); 504 Dynamicweb.Ecommerce.Products.Detail primaryProductImage = productImages.FirstOrDefault(x=>x.IsDefault); //Tag you can use instead: product.GetString("Ecom:Product.ImageDefault.Clean"); 505 506 //check for valid default image 507 if (primaryProductImage == null) 508 { 509 primaryProductImage = new Dynamicweb.Ecommerce.Products.Detail { Value = "" }; 510 } 511 else if (primaryProductImage.Value == null) 512 { 513 primaryProductImage.Value = ""; 514 } 515 516 string primaryProductImageUrl = "/admin/public/getimage.ashx?image=" + primaryProductImage.Value + "&altFmImage_path=/Files/Images/ecom/Products/no-image.jpg&width=200&height=125&Compression=90&Crop=5"; 517 if (String.IsNullOrEmpty(primaryProductImage.Value)) 518 { 519 primaryProductImageUrl = "/admin/public/getimage.ashx?image=/Files/Images/ecom/Products/no-image.jpg&width=200&height=125&Compression=90&Crop=5"; 520 } 521 //Sorted: first by imagegroup then by sortorder 522 //@foreach (var productImage in productImages) 523 //{ 524 //productImage.Value; //This is the imagepath eks. /Images/products/R12155_10_2.jpg 525 //productImage.IsDefault; //If the image is default or not. 526 //} 527 528 //Other packagings 529 //var otherPackagingProducts = Firstweb.Custom.CustomCode.Frontend.Helpers.OtherPackagingProducts.GetOtherPackagingProducts(mainProductID, false).Where(i => i.Id != productID); 530 //var showOtherPackagingProducts = otherPackagingProducts.Count() > 0; 531 532 int loopCount = product.GetInteger("Products.LoopCounter") - 1; 533 <div class="col-xs-12 col-sm-3 xs-m-b-1"> 534 535 <article class="instant-search-product bg-white productCount @loopCount" data-bind="css: {'item--selected': navSelectedItem() == @loopCount}"> 536 <div class="cursor-pointer info" 537 data-bind="click: function() { window.location.href='@productLink'}"> 538 <div class="hidden-xs product-image"> 539 <img class="img-responsive center-block" src="@primaryProductImageUrl"> 540 </div> 541 542 <div class="name"> 543 <p>@productName</p> 544 545 546 <span>@Translate("Product.NumberShort", "Varenr.") @productNumber</span> 547 </div> 548 </div> 549 550 @if (Firstweb.Custom.CustomCode.Tapas.Context.Current.ShopFunctionsVisibility.ShowShopFunctions()) 551 { 552 <div class="buy-container" data-bind="defineObservable: { quantity: 1 }"> 553 554 <input class="product-quantity" type="number" name="quantity" data-bind="value: quantity" /> 555 556 <button class="btn btn-primary btn-xs add-to-cart" 557 data-bind="click: function(evt) { $parent.onAddToCart('@productID', quantity()) }"> 558 @Translate("Product.AddToCart", "Tilføj til kurv") 559 </button> 560 </div> 561 } 562 </article> 563 564 </div> 565 566 } 567 568 569 570 @helper renderQuantityBox(int quantity) 571 { 572 <input class="product-quantity" type="number" name="quantity" value="@quantity" /> 573 } 574 575 576 @helper renderLogin() 577 { 578 <button class="btn btn-primary" data-toggle="modal" data-target=".loginModal">@Translate("Product.LoginToShop", "Log ind for at købe")</button> 579 } 580 @helper renderResellerLink() 581 { 582 <a href="@Firstweb.Custom.CustomCode.Tapas.Context.Current.ShopFunctionsVisibility.ReplaceLink()" class="btn btn-primary">@Translate("Product.FindReseller", "Find forhandler")</a> 583 } 584 585 @inherits RazorTemplateBase<RazorTemplateModel<Template>> 586 @using Dynamicweb.Rendering 587 @using Dynamicweb.Environment 588 589 @helper renderBreadcrumbs(string productId = "") 590 { 591 string currentGroupId = Dynamicweb.Context.Current.Request.GetString("GroupID"); 592 string productPageID = Firstweb.Custom.CustomCode.Tapas.Context.AreaPages.GetPageId("productcatalog"); 593 string productPageHref = "/Default.aspx?Id=" + productPageID; 594 var breadCrumbGroupList = Firstweb.Custom.CustomCode.Frontend.Helpers.EcomGroups.getBreadCrumbGroupList(currentGroupId, true); 595 596 if (!String.IsNullOrEmpty(productId)) { 597 breadCrumbGroupList = Firstweb.Custom.CustomCode.Frontend.Helpers.EcomGroups.getBreadCrumbGroupListByProduct(productId, true); 598 } 599 600 <div class="col-xs-12"> 601 <ul class="breadcrumb"> 602 <li><a href="@productPageHref" title="@Translate("Firstweb.Content.Breadcrumbs.ProductPage", "Produkter")">@Translate("Firstweb.Content.Breadcrumbs.ProductPage", "Produkter")</a></li> 603 @foreach (var g in breadCrumbGroupList) { 604 string breadCrumbLink = String.Format("/Default.aspx?Id={0}&amp;GroupId={1}", productPageID, g.Id); 605 <li> <a href='@breadCrumbLink' title="@g.Name">@g.Name </a></li> 606 } 607 </ul> 608 </div> 609 } 610 611 @{ 612 string sortOrder = GetString("Ecom:ProductList.SortOrder"); 613 bool isAjaxRequest = Dynamicweb.Context.Current.Request.GetBoolean("ajaxTapas"); 614 string searchQuery = Dynamicweb.Context.Current.Request.GetString("Search"); 615 string currentGroupId = Dynamicweb.Context.Current.Request.GetString("GroupID"); 616 int pageId = Dynamicweb.Frontend.PageView.Current().ID; 617 var breadCrumbGroupList = Firstweb.Custom.CustomCode.Frontend.Helpers.EcomGroups.getBreadCrumbGroupList(currentGroupId, false); 618 bool IsGroupList = !String.IsNullOrEmpty(currentGroupId); 619 620 int totalPages = GetInteger("Ecom:ProductList.TotalPages"); 621 int currentPage = GetInteger("Ecom:ProductList.CurrentPage"); 622 int productCount = GetInteger("Ecom:ProductList.PageProdCnt"); 623 bool productsFound = (productCount > 0); 624 bool IsOutletShop = Firstweb.Custom.CustomCode.Frontend.Helpers.Millarco.IsOutletShop(); 625 626 int ProductGroupVideoList = GetInteger("Ecom:Group:Field.FirstwebProductGroupVideoList"); 627 628 bool isGroupView = GetBoolean("Ecom:Group:Field.groupview"); 629 } 630 631 @if (!isAjaxRequest) 632 { 633 <div class="container"> 634 <div class="row"> 635 @renderBreadcrumbs() 636 </div> 637 </div> 638 639 <div class="millarco-productlist"> 640 641 <section> 642 643 @if (IsGroupList) 644 { 645 @RenderGroupHeader() 646 } 647 else if (!String.IsNullOrWhiteSpace(searchQuery)) 648 { 649 <div class="container xs-p-t-3"> 650 @RenderSearchHeader(searchQuery) 651 </div> 652 } 653 else if (!IsOutletShop) 654 { 655 <div class="container xs-p-t-3"> 656 @RenderParagraphHeader() 657 </div> 658 } 659 else 660 { 661 @RenderOutletShopHeader() 662 } 663 664 </section> 665 666 @if (!isGroupView) 667 { 668 <div class="container product-container"> 669 670 <main data-bind="viewModel: 'ProductListViewModel'"> 671 <div class="row"> 672 <div class="col-lg-3 product-groups-wrapper"> 673 <p class="h3">@Translate("ProductSubNavTitle", "Produkter")</p> 674 @if (productsFound) 675 { 676 if (IsGroupList) 677 { 678 <div class="product-groups"> 679 @RenderGroupLevelFilter(Firstweb.Custom.CustomCode.Frontend.Helpers.EcomGroups.GetFilterTopLevelGroup(), currentGroupId, currentGroupId, pageId) 680 </div> 681 } 682 } 683 </div> 684 <div class="col-lg-9"> 685 <div class="row"> 686 @if (productsFound) 687 { 688 <div class="col-xs-12 filter-section"> 689 <form method="get" 690 action="/Default.aspx" 691 data-bind="formSubmitOnChange: { 692 text: '@Translate("Productlist.UpdatingFilters", "Opdaterer filter")', 693 delay: '1000' }"> 694 <input type="hidden" name="id" value="@GetString("Ecom:ProductList:Page.ID")" /> 695 696 @if (!String.IsNullOrEmpty(currentGroupId)) 697 { 698 <input type="hidden" name="groupid" value="@currentGroupId" /> 699 } 700 @if (!String.IsNullOrEmpty(searchQuery)) 701 { 702 <input type="hidden" name="search" value="@searchQuery" /> 703 } 704 705 @RenderSorting(sortOrder) 706 707 @RenderFacets() 708 </form> 709 </div> 710 } 711 <div class="col-xs-12 productList" 712 data-bind="asyncPriceLoad: productListLoad, 713 loadOnBool: { observableBool: CartLoading, text: 'Tilføjer produkt' }, 714 css: 'loaded'"> 715 716 <div class="row row-ce"> 717 @RenderProductList(GetLoop("Products"), productsFound) 718 </div> 719 720 @if (ProductGroupVideoList > 0) 721 { 722 @RenderParagraphContent(ProductGroupVideoList) 723 } 724 725 @if (totalPages > 1 && currentPage == 1) 726 { 727 <div class="loadMoreProducts" 728 data-bind="loadMoreProducts: { 729 beforeLoad: function() { $root.stuffLoadingQueue({load: true}) }, 730 afterLoad: function() { $root.stuffLoadingQueue({load: false}) }, 731 text: '@Translate("Productlist.LoadingProducts", "Henter produkter")', 732 currentPage: @currentPage, 733 totalPages: @totalPages 734 }"> 735 </div> 736 } 737 738 @if (!String.IsNullOrEmpty(GetString("Ecom:Group:Field.GroupDescriptionBottom"))) 739 { 740 <div class="group-description">@GetString("Ecom:Group:Field.GroupDescriptionBottom")</div> 741 } 742 </div> 743 </div> 744 </div> 745 </div> 746 </main> 747 </div> 748 } 749 else 750 { 751 int subGroupCount = 0; 752 List<LoopItem> subGroups = GetLoop("Subgroups"); 753 bool anySelectedGroups = subGroups.Any(g => g.GetBoolean("Ecom:Group:Field.selectedgroup.Value")); 754 bool anyUnselectedGroups = subGroups.Any(g => !g.GetBoolean("Ecom:Group:Field.selectedgroup.Value")); 755 string hideIfAnySelectedGroupsClass = !anySelectedGroups && anyUnselectedGroups ? "" : "hidden"; 756 757 <div class="container"> 758 <main class="group-view"> 759 <div class="row"> 760 <div class="col-lg-12"> 761 @if (anySelectedGroups) 762 { 763 <div class="selected-groups"> 764 <p class="h2 margin-top-40px">@Translate("GroupViewTitle", "Udvalgte kategorier")</p> 765 <div class="row"> 766 @foreach (LoopItem group in subGroups.Where(g => g.GetBoolean("Ecom:Group:Field.selectedgroup.Value"))) 767 { 768 string imagePath = group.GetString("Ecom:Group.SmallImage"); 769 string imagePathCustom = group.GetString("Ecom:Group:Field.selectedgroupimage.Value.Clean"); 770 string image; 771 string cssBackground; 772 string groupName = group.GetString("Ecom:Group.Name"); 773 string groupImgSize = group.GetString("Ecom:Group:Field.groupImageSize"); 774 string groupHeaderColor = group.GetString("Ecom:Group:Field.groupHeaderColor"); 775 string groupHeaderFontSize = group.GetString("Ecom:Group:Field.groupHeaderFontSize") + "px"; 776 bool headerBg = group.GetBoolean("Ecom:Group:Field.GroupHeaderBgColor"); 777 string groupHeaderBg = ""; 778 if (headerBg) 779 { 780 groupHeaderBg = "show-bg"; 781 } 782 if ( groupImgSize != "100%" ) 783 { 784 groupImgSize = "200px"; 785 } 786 787 if (!string.IsNullOrEmpty(imagePathCustom)) 788 { 789 image = "/admin/public/GetImage.ashx?image=" + imagePathCustom + "&width=400"; 790 cssBackground = "background:#fff url('" + image + "') no-repeat center center / cover;"; 791 } 792 else 793 { 794 image = "/admin/public/GetImage.ashx?image=" + imagePath + "&width=400"; 795 cssBackground = "background:#fff url('" + image + "') no-repeat center center / " + groupImgSize + ";"; 796 } 797 798 <div class="col-12 col-sm-6 col-lg-4"> 799 <a href="@group.GetString("Ecom:Group.Link.Clean")"> 800 <div style="@cssBackground" class="img-responsive margin-bottom-24px group-image"> 801 <div class="group-name @groupHeaderColor @groupHeaderBg" style="font-size: @groupHeaderFontSize">@groupName</div> 802 </div> 803 </a> 804 </div> 805 } 806 </div> 807 </div> 808 } 809 810 @if (anySelectedGroups && anyUnselectedGroups) 811 { 812 <div class="row margin-top-18px margin-bottom-18px"> 813 <div class="col-12"> 814 <div class="groups-view-all centerText"> 815 <div onclick="$('.all-groups').removeClass('hidden'), $(this).addClass('hidden');" class="btn btn-primary">@Translate("GroupViewMoreButton", "Se alle grupper")</div> 816 </div> 817 </div> 818 </div> 819 } 820 821 <div class="all-groups @hideIfAnySelectedGroupsClass"> 822 <p class="h2 margin-top-40px">@Translate("AllGroupViewTitle", "Alle kategorier")</p> 823 <div class="row"> 824 @foreach (LoopItem group in subGroups.Where(g => !g.GetBoolean("Ecom:Group:Field.selectedgroup.Value") && g.GetBoolean("Ecom:Group:Field.FirstwebShowInGroupFilter.Value"))) 825 { 826 string imagePath = group.GetString("Ecom:Group.SmallImage"); 827 string imagePathCustom = group.GetString("Ecom:Group:Field.selectedgroupimage.Value.Clean"); 828 string image; 829 string cssBackground; 830 string groupName = group.GetString("Ecom:Group.Name"); 831 string groupImgSize = group.GetString("Ecom:Group:Field.groupImageSize"); 832 string groupHeaderColor = group.GetString("Ecom:Group:Field.groupHeaderColor"); 833 string groupHeaderFontSize = group.GetString("Ecom:Group:Field.groupHeaderFontSize") + "px"; 834 bool headerBg = group.GetBoolean("Ecom:Group:Field.GroupHeaderBgColor"); 835 string groupHeaderBg = ""; 836 if (headerBg) 837 { 838 groupHeaderBg = "show-bg"; 839 } 840 if ( groupImgSize != "100%" ) 841 { 842 groupImgSize = "200px"; 843 } 844 845 if (!string.IsNullOrEmpty(imagePathCustom)) 846 { 847 image = "/admin/public/GetImage.ashx?image=" + imagePathCustom + "&width=400"; 848 cssBackground = "background:#fff url('" + image + "') no-repeat center center / cover;"; 849 } 850 else 851 { 852 image = "/admin/public/GetImage.ashx?image=" + imagePath + "&width=400"; 853 cssBackground = "background:#fff url('" + image + "') no-repeat center center / " + groupImgSize + ";"; 854 } 855 856 <div class="col-12 col-sm-6 col-lg-4"> 857 <a href="@group.GetString("Ecom:Group.Link.Clean")"> 858 <div style="@cssBackground" class="img-responsive margin-bottom-24px group-image"> 859 <div class="group-name @groupHeaderColor @groupHeaderBg" style="font-size: @groupHeaderFontSize">@groupName</div> 860 </div> 861 </a> 862 </div> 863 } 864 </div> 865 </div> 866 <div class="margin-top-40px margin-bottom-40px"> 867 @if (!String.IsNullOrEmpty(GetString("Ecom:Group:Field.GroupDescriptionBottom"))) 868 { 869 <div class="group-description">@GetString("Ecom:Group:Field.GroupDescriptionBottom")</div> 870 } 871 </div> 872 </div> 873 </div> 874 </main> 875 </div> 876 } 877 878 </div> 879 } 880 else 881 { 882 <div class="productsContainer"> 883 @RenderProductList(GetLoop("Products"), productsFound) 884 </div> 885 } 886 887 @helper RenderProductList(IEnumerable<LoopItem> Loop, bool productsFound) 888 { 889 if (!productsFound) 890 { 891 <div class="is-flex col-xs-12 xs-m-t-3 xs-m-b-4 sm-m-b-7 font-primary"> 892 <h1>@Translate("ProductList.NoProductsFound", ":( There are no products in this category")</h1> 893 </div> 894 } 895 else 896 { 897 var productLoop = Loop.ToList(); 898 int currentPage = GetInteger("Ecom:ProductList.CurrentPage"); 899 int totalPages = GetInteger("Ecom:ProductList.TotalPages"); 900 var count = 0; 901 902 for (int i = 0; i < productLoop.Count(); i++) 903 { 904 var item = productLoop[i]; 905 int loopMod = item.GetInteger("Products.LoopMod4"); 906 bool renderStartRow = i % 3 == 0 ? true : false; 907 bool renderEndRow = i % 3 == 0 ? true : false; 908 909 if (i == 0 && totalPages > 1) 910 { 911 @:<div class="row row-ce" id="@currentPage"> 912 } 913 914 @renderProduct(true, item, true); //This is from renderProduct.cshtml 915 916 917 if (productLoop.Count() - 1 == i && totalPages > 1) 918 { 919 @:</div> 920 } 921 } 922 } 923 } 924 925 @helper RenderOutletShopHeader() 926 { 927 <div class="content-element solid-bg bg-image-and-text-element bg-secondary" style="background-image:url('/Files/Images/@Dynamicweb.Frontend.PageView.Current().CurrentParagraph.Image')"> 928 <div class="container"> 929 <div class="row"> 930 <div class="col-xs-12 col-md-8 col-lg-6"> 931 <div class="text-area"> 932 <div class="rte-content"> 933 @Dynamicweb.Frontend.PageView.Current().CurrentParagraph.Text 934 </div> 935 <div class="red-divider"></div> 936 </div> 937 </div> 938 </div> 939 </div> 940 </div> 941 } 942 943 944 @helper RenderGroupHeader() 945 { 946 int ProductGroupVideoTop = GetInteger("Ecom:Group:Field.FirstwebProductGroupVideoTop"); 947 string Description = GetString("Ecom:Group.Description"); 948 string GroupName = GetString("Ecom:Group.Name"); 949 string BgImage = GetString("Ecom:Group.LargeImage"); 950 bool IsOutletShop = Firstweb.Custom.CustomCode.Frontend.Helpers.Millarco.IsOutletShop(); 951 if (IsOutletShop && !String.IsNullOrEmpty(GetString("Ecom:Group:Field.FirstwebOutletGroupImage.Value.Clean"))) 952 { 953 BgImage = GetString("Ecom:Group:Field.FirstwebOutletGroupImage.Value.Clean"); 954 } 955 956 if (ProductGroupVideoTop > 0) 957 { 958 @RenderParagraphContent(ProductGroupVideoTop) 959 } 960 else 961 { 962 <div class="content-element solid-bg bg-image-and-text-element bg-secondary" style="background-image:url('@BgImage')"> 963 <div class="container"> 964 <div class="row"> 965 <div class="col-xs-12 col-md-8 col-lg-6"> 966 <div class="text-area"> 967 @if (!String.IsNullOrEmpty(Description)) 968 { 969 <div class="rte-content"> 970 @Description 971 </div> 972 } 973 else 974 { 975 <h1 class="xs-m-t-0">@GroupName</h1> 976 } 977 <div class="red-divider"></div> 978 </div> 979 </div> 980 </div> 981 </div> 982 </div> 983 } 984 } 985 986 @helper RenderSearchHeader(string searchQuery) 987 { 988 <h1 class="h1 xs-m-t-0 tertiary-font"> 989 @Translate("ProductList.SearchResultHeader", "S&oslash;geresultat") 990 </h1> 991 992 <h4 class="h4 lg-m-b-0"> 993 @Translate("ProductList.SearchResultText", "Resultater for din s&oslash;gning"): @searchQuery 994 </h4> 995 } 996 997 @helper RenderParagraphHeader() 998 { 999 <h1 class="h1 lg-m-t-0 tertiary-font">@Dynamicweb.Frontend.PageView.Current().CurrentParagraph.Header</h1> 1000 1001 if (!String.IsNullOrEmpty(Dynamicweb.Frontend.PageView.Current().CurrentParagraph.Text)) 1002 { 1003 <p>@Dynamicweb.Frontend.PageView.Current().CurrentParagraph.Text</p> 1004 } 1005 } 1006 1007 1008 @helper RenderGroups(List<Dynamicweb.Ecommerce.Products.Group> breadCrumbGroupList, string currentGroupId) 1009 { 1010 if (breadCrumbGroupList.Count() > 0) 1011 { 1012 var ParentGroup = breadCrumbGroupList.LastOrDefault(); 1013 var baseLink = "/Default.aspx?ID=" + Dynamicweb.Frontend.PageView.Current().ID + "&GroupID="; 1014 if (ParentGroup != null) 1015 { 1016 <section class="product__sub-nav"> 1017 <p class="xs-m-b-0"> 1018 @ParentGroup.Name 1019 </p> 1020 1021 <ul> 1022 @foreach (var subgroup in ParentGroup.Subgroups) 1023 { 1024 <li> 1025 @if (subgroup.Id == currentGroupId) 1026 { 1027 <span>@subgroup.Name</span> 1028 } 1029 else 1030 { 1031 bool DisplayGroup = subgroup.Products.Count() > 0 || subgroup.Subgroups.Where(x => x.Products.Count() > 0).Count() > 0; 1032 if (DisplayGroup) 1033 { 1034 <a href="@baseLink@subgroup.Id">@subgroup.Name</a> 1035 } 1036 } 1037 </li> 1038 } 1039 </ul> 1040 </section> 1041 } 1042 } 1043 } 1044 1045 @helper RenderFacets() 1046 { 1047 foreach (LoopItem facetGroup in GetLoop("FacetGroups")) 1048 { 1049 foreach (LoopItem facet in facetGroup.GetLoop("Facets").Where(x => x.GetLoop("FacetOptions").Any())) 1050 { 1051 string facetName = facet.GetString("Facet.Name"); 1052 string translatedFacetName = Translate("ProductList.FacetName" + facet.GetString("Facet.Name"), facet.GetString("Facet.Name")); 1053 bool hasOptions = facet.GetLoop("FacetOptions").Any(); 1054 string hasOptionsCss = hasOptions ? "xs-p-t-1 xs-p-b-1" : ""; 1055 string FacetIsOpen = facet.GetLoop("FacetOptions").Where(x => x.GetBoolean("FacetOption.Selected")).Any() ? "true" : "false"; 1056 1057 <section class="bg-white filter" data-bind="defineObservable: { sortDropdown: @FacetIsOpen }"> 1058 @if (hasOptions) 1059 { 1060 <button class="filter__toggle xs-p-l-0 xs-p-r-0 clear-button is-flex is-space-between is-flex-align-center width-100" data-bind="click: function() { sortDropdown(!sortDropdown()) }"> 1061 <h3 class="h3 xs-m-t-0 xs-m-b-0 tertiary-font font-size-base filterHeader" 1062 data-bind="toggleClassParent: 'active'"> 1063 @translatedFacetName 1064 </h3> 1065 <span> 1066 <i class="fa fa-chevron-down"></i> 1067 </span> 1068 </button> 1069 } 1070 1071 <div class="filter__options line-height-base" data-bind="css: { hidden: !sortDropdown() }"> 1072 @foreach (LoopItem option in facet.GetLoop("FacetOptions")) 1073 { 1074 var value = option.GetValue("FacetOption.Value"); 1075 string label = option.GetString("FacetOption.Label").Replace("\"", "&#x22;"); 1076 if (label.ToUpper() == "TRUE" || label.ToUpper() == "FALSE") 1077 { 1078 label = Translate("ProductList.FacetOption:" + label, "Ja"); 1079 } 1080 1081 1082 int count = option.GetInteger("FacetOption.Count"); 1083 bool selected = option.GetBoolean("FacetOption.Selected"); 1084 label += " (" + count + ")"; 1085 <div class="form-group"> 1086 <custom-checkbox params="{ label: '@label', 1087 value: '@value', 1088 checked: @(selected.ToString().ToLower()), 1089 name: '@facet.GetString("Facet.QueryParameter")' }" /> 1090 </div> 1091 } 1092 </div> 1093 </section> 1094 } 1095 } 1096 } 1097 1098 1099 @helper RenderSorting(string sortOrder) 1100 { 1101 <section class="bg-white filter filter__container" 1102 data-bind="defineObservable: { 1103 sortOrder: '@sortOrder' || 'ASC', 1104 sortDropdown: false }"> 1105 <button class="filter__toggle clear-button is-flex is-space-between is-flex-align-center clear-button xs-p-l-0 xs-p-r-0 width-100" data-bind="click: function() { sortDropdown(!sortDropdown()) }"> 1106 <p class="h3 xs-m-t-0 xs-m-b-0 tertiary-font font-size-base" 1107 data-bind="toggleClassParent: 'active'"> 1108 @Translate("filtersort", "Sortering") 1109 </p> 1110 1111 <span> 1112 <i class="fa fa-chevron-down"></i> 1113 </span> 1114 </button> 1115 1116 <input type="hidden" name="SortBy" value="ProductNameSort" /> 1117 1118 <section class="filter__options" data-bind="css: { hidden: !sortDropdown() }"> 1119 <div class="form-group"> 1120 <custom-radio params="{ 1121 label: '@Translate("sortnameaz", "Navn: A - &Aring;")', 1122 value: 'ASC', 1123 checked: sortOrder, 1124 name: 'SortOrder' }" /> 1125 </div> 1126 1127 <div class="form-group xs-m-b-0"> 1128 <custom-radio params="{ 1129 label: '@Translate("sortnameza", "Navn: &Aring; - A")', 1130 value: 'DESC', 1131 checked: sortOrder, 1132 name: 'SortOrder' }" /> 1133 </div> 1134 </section> 1135 </section> 1136 } 1137 1138 @helper RenderGroupLevelFilter(IEnumerable<Dynamicweb.Ecommerce.Products.Group> groups, string currentGroupId, string activeGroup, int pageId) 1139 { 1140 var ProductGroups = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(currentGroupId); 1141 bool isTopLevelGroup = ProductGroups.IsTopGroup; 1142 var parentGroup = ProductGroups.PrimaryParentGroupId; 1143 1144 if (isTopLevelGroup) 1145 { 1146 foreach (var group in groups.Where(x => Firstweb.Custom.CustomCode.Frontend.Helpers.EcomGroups.IsFilterGroup(x))) 1147 { 1148 var currentGroup = group.Id.Equals(currentGroupId); 1149 var isCurrentGroup = currentGroup ? "is-active" : ""; 1150 1151 <div class="@isCurrentGroup"> 1152 <a href="/Default.aspx?Id=@pageId&groupid=@group.Id">@group.Name</a> 1153 </div> 1154 1155 if (currentGroup && group.HasChildGroups) 1156 { 1157 <div class="sub-group"> 1158 @foreach (var isSubGroup in group.Subgroups) 1159 { 1160 var setActive = isSubGroup.Id == activeGroup ? "is-active" : ""; 1161 1162 <div class="@setActive"> 1163 <a href="/Default.aspx?Id=@pageId&groupid=@isSubGroup.Id">@isSubGroup.Name</a> 1164 </div> 1165 } 1166 @*@RenderGroupLevelFilter(group.Subgroups, currentGroupId, (level + 1))*@ 1167 </div> 1168 } 1169 } 1170 } 1171 else 1172 { 1173 @RenderGroupLevelFilter(groups, parentGroup, currentGroupId, pageId) 1174 } 1175 }

Denne hjemmeside bruger cookies til trafikmåling og optimering af indhold