Accessories

Error executing template "Designs/Roidmi/eCom/Product/SingleProductDetailsPopup.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_52050ec72ffd411c821545663b150f62.Execute() in D:\DW9\Solutions\witt.dk\Files\Templates\Designs\Roidmi\eCom\Product\SingleProductDetailsPopup.cshtml:line 945
   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 Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2 3 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 4 @using System.Web; 5 6 @SnippetStart("StyleSheet") 7 <link href="/Files/Templates/Designs/Roidmi/assets/css/review.css" rel="stylesheet" /> 8 <link href="/Files/Templates/Designs/Roidmi/assets/css/modal.css" rel="stylesheet" /> 9 @SnippetEnd("StyleSheet") 10 11 12 @functions { 13 14 private double GetPercentage(int number, int total) 15 { 16 double percentage = 0; 17 18 if (number != 0 && total != 0) 19 { 20 double dTotal = Convert.ToDouble(total); 21 double dNumber = Convert.ToDouble(number); 22 23 percentage = 100 / dTotal * dNumber; 24 } 25 26 return Math.Round(percentage, 2); 27 } 28 } 29 30 @helper RenderRating(double rating, string size = "lg") 31 { 32 bool ratingIsDouble = rating % 1 != 0; 33 34 for (int i = 0; i < 5; i++) 35 { 36 if (i < Math.Floor(rating)) 37 { 38 <i class="fas fa-star fa-@size star selected"></i> 39 } 40 else 41 { 42 if (ratingIsDouble) 43 { 44 45 <span class="fa icon-stack"> 46 <i class="fas fa-star-half fa-@size star selected p-absolute"></i> 47 <i class="fas fa-star-half fa-@size star fa-flip-horizontal"></i> 48 </span> 49 50 ratingIsDouble = false; 51 } 52 else 53 { 54 <i class="fa fa-star star fa-@size"></i> 55 } 56 } 57 } 58 } 59 60 @helper RenderComments() 61 { 62 var comments = Dynamicweb.Content.Commenting.Comment.GetComments("ecomProduct", GetString("Ecom:Product.ID"), GetString("Ecom:Product.LanguageID")); 63 64 <div class="review" style="margin-bottom:2rem"> 65 <div class="review-heading"> 66 <div class="border-primary py-1 my-3"> 67 <div class="review-panel"> 68 <div class="panel-content border-primary-right-desktop text-center"> 69 <div class="rating-text-container"><b>@Translate("Rating", "Rating")</b></div> 70 <div class="rating-text-container h2"><b>@comments.RatingAverage()</b></div> 71 <div class="rating-text-container"> 72 @RenderRating(comments.RatingAverage(), "2x") 73 </div> 74 <div class="">(@comments.TotalComments @Translate("Ratings", "Ratings"))</div> 75 </div> 76 77 @{ 78 int star5Count = comments.Where(c => c.Rating == 5).Count(); 79 int star4Count = comments.Where(c => c.Rating == 4).Count(); 80 int star3Count = comments.Where(c => c.Rating == 3).Count(); 81 int star2Count = comments.Where(c => c.Rating == 2).Count(); 82 int star1Count = comments.Where(c => c.Rating == 1).Count(); 83 84 string star5Percentage = GetPercentage(star5Count, comments.TotalComments).ToString().Replace(",", "."); 85 string star4Percentage = GetPercentage(star4Count, comments.TotalComments).ToString().Replace(",", "."); 86 string star3Percentage = GetPercentage(star3Count, comments.TotalComments).ToString().Replace(",", "."); 87 string star2Percentage = GetPercentage(star2Count, comments.TotalComments).ToString().Replace(",", "."); 88 string star1Percentage = GetPercentage(star1Count, comments.TotalComments).ToString().Replace(",", "."); 89 } 90 91 <div class="panel-content text-center"> 92 <div class="progress-container"> 93 <div class="flex-1"> 94 5 <i class="fas fa-star fa-lg star selected"></i> 95 </div> 96 <div class="flex-3 progress-bar-outer"><div class="progress-bar-inner" style="width:@star5Percentage%;"></div></div> 97 <div class="flex-1">@star5Count</div> 98 </div> 99 <div class="progress-container"> 100 <div class="flex-1"> 101 4 <i class="fas fa-star fa-lg star selected"></i> 102 </div> 103 <div class="flex-3 progress-bar-outer"><div class="progress-bar-inner" style="width:@star4Percentage%;"></div></div> 104 <div class="flex-1">@star4Count</div> 105 </div> 106 <div class="progress-container"> 107 <div class="flex-1"> 108 3 <i class="fas fa-star fa-lg star selected"></i> 109 </div> 110 <div class="flex-3 progress-bar-outer"><div class="progress-bar-inner" style="width:@star3Percentage%;"></div></div> 111 <div class="flex-1">@star3Count</div> 112 </div> 113 <div class="progress-container"> 114 <div class="flex-1"> 115 2 <i class="fas fa-star fa-lg star selected"></i> 116 </div> 117 <div class="flex-3 progress-bar-outer"><div class="progress-bar-inner" style="width:@star2Percentage%;"></div></div> 118 <div class="flex-1">@star2Count</div> 119 </div> 120 <div class="progress-container"> 121 <div class="flex-1"> 122 1 <i class="fas fa-star fa-lg star selected"></i> 123 </div> 124 <div class="flex-3 progress-bar-outer"><div class="progress-bar-inner" style="width:@star1Percentage%;"></div></div> 125 <div class="flex-1">@star1Count</div> 126 </div> 127 </div> 128 129 130 131 </div> 132 <div class="text-center" style="margin-top:1rem"> 133 <button id="btnOpenModal" onclick="openModal('commentModal');" class="btn btn--primary">@Translate("Write a review", "Write a review")</button> 134 </div> 135 </div> 136 137 </div> 138 <div class="review-body"> 139 <div class="review-panel"> 140 @foreach (var comment in comments) 141 { 142 <div class="panel-border border-lightgrey p-1" style="width:100%"> 143 <div class="d-flex"> 144 <div class="flex-1 text-center"> 145 <div><b>@comment.Name</b></div> 146 <div class="py-1">@comment.CreatedDate.ToString("dd/MM/yyyy")</div> 147 </div> 148 <div class="flex-1"> 149 <div>@RenderRating(comment.Rating)</div> 150 <div class="py-1"> 151 @comment.Text.Replace(Environment.NewLine, "<br />") 152 </div> 153 </div> 154 </div> 155 </div> 156 } 157 </div> 158 </div> 159 </div> 160 } 161 162 @helper RenderProductCommentForm() 163 { 164 if (Dynamicweb.Security.UserManagement.User.IsExtranetUserLoggedIn()) 165 { 166 var user = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser(); 167 var comments = Dynamicweb.Content.Commenting.Comment.GetComments("ecomProduct", GetString("Ecom:Product.ID"), GetString("Ecom:Product.LanguageID"), true); 168 169 var userComments = comments.Where(c => c.Email == user.Email); 170 171 if (!userComments.Any()) 172 { 173 <form method="post" id="commentform" onsubmit="return comment_validate('@Translate("Please choose a rating from 1 - 5.")')"> 174 @{ 175 var antispamFields = Dynamicweb.SystemTools.Security.FormAntispam.AntiSpamFields("commentform"); 176 } 177 <input type="hidden" name="Command" id="Command" value="Create" /> 178 <input type="hidden" name="Comment.Command" id="Comment.Command" value="Create" /> 179 <input type="hidden" name="Comment.Active" id="Comment.Active" value="true" /> 180 <input type="hidden" name="Comment.ItemType" id="Comment.ItemType" value="ecomProduct" /> 181 <input type="hidden" name="Comment.ItemID" id="Comment.ItemID" value="@GetString("Ecom:Product.ID")" /> 182 <input type="hidden" name="Comment.LangID" value="@GetString("Ecom:Product.LanguageID")" /> 183 184 @antispamFields 185 186 <div class="comment-form"> 187 188 <div class="form-field rating-box-container"> 189 <div class="rating-box"><h4 class="">@Translate("Din bedømmelse"): </h4></div> 190 <div class="rating-box"> 191 192 <input type="hidden" id="Comment.Rating" name="Comment.Rating" value="0" /> 193 194 <!-- Rating Stars Box --> 195 <div class='rating-stars text-center'> 196 <ul id='stars'> 197 <li class='star' title='Poor' data-value='1'> 198 <i class='fa fa-star fa-fw'></i> 199 </li> 200 <li class='star' title='Fair' data-value='2'> 201 <i class='fa fa-star fa-fw'></i> 202 </li> 203 <li class='star' title='Good' data-value='3'> 204 <i class='fa fa-star fa-fw'></i> 205 </li> 206 <li class='star' title='Excellent' data-value='4'> 207 <i class='fa fa-star fa-fw'></i> 208 </li> 209 <li class='star' title='WOW!!!' data-value='5'> 210 <i class='fa fa-star fa-fw'></i> 211 </li> 212 </ul> 213 </div> 214 215 </div> 216 </div> 217 218 <div class="form-field"> 219 <label for="Comment.Name">@Translate("Name"): </label> 220 <span>@user.Name</span> 221 <input type="hidden" name="Comment.Name" id="Comment.Name" placeholder="@Translate("Name")" title="@Translate("Name")" value="@(user.Name)" /> 222 </div> 223 <div class="form-field"> 224 <label for="Comment.Email">@Translate("Email"): </label> 225 <span>@user.Email</span> 226 <input type="hidden" class="form-control" name="Comment.Email" id="Comment.Email" placeholder="@Translate("Email")" value="@user.Email" /> 227 </div> 228 229 230 <div class="form-field"> 231 <label for="Comment.Text" class="visually-hidden-focusable">@Translate("Comment")</label> 232 <textarea name="Comment.Text" rows="5" class="form-control" id="Comment.Text" placeholder="@Translate("Comment")"></textarea> 233 </div> 234 235 <div class="form-field"> 236 <input id="btnCreatePost" class="btn btn--primary" type="submit" value="@Translate("Post Comment")" /> 237 </div> 238 </div> 239 </form> 240 241 } 242 else 243 { 244 <form method="post"> 245 <input type="hidden" name="Command" id="Command" value="Delete" /> 246 <div class="comment-form"> 247 <div class="form-field"> 248 <p>@Translate("Already rated", "You have already rated on this product")</p> 249 <p>@Translate("Want to delete your rating", "Do you want to delete your post?")</p> 250 </div> 251 <div style="margin-top:5rem"> 252 <input class="btn btn--outline" type="submit" value="@Translate("Delete Comment")" /> 253 </div> 254 </div> 255 256 </form> 257 258 259 if (HttpContext.Current.Request["Command"] == "Delete") 260 { 261 userComments.ToList().ForEach(x => { x.Delete(); }); 262 HttpContext.Current.Response.Redirect(HttpContext.Current.Request.RawUrl); 263 } 264 265 } 266 } 267 else 268 { 269 <div class="comment-form"> 270 271 @{ 272 var createProfilePageUrl = $"Default.aspx?Id={Pageview.AreaSettings.GetItem("Settings")?.GetString("CreateProfilePageId")}"; 273 } 274 275 <p class="rating-text-container"><b>@Translate("Please login to write a review", "Please login to write a review")</b></p> 276 277 <form method="post" action="@HttpContext.Current.Request.RawUrl"> 278 <input type="hidden" value="@Model" name="ID" /> 279 <input type="hidden" value="Login" name="LoginAction" /> 280 281 <div class="content"> 282 <div class="form-field"> 283 <label for="pageLoginUsername">@Translate("Username", "Username")</label> 284 <input type="text" class="form-control" name="username" id="pageLoginUsername"> 285 </div> 286 <div class="form-field"> 287 <label for="pageLoginPassword">@Translate("Password", "Password")</label> 288 <input type="password" class="form-control" name="password" id="pageLoginPassword"> 289 </div> 290 <div class="form-field"> 291 292 <input type="submit" class="btn btn--primary" value="login"> 293 294 </div> 295 <div class="form-field"> 296 <div class="footer"> 297 <a href="@createProfilePageUrl" class="btn btn--outline margin-bottom-0">@Translate("Create profile", "Create profile")</a> 298 </div> 299 </div> 300 </div> 301 </form> 302 </div> 303 } 304 } 305 306 @{ 307 308 309 310 if (HttpContext.Current.Request["Comment.Command"] == "Create") 311 { 312 HttpContext.Current.Session["commentCommand"] = "Create"; 313 } 314 315 if (HttpContext.Current.Request["Command"] == "Delete") 316 { 317 HttpContext.Current.Session["commentCommand"] = "Delete"; 318 } 319 320 321 if (HttpContext.Current.Request.RequestType == "GET") 322 { 323 if (HttpContext.Current.Session["commentCommand"] != null) 324 { 325 string session = (string)HttpContext.Current.Session["commentCommand"]; 326 327 if (session == "Delete") 328 { 329 <div id="commentNotification" class="review-notification warning">@Translate("Post deleted")!!!</div> 330 } 331 332 if (session == "Create") 333 { 334 <div id="commentNotification" class="review-notification success">@Translate("Post created")!!!</div> 335 } 336 337 HttpContext.Current.Session["commentCommand"] = null; 338 } 339 } 340 } 341 342 343 @SnippetStart("JavaScriptBottom") 344 <script src="/Files/Templates/Designs/Roidmi/assets/scripts/review.js"></script> 345 @SnippetEnd("JavaScriptBottom") 346 347 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 348 349 350 @helper AddtoCartPopup() 351 { 352 <section class="addtocart-popup"> 353 <div class="heading"> 354 <div class="fa-2x text-green"> 355 <i class="fas fa-check-circle"></i> 356 </div> 357 <div class="h4">@Translate("Added to cart", "Added to cart")</div> 358 </div> 359 @{ 360 361 var addToCartImageUrl = string.Format("/Admin/Public/GetImage.ashx?Image={0}&altFmImage_path=/Files/Images/missing_image.jpg&Format=webp&Width=300&Height=300&Crop=0", GetString("Ecom:Product.ImageDefault.Default.Clean")); 362 363 <div class="product"> 364 <div class="image"> 365 <a href="@GetValue("Ecom:Product.Link.Clean")"> 366 <img src="@addToCartImageUrl" alt="@GetValue("Ecom:Product.Name")" class="img-responsive"> 367 </a> 368 </div> 369 <div class="title">@GetValue("Ecom:Product.Name")</div> 370 <div class="price">@GetString("Ecom:Product.Price.CurrencyCode") @GetString("Ecom:Product.Price.Price")</div> 371 </div> 372 } 373 374 @{ 375 var cartPageId = Pageview.AreaSettings.GetItem("Ecommerce")?.GetString("CartPageId") ?? ""; 376 var cartPageUrl = $"Default.aspx?Id={cartPageId}"; 377 } 378 379 <div class="buttons"> 380 <div><a class="btn btn-default btn-close">@Translate("Continue shopping", "Continue shopping")</a></div> 381 <div><a href="@cartPageUrl" class="btn btn--primary">@Translate("Go to shopping cart", "Go to shopping cart")</a></div> 382 </div> 383 </section> 384 385 <section class="addtocart-popup-related mt-3"> 386 @foreach (var group in GetLoop("ProductRelatedGroups")) 387 { 388 <div class="text-center mb-3"> 389 <h4>@group.GetString("Ecom:Product:RelatedGroup.Name")</h4> 390 </div> 391 <div class="ecom-list-pods"> 392 @foreach (var relatedProduct in group.GetLoop("Products").Take(4)) 393 { 394 var image = relatedProduct.GetString("Ecom:Product.ImageDefault.Default.Clean"); 395 396 var imageUrl = string.Format("/Admin/Public/GetImage.ashx?Image={0}&altFmImage_path=/Files/Images/missing_image.jpg&Format=webp&Width=300&Height=300&Crop=0", image); 397 398 var baseURL = "https://" + new Uri(HttpContext.Current.Request.Url.AbsoluteUri).Host; 399 string relatedFriendlyURL = baseURL + Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?id=" + GetPageIdByNavigationTag("AddtoCartPopup")); 400 401 402 string relatedAsyncUrl = relatedFriendlyURL + "?productid=" + relatedProduct.GetString("Ecom:Product.ID") + "&cartcmd=add&redirect=false"; 403 404 string shopPageId = Pageview.AreaSettings.GetItem("Ecommerce").GetString("ShopPageId"); 405 string relatedUri = $"Default.aspx?ID={shopPageId}&ProductID={relatedProduct.GetString("Ecom:Product.ID")}"; 406 407 <div class="ecom-list-pods__item text-center"> 408 <div class="image"> 409 <a href="@relatedUri"><img src="@imageUrl" alt="@relatedProduct.GetValue("Ecom:Product.Name")" class="img-responsive"></a> 410 </div> 411 <div class="title">@relatedProduct.GetValue("Ecom:Product.Name")</div> 412 <div class="price">@relatedProduct.GetString("Ecom:Product.Price.CurrencyCode") @relatedProduct.GetString("Ecom:Product.Price.Price")</div> 413 <div class="footer"> 414 415 <button onclick="asyncAddToCart(this, '@relatedAsyncUrl', '@Translate("Added", "Added")')" class="btn btn--primary"> 416 @Translate("Add_to_cart", "Add to cart") 417 </button> 418 419 </div> 420 </div> 421 } 422 423 </div> 424 425 } 426 </section> 427 } 428 429 @{ 430 var imageSizeLarge = 600; 431 var imageSizeThumb = 120; 432 433 var altImage = GetString("Ecom:Product.ImageAlt_Image.Default.Clean"); 434 var altImageList = GetLoop("ImageCategories").SingleOrDefault(g => g.GetString("Category.SystemName") == "Images")?.GetLoop("Category.Images"); 435 436 437 var missingImagePath = "/Files/Images/missing_image.jpg"; 438 var baseImageUrlFormat = "/Admin/Public/GetImage.ashx?Image={0}&altFmImage_path={1}&Format=webp&Height={2}&DoNotUpscale=1"; 439 var thumbImageUrlFormat = "/Admin/Public/GetImage.ashx?Image={0}&Format=webp&Height={1}&Crop=0"; 440 var standardImagePath = string.Format(baseImageUrlFormat, GetString("Ecom:Product.ImageDefault.Default.Clean"), missingImagePath, imageSizeLarge); 441 var standardImageThumbPath = string.Format(thumbImageUrlFormat, GetString("Ecom:Product.ImageDefault.Default.Clean"), imageSizeThumb); 442 443 var fieldDisplayGroups = GetLoop("FieldDisplayGroups"); 444 445 var Manuals = GetLoop("ImageCategories").SingleOrDefault(x => x.GetString("Category.SystemName") == "Manual")?.GetLoop("Category.Images"); 446 var TechnicalDrawings = GetLoop("ImageCategories").SingleOrDefault(x => x.GetString("Category.SystemName") == "TechnicalDrawings")?.GetLoop("Category.Images"); 447 var Installation = GetLoop("ImageCategories").SingleOrDefault(x => x.GetString("Category.SystemName") == "Installation")?.GetLoop("Category.Images"); 448 var TechnicalSpecifications = GetLoop("ImageCategories").SingleOrDefault(x => x.GetString("Category.SystemName") == "TechnicalSpecifications")?.GetLoop("Category.Images"); 449 var EnergyLabel = GetLoop("ImageCategories").SingleOrDefault(x => x.GetString("Category.SystemName") == "EnergyLabel")?.GetLoop("Category.Images"); 450 var Bruchure = GetLoop("ImageCategories").SingleOrDefault(x => x.GetString("Category.SystemName") == "Bruchure")?.GetLoop("Category.Images"); 451 var UserGuide = GetLoop("ImageCategories").SingleOrDefault(x => x.GetString("Category.SystemName") == "userguide")?.GetLoop("Category.Images"); 452 453 string ManualsURL = GetDownloadsURL(Manuals); 454 string TechnicalDrawingsURL = GetDownloadsURL(TechnicalDrawings); 455 string InstallationURL = GetDownloadsURL(Installation); 456 string TechnicalSpecificationsURL = GetDownloadsURL(TechnicalSpecifications); 457 string EnergyLabelURL = GetDownloadsURL(EnergyLabel); 458 string BrochureURL = GetDownloadsURL(Bruchure); 459 string userguideURL = GetDownloadsURL(UserGuide); 460 461 var downloadUrls = new string[] { ManualsURL, TechnicalDrawingsURL, InstallationURL, TechnicalSpecificationsURL, EnergyLabelURL, BrochureURL }; 462 var hasDownLoadUrl = downloadUrls.Any(x => x.Length > 0); 463 464 //var relatedGroups = GetLoop("ProductRelatedGroups"); 465 466 List<string> Highlights = new List<string>(); 467 468 for (int i = 1; i <= 5; i++) 469 { 470 string highlight = GetString("Ecom:Product:Field.Highlights" + i); 471 472 if (!string.IsNullOrEmpty(highlight)) 473 { 474 Highlights.Add(highlight); 475 } 476 } 477 478 479 //SEO 480 if (string.IsNullOrWhiteSpace(Pageview.Page.Description)) 481 { 482 Pageview.Meta.AddTag("description", GetString("Ecom:Product.MetaDescription")); 483 } 484 if (string.IsNullOrWhiteSpace(Pageview.Page.Keywords)) 485 { 486 Pageview.Meta.AddTag("keywords", GetString("Ecom:Product.MetaKeywords")); 487 } 488 if (string.IsNullOrWhiteSpace(Pageview.Page.MetaTitle)) 489 { 490 Pageview.Meta.Title = GetString("Ecom:Product.MetaTitle"); 491 } 492 if (string.IsNullOrWhiteSpace(Pageview.Page.MetaCanonical)) 493 { 494 Pageview.Meta.AddTag("canonical", GetString("Ecom:Product.Canonical")); 495 } 496 var gaToken = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Settings")?.GetString("GTMToken"); 497 var gtmToken = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Settings")?.GetString("GoogleAnalyticsToken"); 498 } 499 500 @{ 501 var baseurl = "https://" + new Uri(HttpContext.Current.Request.Url.AbsoluteUri).Host; 502 string addToCartPopupURL = baseurl + Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?id=" + GetPageIdByNavigationTag("AddtoCartPopup")); 503 string asyncUrl = addToCartPopupURL + "?productid=" + GetString("Ecom:Product.ID") + "&cartcmd=add&redirect=false"; 504 } 505 506 <div class="ecom-product-detail-grid"> 507 <div class="product__images"> 508 <div class="product__images--default-image"> 509 <img src="@standardImagePath" class="img-responsive" id="ProductStandardImage" /> 510 </div> 511 @if (altImageList != null && altImageList.Any()) 512 { 513 <div class="product__images--thumb-image"> 514 <img src="@standardImageThumbPath" data-src="@standardImagePath" class="img-responsive" /> 515 @foreach (var img in altImageList) 516 { 517 var imgurl = img.GetString("Ecom:Product:Detail.Image.Clean"); 518 var imgUrlLarge = string.Format(baseImageUrlFormat, imgurl, missingImagePath, imageSizeLarge); 519 var imgUrlThumb = string.Format(thumbImageUrlFormat, imgurl, imageSizeThumb); 520 <img src="@imgUrlThumb" data-src="@imgUrlLarge" class="img-responsive" /> 521 } 522 </div> 523 } 524 else if (!string.IsNullOrWhiteSpace(altImage) && System.IO.File.Exists(System.Web.HttpContext.Current.Server.MapPath(altImage))) 525 { 526 <div class="product__images--thumb-image"> 527 <img src="@standardImageThumbPath" data-src="@standardImagePath" class="img-responsive" /> 528 @{ 529 var imgUrlLarge = string.Format(baseImageUrlFormat, altImage, missingImagePath, imageSizeLarge); 530 var imgUrlThumb = string.Format(thumbImageUrlFormat, altImage, imageSizeThumb); 531 <img src="@imgUrlThumb" data-src="@imgUrlLarge" class="img-responsive" /> 532 533 } 534 </div> 535 } 536 </div> 537 <div class="product__info"> 538 @if (GetInteger("Ecom:Product.VariantCount") == 0) 539 { 540 <h1>@GetValue("Ecom:Product.Name")</h1> 541 542 <br /> 543 <div class="product__text"> 544 @*<span class="shortdescription"><small>@GetValue("Ecom:Product.ShortDescription")</small></span>*@ 545 <span class="longdescription">@GetValue("Ecom:Product.ShortDescription")</span> 546 @if (Highlights.Any()) 547 { 548 <div class="product__highlights"> 549 <ul> 550 @foreach (var highlight in Highlights) 551 { 552 <li>@highlight</li> 553 } 554 </ul> 555 </div> 556 } 557 </div> 558 @*if (relatedGroups.Any()) 559 { 560 <div class="product__related"> 561 @foreach (var item in relatedGroups) 562 { 563 var products = item.GetLoop("Products"); 564 <div>@item.GetString("Ecom:Product:RelatedGroup.Name") @products.Count</div> 565 foreach (var product in products) 566 { 567 @product.Template_Tags() 568 @product.GetString("Ecom:Product.LinkGroup") 569 <a href="@product.GetString("Ecom:Product.Link.Clean")">test</a> 570 } 571 } 572 573 </div> 574 }*@ 575 576 <div class="product__price"> 577 @{ 578 var hasInformativePrice = GetDouble("Ecom:Product.InformativePrice.PriceWithVAT.Value") > 0 ? true : false; 579 } 580 581 582 @if (!hasInformativePrice) 583 { 584 <span class="product__price--amount">@GetValue("Ecom:Product.Price.PriceWithVATFormatted")</span> 585 } 586 else 587 { 588 <div> 589 <span class="product__price--amount--before"><s>@GetValue("Ecom:Product.InformativePrice.PriceWithVATFormatted")</s></span> 590 </div> 591 <div> 592 <span class="product__price--amount--sale">@GetValue("Ecom:Product.Price.PriceWithVATFormatted")</span> 593 </div> 594 } 595 </div> 596 597 <div class="stock__state"> 598 599 @if (GetDouble("Ecom:Product.Stock") > 0) 600 { 601 <span class="text-success text-green">@Translate("In Stock")</span> 602 } 603 else 604 { 605 <span class="text-danger">@Translate("Out of stock")</span> 606 } 607 608 </div> 609 610 if (GetDouble("Ecom:Product.Stock") > 0) 611 { 612 613 <div class="product__action"> 614 <form method="post" role="form"> 615 <input type="hidden" name="ID" value="@GetValue("Ecom:Product:Page.ID")" /> 616 <input type="hidden" name="ProductID" value="@GetValue("Ecom:Product.ID")" /> 617 <input type="hidden" name="CartCmd" value="add" /> 618 619 @if (GetPageIdByNavigationTag("AddtoCartPopup") > 0) 620 { 621 if (!string.IsNullOrWhiteSpace(gtmToken) && !string.IsNullOrWhiteSpace(gtmToken)) 622 { 623 <button type="button" onclick="addToCart(this);" class="btn btn--primary" style="width:100%;">@Translate("Add to basket", "Add to basket")</button> 624 } 625 else 626 { 627 <button type="button" onclick="asyncAddToCartAndOpenModal(this, '@asyncUrl');" class="btn btn--primary" style="width:100%;">@Translate("Add to basket", "Add to basket")</button> 628 } 629 } 630 else 631 { 632 if (!string.IsNullOrWhiteSpace(gtmToken) && !string.IsNullOrWhiteSpace(gtmToken)) 633 { 634 <button type="button" onclick="AddToCartGTM(this, @BuildGMTParameterString());" class="btn btn--primary" style="width:100%;">@Translate("Add to basket", "Add to basket")</button> 635 } 636 else 637 { 638 <button type="button" class="btn btn--primary" style="width:100%;">@Translate("Add to basket", "Add to basket")</button> 639 } 640 } 641 642 643 </form> 644 </div> 645 } 646 647 } 648 </div> 649 </div> 650 651 <div class="product__tab--container"> 652 <div class="tabs"> 653 <button class="tab-links " data-targetid="first">@Translate("Specifications")</button> 654 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product.LongDescription"))) 655 { 656 <button class="tab-links" data-targetid="second">@Translate("More Information")</button> 657 } 658 @if (hasDownLoadUrl) 659 { 660 <button class="tab-links" data-targetid="third">@Translate("Downloads")</button> 661 } 662 663 <button class="tab-links" data-targetid="fourth">@Translate("Reviews")</button> 664 665 </div> 666 <div class="tabcontent--container"> 667 <div id="first" class="tab-content active"> 668 @if (fieldDisplayGroups.Any()) 669 { 670 var fdgService = new Dynamicweb.Ecommerce.Products.FieldDisplayGroups.FieldDisplayGroupService(); 671 672 foreach (var fdg in fieldDisplayGroups) 673 { 674 var ofdg = fdgService.GetById(fdg.GetInteger("Ecom:FieldDisplayGroup.ID")); 675 676 if (ofdg.ShopIdsList.Contains(Pageview.Area.EcomShopId)) 677 { 678 679 680 var fields = fdg.GetLoop("Fields"); 681 682 var fieldCount = 0; 683 684 foreach (var field in fields) 685 { 686 if (fieldCount > 0) 687 { 688 break; 689 } 690 691 string val = field.GetString("Ecom:FieldDisplayGroup.Field.Value"); 692 693 if (!string.IsNullOrEmpty(val)) 694 { 695 fieldCount++; 696 } 697 } 698 699 700 if (fieldCount > 0) 701 { 702 <p class="text-bold">@fdg.GetValue("Ecom:FieldDisplayGroup.Name")</p> 703 704 705 <table class="table table-hover"> 706 @{ 707 foreach (var field in fields) 708 { 709 710 var type = field.GetString("Ecom:FieldDisplayGroup.Field.TypeName"); 711 string fieldName = field.GetString("Ecom:FieldDisplayGroup.Field.Name"); 712 string value = field.GetString("Ecom:FieldDisplayGroup.Field.OptionLabel"); 713 714 715 value = String.IsNullOrEmpty(value) ? field.GetString("Ecom:FieldDisplayGroup.Field.Value") : value; 716 717 if (type == "List") 718 { 719 value = value.Replace(",", "<br />"); 720 } 721 722 value = value.Replace(Environment.NewLine, "<br />"); 723 724 725 726 if (!string.IsNullOrEmpty(value)) 727 { 728 <tr class="active"> 729 @{ 730 switch (value) 731 { 732 case "True": 733 value = Translate("Yes"); 734 break; 735 case "False": 736 value = Translate("No"); 737 break; 738 739 case "Ja": 740 value = Translate("Yes"); 741 break; 742 case "Nej": 743 value = Translate("No"); 744 break; 745 } 746 } 747 748 <td class="label">@fieldName</td> 749 <td class="value">@value</td> 750 </tr> 751 } 752 753 754 } 755 } 756 757 </table> 758 } 759 } 760 } 761 } 762 </div> 763 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product.LongDescription"))) 764 { 765 <div id="second" class="tab-content"> 766 @GetString("Ecom:Product.LongDescription") 767 </div> 768 } 769 @if (hasDownLoadUrl) 770 { 771 <div id="third" class="tab-content"> 772 <div class="d-flex flex-wrap"> 773 @if (!string.IsNullOrWhiteSpace(TechnicalDrawingsURL)) 774 { 775 <div class="col-sm-3"> 776 <div class="product-download-box bg-lightgrey my-15"> 777 <div class=""> 778 <a target="_blank" href="@TechnicalDrawingsURL"> 779 <img src="/Files/Templates/Designs/Witt/assets/images/product-downloads/technical_drawings.svg" /> 780 </a> 781 </div> 782 <div class="px-15"> 783 <div class="text-bold">@Translate("Technical Drawing")</div> 784 <div class="text-bold"> 785 <a class="text-bold" download="" target="_blank" href="@TechnicalDrawingsURL"><i class="fas fa-arrow-circle-down"></i> @Translate("Download")</a> 786 </div> 787 </div> 788 789 </div> 790 </div> 791 } 792 793 @if (!string.IsNullOrWhiteSpace(ManualsURL)) 794 { 795 <div class="col-sm-3"> 796 <div class="product-download-box bg-lightgrey my-15"> 797 <div> 798 <a target="_blank" href="@ManualsURL"> 799 <img src="/Files/Templates/Designs/Witt/assets/images/product-downloads/manual.svg" /> 800 </a> 801 </div> 802 <div class="px-15"> 803 <div class="text-bold">@Translate("Manual")</div> 804 <div class="text-bold"> 805 <a class="text-bold" download="" target="_blank" href="@ManualsURL"><i class="fas fa-arrow-circle-down"></i> Download</a> 806 </div> 807 </div> 808 </div> 809 </div> 810 } 811 @if (!string.IsNullOrWhiteSpace(userguideURL)) 812 { 813 <div class="col-sm-3"> 814 <div class="product-download-box bg-lightgrey my-15"> 815 <div> 816 <a target="_blank" href="@userguideURL"> 817 <img src="/Files/Templates/Designs/Witt/assets/images/product-downloads/manual.svg" /> 818 </a> 819 </div> 820 <div class="px-15"> 821 <div class="text-bold">@Translate("User Guide")</div> 822 <div class="text-bold"> 823 <a class="text-bold" download="" target="_blank" href="@userguideURL"><i class="fas fa-arrow-circle-down"></i> Download</a> 824 </div> 825 </div> 826 </div> 827 </div> 828 } 829 @if (!string.IsNullOrWhiteSpace(InstallationURL)) 830 { 831 <div class="col-sm-3"> 832 <div class="product-download-box bg-lightgrey my-15"> 833 <div> 834 <a target="_blank" href="@InstallationURL"> 835 <img src="/Files/Templates/Designs/Witt/assets/images/product-downloads/installation_manual.svg" /> 836 </a> 837 </div> 838 <div class="px-15"> 839 <div class="text-bold">@Translate("Installation Manual")</div> 840 <div class="text-bold"> 841 <a class="text-bold" target="_blank" download="" href="@InstallationURL"><i class="fas fa-arrow-circle-down"></i> Download</a> 842 </div> 843 </div> 844 </div> 845 </div> 846 } 847 @if (!string.IsNullOrWhiteSpace(EnergyLabelURL)) 848 { 849 <div class="col-sm-3"> 850 <div class="product-download-box bg-lightgrey my-15"> 851 <div> 852 <a target="_blank" href="@EnergyLabelURL"> 853 <img src="/Files/Templates/Designs/Witt/assets/images/product-downloads/energy_label.svg" /> 854 </a> 855 </div> 856 <div class="px-15"> 857 <div class="text-bold">@Translate("Energy Label")</div> 858 <div class="text-bold"> 859 <a class="text-bold" target="_blank" download="" href="@EnergyLabelURL"><i class="fas fa-arrow-circle-down"></i> Download</a> 860 </div> 861 </div> 862 </div> 863 </div> 864 } 865 @if (!string.IsNullOrWhiteSpace(TechnicalSpecificationsURL)) 866 { 867 <div class="col-sm-3"> 868 <div class="product-download-box bg-lightgrey my-15"> 869 <div> 870 <a target="_blank" href="@TechnicalSpecificationsURL"> 871 <img src="/Files/Templates/Designs/Witt/assets/images/product-downloads/technical_specifications.svg" /> 872 </a> 873 </div> 874 <div class="px-15"> 875 <div class="text-bold">@Translate("Technical Specifications")</div> 876 <div class="text-bold"> 877 <a class="text-bold" target="_blank" download="" href="@TechnicalSpecificationsURL"><i class="fas fa-arrow-circle-down"></i> Download</a> 878 </div> 879 </div> 880 </div> 881 </div> 882 } 883 @if (!string.IsNullOrWhiteSpace(BrochureURL)) 884 { 885 <div class="col-sm-3"> 886 <div class="product-download-box bg-lightgrey my-15"> 887 <div> 888 <a target="_blank" href="@BrochureURL"> 889 <img src="/Files/Templates/Designs/Witt/assets/images/product-downloads/brochure.svg" /> 890 </a> 891 </div> 892 <div class="px-15"> 893 <div class="text-bold">@Translate("Brochure")</div> 894 <div class="text-bold"> 895 <a class="text-bold" target="_blank" download="" href="@BrochureURL"><i class="fas fa-arrow-circle-down"></i> Download</a> 896 </div> 897 </div> 898 899 </div> 900 </div> 901 } 902 903 </div> 904 </div> 905 } 906 <div id="fourth" class="tab-content"> 907 @RenderComments() 908 </div> 909 <div id="commentModal" class="modal"> 910 911 <!-- Modal content --> 912 <div class="modal-content"> 913 <span class="close">&times;</span> 914 <div> 915 @RenderProductCommentForm() 916 </div> 917 </div> 918 </div> 919 </div> 920 @GetString("Comments.Stars") 921 </div> 922 923 <div id="addtocartModal" class="modal"> 924 <!-- Modal content --> 925 <div class="modal-content"> 926 <span class="close modal-close">&times;</span> 927 <div id="popupcontent"> 928 @AddtoCartPopup() 929 </div> 930 </div> 931 </div> 932 933 934 @SnippetStart("JavaScriptHead") 935 936 @if (!string.IsNullOrWhiteSpace(gtmToken) && !string.IsNullOrWhiteSpace(gtmToken)) 937 { 938 <script> 939 // Measure a view of product details. This example assumes the detail view occurs on pageload, 940 // and also tracks a standard pageview of the details page. 941 dataLayer.push({ ecommerce: null }); // Clear the previous ecommerce object. 942 dataLayer.push({ 943 'ecommerce': { 944 'detail': { 945 'actionField': { 'list': '@System.Web.HttpUtility.JavaScriptStringEncode(Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(GetString("Ecom:Product.PrimaryOrFirstGroupID")).Name)' }, // 'detail' actions have an optional list property. 946 'products': [{ 947 'name': '@System.Web.HttpUtility.JavaScriptStringEncode(GetString("Ecom:Product.Name"))', // Name or ID is required. 948 'id': '@GetString("Ecom:Product.Number")', 949 'price': '@((GetInteger("Ecom:Product.Price.PricePIP") / 100).ToString("F", System.Globalization.CultureInfo.CreateSpecificCulture("en-US")))', 950 'category': '@System.Web.HttpUtility.JavaScriptStringEncode(Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(GetString("Ecom:Product.PrimaryOrFirstGroupID")).Name)' 951 }] 952 } 953 } 954 }); 955 </script> 956 } 957 @SnippetEnd("JavaScriptHead") 958 959 960 @SnippetStart("JavaScriptBottom") 961 962 <script src="/Files/Templates/Designs/Roidmi/assets/scripts/modal.js"></script> 963 964 <script> 965 function addToCart(btn) { 966 asyncAddToCartAndOpenModal(btn, '@asyncUrl'); 967 AddToCartGTMNoSubmit(btn, @BuildGMTParameterString()); 968 } 969 </script> 970 971 972 @SnippetEnd("JavaScriptBottom") 973 974 975 976 977 978 @functions { 979 private string BuildGMTParameterString() 980 { 981 //currencyCode, productName, productId, productPrice, productCategory, quantity 982 var p = GetInteger("Ecom:Product.Price.PricePIP") / 100; 983 return $"'{GetString("Ecom:Product.Price.CurrencyCode")}', '{ System.Web.HttpUtility.JavaScriptStringEncode(GetString("Ecom:Product.Name"))}', '{GetString("Ecom:Product.Number")}', '{p.ToString("F", System.Globalization.CultureInfo.CreateSpecificCulture("en-US"))}', '{System.Web.HttpUtility.JavaScriptStringEncode(Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(GetString("Ecom:Product.PrimaryOrFirstGroupID")).Name)}', 1"; 984 } 985 986 private string GetDownloadsURL(List<LoopItem> items) 987 { 988 var languagecode = Pageview.Area.CultureInfo.TwoLetterISOLanguageName; 989 languagecode = languagecode == "da" ? languagecode = "dk" : languagecode; 990 991 string downloadsUrl = ""; 992 993 if (items != null && items.Count > 0) 994 { 995 if (items.Any(x => x.GetString("Ecom:Product:Detail.Image.Clean").Contains("_" + languagecode))) 996 { 997 foreach (var item in items) 998 { 999 if (item.GetString("Ecom:Product:Detail.Image.Clean").Contains("_" + languagecode)) 1000 { 1001 downloadsUrl = item.GetString("Ecom:Product:Detail.Image.Clean"); 1002 break; 1003 } 1004 } 1005 } 1006 else 1007 { 1008 foreach (var item in items) 1009 { 1010 1011 downloadsUrl = item.GetString("Ecom:Product:Detail.Image.Clean"); 1012 } 1013 } 1014 } 1015 1016 return downloadsUrl; 1017 } 1018 1019 }
Your basket
Your cart is empty
Login
Other languages