Error executing template "Designs/RoadPro/eCom/Productlist/ProductList.cshtml" System.ArgumentException: An item with the same key has already been added. at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) at Dynamicweb.Ecommerce.Products.GroupRelation.GetGroupRelationsByParentId(String theParentId) at Dynamicweb.Ecommerce.Products.GroupService.GetSubgroups(Group group, Boolean showUnTranslated) at Dynamicweb.Ecommerce.Products.Group.get_Subgroups() at CompiledRazorTemplates.Dynamic.RazorEngine_ac4fb9e264bd46a7a394111870d43d0e.<>c__DisplayClass3_0.<RenderEcomNavigation>b__0(TextWriter __razor_helper_writer) in F:\Domains\Sites\dev-rpro.mydwsite3.com\Files\Templates\Designs\RoadPro\eCom\Productlist\ProductList.cshtml:line 348 at CompiledRazorTemplates.Dynamic.RazorEngine_ac4fb9e264bd46a7a394111870d43d0e.<>c__DisplayClass3_0.<RenderEcomNavigation>b__0(TextWriter __razor_helper_writer) in F:\Domains\Sites\dev-rpro.mydwsite3.com\Files\Templates\Designs\RoadPro\eCom\Productlist\ProductList.cshtml:line 376 at CompiledRazorTemplates.Dynamic.RazorEngine_ac4fb9e264bd46a7a394111870d43d0e.<>c__DisplayClass3_0.<RenderEcomNavigation>b__0(TextWriter __razor_helper_writer) in F:\Domains\Sites\dev-rpro.mydwsite3.com\Files\Templates\Designs\RoadPro\eCom\Productlist\ProductList.cshtml:line 376 at CompiledRazorTemplates.Dynamic.RazorEngine_ac4fb9e264bd46a7a394111870d43d0e.<>c__DisplayClass2_0.<RenderField>b__0(TextWriter __razor_helper_writer) in F:\Domains\Sites\dev-rpro.mydwsite3.com\Files\Templates\Designs\RoadPro\eCom\Productlist\ProductList.cshtml:line 222 at CompiledRazorTemplates.Dynamic.RazorEngine_ac4fb9e264bd46a7a394111870d43d0e.Execute() in F:\Domains\Sites\dev-rpro.mydwsite3.com\Files\Templates\Designs\RoadPro\eCom\Productlist\ProductList.cshtml:line 208 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; 4 @using Dynamicweb.Frontend; 5 @{ string designName = GetString("Template:DesignBaseUrl").Replace("/Files/Templates/Designs/", "").Replace("/", "");}@functions{ 6 public static string GetImage(string sourceString, int imageWidth, int imageHeight, int imageWidthTablet = 0, int imageHeightTablet = 0, int imageWidthMobile = 0, int imageHeightMobile = 0, string imageFormat = "jpg", int imageCompression = 0, int imageCrop = 5, string background = "", string designName = "RoadPro") 7 { 8 Dynamicweb.Frontend.PageView currentPageview = Dynamicweb.Frontend.PageView.Current(); 9 string currDevice = currentPageview.Device.ToString(); 10 string alternativeImage = !String.IsNullOrEmpty(currentPageview.Area.Item["NoImage"].ToString()) ? currentPageview.Area.Item["NoImage"].ToString() : "/Files/Templates/Designs/"+ designName + "/images/alternativeImage.jpg"; 11 string widthString = ""; 12 string heightString = ""; 13 string getImageFormat = imageFormat != "jpg" ? "&Format=" + imageFormat : ""; 14 string getImageCompression = imageCompression != 0 ? "&Compression=" + imageCompression : ""; 15 string bgColor = !string.IsNullOrEmpty(background) ? "&Background="+background : ""; 16 int getImageWidth = imageWidth != 0 ? imageWidth : 0; 17 int getImageHeight = imageHeight != 0 ? imageHeight : 0; 18 19 if (currDevice == Dynamicweb.Frontend.Devices.DeviceType.Tablet.ToString()) 20 { 21 getImageWidth = imageWidthTablet != 0 ? imageWidthTablet : getImageWidth; 22 getImageHeight = imageHeightTablet != 0 ? imageHeightTablet : getImageHeight; 23 } 24 else if (currDevice == Dynamicweb.Frontend.Devices.DeviceType.Mobile.ToString()) 25 { 26 getImageWidth = imageWidthMobile != 0 ? imageWidthMobile : getImageWidth; 27 getImageHeight = imageHeightMobile != 0 ? imageHeightMobile : getImageHeight; 28 } 29 30 if (getImageWidth != 0) 31 { 32 widthString = "&Width=" + getImageWidth; 33 } 34 if (getImageHeight != 0) 35 { 36 heightString = "&Height=" + getImageHeight; 37 } 38 39 string output = "/Admin/Public/GetImage.ashx?Image=" + sourceString + widthString + heightString + "&altFmImage_path=" + alternativeImage + getImageFormat + getImageCompression + "&Crop=" + imageCrop + bgColor; 40 return output; 41 } 42 } 43 @inherits RazorTemplateBase<RazorTemplateModel<Template>> 44 @using Dynamicweb.Rendering; 45 46 @functions{ 47 private string GetImagePathUrl(string small, string medium, string large, string pattern) 48 { 49 string imagePath; 50 51 if (!string.IsNullOrEmpty(small)) 52 imagePath = small; 53 else if (!string.IsNullOrEmpty(medium)) 54 imagePath = medium; 55 else if (!string.IsNullOrEmpty(large)) 56 imagePath = large; 57 else 58 imagePath = pattern; 59 60 return imagePath; 61 } 62 } 63 @{ 64 Dynamicweb.Content.Items.Item item = Pageview.Area.Item; 65 bool isLoggedIn = Dynamicweb.Security.UserManagement.User.IsExtranetUserLoggedIn(); 66 bool isFrontEnd = Dynamicweb.Environment.ExecutingContext.IsFrontEnd(); 67 var request = System.Web.HttpContext.Current.Request.Params; 68 List<LoopItem> prodLoop = GetLoop("Products"); 69 int totalPagesNum = GetInteger("Ecom:ProductList.TotalPages"); 70 int curPage = !string.IsNullOrEmpty(request["PageNum"]) ? Convert.ToInt32(request["PageNum"].ToString()) : 1; 71 bool noResults = false; 72 bool showQuantity = item["ShowQuantityField"].ToString() == "True" ? true : false; 73 string currentPageId = Pageview.Page.ID.ToString(); 74 string imagesFolder = "/Files/Files/" + designName + "/Products/"; 75 string totalPages = GetString("Ecom:ProductList.TotalPages"); 76 string nextPage = GetString("Ecom:ProductList.NextPage"); 77 string pagingHref = ""; 78 string sortBy = !string.IsNullOrEmpty(request["sortby"]) ? request["sortby"] : ""; 79 string sortOrder = !string.IsNullOrEmpty(request["SortOrder"]) ? request["SortOrder"] : ""; 80 string minPrice = prodLoop.OrderBy(s => s.GetDouble("Ecom:Product.Price.Price")).First().GetString("Ecom:Product.Price.Price"); 81 string maxPrice = prodLoop.OrderByDescending(s => s.GetDouble("Ecom:Product.Price.Price")).First().GetString("Ecom:Product.Price.Price"); 82 string qString = !string.IsNullOrEmpty(request["q"]) ? request["q"] : ""; 83 string dataView = System.Web.HttpContext.Current.Request.Cookies["dataList"] != null ? System.Web.HttpContext.Current.Request.Cookies["dataList"].Value : ""; 84 string groupsIds = !string.IsNullOrEmpty(System.Web.HttpContext.Current.Request.Params["groupid"]) ? System.Web.HttpContext.Current.Request.Params["groupid"] : ""; 85 } 86 87 @* FILTERS *@ 88 <div id="filtersContainer" class="col-xs-12 col-sm-3 noPaddingLeft"> 89 @using System.Linq 90 @{ 91 var parametersList = GetLoop("Query.Parameters"); 92 string groupId = !string.IsNullOrEmpty(System.Web.HttpContext.Current.Request.Params["GroupID"]) ? System.Web.HttpContext.Current.Request.Params["GroupID"].ToString() : ""; 93 string price = !string.IsNullOrEmpty(System.Web.HttpContext.Current.Request.Params["Price"]) ? System.Web.HttpContext.Current.Request.Params["Price"] : ""; 94 string pageSizeNum = !string.IsNullOrEmpty(System.Web.HttpContext.Current.Request.Params["PageSize"]) ? System.Web.HttpContext.Current.Request.Params["PageSize"] : ""; 95 } 96 97 <h2>@Translate("filters","Filters")</h2> 98 99 <!-- REMOVE FILTERS --> 100 101 <div class="col-xs-12 removeFiltersContainer"> 102 @foreach (LoopItem facetGroup in GetLoop("FacetGroups")) 103 { 104 foreach (LoopItem facet in facetGroup.GetLoop("Facets")) 105 { 106 if (facet.GetLoop("FacetOptions").Any(r => r.GetBoolean("FacetOption.Selected"))) 107 { 108 <a data-queryname="@(facet.GetString("Facet.QueryParameter"))" class="btn btn-bg filter-selected hidden" href="#">@Translate("clearFilters", "Clear filters") <i class="fa fa-times"></i></a> 109 } 110 } 111 } 112 <a class="removeAll btn btn-bg" href="#">@Translate("clearFilters", "Clear filters") <i class="fa fa-times"></i></a> 113 </div> 114 115 <form id="filtersForm" class="col-xs-12 noPadding-xs" action="/Default.aspx"> 116 <input type="hidden" name="ID" value="@Pageview.Page.ID"/> 117 <input type="hidden" name="GroupID" value="@groupId" /> 118 <input type="hidden" name="sortby" value="@sortBy"/> 119 <input type="hidden" name="SortOrder" value="@sortOrder"/> 120 <input type="hidden" name="PageSize" value="@pageSizeNum"/> 121 <input type="hidden" name="q" value="@qString"/> 122 123 @* Price range 124 @if(!noResults) { 125 <fieldset class="hide"> 126 <legend class="filterTitle notClick">@Translate("price", "Price")</legend> 127 <input id="amount" type="text" name="Price" value="" /> 128 <div id="slider-range"></div> 129 </fieldset> 130 } 131 *@ 132 @foreach (LoopItem facetGroup in GetLoop("FacetGroups")) 133 { 134 foreach (LoopItem facet in facetGroup.GetLoop("Facets")) 135 { 136 string parameterType = parametersList.First(x => x.GetString("Parameter.Name") == facet.GetString("Facet.QueryParameter")).GetString("Parameter.Type"); 137 string templateOutput = "string"; 138 139 if (parameterType.Contains("[]")) 140 { 141 switch (facet.GetString("Facet.Name")) 142 { 143 case "Category": 144 templateOutput = "multiselect"; 145 break; 146 case "Price": 147 templateOutput = "range"; 148 break; 149 default: 150 templateOutput = "checkboxes"; 151 break; 152 } 153 } 154 else if (parameterType.Contains("Boolean")) 155 { 156 switch (facet.GetString("Facet.Name")) 157 { 158 case "fieldName": 159 templateOutput = "select"; 160 break; 161 case "fieldName2": 162 templateOutput = "radio"; 163 break; 164 default: 165 templateOutput = "checkbox"; 166 break; 167 } 168 } 169 else if (!string.IsNullOrWhiteSpace(facet.GetString("Facet.OptionCount"))) 170 { 171 switch (facet.GetString("Facet.Name")) 172 { 173 case "fieldName": 174 templateOutput = "select"; 175 break; 176 case "fieldName2": 177 templateOutput = "radios"; 178 break; 179 case "fieldName3": 180 templateOutput = "multiselect"; 181 break; 182 case "fieldName4": 183 templateOutput = "text"; 184 break; 185 case "Price": 186 templateOutput = "range"; 187 break; 188 default: 189 templateOutput = "checkboxes"; 190 break; 191 } 192 } 193 else 194 { 195 switch (facet.GetString("Facet.Name")) 196 { 197 case "fieldName": 198 templateOutput = "autocomplete"; 199 break; 200 case "Price": 201 templateOutput = "range"; 202 break; 203 default: 204 templateOutput = "text"; 205 break; 206 } 207 } 208 @RenderField(facet, parameterType, templateOutput, noResults) 209 } 210 } 211 </form> 212 213 @helper RenderField(LoopItem loopItem, string parameterType, string templateOutput, bool noResults) 214 { 215 string parameter = loopItem.GetString("Facet.QueryParameter"); 216 string name = loopItem.GetString("Facet.Name"); 217 List<LoopItem> facetOptionsList = loopItem.GetLoop("FacetOptions"); 218 var facetOptions = noResults ? facetOptionsList.OrderByDescending(o => o.GetInteger("FacetOption.Count")).ThenBy(or => or.GetString("FacetOption.Label")) : loopItem.GetLoop("FacetOptions").Where(f => f.GetInteger("FacetOption.Count") != 0).OrderByDescending(o => o.GetInteger("FacetOption.Count")).ThenBy(or => or.GetString("FacetOption.Label")); 219 220 if (name == "EcomGroups") 221 { 222 @RenderEcomNavigation(null) 223 } 224 else{ 225 switch (templateOutput) 226 { 227 case "multiselect": 228 if (loopItem.GetLoop("FacetOptions").Any()) 229 { 230 <fieldset> 231 <legend>@name</legend> 232 <select data-selected-text-format="count" data-live-search="true" data-size="8" name="@parameter" multiple> 233 @foreach (LoopItem option in facetOptionsList.OrderByDescending(o => o.GetInteger("FacetOption.Label"))) 234 { 235 bool facetOptionChecked = option.GetBoolean("FacetOption.Selected"); 236 string value = option.GetString("FacetOption.Value"); 237 string nameOption = option.GetString("FacetOption.Name"); 238 239 <option selected="@facetOptionChecked" value="@value">@option.GetString("FacetOption.Label")</option> 240 } 241 </select> 242 </fieldset> 243 } 244 245 break; 246 case "checkboxes": 247 248 if (loopItem.GetLoop("FacetOptions").Any()) 249 { 250 int count = 0; 251 252 <fieldset data-type="@parameterType"> 253 <legend class="filterTitle">@name</legend> 254 <div class="filtersContainer hide"> 255 @foreach (LoopItem option in facetOptions) 256 { 257 bool facetOptionChecked = option.GetBoolean("FacetOption.Selected"); 258 string value = option.GetString("FacetOption.Value"); 259 string nameOption = option.GetString("FacetOption.Name"); 260 count++; 261 string classString = count > 5 ? "hide" : ""; 262 263 <label id="value_@value" class="checkBoxContainer @classString"> 264 <input checked="@facetOptionChecked" type="checkbox" value="@value" name="@parameter"> 265 <span> 266 @option.GetString("FacetOption.Label") 267 @if (option.GetInteger("FacetOption.Count") > 0) 268 { 269 @:@string.Format("({0})", option.GetString("FacetOption.Count")) 270 } 271 </span> 272 </label> 273 } 274 275 @if (loopItem.GetLoop("FacetOptions").Where(f => f.GetInteger("FacetOption.Count") != 0).Count() > 5) 276 { 277 <span class="seeMore" data-more='@Translate("seeMore", "See more")' data-hide='@Translate("only5", "Show only 5")'>@Translate("seeMore", "See more")</span> 278 } 279 </div> 280 </fieldset> 281 } 282 283 break; 284 case "select": 285 286 break; 287 case "checkbox": 288 289 if (loopItem.GetLoop("FacetOptions").Any()) 290 { 291 <fieldset data-type="@parameterType"> 292 @foreach (LoopItem option in facetOptionsList.Where(f => f.GetInteger("FacetOption.Count") != 0).OrderByDescending(o => o.GetInteger("FacetOption.Count")).ThenBy(or => or.GetString("FacetOption.Label"))) 293 { 294 bool facetOptionChecked = option.GetBoolean("FacetOption.Selected"); 295 string value = option.GetString("FacetOption.Value") == "True" ? "True" : ""; 296 string nameOption = option.GetString("FacetOption.Name"); 297 298 if (value == "True") 299 { 300 <legend class="filterTitle">@name</legend> 301 <div class="filtersContainer hide"> 302 <label id="value_@value" class="checkBoxContainer"> 303 <input checked="@facetOptionChecked" type="checkbox" value="@value" name="@parameter"> <span>@name (@option.GetString("FacetOption.Count"))</span> 304 </label> 305 </div> 306 } 307 } 308 </fieldset> 309 } 310 311 break; 312 case "radio": 313 314 break; 315 case "radios": 316 317 break; 318 case "autocomplete": 319 320 break; 321 case "range": 322 break; 323 default: 324 <fieldset data-type="@parameterType"> 325 <legend class="filterTitle">@name</legend> 326 <div class="filtersContainer"> 327 <input type="text" name="@parameter" value=""/> 328 </div> 329 </fieldset> 330 break; 331 } 332 } 333 } 334 335 336 @helper RenderEcomNavigation(Dynamicweb.Ecommerce.Products.GroupCollection groupCollection) 337 { 338 groupCollection = groupCollection ?? new Dynamicweb.Ecommerce.Shops.Shop((string) Dynamicweb.Frontend.PageView.Current() 339 .Area.EcomShopId) 340 .get_TopLevelGroups((string) Dynamicweb.Frontend.PageView.Current() 341 .Area.EcomLanguageId); 342 343 foreach (var group in groupCollection) 344 { 345 string groupName = group.Name; 346 string groupId = group.Id; 347 348 if (group.Subgroups.Any()) 349 { 350 int numberOfParentGroups = group.ParentGroups.Count; 351 string hideSubgroups = numberOfParentGroups == 0 ? "hide" : ""; 352 353 <fieldset class="groupFieldset level_@numberOfParentGroups"> 354 <legend class="filterTitle deep_@numberOfParentGroups"> 355 356 @* IF SUB-GROUPS SHOULD NOT HAVE A CHECKBOX 357 @if ((bool) Pageview.Area.Item["ParentGroupsWithCheckbox"]) 358 *@ 359 @if (numberOfParentGroups > 0 || ((bool)Pageview.Area.Item["ParentGroupsWithCheckbox"] && numberOfParentGroups == 0) ) 360 { 361 <label id="value_@groupId" class="checkBoxContainer "> 362 <input type="checkbox" value="@groupId" name="group"> 363 <span> 364 @groupName 365 </span> 366 </label> 367 } 368 else 369 { 370 <input class="hidden" type="checkbox" value="@groupId" name="group"> 371 @groupName 372 } 373 </legend> 374 375 <div class="filtersContainer containerDeep_@numberOfParentGroups @hideSubgroups"> 376 @RenderEcomNavigation(group.Subgroups) 377 </div> 378 </fieldset> 379 } 380 else 381 { 382 <label id="value_@groupId" class="checkBoxContainer "> 383 <input type="checkbox" value="@groupId" name="group"> 384 <span> 385 @groupName 386 </span> 387 </label> 388 } 389 390 } 391 } 392 </div> 393 <div id="listContainer" class="col-xs-12 col-sm-9 noPaddingRight" data-amountrequired='@Translate("amountIsRequired","Amount is required.")'> 394 @* SORT AND ORDER *@ 395 <div class="headerBox col-xs-12 noPadding"> 396 <span class="col-sm-4 col-xs-12 noPaddingLeft">@prodLoop.Count() @Translate("of", "of") @GetString("Ecom:ProductList.PageProdCnt") @Translate(GetInteger("Ecom:ProductList.PageProdCnt") > 1 ? "items" : "item")</span> 397 <form id="orderProdList" class="col-sm-8 col-xs-12 hidden-xs pull-right noPadding" action="/" name="ExtUserForm_Main" method="GET"> 398 <input type="hidden" name="ID" value="@Pageview.Page.ID"> 399 <input type="hidden" name="GroupID" value="@(GetGlobalValue("Ecom:ProductList:Page.GroupID"))"> 400 401 <fieldset class="col-lg-5 col-md-5 col-sm-12 col-xs-6 noPadding-sm noPadding-xs pageSize"> 402 <label for="pageSize">@Translate("pageSize", "Page size"):</label> 403 <select id="pageSize" name="PageSize"> 404 @{ 405 int multipleOf = 12; 406 int maxOf = 36; 407 string pageSize = GetString("Ecom:ProductList.PageSize"); 408 string selected = !string.IsNullOrEmpty(request["PageNum"]) ? request["PageNum"].ToString() : pageSize; 409 410 while (multipleOf <= maxOf) 411 { 412 string selectedOption = selected == multipleOf.ToString() ? "selected" : ""; 413 414 <option @selectedOption value="@multipleOf">@multipleOf</option> 415 multipleOf = multipleOf + 12; 416 if(multipleOf > GetInteger("Ecom:ProductList.PageProdCnt")){ 417 break; 418 } 419 } 420 <option selected="@(selected == "9999")" value="9999">@Translate("all", "All")</option> 421 } 422 </select> 423 </fieldset> 424 <fieldset class="col-lg-5 col-md-6 col-sm-6 col-xs-6 hidden"> 425 <label class="pull-left">@Translate("sortBy", "Sort by"):</label> 426 <select id="sortSelect" name="sortby"> 427 <option selected="@(sortBy == "Created")" value="Created">@Translate("created", "Created")</option> 428 <option selected="@(sortBy == "Price")" value="Price">@Translate("price", "Price")</option> 429 <option selected="@(sortBy == "Name_sortable")" value="Name_sortable">@Translate("name", "Name")</option> 430 </select> 431 </fieldset> 432 <fieldset class=" col-lg-7 col-md-6 col-sm-6 col-xs-6 hidden"> 433 <label class="pull-left">@Translate("order", "Order"):</label> 434 <select id="orderSelect" name="SortOrder"> 435 <option selected="@(sortOrder == "ASC")" value="ASC">@Translate("asc", "ASC")</option> 436 <option selected="@(sortOrder == "DESC")" value="DESC">@Translate("desc", "DESC")</option> 437 </select> 438 </fieldset> 439 <fieldset class="col-lg-7 col-md-7 col-sm-12 col-xs-6 noPadding"> 440 <label class="pull-left">@Translate("sort", "Sort"):</label> 441 <select id="sortOrderJoin" name="sortOrderJoin"> 442 @*<option data-sort="Price" data-order="ASC" selected="@(sortOrder == "ASC" && sortBy == "Price" )" value="">@Translate("priceLh", "Price (Low to High)")</option> 443 <option data-sort="Price" data-order="DESC" selected="@(sortOrder == "DESC" && sortBy == "Price" )" value="">@Translate("priceHl", "Price (High to Low)")</option> 444 *@<option data-sort="Name_sortable" data-order="ASC" selected="@(sortOrder == "ASC" && sortBy == "Name_sortable" )" value="">@Translate("titleAz", "Title (A - Z)")</option> 445 <option data-sort="Name_sortable" data-order="DESC" selected="@(sortOrder == "DESC" && sortBy == "Name_sortable" )" value="">@Translate("titleZa", "Title (Z - A)")</option> 446 </select> 447 </fieldset> 448 </form> 449 </div> 450 @if (qString != "") 451 { 452 <form action="/Default.aspx" id="searchFormList"> 453 <input type="hidden" name="ID" value="@(item["SearchResults"])"> 454 <fieldset class="TextInput mandatory"> 455 <label for="searchSubmitList" class="hide">@Translate("search", "Search")</label> 456 <input id="searchSubmitList" data-error='@Translate("searchText", "Search for something")' type="text" name="q" value="@qString"> 457 </fieldset> 458 <button type="submit"> 459 <i class="fa fa-search"></i> 460 </button> 461 </form> 462 } 463 464 <ul data-maxcompare='@Translate("maxCompare", "Maximum to compare: 3")' data-list="@dataView" id="productsList" class="productsList hidden"> 465 @foreach (LoopItem product in prodLoop) 466 { 467 bool isGiftCard = product.GetInteger("Ecom:Product.Type") == 3; 468 string productNumber = product.GetString("Ecom:Product.Number"); 469 string imagePattern = imagesFolder + productNumber.Replace("/","_") + ".jpg"; 470 string image = GetImagePathUrl(product.GetString("Ecom:Product.ImageSmall.Clean"), product.GetString("Ecom:Product.ImageMedium.Clean"), product.GetString("Ecom:Product.ImageLarge.Clean"), imagePattern); 471 string productName = product.GetString("Ecom:Product.Name"); 472 string productID = product.GetString("Ecom:Product.ID"); 473 string productVariantID = product.GetString("Ecom:Product.VariantID"); 474 string productShortDescription = product.GetString("Ecom:Product.ShortDescription"); 475 string link = product.GetString("Ecom:Product.LinkGroup.Clean"); 476 string productLanguage = product.GetString("Ecom:Product.LanguageID"); 477 string variantDefaultId = product.GetString("Ecom:Product.DefaultVariantComboID"); 478 string variantCurrentId = product.GetString("Ecom:Product.VariantID"); 479 string variantId = (!string.IsNullOrEmpty(variantCurrentId)) ? variantCurrentId : variantDefaultId; 480 string compareLink = productID + "$" + productLanguage + "$" + productVariantID; 481 bool productIsFavoriteBool = product.GetBoolean("Ecom:Product.IsProductInFavoriteList"); 482 string productRemoveFromList = "/Default.aspx?Id=" + currentPageId + "&ProductID=" + productID + "&CCRemoveFromMyLists=" + productID + "&CCRemoveFromListVariantID=" + variantDefaultId + "&CCRemoveFromListLanguageID=" + productLanguage; 483 string productAddToList = "/Default.aspx?Id=" + currentPageId + "&ProductID=" + productID + "&CCAddToMyLists=" + productID + "&CCAddToListVariantID="+ variantDefaultId + "&CCAddToListLanguageID=" + productLanguage; 484 string favoriteUrl = productIsFavoriteBool ? productRemoveFromList : productAddToList; 485 string miniCartPage = (item["MiniCart"] ?? "").ToString(); 486 bool newProduct = product.GetBoolean("Ecom:Product:Field.New"); 487 List<LoopItem> variantCombinations = product.GetLoop("VariantCombinations"); 488 string brand = product.GetString("Ecom:Product:Field.Brand"); 489 490 @* Logic: If there is any variant check if there is any selected/default variant to load the price if not load price from first (by order xpto) variant. *@ 491 int productStock = !variantCombinations.Any() ? product.GetInteger("Ecom:Product.AvailableAmount") : variantCombinations.FirstOrDefault(x => x.GetString("Ecom:Product.DefaultVariantComboID").Equals(x.GetString("Ecom:VariantCombination.VariantID"))) == null ? variantCombinations.OrderBy(x => x.GetString("Ecom:VariantCombination.VariantID")).FirstOrDefault().GetInteger("Ecom:Product.AvailableAmount") : variantCombinations.FirstOrDefault(x => x.GetString("Ecom:Product.DefaultVariantComboID").Equals(x.GetString("Ecom:VariantCombination.VariantID"))).GetInteger("Ecom:Product.AvailableAmount"); 492 string productPrice = !variantCombinations.Any() ? product.GetString("Ecom:Product.Price") : variantCombinations.FirstOrDefault(x => x.GetString("Ecom:Product.DefaultVariantComboID").Equals(x.GetString("Ecom:VariantCombination.VariantID"))) == null ? variantCombinations.OrderBy(x => x.GetString("Ecom:VariantCombination.VariantID")).FirstOrDefault().GetString("Ecom:Product.Price") : variantCombinations.FirstOrDefault(x => x.GetString("Ecom:Product.DefaultVariantComboID").Equals(x.GetString("Ecom:VariantCombination.VariantID"))).GetString("Ecom:Product.Price"); 493 string stockStatus = productStock > 0 ? "fa-check" : "fa-close"; 494 495 <li class="col-xs-12 col-sm-6 col-lg-4 noPadding-left"> 496 <div class="col-xs-12 noPadding"> 497 <figure class="col-xs-12 noPadding"> 498 <a href="@link"> 499 <img src="@GetImage(image, 400, 0)" alt="@productName" title="@productName" class="img-responsive"/> 500 @if (newProduct) 501 { 502 <div class="newProduct btn-primary">@Translate("new", "New")</div> 503 } 504 </a> 505 </figure> 506 507 <div class="col-xs-12 noPadding"> 508 <div class="col-xs-12 noPadding"> 509 <h2>@brand</h2> 510 <div> 511 <a itemprop="name" href="@link">@productName</a> 512 </div> 513 @if (!string.IsNullOrEmpty(productNumber)) 514 { 515 <div class="prodNumber"> 516 @Translate("item", "Item #"): @productNumber 517 </div> 518 } 519 </div> 520 521 @*<div class="col-xs-4 noPaddingRight pull-right priceContainer"> 522 <form name="addToCart" action="@Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(miniCartPage)" method="post" data-outofstock='@Translate("outOfStock", "Out of stock")'> 523 <input type="hidden" name="redirect" value="false"> 524 <input type="hidden" name="productid" value="@productID"/> 525 <input type="hidden" name="cartcmd" value="add"/> 526 @if (!showQuantity || isGiftCard) 527 { 528 <input data-outofstock='@Translate("outOfStock", "Out of stock")' data-stocktranslate='@Translate("currentStock", "The current stock is")' data-available='@productStock' type="hidden" class="quantityInput" name="quantity" value="1"/> 529 } 530 531 @if (!isGiftCard) 532 { 533 <span class="listPrice" itemprop="price">@productPrice</span> 534 } 535 @if (isLoggedIn && isFrontEnd && !variantCombinations.Any()) 536 { 537 string icon = productIsFavoriteBool ? "fa-heart" : "fa-heart-o"; 538 539 <a title='@Translate("favorites", "Favorites")' class="favorite" data-favorite="@productIsFavoriteBool" data-user="@Dynamicweb.Security.UserManagement.User.IsExtranetUserLoggedIn()" href="@favoriteUrl"><i class="fa @icon"></i></a> 540 } 541 542 @if (variantCombinations.Any()) 543 { 544 string sizeSelect = "<fieldset class='Select mandatory'><select data-width='100%' name='variantID'>"; 545 546 foreach (LoopItem a in variantCombinations.OrderBy(x => x.GetString("Ecom:VariantCombination.VariantID"))) 547 { 548 bool isFavoriteBool = a.GetBoolean("Ecom:Product.IsProductInFavoriteList"); 549 string variantPrice = a.GetString("Ecom:Product.Price"); 550 string selectedVariant = a.GetString("Ecom:Product.DefaultVariantComboID") == a.GetString("Ecom:VariantCombination.VariantID") ? "selected" : ""; 551 string variantCombinationId = a.GetString("Ecom:VariantCombination.VariantID"); 552 string showSelectedFavorite = selectedVariant == "selected" ? "" : "hidden"; 553 string icon = isFavoriteBool ? "fa-heart" : "fa-heart-o"; 554 string addToList = a.GetString("Ecom:Product.AddToFavorites"); 555 string removeFromList = a.GetString("Ecom:Product.RemoveFromFavorites"); 556 favoriteUrl = isFavoriteBool ? removeFromList : addToList; 557 558 sizeSelect += "<option data-favorite='" + isFavoriteBool + "' " + selectedVariant + " data-stock='" + a.GetInteger("Ecom:Product.AvailableAmount") + "' data-price='" + variantPrice + "' id='" + variantCombinationId + "' value='" + variantCombinationId + "'>" + a.GetString("Ecom:VariantCombination.VariantText") + "</option>"; 559 if (isLoggedIn && isFrontEnd) 560 { 561 <a data-add='@addToList' data-remove='@removeFromList' data-variant='@variantCombinationId.Replace(".", "_")' title='@Translate("favorites", "Favorites")' class="favorite @showSelectedFavorite" data-favorite="@isFavoriteBool" data-user="@Dynamicweb.Security.UserManagement.User.IsExtranetUserLoggedIn()" href="@favoriteUrl"><i class="fa @icon"></i></a> 562 } 563 } 564 sizeSelect += "</select></fieldset>"; 565 @sizeSelect 566 } 567 @if (showQuantity) 568 { 569 <fieldset class="quantity-container pull-left"> 570 <label for="quantity">@Translate("qty", "Qty")</label> 571 <input data-outofstock='@Translate("outOfStock", "Out of stock")' data-stocktranslate='@Translate("currentStock", "The current stock is")' class="hidden quantityInput" maxlength="5" data-available='@productStock' type="number" name="quantity" value="1"/> 572 <select data-width="100%" name="quantitySelect" @(productStock <= 0 ? "disabled" : "")> 573 574 @if (variantCombinations.Any() && productStock > 0) 575 { 576 for (int num = 1; (num < 10); num++) 577 { 578 <option value="@num">@num</option> 579 } 580 } 581 else if (productStock > 0) 582 { 583 for (int num = 1; (num < 10) && num <= productStock; num++) 584 { 585 <option value="@num">@num</option> 586 } 587 } 588 else 589 { 590 <option value="1">1</option> 591 } 592 593 @if (productStock >= 10 || variantCombinations.Any()) 594 { 595 <option value="10+">10+</option> 596 } 597 598 </select> 599 </fieldset> 600 } 601 602 @if (isGiftCard) 603 { 604 <fieldset class="pull-left giftCardAmount"> 605 <label class="hidden" for="Amount">@Translate("amount", "Amount")</label> 606 <span>@product.GetString("Ecom:Product.Price.Currency.Symbol")</span> 607 <input placeholder="@Translate("amount")" type="number" name="Amount" step="0.01" min="0.01" value="@product.GetString("Ecom:Product.Price.Price")"/> 608 </fieldset> 609 } 610 611 <a class="addToCart btn btn-bg" href="/Default.aspx?ID=@currentPageId&productid=@productID&variantID=@variantId&cartcmd=add"><i class="fa fa-shopping-cart"></i> <span data-add='@Translate("addToCart", "Add to cart")' data-added='@Translate("added", "Added")'>@Translate("addToCart", "Add to cart")</span></a> 612 <input class="hide" type="submit" value="@Translate("addToCart", "Add to cart")"> 613 614 <div class="stockStatus col-xs-12 noPadding"><i class="fa @stockStatus"></i> @Translate("stock", "Stock")</div> 615 616 </form> 617 618 </div>*@ 619 @*@if (!isGiftCard) 620 { 621 <div class="addToCompare pull-left col-xs-12 col-sm-7 noPadding"> 622 <label class="weightNormal" for="addToCompare_@productID"> 623 <input data-link="@compareLink" type="checkbox" id="addToCompare_@productID" name="addToCompare_@productID" value=""/> 624 @Translate("addToCompare", "Add to compare") 625 </label> 626 </div> 627 }*@ 628 </div> 629 </div> 630 </li> 631 } 632 </ul> 633 634 <div class="footerBox col-xs-12 noPadding"> 635 <span class="col-xs-6 noPadding">@prodLoop.Count() @Translate("of", "of") @GetString("Ecom:ProductList.PageProdCnt") @Translate(GetInteger("Ecom:ProductList.PageProdCnt") > 1 ? "items" : "item")</span> 636 @if (GetInteger("Ecom:ProductList.TotalPages") > 1) 637 { 638 string active = ""; 639 string prevPage = GetString("Ecom:ProductList.PrevPage.Clean"); 640 string nextListPage = GetString("Ecom:ProductList.NextPage.Clean"); 641 string pageText = ""; 642 string requestUrl = Pageview.GlobalTags.GetTagByName("Global:Request.Url").Value.ToString(); 643 644 <ul class="pagination"> 645 @if (prevPage != "") 646 { 647 @PageItem("class=\"previous\"", prevPage, pageText) 648 } 649 @if (curPage > 2 && totalPagesNum > 3) 650 { 651 for (int i = 1; i <= 1; i++) 652 { 653 active = curPage == i ? "class=\"active\"" : ""; 654 pagingHref = requestUrl.Contains("PageNum") ? requestUrl.Replace("PageNum=" + curPage, "PageNum=" + i) : requestUrl + "&PageNum=" + i; 655 @PageItem(active, pagingHref, i.ToString()) 656 } 657 if (totalPagesNum > 4) 658 { 659 @Ellipsis() 660 } 661 } 662 @foreach (LoopItem page in GetLoop("Ecom:ProductList.Pages3")) 663 { 664 string hrefEncoded = page.GetString("Ecom:ProductList.Pages3.Page.UrlHtmlEncoded"); 665 string page3Number = page.GetString("Ecom:ProductList.Pages3.Page.Number"); 666 667 if (page.GetBoolean("Ecom:ProductList.Pages3.Page.IsCurrent")) 668 { 669 @PageItem("class=\"active\"", hrefEncoded, page3Number) 670 } 671 else 672 { 673 @PageItem("", hrefEncoded, page3Number) 674 } 675 } 676 @if (curPage < totalPagesNum - 1 && totalPagesNum > 3) 677 { 678 if (totalPagesNum > 4) 679 { 680 @Ellipsis() 681 } 682 for (int i = totalPagesNum; i <= totalPagesNum; i++) 683 { 684 active = curPage == i ? "class=\"active\"" : ""; 685 pagingHref = requestUrl.Contains("PageNum") ? requestUrl.Replace("PageNum=" + curPage, "PageNum=" + i) : requestUrl + "&PageNum=" + i; 686 @PageItem(active, pagingHref, i.ToString()) 687 } 688 } 689 @if (nextListPage != "") 690 { 691 string nextText = ""; 692 693 @PageItem("class=\"next\"", nextListPage, nextText, "data-numPages=\""+totalPagesNum+"\"") 694 } 695 </ul> 696 } 697 </div> 698 </div> 699 700 @SnippetStart("jsOnLoad") 701 onLoadProductList("@minPrice.Replace(",", "")", "@maxPrice.Replace(",", "")", "@price", "@groupsIds"); 702 @SnippetEnd("jsOnLoad") 703 704 @helper PageItem(string cssClass, string href, string text, string dataAttr = "") 705 { 706 <li @cssClass @dataAttr> 707 <a href="@href">@text</a> 708 </li> 709 } 710 @helper Ellipsis() 711 { 712 <li><span>...</span></li> 713 } 714 715 @helper Truncate(string str_input,int num_length) 716 { 717 if(str_input.Length <= num_length){ 718 @str_input 719 }else{ 720 @str_input.Substring(0,num_length)<text>...</text> 721 } 722 }