Error executing template "Designs/botex/eCom/Productlist/botex-espresso.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_c68442e698724093a52d544ea59d7507.Execute() in D:\dynamicweb.net\Solutions\FlexMedia\botex.cloud.dynamicweb-cms.com\Website\files\Templates\Designs\botex\eCom\Productlist\botex-espresso.cshtml:line 144
   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 Co3.Espresso.Website.TemplateBases.Paragraphs.Module 2 @using Dynamicweb.Content.Items.Metadata 3 @using Dynamicweb.Content.Items 4 @using System.Globalization; @using System.Text.RegularExpressions; @using Dynamicweb.Ecommerce.Common; @using Co3.Espresso.Website.Services; @using Dynamicweb.Ecommerce.Orders @using Dynamicweb.Ecommerce.Orders.Discounts @functions { CultureInfo AreaCultureInfo = Dynamicweb.Frontend.PageView.Current().Area.CultureInfo; public string GetSortingParameterName( string sortingParameterName ) { string returnValue; if ( sortingParameterName == "Name" || sortingParameterName == "Price" ) { returnValue = "Sort" + sortingParameterName; } else if ( sortingParameterName == "UserDefined" ) { returnValue = "PrimaryGroupSort"; } else if ( sortingParameterName == "UnitStock" ) { returnValue = "Stock"; } else { returnValue = sortingParameterName; } return returnValue; } public Double getDiffPriceForDiscount( string orderId ) { Double returnValue = 0; DiscountCollection discounts = Discount.GetDiscounts(); Order order = Order.GetOrderById( orderId ); if ( discounts != null && order != null ) { Discount botexGlobalOrdreRabat = discounts.FirstOrDefault( d => d.Active ); if ( botexGlobalOrdreRabat != null ) { returnValue = ( botexGlobalOrdreRabat.OrderTotalPrice + order.ShippingFee.PriceWithVAT ) - order.Price.PriceWithVAT; } else { returnValue = 0; } } return returnValue; } public string getProductLink( string groupID, string productID, string variantID = "" ) { string result = string.Empty; string displayPage = Co3.Espresso.Website.Services.ProductService.Instance.GetGroupDisplayPage( groupID ); if( string.IsNullOrEmpty( displayPage ) == false ) { if( string.IsNullOrEmpty( variantID ) == false ) { result = "{0}&ProductID={1}&variantID={2}"; result = string.Format( result, displayPage, productID, variantID ); } else { result = "{0}&ProductID={1}"; result = string.Format( result, displayPage, productID ); } } return result; } public bool isProductGroupPublishedOnWebsite( string groupID ) { bool result = false; string displayPage = Co3.Espresso.Website.Services.ProductService.Instance.GetGroupDisplayPage( groupID ); if( string.IsNullOrEmpty( displayPage ) == false ) { result = true; } return result; } public string getNewsLink( string categoryName, string newsID ) { string result = NewsService.Instance.GetNewsDisplayPage( categoryName, newsID ); string displayPage = NewsService.Instance.GetNewsDisplayPage( categoryName, newsID ); if( string.IsNullOrEmpty( displayPage ) == false ) { result = "/" + displayPage.Replace( "Id", "ID" ).Replace( "#", "&PID=" ) + "&M=NewsV2&Action=1&NewsID=" + newsID; //result = SearchEngineFriendlyURLs.GetFriendlyUrl( result ); } return result; } public string getImageURL( string url, int width = 2560, int height = 1280, int crop = 5, int quality = 75, string format = "jpg" ) { string result = string.Empty; if( string.IsNullOrEmpty( url ) == false ) { result = "/admin/public/getimage.ashx?Image={0}&Width={1}&Height={2}&Format={3}&Quality={4}&Crop={5}"; result = string.Format( result, url, width, height, format, quality, crop ); } return result; } public string getPriceFormatted( string price ) { string result = string.Empty; if( string.IsNullOrEmpty( price ) == true ) { price = Context.Currency.Format(0.00, false); } if ( Context.Currency.SymbolPlace == 0 ) { result = string.Format( "<span class=\"e-product-price-symbol\">{1}</span>&nbsp;{0}", price, Context.Currency.Symbol ); } else{ result = string.Format( "{0}&nbsp;<span class=\"e-product-price-symbol\">{1}</span>", price, Context.Currency.Code ); } return result; } public string getShortDate( DateTime date ) { string result = string.Empty; result = date.Date.ToString( AreaCultureInfo.DateTimeFormat.ShortDatePattern ).Replace( "-" , "." ); return result; } public string getLongDate( DateTime date ) { string result = string.Empty; result = date.Date.ToString( AreaCultureInfo.DateTimeFormat.LongDatePattern ); return result; } } 5 6 @{ 7 string pageUrl = GetGlobalValue("Global:Pageview.Url"); 8 string sortBy = GetSortingParameterName(string.IsNullOrEmpty(System.Web.HttpContext.Current.Request["SortBy"]) ? Espresso.Item.ModuleOverride_SortBy : System.Web.HttpContext.Current.Request["SortBy"]); 9 string sortOrder = string.IsNullOrEmpty(System.Web.HttpContext.Current.Request["SortOrder"]) ? Espresso.Item.ModuleOverride_SortOrder : System.Web.HttpContext.Current.Request["SortOrder"]; 10 string pageSize = string.IsNullOrEmpty(System.Web.HttpContext.Current.Request["PageSize"]) ? Espresso.Item.ModuleOverride_PageSize : System.Web.HttpContext.Current.Request["PageSize"]; 11 string pageNum = string.IsNullOrEmpty(System.Web.HttpContext.Current.Request["PageNum"]) ? GetString("Ecom:ProductList.CurrentPage") : System.Web.HttpContext.Current.Request["PageNum"]; 12 string productListClassList = "col-12"; 13 if( Espresso.Item.FiltersShow == "True" ) { 14 productListClassList = "col-12 col-lg-8 col-xl-9"; 15 } 16 17 var paragraph = Dynamicweb.Frontend.PageView.Current().CurrentParagraph; 18 Item item = Dynamicweb.Content.Items.ItemManager.Storage.GetById(paragraph.ItemType, paragraph.ItemId); 19 string includeResponsiveWidthId = item["ItemWidth"].ToString(); 20 Item includeResponsiveWidth = Dynamicweb.Content.Items.ItemManager.Storage.GetById("ParagraphInclude_WidthResponsive", includeResponsiveWidthId); 21 22 dynamic width = new { 23 xs = includeResponsiveWidth["xs"] ?? "12", 24 sm = includeResponsiveWidth["sm"] ?? "6", 25 md = includeResponsiveWidth["md"] ?? "4", 26 lg = includeResponsiveWidth["lg"] ?? "4", 27 xl = includeResponsiveWidth["xl"] ?? "4" 28 }; 29 } 30 31 32 <div class="js-e-productlist js-e-loading-overlay-override"> 33 @if( Espresso.Item.SortShow == "True" || Espresso.Item.PagingShow == "True" || Espresso.Item.HeadingShow == "True" ){ 34 <div class="js-e-productslist-header small"> 35 <div class="row align-items-end"> 36 @if( ( Espresso.Item.SortShow == "True" || Espresso.Item.PagingShow == "True" ) && Espresso.Item.HeadingShow == "True" ){ 37 <div class="col-md-12"> 38 <h1 class="">@Espresso.Item.Name</h1> 39 </div> 40 } 41 @if( Espresso.Item.FiltersShow == "True" ){ 42 <div class="d-none d-lg-block col-lg-4 col-xl-3"> 43 <div class="e-productslist-header"> 44 <p class="h2 small m-0"> 45 <i class="material-icons material-icons-large text-primary d-none">playlist_add_check</i> <small>@Translate( "eCom Productlist Filters - Customize Selection - Heading", "Customize selection" )</small> 46 </p> 47 </div> 48 </div> 49 } 50 @if( Espresso.Item.SortShow == "True" || Espresso.Item.PagingShow == "True" || Espresso.Item.HeadingShow == "True" ){ 51 <div class="@productListClassList px-1"> 52 <div class="e-productslist-header small"> 53 @if( ( Espresso.Item.SortShow == "False" && Espresso.Item.PagingShow == "False" ) && Espresso.Item.HeadingShow == "True" ){ 54 <h1 class="h3 m-0">@Espresso.Item.Name (<span class="js-e-productlist-product-count"></span>)</h1> 55 } 56 else{ 57 <div class="row"> 58 @if( Espresso.Item.SortShow == "True" ){ 59 @*<div class="col-6 @( Espresso.Item.PagingShow != "True" ? "ml-auto" : "" )"> 60 <div class="js-e-productlist-sort">*@ 61 <script id="js-e-handlebars-partial-productlist-sort" type="text/x-handlebars-template"> 62 63 <fieldset class="form-inline"> 64 <div class="form-group @( Espresso.Item.PagingShow != "True" ? "justify-content-end" : "" )"> 65 @*<label for="Sort" class="mr-1"> 66 @Translate( "eCom Productlist - Sorting - Label", "Sort: ") 67 </label>*@ 68 <select name="Sort" class="js-e-productlist-sort-select custom-select custom-select-sm" style="padding-bottom:0.25em; padding-right: 2em;"> 69 <option value="">@Translate( "eCom Productlist - Sorting - Relevance - ASC - Label", "Relevance")</option> 70 <option value="SortName ASC" {{#compare sort.sort '===' 'SortName ASC'}}selected{{/compare}}>@Translate( "eCom Productlist - Sorting - Name - ASC - Label", "Name - low to high")</option> 71 <option value="SortName DESC" {{#compare sort.sort '===' 'SortName DESC'}}selected{{/compare}}>@Translate( "eCom Productlist - Sorting - Name - DESC - Label", "Name - high to low")</option> 72 @*<option value="Created ASC" {{#compare sort.sort '===' 'Created ASC'}}selected{{/compare}}>@Translate( "eCom Productlist - Sorting - Created - ASC - Label", "Created")</option>*@ 73 <option value="SortPrice ASC" {{#compare sort.sort '===' 'SortPrice ASC'}}selected{{/compare}}>@Translate( "eCom Productlist - Sorting - Price - ASC - Label", "Price - low to high")</option> 74 <option value="SortPrice DESC" {{#compare sort.sort '===' 'SortPrice DESC'}}selected{{/compare}}>@Translate( "eCom Productlist - Sorting - Price - DESC - Label", "Price - high to low")</option> 75 </select> 76 </div> 77 </fieldset> 78 79 </script> 80 @* </div> 81 </div>*@ 82 83 } 84 @if( Espresso.Item.PagingShow == "True" ){ 85 <div class="col-12"> 86 <div class="row align-items-center d-flex e-products-paging h-100 small js-e-products-paging justify-content-center"> 87 <script id="js-e-handlebars-tmpl-productlist-paging" type="text/x-handlebars-template"> 88 89 90 <div class="col-6 text-left for-productslist-header"> 91 @*<select name="Sort" class="js-e-productlist-sort-select custom-select custom-select-sm" style="padding-bottom:0.25em;"> 92 <option value="Name DESC" {{#compare sort.sort '===' 'Name DESC'}}selected{{/compare}}>@Translate( "eCom Productlist - Sorting - Name - DESC - Label", "Name")</option> 93 <option value="Created ASC" {{#compare sort.sort '===' 'Created ASC'}}selected{{/compare}}>@Translate( "eCom Productlist - Sorting - Created - ASC - Label", "Created")</option> 94 <option value="Price ASC" {{#compare sort.sort '===' 'Price ASC'}}selected{{/compare}}>@Translate( "eCom Productlist - Sorting - Price - ASC - Label", "Price - low to high")</option> 95 <option value="Price DESC" {{#compare sort.sort '===' 'Price DESC'}}selected{{/compare}}>@Translate( "eCom Productlist - Sorting - Price - DESC - Label", "Price - high to low")</option> 96 </select>*@ 97 {{> productlistSort}} 98 </div> 99 <div class="col-6 text-right for-productslist-header"> 100 <small class="text-nowrap"> 101 {{#if page.productCount}} 102 <strong>{{page.viewing.from}} - {{page.viewing.to}}</strong> @Translate( "eCom Productlist Paging - Product Count Of - Text", "of" ) 103 {{/if}} 104 <strong> {{page.productCount}}</strong> 105 </small> 106 </div> 107 108 109 110 <div class="col-4 text-left for-productslist-footer"> 111 {{#compare page.prevPage '!==' 0 }} 112 <a href="{{page.pagingUrl}}={{page.prevPage}}" class="btn-link js-e-productlist-set-pagenum" data-page-num="{{page.prevPage}}"> 113 <span class="d-inline">@Translate( "eCom Productlist Paging - Previous - Text", "Previous" )</span> 114 </a> 115 {{/compare}} 116 </div> 117 <div class="col-4 text-center for-productslist-footer"> 118 <small class="text-nowrap"> 119 {{#if page.productCount}} 120 <strong>{{page.viewing.from}} - {{page.viewing.to}}</strong> @Translate( "eCom Productlist Paging - Product Count Of - Text", "of" ) 121 {{/if}} 122 <strong> {{page.productCount}}</strong> 123 </small> 124 </div> 125 <div class="col-4 text-right for-productslist-footer"> 126 {{#compare page.nextPage '!==' 0 }} 127 <a href="{{page.pagingUrl}}={{page.nextPage}}" class="btn-link js-e-productlist-set-pagenum" data-page-num="{{page.nextPage}}"> 128 <span class="d-inline">@Translate( "eCom Productlist Paging - Next - Text", "Next" )</span></a> 129 {{/compare}} 130 </div> 131 132 133 134 135 136 137 @*<small class="text-nowrap"> 138 {{#if page.productCount}} 139 <strong>{{page.viewing.from}} - {{page.viewing.to}}</strong> @Translate( "eCom Productlist Paging - Product Count Of - Text", "of" ) 140 {{/if}} 141 <strong> {{page.productCount}}</strong> 142 </small> 143 {{#compare page.prevPage '!==' 0 }} 144 <a href="{{page.pagingUrl}}={{page.prevPage}}" class="btn-link btn-lg py-0 m-0 pos-a l-0 px-2 js-e-productlist-set-pagenum" data-page-num="{{page.prevPage}}"> 145 <span class="d-none d-lg-inline">@Translate( "eCom Productlist Paging - Previous - Text", "Previous" )</span> 146 </a> 147 {{/compare}} 148 {{#compare page.nextPage '!==' 0 }} 149 <a href="{{page.pagingUrl}}={{page.nextPage}}" class="btn-link btn-lg py-0 m-0 pos-a r-0 px-2 js-e-productlist-set-pagenum" data-page-num="{{page.nextPage}}"> 150 <span class="d-none d-lg-inline">@Translate( "eCom Productlist Paging - Next - Text", "Next" )</span></a> 151 {{/compare}}*@ 152 153 154 @*{{#compare page.pageSize '!==' 999}} 155 {{#compare page.totalPages '>' 1 }} 156 <a href="{{page.pagingUrl}}=9999" class="btn btn-link btn-lg p-0 pl-1 js-e-productlist-set-pagesize d-none d-md-inline" data-page-size="999"> 157 @Translate( "eCom Productlist Paging - Show All - Text", "Show all") 158 </a> 159 {{/compare}} 160 {{/compare}} 161 {{#compare page.pageSize '===' 999}} 162 <a href="#" class="btn btn-link btn-lg p-0 pl-1 js-e-productlist-set-pagesize d-none" data-page-size="@Espresso.Item.Pagesize">@Translate( "eCom Productlist Paging - Reset - Link", "Reset")</a> 163 {{/compare}}*@ 164 165 </script> 166 </div> 167 </div> 168 169 } 170 else{ 171 <div class="col-6 order-first"><span class="js-e-productlist-product-count"></span> @Translate( "eCom Productlist - Product count - Text", "products")</div> 172 } 173 </div> 174 } 175 </div> 176 </div> 177 } 178 @if( Espresso.Item.FiltersShow == "True" ){ 179 <div class="col-12 d-lg-none"> 180 <button class="btn btn-block btn-primary mb-2" type="button" data-toggle="modal" data-target="#js-e-productlist-filters-modal">@Translate( "eCom Productlist Filters - Customize Selection - Button", "Customize selection" )</button> 181 </div> 182 } 183 </div> 184 </div> 185 } 186 187 <div class="row"> 188 <div class="d-none d-lg-block col-lg-4 col-xl-3"> 189 <form class="js-e-productlist-form"> 190 <input type="hidden" name="ID" value="@Espresso.Page.ID"> 191 <input type="hidden" name="PageNum" value="@pageNum"> 192 <input type="hidden" name="PageUrl" value="@pageUrl"> 193 <input type="hidden" name="Sort" value="@sortBy @sortOrder"> 194 <input type="hidden" name="SortBy" value="@sortBy"> 195 <input type="hidden" name="SortOrder" value="@sortOrder"> 196 <input type="hidden" name="PageSize" value="@pageSize"> 197 198 199 @foreach ( LoopItem query in GetLoop( "Query.Parameters" ) ) 200 { 201 if ( string.IsNullOrEmpty( query.GetString( "Parameter.Value" ) ) == false ) 202 { 203 if ( query.GetBoolean( "Parameter.IsHandledAsFacet" ) == false && query.GetString( "Parameter.Name" ) != "q" ) 204 { 205 <input type="hidden" name="@query.GetString( "Parameter.Name" )" value="@query.GetString( "Parameter.Value" )"> 206 } 207 } 208 } 209 210 @if( Espresso.Item.FiltersShow == "True" ) { 211 foreach (LoopItem facetGroup in GetLoop("FacetGroups") ) { 212 <input type="hidden" name="fg" value="@facetGroup.GetString("FacetGroup.Name")"> 213 } 214 <input type="hidden" class="js-e-visible-options-count" value="@Espresso.Item.FiltersVisibleOptionCount"> 215 <div id="js-e-productlist-filters"> 216 @*@foreach( LoopItem query in GetLoop("Query.Parameters") ) { 217 if( string.IsNullOrEmpty( query.GetString("Parameter.Value") ) == false ) { 218 <input type="hidden" name="@query.GetString("Parameter.Name")" value="@query.GetString("Parameter.Value")"> 219 } 220 }*@ 221 <script id="js-e-handlebars-tmpl-productlist-filters" type="text/x-handlebars-template"> 222 {{#if page.filtersAppliedCount}} 223 <div class="e-productlist-filters-group"> 224 <p class="e-productlist-filters-group-header font-weight-bold small mb-0"> 225 <span class="e-productlist-filters-group-name small py-1">@Translate("eCom Productlist Filters - Selected - Text", "Selected filters")</span> 226 @*<button type="button" class="small btn btn-link pr-0 js-e-productlist-filters-clear-all">@Translate("eCom Productlist Filters - Reset Filters - Button", "Reset all")</button>*@ 227 <label class="small btn-link pr-0 py-1 my-0 js-e-productlist-filters-clear-all">@Translate("eCom Productlist Filters - Reset Filters - Button", "Reset all")</label> 228 </p> 229 <div class="small"> 230 <ul class="e-productlist-filters-group-options-selected list-unstyled small mb-1"> 231 {{#each facets}} 232 {{#if selectedOptions.length}} 233 {{#each selectedOptions}} 234 <li class="e-productlist-filters-option-selected"><a class="js-e-productlist-filters-remove" href="#" data-value="{{value}}"><i class="material-icons material-icons-fixed text-danger text-left mr-1">clear</i>{{../name}}: {{label}}</a></li> 235 {{/each}} 236 {{/if}} 237 {{/each}} 238 {{#if page.q}} 239 <li class="e-productlist-filters-option-selected"><a class="js-e-productlist-filters-search-clear" href="#"><i class="material-icons material-icons-fixed text-danger mr-1">clear</i>@Translate("eCom Productlist Filters - Search - Text", "Search"): {{page.q}}</a></li> 240 {{/if}} 241 {{#compare page.minPrice.clean '&&' page.maxPrice.clean}} 242 <li class="e-productlist-filters-option-selected"><a class="js-e-productlist-filters-range-clear" href="#" data-group-id="js-e-productlist-filters-range-group-price"><i class="material-icons material-icons-fixed text-danger mr-1">clear</i>@Translate("eCom Productlist Filters - Price - Heading", "Price"): {{{page.minPrice.formatted}}} - {{{page.maxPrice.formatted}}}</a></li> 243 {{/compare}} 244 </ul> 245 </div> 246 </div> 247 {{/if}} 248 @if( Espresso.Item.FiltersNavigationShow == "True" ){ 249 <div class="e-productlist-filters-group js-e-productlist-filters-group"> 250 <p class="e-productlist-filters-group-header font-weight-bold small mb-0"> 251 <a class="e-productlist-filters-group-collapse-toggle text-black" data-toggle="collapse" data-target="#e-productlist-filters-group-navigation"> 252 <i class="material-icons">arrow_drop_down</i> 253 <span class="e-productlist-filters-group-name small py-1"> 254 @Espresso.Item.NavigationHeading 255 </span> 256 </a> 257 </p> 258 <fieldset id="e-productlist-filters-group-navigation" class="e-productlist-filters-group-options mb-2 small collapse show"> 259 <div class="e-nav-local e-nav-local-vertical"> 260 <nav class="e-nav-local-container"> 261 <ul class="nav flex-column"> 262 @RenderNavigation( new { 263 id = "dwnav-local-" + Espresso.Id, 264 parentid = string.IsNullOrEmpty( Espresso.Item.NavigationParentPage ) == false ? Espresso.Item.NavigationParentPage : Espresso.Page.ID, 265 template = "local-vertical.xslt", 266 startlevel = Espresso.Item.NavigationLevelStart, 267 endlevel = Espresso.Item.NavigationLevelEnd, 268 expandmode = "path", 269 } ) 270 </ul> 271 </nav> 272 </div> 273 </fieldset> 274 </div> 275 } 276 @if( Espresso.Item.FiltersSearchShow == "True" ){ 277 <div class="e-productlist-filters-group js-e-productlist-filters-group"> 278 <p class="e-productlist-filters-group-header font-weight-bold small mb-0"> 279 <a class="e-productlist-filters-group-collapse-toggle {{#unless page.q}}collapsed{{/unless}}" data-toggle="collapse" data-target="#e-productlist-filters-group-search"> 280 <i class="material-icons">arrow_drop_down</i> 281 <span class="e-productlist-filters-group-name small py-1">@Translate("eCom Productlist Filters - Search - Heading", "Search")</span> 282 </a> 283 {{#if page.q}} 284 <button type="button" class="btn btn-link pr-0 js-e-productlist-filters-search-clear"> 285 @Translate("eCom Productlist Filter - Group Reset - Button", "Reset") 286 </button> 287 {{/if}} 288 </p> 289 <fieldset id="e-productlist-filters-group-search" class="e-productlist-filters-group-options mb-2 small collapse {{#if page.q}}show{{/if}}"> 290 <div class="js-e-search-input-group e-search-input-group {{#unless page.q}}is-empty{{/unless}}"> 291 <label class="e-search-label" for="filter_search"><i class="material-icons">search</i></label> 292 <input type="text" class="js-e-search-input e-search-input e-productlist-filters-search-input form-control-plaintext" name="q" id="filter_search" value="{{page.q}}"> 293 <span class="js-e-search-clear e-search-clear"><i class="material-icons">close</i></span> 294 <button class="e-search-submit btn btn-primary js-e-productlist-filters-search-submit" type="button"><i class="material-icons pa-0">search</i></button> 295 </div> 296 </fieldset> 297 </div> 298 } 299 300 301 302 {{#each facets}} 303 {{#compare count '>' 0}} 304 <div class="e-productlist-filters-group js-e-productlist-filters-group"> 305 <p class="e-productlist-filters-group-header font-weight-bold small mb-0"> 306 <a class="e-productlist-filters-group-collapse-toggle {{#unless selectedOptions.length }}{{#compare @@first '&&' @@root.page.hasNoInteraction}}{{else}}collapsed{{/compare}}{{/unless}}" data-toggle="collapse" data-target="#e-productlist-filters-group-{{param}}"> 307 <i class="material-icons">arrow_drop_down</i> 308 <span class="e-productlist-filters-group-name small py-1">{{label}}</span> 309 </a> 310 {{#if selectedOptions.length}} 311 <label for="reset-filter-{{param}}" class="small m-0 btn-link pr-0"> 312 @Translate("eCom Productlist Filter - Group Reset - Label", "Reset") 313 </label> 314 {{/if}} 315 </p> 316 <fieldset id="e-productlist-filters-group-{{param}}" class="e-productlist-filters-group-options js-e-productlist-filters-group-options mb-2 small collapse {{#if selectedOptions.length }}is-expanded{{else}}{{#compare @@first '&&' @@root.page.hasNoInteraction}}is-expanded{{/compare}}{{/if}}"> 317 <div class="{{#compare count '>' @Espresso.Item.FiltersVisibleOptionCount }}js-e-productlist-filters-options-collapse-peek e-productlist-filters-options-collapse-peek is-peeking{{/compare}}"> 318 <div class="e-productlist-filters-option js-e-productlist-filters-option"> 319 <label for="reset-filter-{{param}}" class="custom-control custom-checkbox"> 320 <input class="js-e-productlist-filters-option-reset-group custom-control-input" name="reset-filter-{{param}}" id="reset-filter-{{param}}" type="checkbox" value="true" {{#compare isCleared '||' isEmpty}}checked{{/compare}}> 321 <span class="custom-control-indicator"></span> 322 <span class="custom-control-description small">@Translate("eCom Productlist Filter - Options View All - Label", "All")</span> 323 </label> 324 </div> 325 {{#each options}} 326 <div class="e-productlist-filters-option js-e-productlist-filters-option {{#if isSelected}}is-selected{{/if}} {{#if isDisabled}}is-disabled text-muted{{/if}}"> 327 <label for="{{id}}" class="custom-control custom-checkbox"> 328 <input id="{{id}}" name="{{param}}" class="js-e-productlist-filter custom-control-input" type="checkbox" value="{{value}}" {{#if isSelected}}checked{{/if}} {{#if isDisabled}}disabled{{/if}}> 329 <span class="custom-control-indicator"></span> 330 <span class="custom-control-description small">{{label}} <span class="e-productlist-filters-option-count small text-muted">({{count}})</span></span> 331 </label> 332 </div> 333 {{/each}} 334 {{#compare count '>' @Espresso.Item.FiltersVisibleOptionCount }} 335 <a href="#" class="js-e-productlist-filters-options-collapse-peek-toggle e-productlist-filters-options-collapse-peek-toggle small" data-closed-text="@Translate("eCom Productlist Filter - Options Show More - Link", "Show more")" data-open-text="@Translate("eCom Productlist Filter - Options Show Less - Link", "Show less")"><i class="material-icons">keyboard_arrow_down</i></a> 336 {{/compare}} 337 </div> 338 </fieldset> 339 </div> 340 {{/compare}} 341 {{/each}} 342 @if( Espresso.Item.FiltersPriceRangeShow == "True" ){ 343 <div class="e-productlist-filters-group js-e-productlist-filters-group"> 344 <p class="e-productlist-filters-group-header font-weight-bold small mb-0"> 345 <a class="e-productlist-filters-group-collapse-toggle {{#compare page.minPrice.clean '!!' page.maxPrice.clean}}collapsed{{/compare}}" data-toggle="collapse" data-target="#e-productlist-filters-group-pricerange"> 346 <i class="material-icons">arrow_drop_down</i> 347 <span class="e-productlist-filters-group-name small py-1">@Translate("eCom Productlist Filters - Price Range - Heading", "Price")</span> 348 </a> 349 {{#compare page.minPrice.clean '||' page.maxPrice.clean}} 350 <button type="button" class="btn btn-link pr-0 js-e-productlist-filters-range-clear"> 351 @Translate("eCom Productlist Filter - Group Reset - Button", "Reset") 352 </button> 353 {{/compare}} 354 </p> 355 <fieldset id="e-productlist-filters-group-pricerange" class="e-productlist-filters-group-options mb-2 small collapse {{#compare page.minPrice.clean '||' page.maxPrice.clean}}show{{/compare}}"> 356 <div id="js-e-productlist-filters-range-group-price" class="row mt-1 e-productlist-filters-range-group js-e-productlist-filters-range-group"> 357 <div class="col-12 col-lg-4 mb-1"> 358 <input type="text" class="form-control js-e-productlist-filters-range js-e-productlist-filters-range-min" name="PriceRangeMin" id="PriceRangeMin" value="{{page.minPrice.clean}}" placeholder="@Translate("eCom Productlist Filters - Price Min - Text", "From")" min="0"> 359 </div> 360 <div class="col-12 col-lg-4 mb-1"> 361 <input type="text" class="form-control js-e-productlist-filters-range js-e-productlist-filters-range-max" name="PriceRangeMax" id="PriceRangeMax" value="{{page.maxPrice.clean}}" placeholder="@Translate("eCom Productlist Filters - Price Max - Text", "To")" data-msg-rangeValid="@Translate("eCom Productlist Filters - Price Error - Msg", "Prices entered incorrectly")"> 362 </div> 363 <div class="col-12 col-lg-3"> 364 <button type="button" class="btn btn-primary px-0 btn-sm btn-block e-productlist-filters-apply-range js-e-productlist-filters-apply-range"><i class="material-icons">sync</i></button> 365 </div> 366 </div> 367 </fieldset> 368 </div> 369 } 370 </div> 371 </script> 372 373 </div> 374 } 375 </form> 376 </div> 377 378 <div class="@productListClassList"> 379 <div id="js-e-productlist-products"> 380 <!-- Products for search engines that do not support dynamic rendering with js --> <ul itemscope itemtype="http://schema.org/ItemList"> @foreach ( LoopItem product in GetLoop( "Products" ) ) { string productLink = getProductLink( product.GetString("Ecom:Product.PrimaryOrFirstGroupID"), product.GetString("Ecom:Product.ID") ); <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product"> <a href="@productLink" title="@product.GetString("Ecom:Product.Name")" itemprop="url"> <h3 itemprop="name">@product.GetString("Ecom:Product.Name")</h3> <p itemprop="description">@product.GetString("Ecom:Product.ShortDescription")</p> </a> </li> } </ul> @if ( GetLoop( "Ecom:ProductList.Pages" ).Count > 0 ) { <ol> @foreach ( LoopItem page in GetLoop( "Ecom:ProductList.Pages" ) ) { string pagingPageUrl = page.GetString( "Ecom:ProductList.Pages.Page.Url" ); string pagingPageNumber = page.GetString( "Ecom:ProductList.Pages.Page.Number" ); <li> <a href="@pagingPageUrl">@pagingPageNumber</a> </li> } </ol> } <!--/ Products for search engines that do not support dynamic rendering with js --> 381 @using Dynamicweb.Admin.dk.dynamicweb.templates <script id="js-e-handlebars-tmpl-productlist-products" type="text/x-handlebars-template"> <div class="e-products"> <div class="e-loading-overlay e-products-loading-overlay js-e-products-loading-overlay is-loading"> <div class="e-loading-spinner"></div> </div> {{#if page.productCount}} <div class="row"> {{#each products}} @using Dynamicweb.Admin.dk.dynamicweb.templates <div title="{{fixedLowPrice}}" class="col-@width.xs col-sm-@width.sm col-md-@width.md col-lg-@width.lg col-xl-@width.xl e-products-item-wrapper {{#if imageMedium}}with-bg{{/if}}"> <div class="background-image" style="background-image: url('{{imageMedium}}');"></div> <div class="content-wrapper"> {{#if gotDiscount}} <div class="discount-badge {{#if hasBlackFridayDiscount }}{{else}}d-none{{/if}}"><span class="small">TILBUD</span></div> {{/if}} <div class="e-products-item js-e-products-item"> <div class="e-products-item-container"> <div class="e-products-item-image-container"> <a class="e-products-item-image-wrapper" href="{{url}}"> <img src="{{imageSmall}}" alt="" class="e-products-item-image"> </a> </div> <div class="e-products-item-text-container text-center p-1"> <h3 class="e-products-item-name mb-0"><a href="{{url}}">{{name}}</a></h3> {{#if descriptionShortExtra01}} <p class="e-products-item-text mb-0"> <a href="{{url}}"> {{descriptionShortExtra01}} </a> </p> {{/if}} <p class="e-products-item-text mb-0"> {{#if hasVariants}} <a href="{{url}}"> <p class="e-products-item-price text-muted"> {{#if hasBlackFridayDiscount}} {{{lowestPrice}}} {{#if priceBefore}} <br>{{{priceBefore}}} {{/if}} {{else}} {{#if fixedLowPrice}} <span class="d-inline-block text-uppercase font-weight-normal mt-2 mb-1 pl-2 pr-2 b-productlist-fixed-label">Fast lav pris</span><br> {{else}} {{#if priceBefore}} <span class="d-inline-block text-uppercase font-weight-normal mt-2 mb-1 pl-2 pr-2 b-productlist-pct-label">Tilbud {{priceReducedInPct}}%</span><br> <span class="">{{{priceBefore}}}</span> {{/if}} {{/if}} @Translate( "eCom Productlist - From prices - Text", "Priser fra" ): {{{lowestPrice}}} {{/if}} </p> </a> {{else}} <p class="e-products-item-price text-muted"> <a href="{{url}}"> {{#if hasBlackFridayDiscount}} {{{lowestPrice}}} {{#if priceBefore}} <br>{{{priceBefore}}} {{/if}} {{else}} {{#if fixedLowPrice}} <span class="d-inline-block text-uppercase font-weight-normal mt-2 mb-1 pl-2 pr-2 b-productlist-fixed-label">Fast lav pris</span><br> {{else}} {{#if priceBefore}} <span class="d-inline-block text-uppercase font-weight-normal mt-2 mb-1 pl-2 pr-2 b-productlist-pct-label">Tilbud {{priceReducedInPct}}%</span><br> <span class="">{{{priceBefore}}}</span> {{/if}} {{/if}} {{{lowestPrice}}} {{/if}} </a> </p> {{/if}} </p> </div> </div> </div> </div> </div> {{/each}} </div> {{else}} <div class="alert alert-warning mt-2" role="alert"> <strong><i class="material-icons material-icons-2x">sentiment_dissatisfied</i> @Translate( "eCom Productlist - Sorry - Text", "Sorry..")</strong> <br> @Translate( "eCom Productlist - No Products - Text", "No products match your choices.") </div> {{/if}} </div> </script> 382 </div> 383 @if( Espresso.Item.FooterShow == "True" ){ 384 <div class="row"> 385 <div class="col-12 px-0"> 386 <div class="e-products-footer small row pt-1"> 387 <div class="col-6"> 388 <small>@Translate( "eCom Productlist - Price Info - Text Public", "All prices are incl. VAT" )</small> 389 </div> 390 391 @if( Espresso.Item.PagingShow == "True" ){ 392 <div class="col-12"> 393 <div class="row align-items-center d-flex e-products-paging h-100 small js-e-products-paging justify-content-center"> 394 <script id="js-e-handlebars-tmpl-productlist-paging" type="text/x-handlebars-template"> 395 396 397 <div class="col-6 text-left for-productslist-header"> 398 @*<select name="Sort" class="js-e-productlist-sort-select custom-select custom-select-sm" style="padding-bottom:0.25em;"> 399 <option value="Name DESC" {{#compare sort.sort '===' 'Name DESC'}}selected{{/compare}}>@Translate( "eCom Productlist - Sorting - Name - DESC - Label", "Name")</option> 400 <option value="Created ASC" {{#compare sort.sort '===' 'Created ASC'}}selected{{/compare}}>@Translate( "eCom Productlist - Sorting - Created - ASC - Label", "Created")</option> 401 <option value="Price ASC" {{#compare sort.sort '===' 'Price ASC'}}selected{{/compare}}>@Translate( "eCom Productlist - Sorting - Price - ASC - Label", "Price - low to high")</option> 402 <option value="Price DESC" {{#compare sort.sort '===' 'Price DESC'}}selected{{/compare}}>@Translate( "eCom Productlist - Sorting - Price - DESC - Label", "Price - high to low")</option> 403 </select>*@ 404 {{> productlistSort}} 405 </div> 406 <div class="col-6 text-right for-productslist-header"> 407 <small class="text-nowrap"> 408 {{#if page.productCount}} 409 <strong>{{page.viewing.from}} - {{page.viewing.to}}</strong> @Translate( "eCom Productlist Paging - Product Count Of - Text", "of" ) 410 {{/if}} 411 <strong> {{page.productCount}}</strong> 412 </small> 413 </div> 414 415 416 417 <div class="col-4 text-left for-productslist-footer"> 418 {{#compare page.prevPage '!==' 0 }} 419 <a href="{{page.pagingUrl}}={{page.prevPage}}" class="btn-link js-e-productlist-set-pagenum" data-page-num="{{page.prevPage}}"> 420 <span class="d-inline">@Translate( "eCom Productlist Paging - Previous - Text", "Previous" )</span> 421 </a> 422 {{/compare}} 423 </div> 424 <div class="col-4 text-center for-productslist-footer"> 425 <small class="text-nowrap"> 426 {{#if page.productCount}} 427 <strong>{{page.viewing.from}} - {{page.viewing.to}}</strong> @Translate( "eCom Productlist Paging - Product Count Of - Text", "of" ) 428 {{/if}} 429 <strong> {{page.productCount}}</strong> 430 </small> 431 </div> 432 <div class="col-4 text-right for-productslist-footer"> 433 {{#compare page.nextPage '!==' 0 }} 434 <a href="{{page.pagingUrl}}={{page.nextPage}}" class="btn-link js-e-productlist-set-pagenum" data-page-num="{{page.nextPage}}"> 435 <span class="d-inline">@Translate( "eCom Productlist Paging - Next - Text", "Next" )</span></a> 436 {{/compare}} 437 </div> 438 439 440 441 442 443 444 @*<small class="text-nowrap"> 445 {{#if page.productCount}} 446 <strong>{{page.viewing.from}} - {{page.viewing.to}}</strong> @Translate( "eCom Productlist Paging - Product Count Of - Text", "of" ) 447 {{/if}} 448 <strong> {{page.productCount}}</strong> 449 </small> 450 {{#compare page.prevPage '!==' 0 }} 451 <a href="{{page.pagingUrl}}={{page.prevPage}}" class="btn-link btn-lg py-0 m-0 pos-a l-0 px-2 js-e-productlist-set-pagenum" data-page-num="{{page.prevPage}}"> 452 <span class="d-none d-lg-inline">@Translate( "eCom Productlist Paging - Previous - Text", "Previous" )</span> 453 </a> 454 {{/compare}} 455 {{#compare page.nextPage '!==' 0 }} 456 <a href="{{page.pagingUrl}}={{page.nextPage}}" class="btn-link btn-lg py-0 m-0 pos-a r-0 px-2 js-e-productlist-set-pagenum" data-page-num="{{page.nextPage}}"> 457 <span class="d-none d-lg-inline">@Translate( "eCom Productlist Paging - Next - Text", "Next" )</span></a> 458 {{/compare}}*@ 459 460 461 @*{{#compare page.pageSize '!==' 999}} 462 {{#compare page.totalPages '>' 1 }} 463 <a href="{{page.pagingUrl}}=9999" class="btn btn-link btn-lg p-0 pl-1 js-e-productlist-set-pagesize d-none d-md-inline" data-page-size="999"> 464 @Translate( "eCom Productlist Paging - Show All - Text", "Show all") 465 </a> 466 {{/compare}} 467 {{/compare}} 468 {{#compare page.pageSize '===' 999}} 469 <a href="#" class="btn btn-link btn-lg p-0 pl-1 js-e-productlist-set-pagesize d-none" data-page-size="@Espresso.Item.Pagesize">@Translate( "eCom Productlist Paging - Reset - Link", "Reset")</a> 470 {{/compare}}*@ 471 472 </script> 473 </div> 474 </div> 475 476 } 477 @if ( Espresso.Item.FiltersShow == "True" ) { 478 <button class="btn btn-block btn-primary mt-2 d-lg-none" type="button" data-toggle="modal" data-target="#js-e-productlist-filters-modal">@Translate( "eCom Productlist Filters - Customize Selection - Button", "Customize selection")</button> 479 } 480 </div> 481 </div> 482 </div> 483 } 484 485 </div> 486 </div> 487 </div> 488 489 @if( Espresso.Item.FiltersShow == "True" ) { 490 <div id="js-e-productlist-filters-modal" class="modal fade e-productlist-filters-modal js-e-productlist-filters-modal modal-fullscreen d-lg-none" data-backdrop="false"> 491 <script id="js-e-handlebars-tmpl-productlist-filters-modal" type="text/x-handlebars-template"> 492 <div class="modal-dialog"> 493 <div class="modal-content"> 494 <button type="button" class="close" data-dismiss="modal"> 495 <i class="material-icons">close</i> 496 </button> 497 <legend class="modal-header"> 498 @Translate("eCom Productlist Filters - Customize Selection - Heading", "Customize Selection") 499 </legend> 500 <div class="modal-body"> 501 <ul class="list-group"> 502 <strong>@Translate("eCom Productlist Filters - Customize Selection - Heading", "Customize Selection")</strong> 503 {{#each facets}} 504 <li class="list-group-item e-productlist-filters-group"> 505 <h4 class="mb-1"> 506 <a id="filter-header-{{param}}" class="e-productlist-filters-group-header" data-toggle="collapse" data-target="#filter-modal-panel-{{param}}"> 507 {{label}} 508 {{#if selectedOptions.length}} 509 <span>({{selectedOptions.length}})</span> 510 {{/if}} 511 <i class="material-icons e-productlist-filters-collapse-icon">arrow_drop_down</i> 512 </a> 513 </h4> 514 <div id="filter-modal-panel-{{param}}" class="e-productlist-filters-collapse form-group collapse js-e-productlist-filters-collapse {{#if selectedOptions.length }}in{{/if}} mb-1"> 515 <div class="row mt-2"> 516 <div class="col-6 col-sm-4 col-md-3"> 517 <input class="js-e-productlist-filters-reset-all" name="reset-filter-{{param}}" id="reset-filter-{{param}}" type="checkbox" value="true" {{#compare isCleared '||' isEmpty}}checked{{/compare}}> 518 <label for="reset-filter-{{param}}"> 519 @Translate("eCom Productlist Filters - All - Label", "All ") 520 </label> 521 </div> 522 {{#each options}} 523 <div class="col-6 col-sm-4 col-md-3"> 524 <input type="checkbox" value="{{value}}" {{#if isSelected}}checked{{/if}} {{#if isDisabled}}disabled{{/if}}> 525 <label class="js-e-productlist-filters-label-mobile" for="{{id}}"> 526 {{label}} <span class="small">({{count}})</span> 527 </label> 528 </div> 529 {{/each}} 530 </div> 531 </div> 532 </li> 533 {{/each}} 534 535 536 @if ( Espresso.Item.FiltersPriceRangeShow == "True" ) 537 { 538 <li class="list-group-item e-productlist-filters-group"> 539 <h4 class="mb-1"> 540 <a id="filter-header-price" class="e-productlist-filters-group-header" data-toggle="collapse" data-target="#filter-modal-panel-price"> 541 @Translate( "eCom Productlist Filters - Price Range - Heading", "Price" ) 542 {{#compare page.minPrice.clean '&&' page.maxPrice.clean}} 543 <span>(1)</span> 544 {{/compare}} 545 <i class="material-icons e-productlist-filters-collapse-icon">arrow_drop_down</i> 546 </a> 547 </h4> 548 <div id="filter-modal-panel-price" class="e-productlist-filters-collapse form-group collapse js-e-productlist-filters-collapse {{#compare page.minPrice.clean '||' page.maxPrice.clean}}in{{/compare}} mb-1"> 549 <div class="row mt-1 e-productlist-filters-range-group js-e-productlist-filters-range-group"> 550 <div class="col-4"> 551 <input type="number" class="form-control js-e-productlist-filters-range js-e-productlist-filters-range-min" name="PriceRangeMin" id="PriceRangeMinModal" value="{{page.minPrice.clean}}" placeholder="@Translate( "eCom Productlist - Filters Price Min - Text ", "From " )" min="0"> 552 </div> 553 <div class="col-4"> 554 <input type="number" class="form-control js-e-productlist-filters-range js-e-productlist-filters-range-max" name="PriceRangeMax" id="PriceRangeMaxModal" value="{{page.maxPrice.clean}}" placeholder="@Translate( "eCom Productlist Filters - Price Max - Text ", "To " )" data-msg-pricerange="@Translate( "eCom Productlist Filters - Price Error - Msg ", "Prices entered incorrectly " )"> 555 </div> 556 <div class="col-1"> 557 <button type="button" class="btn btn-link px-0 e-productlist-filters-clear-range js-e-productlist-filters-range-clear" data-group-id="js-e-productlist-filters-range-group-price"><i class="material-icons">clear</i></button> 558 </div> 559 <div class="col-3"> 560 <button type="button" class="btn btn-primary px-0 btn-sm btn-block e-productlist-filters-apply-range js-e-productlist-filters-apply-range"><i class="material-icons">sync</i></button> 561 </div> 562 </div> 563 </div> 564 </li> 565 } 566 567 568 </ul> 569 <div class="modal-footer"> 570 <a href="#" class="btn btn-outline-primary js-e-productlist-filters-clear-all">@Translate("eCom Productlist Filters - Reset Filter - Link", "Reset all")</a> 571 <button type="button" class="btn btn-primary" data-dismiss="modal"> 572 @Translate("eCom Productlist Filters - Apply - Button", "Apply") 573 </button> 574 </div> 575 </div> 576 </div> 577 </script> 578 </div> 579 580 } 581
keyboard_arrow_up