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_78a929b8aca741e1abdb17353d2408f0.<>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 1115
   at CompiledRazorTemplates.Dynamic.RazorEngine_78a929b8aca741e1abdb17353d2408f0.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 = 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 773 if (!string.IsNullOrEmpty(imagePathCustom)) 774 { 775 image = "/admin/public/GetImage.ashx?image=" + imagePathCustom + "&width=400"; 776 cssBackground = "background:#fff url('" + image + "') no-repeat center center / cover;"; 777 } 778 else 779 { 780 image = "/admin/public/GetImage.ashx?image=" + imagePath + "&width=400"; 781 cssBackground = "background:#fff url('" + image + "') no-repeat center center / 200px;"; 782 } 783 string groupName = group.GetString("Ecom:Group.Name"); 784 785 <div class="col-12 col-sm-6 col-lg-4"> 786 <a href="@group.GetString("Ecom:Group.Link.Clean")"> 787 <div style="@cssBackground" class="img-responsive margin-bottom-24px group-image"> 788 <div class="group-name">@groupName</div> 789 </div> 790 </a> 791 </div> 792 } 793 </div> 794 </div> 795 } 796 797 @if (anySelectedGroups && anyUnselectedGroups) 798 { 799 <div class="row margin-top-18px margin-bottom-18px"> 800 <div class="col-12"> 801 <div class="groups-view-all centerText"> 802 <div onclick="$('.all-groups').removeClass('hidden'), $(this).addClass('hidden');" class="btn btn-primary">@Translate("GroupViewMoreButton", "Se alle grupper")</div> 803 </div> 804 </div> 805 </div> 806 } 807 808 <div class="all-groups @hideIfAnySelectedGroupsClass"> 809 <p class="h2 margin-top-40px">@Translate("AllGroupViewTitle", "Alle kategorier")</p> 810 <div class="row"> 811 @foreach (LoopItem group in subGroups.Where(g => !g.GetBoolean("Ecom:Group:Field.selectedgroup.Value"))) 812 { 813 string imagePath = group.GetString("Ecom:Group.SmallImage"); 814 string imagePathCustom = group.GetString("Ecom:Group:Field.selectedgroupimage.Value.Clean"); 815 string image; 816 string cssBackground; 817 818 if (!string.IsNullOrEmpty(imagePathCustom)) 819 { 820 image = "/admin/public/GetImage.ashx?image=" + imagePathCustom + "&width=400"; 821 cssBackground = "background:#fff url('" + image + "') no-repeat center center / cover;"; 822 } 823 else 824 { 825 image = "/admin/public/GetImage.ashx?image=" + imagePath + "&width=400"; 826 cssBackground = "background:#fff url('" + image + "') no-repeat center center / 200px;"; 827 } 828 string groupName = group.GetString("Ecom:Group.Name"); 829 830 <div class="col-12 col-sm-6 col-lg-4"> 831 <a href="@group.GetString("Ecom:Group.Link.Clean")"> 832 <div style="@cssBackground" class="img-responsive margin-bottom-24px group-image"> 833 <div class="group-name">@groupName</div> 834 </div> 835 </a> 836 </div> 837 } 838 </div> 839 </div> 840 <div class="margin-top-40px margin-bottom-40px"> 841 @if (!String.IsNullOrEmpty(GetString("Ecom:Group:Field.GroupDescriptionBottom"))) 842 { 843 <div class="group-description">@GetString("Ecom:Group:Field.GroupDescriptionBottom")</div> 844 } 845 </div> 846 </div> 847 </div> 848 </main> 849 </div> 850 } 851 852 </div> 853 } 854 else 855 { 856 <div class="productsContainer"> 857 @RenderProductList(GetLoop("Products"), productsFound) 858 </div> 859 } 860 861 @helper RenderProductList(IEnumerable<LoopItem> Loop, bool productsFound) 862 { 863 if (!productsFound) 864 { 865 <div class="is-flex col-xs-12 xs-m-t-3 xs-m-b-4 sm-m-b-7 font-primary"> 866 <h1>@Translate("ProductList.NoProductsFound", ":( There are no products in this category")</h1> 867 </div> 868 } 869 else 870 { 871 var productLoop = Loop.ToList(); 872 int currentPage = GetInteger("Ecom:ProductList.CurrentPage"); 873 int totalPages = GetInteger("Ecom:ProductList.TotalPages"); 874 var count = 0; 875 876 for (int i = 0; i < productLoop.Count(); i++) 877 { 878 var item = productLoop[i]; 879 int loopMod = item.GetInteger("Products.LoopMod4"); 880 bool renderStartRow = i % 3 == 0 ? true : false; 881 bool renderEndRow = i % 3 == 0 ? true : false; 882 883 if (i == 0 && totalPages > 1) 884 { 885 @:<div class="row row-ce" id="@currentPage"> 886 } 887 888 @renderProduct(true, item, true); //This is from renderProduct.cshtml 889 890 891 if (productLoop.Count() - 1 == i && totalPages > 1) 892 { 893 @:</div> 894 } 895 } 896 } 897 } 898 899 @helper RenderOutletShopHeader() 900 { 901 <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')"> 902 <div class="container"> 903 <div class="row"> 904 <div class="col-xs-12 col-md-8 col-lg-6"> 905 <div class="text-area"> 906 <div class="rte-content"> 907 @Dynamicweb.Frontend.PageView.Current().CurrentParagraph.Text 908 </div> 909 <div class="red-divider"></div> 910 </div> 911 </div> 912 </div> 913 </div> 914 </div> 915 } 916 917 918 @helper RenderGroupHeader() 919 { 920 int ProductGroupVideoTop = GetInteger("Ecom:Group:Field.FirstwebProductGroupVideoTop"); 921 string Description = GetString("Ecom:Group.Description"); 922 string GroupName = GetString("Ecom:Group.Name"); 923 string BgImage = GetString("Ecom:Group.LargeImage"); 924 bool IsOutletShop = Firstweb.Custom.CustomCode.Frontend.Helpers.Millarco.IsOutletShop(); 925 if (IsOutletShop && !String.IsNullOrEmpty(GetString("Ecom:Group:Field.FirstwebOutletGroupImage.Value.Clean"))) 926 { 927 BgImage = GetString("Ecom:Group:Field.FirstwebOutletGroupImage.Value.Clean"); 928 } 929 930 if (ProductGroupVideoTop > 0) 931 { 932 @RenderParagraphContent(ProductGroupVideoTop) 933 } 934 else 935 { 936 <div class="content-element solid-bg bg-image-and-text-element bg-secondary" style="background-image:url('@BgImage')"> 937 <div class="container"> 938 <div class="row"> 939 <div class="col-xs-12 col-md-8 col-lg-6"> 940 <div class="text-area"> 941 @if (!String.IsNullOrEmpty(Description)) 942 { 943 <div class="rte-content"> 944 @Description 945 </div> 946 } 947 else 948 { 949 <h1 class="xs-m-t-0">@GroupName</h1> 950 } 951 <div class="red-divider"></div> 952 </div> 953 </div> 954 </div> 955 </div> 956 </div> 957 } 958 } 959 960 @helper RenderSearchHeader(string searchQuery) 961 { 962 <h1 class="h1 xs-m-t-0 tertiary-font"> 963 @Translate("ProductList.SearchResultHeader", "S&oslash;geresultat") 964 </h1> 965 966 <h4 class="h4 lg-m-b-0"> 967 @Translate("ProductList.SearchResultText", "Resultater for din s&oslash;gning"): @searchQuery 968 </h4> 969 } 970 971 @helper RenderParagraphHeader() 972 { 973 <h1 class="h1 lg-m-t-0 tertiary-font">@Dynamicweb.Frontend.PageView.Current().CurrentParagraph.Header</h1> 974 975 if (!String.IsNullOrEmpty(Dynamicweb.Frontend.PageView.Current().CurrentParagraph.Text)) 976 { 977 <p>@Dynamicweb.Frontend.PageView.Current().CurrentParagraph.Text</p> 978 } 979 } 980 981 982 @helper RenderGroups(List<Dynamicweb.Ecommerce.Products.Group> breadCrumbGroupList, string currentGroupId) 983 { 984 if (breadCrumbGroupList.Count() > 0) 985 { 986 var ParentGroup = breadCrumbGroupList.LastOrDefault(); 987 var baseLink = "/Default.aspx?ID=" + Dynamicweb.Frontend.PageView.Current().ID + "&GroupID="; 988 if (ParentGroup != null) 989 { 990 <section class="product__sub-nav"> 991 <p class="xs-m-b-0"> 992 @ParentGroup.Name 993 </p> 994 995 <ul> 996 @foreach (var subgroup in ParentGroup.Subgroups) 997 { 998 <li> 999 @if (subgroup.Id == currentGroupId) 1000 { 1001 <span>@subgroup.Name</span> 1002 } 1003 else 1004 { 1005 bool DisplayGroup = subgroup.Products.Count() > 0 || subgroup.Subgroups.Where(x => x.Products.Count() > 0).Count() > 0; 1006 if (DisplayGroup) 1007 { 1008 <a href="@baseLink@subgroup.Id">@subgroup.Name</a> 1009 } 1010 } 1011 </li> 1012 } 1013 </ul> 1014 </section> 1015 } 1016 } 1017 } 1018 1019 @helper RenderFacets() 1020 { 1021 foreach (LoopItem facetGroup in GetLoop("FacetGroups")) 1022 { 1023 foreach (LoopItem facet in facetGroup.GetLoop("Facets").Where(x => x.GetLoop("FacetOptions").Any())) 1024 { 1025 string facetName = facet.GetString("Facet.Name"); 1026 string translatedFacetName = Translate("ProductList.FacetName" + facet.GetString("Facet.Name"), facet.GetString("Facet.Name")); 1027 bool hasOptions = facet.GetLoop("FacetOptions").Any(); 1028 string hasOptionsCss = hasOptions ? "xs-p-t-1 xs-p-b-1" : ""; 1029 string FacetIsOpen = facet.GetLoop("FacetOptions").Where(x => x.GetBoolean("FacetOption.Selected")).Any() ? "true" : "false"; 1030 1031 <section class="bg-white filter" data-bind="defineObservable: { sortDropdown: @FacetIsOpen }"> 1032 @if (hasOptions) 1033 { 1034 <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()) }"> 1035 <h3 class="h3 xs-m-t-0 xs-m-b-0 tertiary-font font-size-base filterHeader" 1036 data-bind="toggleClassParent: 'active'"> 1037 @translatedFacetName 1038 </h3> 1039 <span> 1040 <i class="fa fa-chevron-down"></i> 1041 </span> 1042 </button> 1043 } 1044 1045 <div class="filter__options line-height-base" data-bind="css: { hidden: !sortDropdown() }"> 1046 @foreach (LoopItem option in facet.GetLoop("FacetOptions")) 1047 { 1048 var value = option.GetValue("FacetOption.Value"); 1049 string label = option.GetString("FacetOption.Label").Replace("\"", "&#x22;"); 1050 if (label.ToUpper() == "TRUE" || label.ToUpper() == "FALSE") 1051 { 1052 label = Translate("ProductList.FacetOption:" + label, "Ja"); 1053 } 1054 1055 1056 int count = option.GetInteger("FacetOption.Count"); 1057 bool selected = option.GetBoolean("FacetOption.Selected"); 1058 label += " (" + count + ")"; 1059 <div class="form-group"> 1060 <custom-checkbox params="{ label: '@label', 1061 value: '@value', 1062 checked: @(selected.ToString().ToLower()), 1063 name: '@facet.GetString("Facet.QueryParameter")' }" /> 1064 </div> 1065 } 1066 </div> 1067 </section> 1068 } 1069 } 1070 } 1071 1072 1073 @helper RenderSorting(string sortOrder) 1074 { 1075 <section class="bg-white filter filter__container" 1076 data-bind="defineObservable: { 1077 sortOrder: '@sortOrder' || 'ASC', 1078 sortDropdown: false }"> 1079 <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()) }"> 1080 <p class="h3 xs-m-t-0 xs-m-b-0 tertiary-font font-size-base" 1081 data-bind="toggleClassParent: 'active'"> 1082 @Translate("filtersort", "Sortering") 1083 </p> 1084 1085 <span> 1086 <i class="fa fa-chevron-down"></i> 1087 </span> 1088 </button> 1089 1090 <input type="hidden" name="SortBy" value="ProductNameSort" /> 1091 1092 <section class="filter__options" data-bind="css: { hidden: !sortDropdown() }"> 1093 <div class="form-group"> 1094 <custom-radio params="{ 1095 label: '@Translate("sortnameaz", "Navn: A - &Aring;")', 1096 value: 'ASC', 1097 checked: sortOrder, 1098 name: 'SortOrder' }" /> 1099 </div> 1100 1101 <div class="form-group xs-m-b-0"> 1102 <custom-radio params="{ 1103 label: '@Translate("sortnameza", "Navn: &Aring; - A")', 1104 value: 'DESC', 1105 checked: sortOrder, 1106 name: 'SortOrder' }" /> 1107 </div> 1108 </section> 1109 </section> 1110 } 1111 1112 @helper RenderGroupLevelFilter(IEnumerable<Dynamicweb.Ecommerce.Products.Group> groups, string currentGroupId, string activeGroup, int pageId) 1113 { 1114 var ProductGroups = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(currentGroupId); 1115 bool isTopLevelGroup = ProductGroups.IsTopGroup; 1116 var parentGroup = ProductGroups.PrimaryParentGroupId; 1117 1118 if (isTopLevelGroup) 1119 { 1120 foreach (var group in groups.Where(x => Firstweb.Custom.CustomCode.Frontend.Helpers.EcomGroups.IsFilterGroup(x))) 1121 { 1122 var currentGroup = group.Id.Equals(currentGroupId); 1123 var isCurrentGroup = currentGroup ? "is-active" : ""; 1124 1125 <div class="@isCurrentGroup"> 1126 <a href="/Default.aspx?Id=@pageId&groupid=@group.Id">@group.Name</a> 1127 </div> 1128 1129 if (currentGroup && group.HasChildGroups) 1130 { 1131 <div class="sub-group"> 1132 @foreach (var isSubGroup in group.Subgroups) 1133 { 1134 var setActive = isSubGroup.Id == activeGroup ? "is-active" : ""; 1135 1136 <div class="@setActive"> 1137 <a href="/Default.aspx?Id=@pageId&groupid=@isSubGroup.Id">@isSubGroup.Name</a> 1138 </div> 1139 } 1140 @*@RenderGroupLevelFilter(group.Subgroups, currentGroupId, (level + 1))*@ 1141 </div> 1142 } 1143 } 1144 } 1145 else 1146 { 1147 @RenderGroupLevelFilter(groups, parentGroup, currentGroupId, pageId) 1148 } 1149 }

Denna webbplats använder cookies för diagnostik och optimering av innehållet