Error executing template "Designs/Swift/eCom/ProductCatalog/ProductViewDetail.cshtml"
System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) ---> System.ComponentModel.Win32Exception (0x80004005): The network path was not found
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.Open()
   at Dynamicweb.Data.DatabaseConnectionProvider.CreateConnection(Boolean open)
   at Dynamicweb.Data.Database.CreateConnection()
   at Dynamicweb.Data.Database.CreateDataReader(CommandBuilder commandBuilder, IDbConnection connection, IDbTransaction transaction, Int32 commandTimeout)
   at Dynamicweb.Ecommerce.Products.DetailRepository.GetInheritedDetailsBulk(List`1 productIds, String detailType)
   at Dynamicweb.Ecommerce.Products.DetailService.GetDetailsBulk(IEnumerable`1 productKeys, String detailType, Boolean excludeDefaultImage)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetDefaultImage(MediaViewModelSettings settings, String productId, String languageId, String variantId, Lazy`1 productImages, Lazy`1 details)
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetDefaultImage(MediaViewModelSettings settings, Product product, Lazy`1 productImages, Lazy`1 details)
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass3_2.<BulkCreateView>b__62()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_81e4c9f300324ba988c18cba5103e786.Execute() in D:\dynamicweb.net\Solutions\Nextech\superhome.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\eCom\ProductCatalog\ProductViewDetail.cshtml:line 10
   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()
ClientConnectionId:00000000-0000-0000-0000-000000000000
Error Number:53,State:0,Class:20

1 @inherits ViewModelTemplate<ProductViewModel> 2 @using Dynamicweb.Rendering 3 @using Dynamicweb.Ecommerce.ProductCatalog 4 @using Dynamicweb.Core 5 @using NextechDWAddIn.Common 6 7 @{ 8 string metaDescription = string.IsNullOrEmpty(Model.MetaDescription) ? Model.Name : Model.MetaDescription; 9 10 Pageview.Meta.AddTag($"<meta property=\"og:image\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{Model.DefaultImage.Value}\">"); 11 Pageview.Meta.AddTag($"<meta property=\"og:image:alt\" content=\"{Model.Name}\">"); 12 Pageview.Meta.AddTag($"<meta property=\"og:description\" content=\"{metaDescription}\">"); 13 14 Pageview.Meta.AddTag("twitter:image", Model.DefaultImage.Value); 15 Pageview.Meta.AddTag("twitter:image:alt", Model.Name); 16 Pageview.Meta.AddTag("twitter:description", metaDescription); 17 18 //CS NT..Google tag manager new fields 19 string brand = ""; 20 if (Model.ProductFields != null && Model.ProductFields.Count > 0) 21 { 22 foreach (var p in Model.ProductFields) 23 { 24 if (p.Key == "Brand" && p.Value != null) 25 { 26 brand = p.Value.ToString(); 27 } 28 } 29 } 30 31 string itemCategory = ""; 32 string itemCategory2 = ""; 33 string itemCategory3 = ""; 34 string itemCategory4 = ""; 35 string itemCategory5 = ""; 36 var prodCategories = CommonFunctions.GetProductCategories(Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(Model.PrimaryOrDefaultGroup.Id)); 37 if (prodCategories != null && prodCategories.Count >= 1) 38 { 39 prodCategories.Reverse(); 40 for(int i = 0; i < prodCategories.Count; i++) 41 { 42 if(i == 0) 43 { 44 itemCategory = prodCategories[i]; 45 }else if(i == 1) 46 { 47 itemCategory2 = prodCategories[i]; 48 } 49 else if (i == 2) 50 { 51 itemCategory3 = prodCategories[i]; 52 } 53 else if (i == 3) 54 { 55 itemCategory4 = prodCategories[i]; 56 } 57 else if (i == 4) 58 { 59 itemCategory5 = prodCategories[i]; 60 } 61 } 62 } 63 64 //raptor 65 string userId = Converter.ToString(Pageview.User?.ID); 66 string categoryPathRaptor = CommonFunctions.GetCategoryPath(Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(Model.PrimaryOrDefaultGroup.Id)); 67 } 68 69 @{ 70 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 71 { 72 Dynamicweb.Context.Current.Items["ProductDetails"] = Model; 73 } 74 else 75 { 76 Dynamicweb.Context.Current.Items.Add("ProductDetails", Model); 77 } 78 79 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 80 if (isLazyLoadingForProductInfoEnabled) 81 { 82 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 83 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 84 bool hasVariantId = !string.IsNullOrEmpty(Model.VariantId); 85 string variantIdParam = hasVariantId ? $"/{Model.VariantId}" : ""; 86 string priceFilledProperties = $"Price,PriceFormatted{(showPricesWithVat == "false" && !neverShowVat ? ",PriceWithVat,PriceWithVatFormatted" : "")}"; 87 string productInfoFeed = $@"/dwapi/ecommerce/products/{Model.Id}{variantIdParam} 88 ?UserId={Converter.ToString(Pageview.User?.ID)} 89 &LanguageId={Pageview.Area.EcomLanguageId}&CurrencyCode={Pageview.Area.EcomCurrencyId}&CountryCode={Pageview.Area.EcomCountryCode}&ShopId={Pageview.Area.EcomShopId} 90 &FilledProperties=Id,Price,PriceBeforeDiscount,StockLevel,VariantInfo,NeverOutOfstock,Prices 91 &PriceSettings.ShowPricesWithVat={Pageview.Area.EcomPricesWithVat} 92 &PriceSettings.FilledProperties={priceFilledProperties} 93 &getproductinfo=true"; 94 Dynamicweb.Context.Current.Items["ProductInfoFeed"] = productInfoFeed; 95 96 <script type="module"> 97 swift.LiveProductInfo.init(); 98 </script> 99 } 100 } 101 102 <script> 103 gtag("event", "view_item", { 104 currency: "@Model.Price.CurrencyCode", 105 value: @PriceViewModelExtensions.ToStringInvariant(Model.Price), 106 items: [ 107 { 108 item_id: "@Model.Number", 109 item_name: "@Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(Model.Name)", 110 currency: "@Model.Price.CurrencyCode", 111 price: @PriceViewModelExtensions.ToStringInvariant(Model.Price), 112 item_brand: "@brand", 113 item_category: "@itemCategory", 114 item_category2: "@itemCategory2", 115 item_category3: "@itemCategory3", 116 item_category4: "@itemCategory4", 117 item_category5: "@itemCategory5" 118 } 119 ] 120 }); 121 </script> 122 123 <script> 124 //CS NT 20240729 125 126 function SendRaptorItemVisitEvent(productId, productName, categoryPath, userId) { 127 128 if(CookieScript.instance.currentState().categories.indexOf('targeting') >= 0) 129 { 130 //console.log('SendRaptorItemVisitEvent targeting permission exists'); 131 raptor.push("trackEvent", { p1: "visit", p2: productId, p3: productName, p4: categoryPath }); 132 133 //raptor.trackEvent("visit",productId,productName,categoryPath,"","","","","","","","","","","","","","","","","","","",productId); 134 } 135 } 136 137 SendRaptorItemVisitEvent( "@Model.Number", "@Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(Model.Name)", "@categoryPathRaptor", "@userId"); 138 </script> 139 140 <script> 141 window.addEventListener('load', function (event) { 142 swift.Video.init(); 143 }); 144 </script> 145
Error executing template "Designs/Swift/Paragraph/Swift_ProductDetailsImage.cshtml"
System.ArgumentNullException: Value cannot be null.
Parameter name: source
   at System.Linq.Enumerable.Where[TSource](IEnumerable`1 source, Func`2 predicate)
   at CompiledRazorTemplates.Dynamic.RazorEngine_1c17299e9d864e5e80db08bf6cf738be.Execute() in D:\dynamicweb.net\Solutions\Nextech\superhome.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Paragraph\Swift_ProductDetailsImage.cshtml:line 139
   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.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Frontend 4 @using System.IO 5 @using System.Text.RegularExpressions; 6 7 @functions { 8 public ProductViewModel product { get; set; } = new ProductViewModel(); 9 public string galleryLayout { get; set; } 10 public string[] supportedImageFormats { get; set; } 11 public string[] supportedVideoFormats { get; set; } 12 public string[] supportedDocumentFormats { get; set; } 13 public string[] allSupportedFormats { get; set; } 14 15 public class RatioSettings 16 { 17 public string Ratio { get; set; } 18 public string CssClass { get; set; } 19 public string CssVariable { get; set; } 20 public string Fill { get; set; } 21 } 22 23 public RatioSettings GetRatioSettings(string size = "desktop") 24 { 25 var ratioSettings = new RatioSettings(); 26 27 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 28 ratio = ratio != "0" ? ratio : ""; 29 string cssClass = ratio != "" && ratio != "fill" ? " ratio" : ""; 30 string cssVariable = ratio != "" && ratio != "fill" ? "--bs-aspect-ratio: " + ratio : ""; 31 cssClass = ratio == "fill" && size == "mobile" ? " ratio" : cssClass; 32 cssVariable = ratio == "fill" && size == "mobile" ? "--bs-aspect-ratio: 66%" : cssVariable; 33 34 ratioSettings.Ratio = ratio; 35 ratioSettings.CssClass = cssClass; 36 ratioSettings.CssVariable = cssVariable; 37 ratioSettings.Fill = ratio == "fill" ? " h-100" : ""; 38 39 return ratioSettings; 40 } 41 42 public string GetArrowsColor() 43 { 44 var invertColor = Model.Item.GetBoolean("InvertModalArrowsColor"); 45 var arrowsColor = invertColor ? " carousel-dark" : string.Empty; 46 return arrowsColor; 47 } 48 49 public string GetThumbnailPlacement() 50 { 51 return Model.Item.GetRawValueString("ThumbnailPlacement", "bottom"); 52 } 53 54 public string GetThumbnailRowSettingCss() 55 { 56 switch (GetThumbnailPlacement()) 57 { 58 case "bottom": 59 return "d-flex flex-wrap"; 60 case "left": 61 return "d-flex flex-column order-first"; 62 case "right": 63 return "d-flex flex-column order-last"; 64 default: 65 return "d-flex flex-wrap"; 66 } 67 } 68 69 public Dictionary<string, object> GetVideoParams(MediaViewModel asset, string size) 70 { 71 string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Name; 72 string type = GetVideoType(asset.Value); 73 bool openInModal = Model.Item.GetString("OpenVideoInModal") == "true" ? true : false; 74 bool autoPlay = Model.Item.GetBoolean("VideoAutoPlay"); 75 76 var videoParams = new Dictionary<string, object>(); 77 videoParams.Add("AssetName", asset.Name); 78 videoParams.Add("AssetVideoType", type); 79 videoParams.Add("AssetDisplayName", asset.DisplayName); 80 videoParams.Add("OpenVideoInModal", openInModal); 81 videoParams.Add("VideoAutoPlay", autoPlay); 82 videoParams.Add("Size", size); 83 videoParams.Add("Id", Model.ID); 84 return videoParams; 85 86 } 87 88 public string GetVideoType(string assetValue) 89 { 90 string type = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "youtube" : string.Empty; 91 type = assetValue.IndexOf("vimeo", StringComparison.OrdinalIgnoreCase) >= 0 ? "vimeo" : type; 92 type = string.IsNullOrEmpty(type) ? "selfhosted" : type; 93 94 return type; 95 } 96 97 public string GetYoutubeScreenDump(string assetValue, string quality) 98 { 99 var regex = new Regex(@"(?:youtube\.com\/.*[\?&]v=|youtu\.be\/)([\w-]+)"); 100 Match match = regex.Match(assetValue); 101 string videoId = match.Success ? match.Groups[1].Value : string.Empty; 102 string youtubeThumbnail = $"https://img.youtube.com/vi/{videoId}/{quality}.jpg"; 103 return youtubeThumbnail; 104 } 105 } 106 107 @{ 108 ProductViewModel product = null; 109 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 110 { 111 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 112 } 113 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 114 { 115 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 116 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 117 118 if (productList?.Products is object) 119 { 120 product = productList.Products[0]; 121 } 122 } 123 } 124 125 @if (product is object) 126 { 127 @* Supported formats *@ 128 supportedImageFormats = new string[] { ".jpg", ".jpeg", ".webp", ".png", ".gif", ".bmp", ".tiff" }; 129 supportedVideoFormats = new string[] { "youtu.be", "youtube", "vimeo", ".mp4", ".webm" }; 130 supportedDocumentFormats = new string[] { ".pdf", ".docx", ".xlsx", ".ppt", "pptx" }; 131 allSupportedFormats = supportedImageFormats.Concat(supportedVideoFormats).Concat(supportedDocumentFormats).ToArray(); 132 133 @* Collect the assets *@ 134 var selectedAssetCategories = Model.Item.GetList("ImageAssets")?.GetRawValue().OfType<string>(); 135 bool includeImagePatternImages = Model.Item.GetBoolean("ImagePatternImages"); 136 137 @* Needed image data collection to support both DefaultImage, ImagePatterns and Image Assets *@ 138 string defaultImage = product.DefaultImage != null ? product.DefaultImage.Value : ""; 139 IEnumerable<MediaViewModel> assetsImages = product.AssetCategories.Where(x => selectedAssetCategories.Contains(x.SystemName)).SelectMany(x => x.Assets); 140 assetsImages = assetsImages.OrderByDescending(x => x.Value.Equals(defaultImage)); 141 IEnumerable<MediaViewModel> assetsList = new MediaViewModel[] { }; 142 assetsList = assetsList.Union(assetsImages); 143 assetsList = includeImagePatternImages ? assetsList.Union(product.ImagePatternImages) : assetsList; 144 //CS NT assetsList = includeImagePatternImages && assetsList.Count() == 0 ? assetsList.Append(product.DefaultImage) : assetsList; 145 assetsList = includeImagePatternImages && assetsList.Count() == 0 ? assetsList.Append(product.DefaultImage) : assetsList.Prepend(product.DefaultImage);//CS NT Show primary Image 146 147 148 //assetsList = assetsList.Reverse(); 149 assetsList = assetsList.OrderBy(x => x.DisplayName); 150 151 152 bool defaultImageFallback = Model.Item.GetBoolean("DefaultImageFallback"); 153 bool showOnlyPrimaryImage = Model.Item.GetBoolean("ShowOnlyPrimaryImage"); 154 155 int totalAssets = 0; 156 if (showOnlyPrimaryImage == false) 157 { 158 foreach (MediaViewModel asset in assetsList) 159 { 160 var assetValue = asset.Value; 161 foreach (string format in allSupportedFormats) 162 { 163 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) 164 { 165 totalAssets++; 166 } 167 } 168 } 169 } 170 171 if ((totalAssets == 0 && product.DefaultImage != null && selectedAssetCategories.Count() == 0) || (showOnlyPrimaryImage == true && product.DefaultImage != null) || totalAssets == 0 && defaultImageFallback) 172 { 173 assetsList = new List<MediaViewModel>() { product.DefaultImage }; 174 totalAssets = 1; 175 } 176 177 @* Theme settings *@ 178 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 179 180 var badgeParms = new Dictionary<string, object>(); 181 badgeParms.Add("size", "h5"); 182 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 183 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 184 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 185 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 186 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 187 188 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 189 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 190 DateTime createdDate = product.Created.Value; 191 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 192 showBadges = (newBadgeEnabled && Model.Item.GetInt32("NewPublicationDays") == 0) || (newBadgeEnabled && (createdDate.AddDays(Model.Item.GetInt32("NewPublicationDays")) > DateTime.Now)) ? true : showBadges; 193 showBadges = !string.IsNullOrEmpty(Model.Item.GetRawValueString("CampaignBadges")) ? true : showBadges; 194 195 196 197 //CS NT..Price only and sale sticker.. 198 var PS = new Dynamicweb.Ecommerce.Products.ProductService(); 199 var productObj = PS.GetProductById(product.Id, "", Pageview.Area.EcomLanguageId.ToString()); 200 string discountPercentage = ""; 201 string originalPrice = ""; 202 string onOffer = ""; 203 foreach (var prodCustomField in productObj.ProductFieldValues) 204 { 205 if (prodCustomField.ProductField.SystemName == "DiscountPercentage") 206 { 207 discountPercentage = prodCustomField.Value.ToString(); 208 } 209 if (prodCustomField.ProductField.SystemName == "OriginalPrice") 210 { 211 originalPrice = prodCustomField.Value.ToString(); 212 } 213 if (prodCustomField.ProductField.SystemName == "OnOffer") 214 { 215 onOffer = prodCustomField.Value.ToString(); 216 } 217 } 218 originalPrice = (originalPrice == "0") ? "" : ( onOffer == "Yes" ? "€" + originalPrice : ""); 219 bool onlyMono = string.IsNullOrWhiteSpace(originalPrice) && !string.IsNullOrWhiteSpace(discountPercentage) && discountPercentage.Contains("Super") ? true : false; 220 221 //..CS NT..Price only and sale sticker 222 223 @* Get assets from selected categories or get all assets *@ 224 if (totalAssets != 0) 225 { 226 int assetNumber = 0; 227 int thumbnailNumber = 0; 228 int modalAssetNumber = 0; 229 string thumbnailAxisCss = GetThumbnailPlacement() == "bottom" ? "flex-column" : string.Empty; 230 231 <div class="grid d-flex gap-1 h-100 @(thumbnailAxisCss) @(theme) item_@Model.Item.SystemName.ToLower()"> 232 233 234 235 236 @if (totalAssets > 1 && Pageview.Device.ToString() == "Desktop") 237 { 238 <div class="multiple-thumbs-slick @(GetThumbnailRowSettingCss()) gap-3 g-col" data-col-size="1" id="SmallScreenImagesThumbnails_@Model.ID" style=" max-width: min-content;height: fit-content;visibility:hidden;"> 239 @foreach (MediaViewModel asset in assetsList) 240 { 241 var assetValue = asset.Value; 242 string assetName = asset.Name; 243 assetName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; 244 string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : null; 245 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 246 247 string imagePath = Dynamicweb.Context.Current.Server.UrlEncode(assetValue); 248 imagePath = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "https://img.youtube.com/vi/" + assetValue.Substring(assetValue.LastIndexOf('/') + 1) + "/mqdefault.jpg" : imagePath; 249 //string imagePathThumb = assetValue.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase) ? imagePath.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) < 0 && imagePath.IndexOf(".mp4", StringComparison.OrdinalIgnoreCase) < 0 ? $"/Admin/Public/GetImage.ashx?image={imagePath}&width=180&format=webp" : imagePath : assetValue; 250 string imagePathThumb = assetValue.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase) ? imagePath.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) < 0 && imagePath.IndexOf(".mp4", StringComparison.OrdinalIgnoreCase) < 0 ? $"/Admin/Public/GetImage.ashx?image={imagePath}&width=180&format=jpg" : imagePath : assetValue; //BG-20240724 251 252 RatioSettings ratioSettings = GetRatioSettings("desktop"); 253 254 <div class="border outline-none @(ratioSettings.CssClass) thumbImageNT" data-assetNumber="@thumbnailNumber" style="@(ratioSettings.CssVariable); cursor: pointer; min-width: 5rem; max-width: 5rem;" data-bs-target="#SmallScreenImages_@Model.ID" data-bs-slide-to="@thumbnailNumber"> 255 @foreach (string imageFormat in supportedImageFormats) 256 { //Images 257 if (assetValue.IndexOf(imageFormat, StringComparison.OrdinalIgnoreCase) >= 0) 258 { 259 <img src="@imagePathThumb" alt="@assetName" @assetTitle class="p-0 p-lg-1 w-100 h-100" style="object-fit: contain;"> 260 261 thumbnailNumber++; 262 } 263 } 264 265 @foreach (string videoFormat in supportedVideoFormats) 266 { //Images 267 if (assetValue.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) 268 { 269 270 string type = GetVideoType(asset.Value); 271 272 string videoScreendumpPath = type == "youtube" ? GetYoutubeScreenDump(asset.Value, "mqdefault") : ""; 273 videoScreendumpPath = type == "vimeo" ? string.Empty : videoScreendumpPath; 274 videoScreendumpPath = type == "selfhosted" ? System.Uri.EscapeDataString(asset.Value) : videoScreendumpPath; 275 string videoJsClass = type == "vimeo" ? "js-vimeo-video-thumbnail" : string.Empty; 276 277 <div class="icon-5 position-absolute" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> 278 279 if (type != "selfhosted") 280 { 281 <img src="@videoScreendumpPath" loading="lazy" decoding="async" alt="@assetTitle" @assetTitle class="@videoJsClass mw-100 mh-100" data-asset-value="@asset.Value" style="object-fit: cover;" /> 282 } 283 else 284 { 285 string videoType = Path.GetExtension(asset.Value).ToLower(); 286 287 <video preload="auto" class="h-100 w-100" style="object-fit: contain;"> 288 <source src="@(videoScreendumpPath)#t=0.001" type="video/@videoType.Replace(".", "")"> 289 </video> 290 } 291 292 thumbnailNumber++; 293 } 294 } 295 296 @foreach (string documentFormat in supportedDocumentFormats) 297 { //Images 298 if (assetValue.IndexOf(documentFormat, StringComparison.OrdinalIgnoreCase) >= 0) 299 { 300 <a href="@assetValue" class="ratio ratio-4x3 border outline-none" style="cursor: pointer; min-width: 7rem; max-width: 8rem;" download title="@asset.Value"> 301 @if (asset.Value.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase) >= 0) 302 { 303 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> 304 <div class="icon-3 position-absolute text-light" style="z-index: 1">@ReadFile(iconPath + "download.svg")</div> 305 </div> 306 <img src="@imagePathThumb" alt="@assetName" @assetTitle class="p-0 p-lg-1 mw-100 mh-100" style="object-fit: cover;"> 307 } 308 else 309 { 310 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> 311 <div class="icon-3 position-absolute" style="z-index: 1">@ReadFile(iconPath + "file-text.svg")</div> 312 </div> 313 } 314 </a> 315 316 thumbnailNumber++; 317 } 318 } 319 320 </div> 321 } 322 </div> 323 324 325 <script type="text/javascript"> 326 $(document).ready(function () { 327 328 $('.multiple-thumbs-slick').slick({ 329 infinite: false, 330 slidesToShow: 4, 331 slidesToScroll: 2, 332 vertical: true, 333 verticalSwiping: true, 334 arrows: true, 335 prevArrow:"<button type='button' class='slick-prev'><span class='fa fa-angle-left'></span></button>", 336 nextArrow:"<button type='button' class='slick-next'><span class='fa fa-angle-right'></span></button>", 337 swipeToSlide: true, 338 focusOnSelect: true 339 340 }); 341 342 $('#SmallScreenImagesThumbnails_' + '@Model.ID').css('visibility','inherit'); 343 }); 344 </script> 345 } 346 347 348 349 350 351 <div id="SmallScreenImages_@Model.ID" class="carousel@(GetArrowsColor()) col position-relative g-col" data-col-size="5" data-bs-ride="carousel"> 352 <div class="carousel-inner h-100"> 353 @foreach (MediaViewModel asset in assetsList) 354 { 355 var assetValue = asset.Value; 356 foreach (string format in allSupportedFormats) 357 { 358 if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) 359 { 360 string activeSlide = assetNumber == 0 ? "active" : ""; 361 362 <div class="carousel-item @activeSlide" data-bs-interval="99999"> 363 @{ 364 string size = "mobile"; 365 string imageTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : ""; 366 367 368 <div class="h-100 @(imageTheme)"> 369 @foreach (string imageFormat in supportedImageFormats) 370 { //Images 371 if (assetValue.IndexOf(imageFormat, StringComparison.OrdinalIgnoreCase) >= 0) 372 { 373 if (product is object) 374 { 375 string productName = product.Name; 376 string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; 377 string imageLinkPath = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 378 379 RatioSettings ratioSettings = GetRatioSettings(size); 380 381 var parms = new Dictionary<string, object>(); 382 parms.Add("alt", productName + asset.Keywords); 383 parms.Add("itemprop", "image"); 384 parms.Add("columns", Model.GridRowColumnCount); 385 parms.Add("eagerLoadNewImages", Model.Item.GetBoolean("DisableLazyLoading")); 386 parms.Add("doNotUseGetimage", Model.Item.GetBoolean("DisableGetImage")); 387 if (!string.IsNullOrEmpty(asset.DisplayName)) 388 { 389 parms.Add("title", asset.DisplayName); 390 } 391 392 if (ratioSettings.Ratio == "fill" && galleryLayout != "grid") 393 { 394 parms.Add("cssClass", "w-100 h-100 image-zoom-lg-l-hover"); 395 } 396 else 397 { 398 parms.Add("cssClass", "mw-100 mh-100"); 399 } 400 parms.Add("id","Image_" + product.Id + "_" + assetNumber.ToString());//CS NT 401 string divId = "Image_" + product.Id + "_" + assetNumber.ToString() + "_div"; 402 403 <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" data-bs-toggle="modal" data-bs-target="#modal_@Model.ID"> 404 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide-to="@assetNumber"> 405 <div class="img-zoom-container"> 406 @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, parms) 407 </div> 408 </div> 409 </a> 410 } 411 } 412 } 413 @foreach (string videoFormat in supportedVideoFormats) 414 { //Videos 415 if (assetValue.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) 416 { 417 if (Model.Item.GetString("OpenVideoInModal") == "true") 418 { 419 if (product is object) 420 { 421 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 422 423 string productName = product.Name; 424 productName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; 425 string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; 426 427 RatioSettings ratioSettings = GetRatioSettings(size); 428 429 string type = GetVideoType(asset.Value); 430 431 string videoScreendumpPath = type == "youtube" ? GetYoutubeScreenDump(asset.Value, "maxresdefault") : string.Empty; 432 videoScreendumpPath = type == "selfhosted" ? System.Uri.EscapeDataString(asset.Value) : videoScreendumpPath; 433 string videoJsClass = type == "vimeo" ? "js-vimeo-video-thumbnail" : ""; 434 435 436 <div class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable); cursor: pointer" data-bs-toggle="modal" data-bs-target="#modal_@Model.ID"> 437 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide-to="@assetNumber"> 438 <div class="icon-5 position-absolute" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> 439 @if (type != "selfhosted") 440 { 441 <img src="@videoScreendumpPath" loading="lazy" decoding="async" alt="@productName" @assetTitle class="@videoJsClass mw-100 mh-100" data-asset-value="@asset.Value" style="object-fit: cover;"> 442 } 443 else 444 { 445 string videoType = Path.GetExtension(asset.Value).ToLower(); 446 447 <video preload="auto" class="h-100 w-100" style="object-fit: contain;"> 448 <source src="@(videoScreendumpPath)#t=0.001" type="video/@videoType.Replace(".", "")"> 449 </video> 450 } 451 </div> 452 </div> 453 454 } 455 } 456 else 457 { 458 if (product is object) 459 { 460 var videoParams = GetVideoParams(asset, size); 461 @RenderPartial("Components/VideoPlayer.cshtml", new FileViewModel { Path = asset.Value}, videoParams); 462 463 } 464 } 465 } 466 } 467 @foreach (string documentFormat in supportedDocumentFormats) 468 { //Documents 469 if (assetValue.IndexOf(documentFormat, StringComparison.OrdinalIgnoreCase) >= 0) 470 { 471 if (product is object) 472 { 473 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 474 475 string productName = product.Name; 476 string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; 477 string imageLinkPath = imagePath; 478 479 RatioSettings ratioSettings = GetRatioSettings(size); 480 481 var parms = new Dictionary<string, object>(); 482 parms.Add("alt", productName + asset.Keywords); 483 parms.Add("itemprop", "image"); 484 parms.Add("fullwidth", true); 485 parms.Add("columns", Model.GridRowColumnCount); 486 if (!string.IsNullOrEmpty(asset.DisplayName)) 487 { 488 parms.Add("title", asset.DisplayName); 489 } 490 491 if (ratioSettings.Ratio == "fill" && galleryLayout != "grid") 492 { 493 parms.Add("cssClass", "w-100 h-100 image-zoom-lg-l-hover"); 494 } 495 else 496 { 497 parms.Add("cssClass", "mw-100 mh-100"); 498 } 499 500 <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" download alt="@Translate("Download")"> 501 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> 502 <div class="icon-5 position-absolute" style="z-index: 1">@ReadFile(iconPath + "download.svg")</div> 503 @if (asset.Value.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase) >= 0) 504 { 505 @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, parms) 506 } 507 </div> 508 </a> 509 } 510 511 } 512 } 513 </div> 514 } 515 516 517 </div> 518 assetNumber++; 519 } 520 } 521 } 522 </div> 523 @if (showBadges) 524 { 525 <div class="position-absolute top-0 left-0 p-2 p-lg-3"> 526 @{@RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms)} 527 </div> 528 } 529 530 531 @if(onlyMono) 532 { 533 <div class="position-absolute" style="bottom:0;right:0;"> 534 <img style="width: 60px;" src="/Admin/Public/GetImage.ashx?Width=100&Height=90&Crop=5&DoNotUpscale=True&FillCanvas=True&Image=/Files/Images/General/SUPER LABEL ΜΟΝΟ.png&AlternativeImage=/Images/missing_image.jpg" alt="Only Mono Price" title="" data-image="/Files/Images/SUPER LABEL ΜΟΝΟ.png"> 535 </div> 536 }else if(!string.IsNullOrWhiteSpace(discountPercentage)) 537 { 538 <div class="position-absolute top-0 left-0 stickers-container stickers-container--bottom-right dw-mod"> 539 <div class="stickers-container__tag--sale_ProdPage">@discountPercentage</div> 540 </div> 541 } 542 543 </div> 544 545 546 @if (false && totalAssets > 1) 547 { 548 <div class="@(GetThumbnailRowSettingCss()) gap-3" id="SmallScreenImagesThumbnails_@Model.ID"> 549 @foreach (MediaViewModel asset in assetsList) 550 { 551 var assetValue = asset.Value; 552 string assetName = asset.Name; 553 assetName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; 554 string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : null; 555 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 556 557 string imagePath = Dynamicweb.Context.Current.Server.UrlEncode(assetValue); 558 imagePath = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "https://img.youtube.com/vi/" + assetValue.Substring(assetValue.LastIndexOf('/') + 1) + "/mqdefault.jpg" : imagePath; 559 string imagePathThumb = assetValue.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase) ? imagePath.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) < 0 && imagePath.IndexOf(".mp4", StringComparison.OrdinalIgnoreCase) < 0 ? $"/Admin/Public/GetImage.ashx?image={imagePath}&width=180&format=webp" : imagePath : assetValue; 560 561 RatioSettings ratioSettings = GetRatioSettings("desktop"); 562 563 <div class="border outline-none @(ratioSettings.CssClass) thumbImageNT" data-assetNumber="@thumbnailNumber" style="@(ratioSettings.CssVariable); cursor: pointer; min-width: 5rem; max-width: 5rem;" data-bs-target="#SmallScreenImages_@Model.ID" data-bs-slide-to="@thumbnailNumber"> 564 @foreach (string imageFormat in supportedImageFormats) 565 { //Images 566 if (assetValue.IndexOf(imageFormat, StringComparison.OrdinalIgnoreCase) >= 0) 567 { 568 <img src="@imagePathThumb" alt="@assetName" @assetTitle class="p-0 p-lg-1 w-100 h-100" style="object-fit: contain;"> 569 570 thumbnailNumber++; 571 } 572 } 573 574 @foreach (string videoFormat in supportedVideoFormats) 575 { //Images 576 if (assetValue.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) 577 { 578 579 string type = GetVideoType(asset.Value); 580 581 string videoScreendumpPath = type == "youtube" ? GetYoutubeScreenDump(asset.Value, "mqdefault") : ""; 582 videoScreendumpPath = type == "vimeo" ? string.Empty : videoScreendumpPath; 583 videoScreendumpPath = type == "selfhosted" ? System.Uri.EscapeDataString(asset.Value) : videoScreendumpPath; 584 string videoJsClass = type == "vimeo" ? "js-vimeo-video-thumbnail" : string.Empty; 585 586 <div class="icon-5 position-absolute" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> 587 588 if (type != "selfhosted") 589 { 590 <img src="@videoScreendumpPath" loading="lazy" decoding="async" alt="@assetTitle" @assetTitle class="@videoJsClass mw-100 mh-100" data-asset-value="@asset.Value" style="object-fit: cover;" /> 591 } 592 else 593 { 594 string videoType = Path.GetExtension(asset.Value).ToLower(); 595 596 <video preload="auto" class="h-100 w-100" style="object-fit: contain;"> 597 <source src="@(videoScreendumpPath)#t=0.001" type="video/@videoType.Replace(".", "")"> 598 </video> 599 } 600 601 thumbnailNumber++; 602 } 603 } 604 605 @foreach (string documentFormat in supportedDocumentFormats) 606 { //Images 607 if (assetValue.IndexOf(documentFormat, StringComparison.OrdinalIgnoreCase) >= 0) 608 { 609 <a href="@assetValue" class="ratio ratio-4x3 border outline-none" style="cursor: pointer; min-width: 7rem; max-width: 8rem;" download title="@asset.Value"> 610 @if (asset.Value.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase) >= 0) 611 { 612 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> 613 <div class="icon-3 position-absolute text-light" style="z-index: 1">@ReadFile(iconPath + "download.svg")</div> 614 </div> 615 <img src="@imagePathThumb" alt="@assetName" @assetTitle class="p-0 p-lg-1 mw-100 mh-100" style="object-fit: cover;"> 616 } 617 else 618 { 619 <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> 620 <div class="icon-3 position-absolute" style="z-index: 1">@ReadFile(iconPath + "file-text.svg")</div> 621 </div> 622 } 623 </a> 624 625 thumbnailNumber++; 626 } 627 } 628 629 </div> 630 } 631 </div> 632 } 633 </div> 634 635 @* Modal with slides *@ 636 <div class="modal fade swift_products-details-images-modal" id="modal_@Model.ID" tabindex="-1" aria-labelledby="productDetailsGalleryModalTitle_@Model.ID" aria-hidden="true"> 637 <div class="modal-dialog modal-dialog-centered modal-xl"> 638 <div class="modal-content"> 639 <div class="modal-header visually-hidden"> 640 <h5 class="modal-title" id="productDetailsGalleryModalTitle_@Model.ID">@product.Title</h5> 641 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 642 </div> 643 <div class="modal-body p-2 p-lg-3 h-100"> 644 <div id="ModalCarousel_@Model.ID" class="carousel@(GetArrowsColor()) h-100" data-bs-ride="carousel"> 645 <div class="carousel-inner h-100 @theme"> 646 @foreach (MediaViewModel asset in assetsList) 647 { 648 var assetValue = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; 649 foreach (string supportedFormat in supportedImageFormats.Concat(supportedVideoFormats).ToArray()) 650 { 651 if (assetValue.IndexOf(supportedFormat, StringComparison.OrdinalIgnoreCase) >= 0) 652 { 653 string imagePath = assetValue; 654 string activeSlide = modalAssetNumber == 0 ? "active" : ""; 655 656 var parms = new Dictionary<string, object>(); 657 parms.Add("cssClass", "d-block mw-100 mh-100 m-auto"); 658 parms.Add("fullwidth", true); 659 parms.Add("columns", Model.GridRowColumnCount); 660 661 <div class="carousel-item @activeSlide h-100" data-bs-interval="99999"> 662 @foreach (string imageFormat in supportedImageFormats) 663 { //Images 664 if (assetValue.IndexOf(imageFormat, StringComparison.OrdinalIgnoreCase) >= 0) 665 { 666 @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, parms) 667 } 668 } 669 670 @foreach (string videoFormat in supportedVideoFormats) 671 { //Videos 672 if (assetValue.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) 673 { 674 if (product is object) 675 { 676 var videoParams = GetVideoParams(asset, "modal"); 677 @RenderPartial("Components/VideoPlayer.cshtml", new FileViewModel { Path = asset.Value }, videoParams) 678 } 679 } 680 } 681 </div> 682 modalAssetNumber++; 683 } 684 } 685 } 686 <button class="carousel-control-prev carousel-control-area" type="button" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide="prev"> 687 <span class="carousel-control-prev-icon" aria-hidden="true"></span> 688 <span class="visually-hidden">@Translate("Previous")</span> 689 </button> 690 <button class="carousel-control-next carousel-control-area" type="button" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide="next"> 691 <span class="carousel-control-next-icon" aria-hidden="true"></span> 692 <span class="visually-hidden">@Translate("Next")</span> 693 </button> 694 </div> 695 </div> 696 </div> 697 </div> 698 </div> 699 </div> 700 } 701 else if (Pageview.IsVisualEditorMode) 702 { 703 RatioSettings ratioSettings = GetRatioSettings("desktop"); 704 705 <div class="h-100 @theme"> 706 <div class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)"> 707 <img src="/Files/Images/missing_image.jpg" loading="lazy" decoding="async" class="mh-100 mw-100" style="object-fit: cover;"> 708 </div> 709 </div> 710 } 711 712 713 if(Pageview.Device.ToString() == "Desktop") 714 { 715 <script> 716 $(document).ready(function(){ 717 718 function enableHoverZoom() { 719 $(".carousel-item.active ").hover( 720 function(){ 721 $("#zoomImageResult").css("visibility","visible"); 722 $(".img-zoom-lens").css("visibility","visible"); 723 }, function(){ 724 $("#zoomImageResult").css("visibility","hidden"); 725 $(".img-zoom-lens").css("visibility","hidden"); 726 } 727 ); 728 }; 729 enableHoverZoom(); 730 731 732 imageZoom("Image_@product.Id" + "_0", "zoomImageResult"); 733 $(".img-zoom-lens").css("visibility","hidden"); 734 735 $(".thumbImageNT").on('click', function(event){ 736 imageZoom("Image_@product.Id" + "_" + $(this).attr("data-assetnumber"), "zoomImageResult"); 737 738 enableHoverZoom(); 739 }); 740 741 742 });// end of ready 743 744 window.onload = function() { 745 }; 746 </script> 747 } 748 749 750 } 751 else if (Pageview.IsVisualEditorMode) 752 { 753 <div class="alert alert-dark m-0">@Translate("No products available")</div> 754 } 755 756 757 758

Error executing template "Designs/Swift/Paragraph/Swift_ProductBadges.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_7b30b4f2939043cba1d2ffbb64e19d18.Execute() in D:\dynamicweb.net\Solutions\Nextech\superhome.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Paragraph\Swift_ProductBadges.cshtml:line 72
   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.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Frontend 3 @using Dynamicweb.Content 4 @using Dynamicweb.Ecommerce.ProductCatalog 5 6 @{ 7 ProductViewModel product = null; 8 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 9 { 10 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 11 } 12 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 13 { 14 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 15 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 16 17 if (productList?.Products is object) 18 { 19 product = productList.Products[0]; 20 } 21 } 22 } 23 24 @if (product is object) { 25 var badgeParms = new Dictionary<string, object>(); 26 badgeParms.Add("size", "h7"); 27 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 28 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 29 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 30 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 31 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 32 33 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 34 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 35 horizontalAlign = horizontalAlign == "center" ? "text-center" : horizontalAlign; 36 horizontalAlign = horizontalAlign == "end" ? "text-end" : horizontalAlign; 37 38 Dictionary<string, ParagraphInfoViewModel> badgeConfigurations; 39 List<string> campaignBadgesValues = Model.Item.GetRawValueString("CampaignBadges") != null ? Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList() : new List<string>(); 40 41 if (Dynamicweb.Context.Current.Items.Contains("badgeConfigurations")) 42 { 43 badgeConfigurations = (Dictionary<string, ParagraphInfoViewModel>)Dynamicweb.Context.Current.Items["badgeConfigurations"]; 44 } 45 else 46 { 47 var badgesPage = Pageview.AreaSettings.GetLink("EcommerceBadgesPage") != null ? Pageview.AreaSettings.GetLink("EcommerceBadgesPage").PageId : 0; 48 var allBadges = badgesPage != 0 ? Dynamicweb.Content.Services.Paragraphs.GetParagraphsByPageId(badgesPage) : null; 49 50 badgeConfigurations = new Dictionary<string, ParagraphInfoViewModel>(); 51 foreach (Paragraph badge in allBadges) 52 { 53 var paragraphviewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreateParagraphInfoViewModel(badge); 54 string cssClassName = paragraphviewModel.Item.GetString("CssClassName").Trim().ToLower(); 55 if (!badgeConfigurations.ContainsKey(cssClassName)) 56 { 57 badgeConfigurations.Add(cssClassName, paragraphviewModel); 58 } 59 } 60 Dynamicweb.Context.Current.Items.Add("badgeConfigurations", badgeConfigurations); 61 } 62 63 int badgesCount = 0; 64 if (badgeConfigurations.Any()) 65 { 66 foreach (string campaign in campaignBadgesValues) 67 { 68 if (!string.IsNullOrEmpty(campaign)) 69 { 70 71 FieldValueViewModel availableCampaignsObject; 72 product.ProductFields.TryGetValue("Campaign", out availableCampaignsObject); 73 74 if (availableCampaignsObject != null) 75 { 76 string campaignType = string.Empty; 77 78 if (badgeConfigurations.ContainsKey(campaign)) 79 { 80 ParagraphInfoViewModel paragraphviewModel; 81 if (badgeConfigurations.TryGetValue(campaign, out paragraphviewModel)) 82 { 83 campaignType = paragraphviewModel.Item.GetRawValueString("CampaignType"); 84 } 85 } 86 87 List<FieldOptionValueViewModel> availableCampaigns = (List<FieldOptionValueViewModel>)availableCampaignsObject.Value; 88 89 foreach (FieldOptionValueViewModel availableOption in availableCampaigns) 90 { 91 if (campaignType == availableOption.Value) 92 { 93 badgesCount++; 94 break; 95 } 96 } 97 } 98 } 99 } 100 } 101 102 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 103 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 104 DateTime createdDate = product.Created.Value; 105 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 106 showBadges = (newBadgeEnabled && Model.Item.GetInt32("NewPublicationDays") == 0) || (newBadgeEnabled && (createdDate.AddDays(Model.Item.GetInt32("NewPublicationDays")) > DateTime.Now)) ? true : showBadges; 107 showBadges = (!string.IsNullOrEmpty(Model.Item.GetRawValueString("CampaignBadges")) && badgesCount != 0) ? true : showBadges; 108 109 if (showBadges) 110 { 111 <div class="@badgeSize @horizontalAlign item_@Model.Item.SystemName.ToLower()"> 112 @RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms) 113 </div> 114 } 115 else if (Pageview.IsVisualEditorMode) 116 { 117 <span class="badge bg-success text-light rounded-0">@Translate("Badge example")</span> 118 } 119 } 120 else if (Pageview.IsVisualEditorMode) 121 { 122 <span class="badge bg-success text-light rounded-0">@Translate("Badge example")</span> 123 } 124 125
Error executing template "Designs/Swift/Paragraph/ProductBrand.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_c49857ba78934de2a3a9d7cb90a96a60.Execute() in D:\dynamicweb.net\Solutions\Nextech\superhome.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Paragraph\ProductBrand.cshtml:line 22
   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.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 4 @{ 5 ProductViewModel product = null; 6 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 7 { 8 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 9 } 10 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 11 { 12 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 13 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 14 15 if (productList?.Products is object) 16 { 17 product = productList.Products[0]; 18 } 19 } 20 21 string brand = ""; 22 foreach (var p in product.ProductFields) 23 { 24 if (p.Key == "Brand" && p.Value != null) 25 { 26 brand = p.Value.ToString(); 27 break; 28 } 29 } 30 31 32 //CS NT 33 string productsUrl = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop"); 34 35 } 36 37 @if (product is object) { 38 39 string fontsize = Model.Item.GetRawValueString("Font_Size", "1.25rem"); 40 string brandFontSize = Model.Item.GetRawValueString("BrandSize", "fs-2"); 41 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 42 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 43 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 44 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 45 46 47 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 48 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 49 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 50 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 51 52 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 53 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 54 string order = layout == "horizontal" ? string.Empty : "order-2"; 55 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? "theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 56 theme = GetViewParameter("theme") != null ? GetViewParameterString("theme") : theme; 57 58 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 59 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 60 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 61 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 62 63 string productInfoFeed = ""; 64 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 65 if (isLazyLoadingForProductInfoEnabled) 66 { 67 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 68 { 69 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 70 if (!string.IsNullOrEmpty(productInfoFeed)) 71 { 72 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 73 } 74 } 75 } 76 if (!string.IsNullOrEmpty(brand)) { 77 string brandUrl = productsUrl + "&Brand=[" + brand.Replace("&eacute;","-eacute").Replace("&","%26").Replace(" ","+").Replace("'","%27") + "]"; 78 <div class="@textAlign item_@Model.Item.SystemName.ToLower() brandHeightNT" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 79 80 <div class="@brandFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 81 <!--<a href="/english/products?Brand=@brand" class="product-brand">--> 82 <a href="@brandUrl" class="product-brand"> 83 <span class="product-brand" style="font-size:@fontsize !important">@brand</span> 84 </a> 85 </div> 86 </div> 87 } else { 88 <div class="@textAlign item_@Model.Item.SystemName.ToLower() brandHeightNT" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 89 90 <div class="m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="font-size:@fontsize !important row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 91 <span class="product-brand"></span> 92 </div> 93 </div> 94 } 95 96 } 97 else if (Pageview.IsVisualEditorMode) 98 { 99 <div class="alert alert-dark m-0" role="alert"> 100 <span>@Translate("No products available")</span> 101 </div> 102 } 103
Error executing template "Designs/Swift/Paragraph/Swift_ProductPrice.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_4dd13c80366e43749178b9f16393d5cb.Execute() in D:\dynamicweb.net\Solutions\Nextech\superhome.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Paragraph\Swift_ProductPrice.cshtml:line 37
   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.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 @using NextechDWAddIn.Common 4 5 @{ 6 ProductViewModel product = null; 7 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 8 { 9 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 10 } 11 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 12 { 13 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 14 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 15 16 if (productList?.Products is object) 17 { 18 product = productList.Products[0]; 19 } 20 } 21 22 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 23 bool anonymousUser = Pageview.User == null; 24 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 25 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 26 27 bool productIsDiscontinued = product is object && product.Discontinued; 28 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 29 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 30 31 //CS NT.. 32 string originalPrice = ""; 33 string comparisonPrice = ""; 34 35 if(product != null) 36 { 37 foreach (var pf in product.ProductFields) 38 { 39 if (!string.IsNullOrWhiteSpace(pf.Key) && pf.Value != null && pf.Value.Value != null && !string.IsNullOrWhiteSpace(pf.Value.Value.ToString())) 40 { 41 if (pf.Key == "OriginalPrice") 42 { 43 originalPrice = pf.Value.Value.ToString(); 44 } else if (pf.Key == "ComparisonPrice") 45 { 46 comparisonPrice = CommonFunctions.HandleComparisonPriceAccordingToLaw(pf.Value.Value.ToString()); 47 } 48 } 49 } 50 } 51 //..CS NT 52 53 54 55 bool isProductDetailsPage = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID")) ? true : false; 56 string originalPriceHeight = isProductDetailsPage ? "height:35px;" : "height:25px;"; 57 58 } 59 60 @if (product is object && !hidePrice && !isDiscontinued) { 61 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 62 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 63 64 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-2"); 65 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 66 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 67 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 68 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 69 70 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 71 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 72 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 73 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 74 75 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 76 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 77 string order = layout == "horizontal" ? string.Empty : "order-2"; 78 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? "theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 79 theme = GetViewParameter("theme") != null ? GetViewParameterString("theme") : theme; 80 81 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 82 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 83 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 84 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 85 86 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 87 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 88 89 string priceMin = ""; 90 string priceMax = ""; 91 92 string liveInfoClass = ""; 93 string productInfoFeed = ""; 94 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 95 if (isLazyLoadingForProductInfoEnabled) 96 { 97 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 98 { 99 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 100 if (!string.IsNullOrEmpty(productInfoFeed)) 101 { 102 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 103 } 104 } 105 liveInfoClass = "js-live-info"; 106 } 107 108 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 109 @if (showInformativePrice && product.PriceInformative.Price != 0) 110 { 111 <div class="opacity-50"> 112 <span>@Translate("RRP") </span> 113 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 114 </div> 115 } 116 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 117 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 118 119 120 @if (showPricesWithVat == "false" && !neverShowVat) 121 { 122 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 123 { 124 <span itemprop="price" content="" class="d-none"></span> 125 <span class="text-decoration-line-through js-text-decoration-line-through opacity-75 me-3 text-price js-text-price d-none" data-show-if="LiveProductInfo.product.Price.Price != LiveProductInfo.product.PriceBeforeDiscount.Price"></span> 126 } 127 else 128 { 129 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 130 131 <span itemprop="price" content="@product.Price.PriceWithoutVat" class="d-none"></span> 132 if (product.Price.Price != product.PriceBeforeDiscount.Price) 133 { 134 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 135 } 136 } 137 } 138 else 139 { 140 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 141 { 142 <span itemprop="price" content="" class="d-none"></span> 143 <span class="text-decoration-line-through js-text-decoration-line-through opacity-75 me-3 text-price js-text-price d-none" data-show-if="LiveProductInfo.product.Price.Price != LiveProductInfo.product.PriceBeforeDiscount.Price"></span> 144 } 145 else 146 { 147 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 148 <span itemprop="price" content="@product.Price.Price" class="d-none"></span> 149 if (product.Price.Price != product.PriceBeforeDiscount.Price) 150 { 151 <span class="text-decoration-line-through opacity-75 @order"> 152 <span class="text-price">@beforePrice</span> 153 </span> 154 } 155 } 156 } 157 158 @if (showPricesWithVat == "false" && !neverShowVat) 159 { 160 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 161 { 162 <span class="text-price js-text-price"> 163 <span class="spinner-border" role="status"></span> 164 </span> 165 } 166 else 167 { 168 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 169 170 if (product?.VariantInfo?.VariantInfo != null) 171 { 172 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 173 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 174 } 175 if (priceMin != priceMax) 176 { 177 price = priceMin + " - " + priceMax; 178 } 179 <span class="@theme @contentPadding"> 180 <span class="text-price">@price</span> 181 </span> 182 } 183 } 184 else 185 { 186 187 @*CS NT OriginalPrice.. *@ 188 <div class="@priceFontSize m-0 d-flex @flexDirection @flexGap @horizontalAlign" style="@originalPriceHeight width:100%" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 189 @if(!string.IsNullOrWhiteSpace(originalPrice) && originalPrice != "0") 190 { 191 <span class="" style="/*line-height: 1.7;*/"> 192 <span class="text-decoration-line-through-nt opacity-75 original-price-nt" style="">&nbsp; €@originalPrice &nbsp;</span> 193 </span> 194 } 195 </div> 196 197 @*..CS NT OriginalPrice *@ 198 199 200 201 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 202 { 203 <span class="text-price js-text-price"> 204 <span class="spinner-border" role="status"></span> 205 </span> 206 } 207 else 208 { 209 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 210 price=price.Replace("EUR","€"); 211 212 if (product?.VariantInfo?.VariantInfo != null) 213 { 214 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 215 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 216 } 217 if (priceMin != priceMax) 218 { 219 price = priceMin + " - " + priceMax; 220 } 221 <span class="@theme @contentPadding"> 222 <span class="text-price">@price</span> 223 224 @if(!string.IsNullOrWhiteSpace(comparisonPrice) && comparisonPrice != "0") 225 { 226 <span class="opacity-75" style="font-size:14px;line-height: 2;">€@comparisonPrice</span> 227 } 228 </span> 229 230 } 231 } 232 233 @* Stock state for Schema.org, start *@ 234 @{ 235 Uri url = Dynamicweb.Context.Current.Request.Url; 236 } 237 238 <link itemprop="url" href="@url"> 239 240 @{ 241 bool IsNeverOutOfStock = product.NeverOutOfstock; 242 } 243 244 @if (IsNeverOutOfStock) 245 { 246 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 247 } 248 else 249 { 250 if (product.StockLevel > 0) 251 { 252 <span itemprop="availability" class="d-none">InStock</span> 253 } 254 else 255 { 256 <span itemprop="availability" class="d-none">OutOfStock</span> 257 } 258 } 259 @* Stock state for Schema.org, stop *@ 260 261 </div> 262 263 @if (showPricesWithVat == "false" && !neverShowVat) 264 { 265 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 266 { 267 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 268 } 269 else 270 { 271 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 272 273 if (product?.VariantInfo?.VariantInfo != null) 274 { 275 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 276 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 277 } 278 if (priceMin != priceMax) 279 { 280 price = priceMin + " - " + priceMax; 281 } 282 <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> 283 } 284 } 285 </div> 286 } 287 else if (Pageview.IsVisualEditorMode) 288 { 289 <div class="alert alert-dark m-0" role="alert"> 290 <span>@Translate("No products available")</span> 291 </div> 292 } 293
Error executing template "Designs/Swift/Paragraph/Swift_ProductAddToCart.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_a9485d9c72714da8bccf0211ab992cfe.Execute() in D:\dynamicweb.net\Solutions\Nextech\superhome.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Paragraph\Swift_ProductAddToCart.cshtml:line 107
   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.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Core.Encoders 4 @using NextechDWAddIn.Common 5 6 7 @{ 8 ProductViewModel product = null; 9 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 10 { 11 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 12 } 13 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 14 { 15 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 16 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 17 18 if (productList?.Products is object) 19 { 20 product = productList.Products[0]; 21 } 22 } 23 24 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 25 bool anonymousUser = Pageview.User == null; 26 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 27 bool hideAddToCart = anonymousUsersLimitations.Contains("cart") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHideAddToCart") && isErpConnectionDown; 28 hideAddToCart = Pageview.IsVisualEditorMode ? false : hideAddToCart; 29 30 //CS NT PhoneOrder 31 bool isPhoneOrder = false; 32 if (product.ProductFields != null && product.ProductFields.Count > 0) 33 { 34 foreach (var pf in product.ProductFields) 35 { 36 if (pf.Key == "PhoneOrders" && pf.Value != null && !string.IsNullOrWhiteSpace(pf.Value.ToString())) 37 { 38 isPhoneOrder = pf.Value.ToString() == "1" ? true : false; 39 } 40 } 41 } 42 } 43 44 @if(product is object && isPhoneOrder) 45 { 46 47 string productId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("ProductID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("ProductID") : ""; 48 bool isProductDetailsPage = !string.IsNullOrEmpty(productId); 49 string divStyle = isProductDetailsPage ? "" : "text-align: center"; 50 <div class="w-100" style="@divStyle"> 51 <button id="PhoneOrderBtn" class="PhoneOrderBtnNT"><a href="tel:+77777545"> @Translate("Phone Order") <i class="fas fa-phone"></i></a></button> 52 </div> 53 } 54 else if (product is object && !hideAddToCart) { 55 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 56 horizontalAlign = horizontalAlign == "center" ? "justify-content-center" : horizontalAlign; 57 horizontalAlign = horizontalAlign == "end" ? "justify-content-end" : horizontalAlign; 58 horizontalAlign = horizontalAlign == "full" ? "" : horizontalAlign; 59 60 bool favoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 61 bool quantitySelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowQuantitySelector")) ? Model.Item.GetBoolean("ShowQuantitySelector") : false; 62 bool unitsSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowUnitsSelector")) ? Model.Item.GetBoolean("ShowUnitsSelector") : false; 63 bool hideInventory = !string.IsNullOrEmpty(Model.Item.GetString("HideInventory")) ? Model.Item.GetBoolean("HideInventory") : false; 64 bool hideStockState = !string.IsNullOrEmpty(Model.Item.GetString("HideStockState")) ? Model.Item.GetBoolean("HideStockState") : false; 65 66 string buttonSize = Model.Item.GetRawValueString("ButtonSize", "regular"); 67 string inputSize = string.Empty; 68 69 switch (buttonSize) 70 { 71 case "small": 72 inputSize = " input-group-sm"; 73 buttonSize = " btn-sm"; 74 break; 75 case "regular": 76 buttonSize = string.Empty; 77 break; 78 case "large": 79 inputSize = " input-group-lg"; 80 buttonSize = " btn-lg"; 81 break; 82 } 83 84 string iconPath = "/Files/icons/"; 85 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService")); 86 if (!url.Contains("LayoutTemplate")) 87 { 88 url += url.Contains("?") ? "&LayoutTemplate=Swift_MiniCart.cshtml" : "?LayoutTemplate=Swift_MiniCart.cshtml"; 89 } 90 91 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 92 string disableAddToCart = (product.StockLevel <= 0) ? "disabled" : ""; 93 bool isNeverOutOfStock = product.NeverOutOfstock; 94 disableAddToCart = isNeverOutOfStock && !isLazyLoadingForProductInfoEnabled ? "" : disableAddToCart; 95 96 string whenVariantsExist = Model.Item.GetRawValueString("WhenVariantsExist", "hide"); 97 98 string flexFill = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "flex-fill" : ""; 99 string fullWidth = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "w-100" : ""; 100 string addToCartIcon = Model.Item.GetRawValueString("Icon", iconPath + "shopping-cart.svg"); 101 string addToCartLabel = !addToCartIcon.Contains("_none") ? $"<span class=\"icon-2\">{ReadFile(addToCartIcon)}</span>" : ""; 102 addToCartLabel += !addToCartIcon.Contains("_none") && !Model.Item.GetBoolean("HideButtonText") ? " " : ""; 103 addToCartLabel += !Model.Item.GetBoolean("HideButtonText") ? $"<span class=\"d-none d-md-inline\">{Translate("Add to cart")}</span><span class=\"d-inline d-md-none\">{Translate("Add")}</span>" : ""; 104 105 bool userHasPendingQuote = Dynamicweb.Ecommerce.Common.Context.Cart != null && Dynamicweb.Ecommerce.Common.Context.Cart.IsQuote; 106 107 if (product.VariantInfo.VariantInfo == null || whenVariantsExist == "disable") { 108 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : product.DefaultUnitId; 109 if (string.IsNullOrEmpty(unitId) && product?.UnitOptions != null) { 110 if (product.UnitOptions.FirstOrDefault<UnitOptionViewModel>() != null) { 111 unitId = product.UnitOptions.FirstOrDefault<UnitOptionViewModel>().Id; 112 } 113 } 114 115 double? stepQty = product.PurchaseQuantityStep > 0 ? product.PurchaseQuantityStep : 1; 116 double? minQty = product.PurchaseMinimumQuantity > 0 ? product.PurchaseMinimumQuantity : 1; 117 double? valueQty = minQty > stepQty ? minQty : stepQty; 118 bool isStockType = product.ProductType == Dynamicweb.Ecommerce.Products.ProductType.Stock; 119 bool neverOutOfStock = product.NeverOutOfstock; 120 bool setMaxQty = isStockType && !neverOutOfStock; 121 //CS NT Hide max check. double? maxQty = setMaxQty ? product.StockLevel : null; 122 double? maxQty = null; 123 124 125 126 //CS NT..Google tag manager new fields 127 128 string itemCategory = ""; 129 string itemCategory2 = ""; 130 string itemCategory3 = ""; 131 string itemCategory4 = ""; 132 string itemCategory5 = ""; 133 var prodCategories = CommonFunctions.GetProductCategories(Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(product.PrimaryOrDefaultGroup.Id)); 134 if (prodCategories != null && prodCategories.Count >= 1) 135 { 136 prodCategories.Reverse(); 137 for (int i = 0; i < prodCategories.Count; i++) 138 { 139 if (i == 0) 140 { 141 itemCategory = prodCategories[i]; 142 } 143 else if (i == 1) 144 { 145 itemCategory2 = prodCategories[i]; 146 } 147 else if (i == 2) 148 { 149 itemCategory3 = prodCategories[i]; 150 } 151 else if (i == 3) 152 { 153 itemCategory4 = prodCategories[i]; 154 } 155 else if (i == 4) 156 { 157 itemCategory5 = prodCategories[i]; 158 } 159 } 160 } 161 string brand = ""; 162 if (product.ProductFields != null && product.ProductFields.Count > 0) 163 { 164 foreach (var p in product.ProductFields) 165 { 166 if (p.Key == "Brand" && p.Value != null) 167 { 168 brand = p.Value.ToString(); 169 } 170 } 171 } 172 173 //..CS NT 174 175 176 177 if (unitsSelector && product.UnitOptions.Count > 0) { 178 <form method="post" action="/Default.aspx?ID=@(Pageview.Page.ID)&ProductId=@product.Id" id="UnitSelectorForm_@(product.Id)_@(product.VariantId.Replace(".", "_"))_@Model.ID"> 179 <input type="hidden" name="redirect" value="false"> 180 <input type="hidden" name="VariantID" value="@product.VariantId"> 181 <input type="hidden" name="UnitID" class="js-unit-id" value="@unitId"> 182 </form> 183 } 184 185 <div class="d-flex @horizontalAlign @fullWidth js-input-group item_@Model.Item.SystemName.ToLower()"> 186 <form method="post" action="@url" class="@fullWidth" style="z-index: 1"> 187 <input type="hidden" name="redirect" value="false"> 188 <input type="hidden" name="ProductId" value="@product.Id"> 189 <input type="hidden" name="ProductName" value="@HtmlEncoder.HtmlEncode(product.Name)"> 190 <input type="hidden" name="ProductVariantName" value="@product.VariantName"> 191 <input type="hidden" name="ProductCurrency" value="@Dynamicweb.Ecommerce.Common.Context.Currency.Code"> 192 <input type="hidden" name="ProductPrice" value="@PriceViewModelExtensions.ToStringInvariant(product.Price)"> 193 <input type="hidden" name="ProductReferer" value="component_ProductAddToCart"> 194 <input type="hidden" name="cartcmd" value="add"> 195 196 @*CS NT..*@ 197 <input type="hidden" name="brand" value="@brand"> 198 <input type="hidden" name="itemCategory" value="@itemCategory"> 199 <input type="hidden" name="itemCategory2" value="@itemCategory2"> 200 <input type="hidden" name="itemCategory3" value="@itemCategory3"> 201 <input type="hidden" name="itemCategory4" value="@itemCategory4"> 202 <input type="hidden" name="itemCategory5" value="@itemCategory5"> 203 @*..CS NT*@ 204 205 <input type="submit" class="d-none" onclick="event.preventDefault(); swift.Cart.Update(event)"> @* Fix for enterKey should not redirect to minicart page *@ 206 207 @if (!string.IsNullOrEmpty(product.VariantId)) 208 { 209 <input type="hidden" name="VariantId" value="@product.VariantId"> 210 } 211 212 <template class="js-step-quantity-warning"> 213 <div class="modal-header"> 214 <h1 class="modal-title fs-5">@Translate("The quantity is not valid")</h1> 215 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 216 </div> 217 <div class="modal-body"> 218 @Translate("Please select a quantity that is dividable by") @stepQty 219 </div> 220 </template> 221 222 223 <template class="js-min-quantity-warning"> 224 <div class="modal-header"> 225 <h1 class="modal-title fs-5">@Translate("The product could not be added to the cart")</h1> 226 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 227 </div> 228 <div class="modal-body"> 229 @Translate("The quantity is not valid. You must buy at least") @product.PurchaseMinimumQuantity 230 </div> 231 </template> 232 233 234 @if (userHasPendingQuote) 235 { 236 <input type="hidden" name="PendingQuote" value="true"> 237 238 <template class="js-pending-quote-notice"> 239 <div class="modal-header"> 240 <h1 class="modal-title fs-5">@Translate("Pending Quote")</h1> 241 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="@Translate("Close")"></button> 242 </div> 243 <div class="modal-body"> 244 @Translate("You need to complete your current quote or empty the cart before adding this product to cart.") 245 </div> 246 </template> 247 } 248 249 @if (quantitySelector || (!anonymousUser && product.VariantInfo.VariantInfo != null) || (!anonymousUser && favoritesSelector)) 250 { 251 <input type="hidden" id="Unit_@(product.Id)_@product.VariantId.Replace(".", "_")" name="UnitID" value="@unitId" /> 252 } 253 254 <div class="d-flex flex-row w-100"> 255 @if (!quantitySelector) 256 { 257 <input id="Quantity_@(product.Id)_@product.VariantId.Replace(".", "_")" class="swift_quantity_field" name="Quantity" value="@valueQty" type="hidden" @disableAddToCart> 258 } 259 260 @if (unitsSelector && product.UnitOptions.Count > 0) 261 { 262 string selectedUnitName = !string.IsNullOrEmpty(unitId) && product?.UnitOptions != null ? unitId : product.UnitOptions.FirstOrDefault<UnitOptionViewModel>().Name; 263 264 foreach (var unitOption in product.UnitOptions) 265 { 266 if (unitOption.Id == unitId) 267 { 268 selectedUnitName = unitOption.Name; 269 } 270 } 271 272 <div class="d-flex flex-column gap-2 w-100"> 273 <div class="input-group input-primary-button-group flex-nowrap@(inputSize)"> 274 @if (!anonymousUser && favoritesSelector) 275 { 276 @RenderPartial("Components/ToggleFavorite.cshtml", product) 277 } 278 279 @if (quantitySelector) 280 { 281 <input id="Quantity_@(product.Id)_@product.VariantId.Replace(".", "_")" name="Quantity" value="@valueQty" step="@stepQty" min="@minQty" max="@maxQty" class="form-control swift_quantity-field" style="min-width: 60px; max-width: 100px; z-index: 1" type="number" @disableAddToCart> 282 } 283 284 <button class="btn btn-secondary @flexFill dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> 285 @selectedUnitName 286 </button> 287 288 <ul class="dropdown-menu swift_unit-field"> 289 @foreach (var unitOption in product.UnitOptions) 290 { 291 var selectedUnit = unitOption.Id == unitId ? "selected" : ""; 292 293 <li> 294 <button type="button" class="btn dropdown-item" data-value="@unitOption.Id" onclick="document.querySelector('#UnitSelectorForm_@(product.Id)_@(product.VariantId.Replace(".", "_"))_@Model.ID').querySelector('.js-unit-id').value = this.getAttribute('data-value'); 295 document.querySelector('#Unit_@(product.Id)_@product.VariantId.Replace(".", "_")').value = this.getAttribute('data-value'); 296 swift.PageUpdater.Update(document.querySelector('#UnitSelectorForm_@(product.Id)_@(product.VariantId.Replace(".", "_"))_@Model.ID'))"> 297 <span>@unitOption.Name</span> 298 <span> 299 @if (unitOption.StockLevel > 0 || unitOption.NeverOutOfStock) 300 { 301 if (!Model.Item.GetBoolean("HideInventory") && !unitOption.NeverOutOfStock) 302 { 303 <span class="small text-success">@unitOption.StockLevel @Translate("In stock")</span> 304 } 305 else 306 { 307 <span class="small text-success">@Translate("In stock")</span> 308 } 309 } 310 else 311 { 312 <span class="small text-danger">@Translate("Out of Stock")</span> 313 } 314 </span> 315 </button> 316 </li> 317 } 318 </ul> 319 </div> 320 <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary @(buttonSize) js-add-to-cart-button" style="white-space: nowrap" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)_@Pageview.CurrentParagraph.ID"> 321 @if (!Model.Item.GetBoolean("HideButtonText")) 322 { 323 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 324 @addToCartLabel 325 </span> 326 } 327 else 328 { 329 @addToCartLabel 330 } 331 </button> 332 </div> 333 } 334 else 335 { 336 if (!anonymousUser && favoritesSelector) 337 { 338 @RenderPartial("Components/ToggleFavorite.cshtml", product) 339 } 340 341 <div class="input-group input-primary-button-group flex-nowrap@(inputSize)"> 342 @if (quantitySelector) 343 { 344 <input id="Quantity_@(product.Id)_@product.VariantId.Replace(".", "_")" name="Quantity" value="@valueQty" step="@stepQty" min="@minQty" max="@maxQty" class="form-control swift_quantity-field" style="min-width: 60px; max-width: 100px; z-index: 1" type="number" @disableAddToCart> 345 } 346 347 <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary @(buttonSize) @flexFill js-add-to-cart-button" style="white-space: nowrap" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)_@Pageview.CurrentParagraph.ID"> 348 @if (!Model.Item.GetBoolean("HideButtonText")) 349 { 350 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 351 @addToCartLabel 352 </span> 353 } 354 else 355 { 356 @addToCartLabel 357 } 358 </button> 359 </div> 360 } 361 </div> 362 </form> 363 </div> 364 } else if (whenVariantsExist == "modal") { 365 string ButtonShape = Model.Item.GetRawValueString("VariantButtonShape", "square"); 366 string buttonAspectRatio = Model.Item.GetRawValueString("VariantImageAspectRatio", "56%"); 367 368 string buttonText = Translate("Select"); 369 string variantId = !string.IsNullOrWhiteSpace(product.VariantId) ? product.VariantId : product.DefaultVariantId; 370 371 string variantSelectorServicePageId = !string.IsNullOrEmpty(Model.Item.GetString("VariantSelectorServicePageId")) ? Model.Item.GetLink("VariantSelectorServicePageId").PageId.ToString() : ""; 372 variantSelectorServicePageId = variantSelectorServicePageId != "" ? variantSelectorServicePageId : GetPageIdByNavigationTag("VariantSelectorService").ToString(); 373 374 <div class="d-flex @horizontalAlign w-100 item_@Model.Item.SystemName.ToLower()"> 375 @if (!anonymousUser && favoritesSelector) 376 { 377 @RenderPartial("Components/ToggleFavorite.cshtml", product) 378 } 379 <form action="/Default.aspx?ID=@variantSelectorServicePageId" data-response-target-element="DynamicModalContent" data-preloader="inline" style="z-index: 1" class="@fullWidth"> 380 <input type="hidden" name="ProductID" value="@product.Id"> 381 <input type="hidden" name="VariantID" value="@variantId"> 382 <input type="hidden" name="QuantitySelector" value="@quantitySelector.ToString()"> 383 <input type="hidden" name="HideInventory" value="@hideInventory.ToString()"> 384 <input type="hidden" name="HideStockState" value="@hideStockState.ToString()"> 385 <input type="hidden" name="ButtonLayout" value="@ButtonShape"> 386 <input type="hidden" name="ButtonAspectRatio" value="@buttonAspectRatio"> 387 <input type="hidden" name="VariantSelectorServicePage" value="@variantSelectorServicePageId"> 388 <input type="hidden" name="ViewType" value="ModalContent"> 389 @if (isLazyLoadingForProductInfoEnabled) 390 { 391 @* If lazy loading is enabled, bypass it because we're loading a modal window, so render everything as if it was server-side *@ 392 <input type="hidden" name="getproductinfo" value="true"> 393 } 394 <button type="button" onclick="swift.PageUpdater.Update(event)" class="btn btn-primary@(buttonSize) @fullWidth" title="@Translate("Select")" data-bs-toggle="modal" data-bs-target="#DynamicModal" id="OpenVariantSelectorModal@(product.Id)_@Pageview.CurrentParagraph.ID">@buttonText</button> 395 </form> 396 </div> 397 } 398 } else if (Pageview.IsVisualEditorMode) { 399 <div class="alert alert-dark m-0">@Translate("No products available")</div> 400 } 401
Out of stock
Error executing template "Designs/Swift/Paragraph/Swift_BackInStockNotification.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_0adff8eae4f54351aca0fca4c0f7e659.Execute() in D:\dynamicweb.net\Solutions\Nextech\superhome.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Paragraph\Swift_BackInStockNotification.cshtml:line 46
   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.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using System.Linq 3 @using Dynamicweb.Ecommerce 4 @using Dynamicweb.Ecommerce.ProductCatalog 5 @using Dynamicweb.Ecommerce.Products 6 @using Dynamicweb.Ecommerce.Stocks 7 8 @functions 9 { 10 private static bool BackInStockRegisteredForUser(ProductViewModel product, string unitId = "", long stocklocationId = 0) 11 { 12 if (!Dynamicweb.Security.UserManagement.User.IsExtranetUserLoggedIn()) return false; 13 14 Product productObject = Services.Products.GetProductById(product.Id, product.VariantId, product.LanguageId); 15 StockLocation stockLocation = Services.StockService.GetStockLocation(stocklocationId); 16 double unitStock = productObject.GetUnitStock(stockLocation, unitId); 17 return unitStock <= 0d && ProductBackInStockNotification.BackInStockNotificationExists(productObject, unitId); 18 } 19 } 20 21 @{ 22 ProductViewModel product = null; 23 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 24 { 25 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 26 } 27 else if (Pageview.Page.Item["DummyProduct"] != null) 28 { 29 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 30 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 31 32 if (productList?.Products is object) 33 { 34 product = productList.Products[0]; 35 } 36 } 37 } 38 39 @if ((product is object && product.ProductType == Dynamicweb.Ecommerce.Products.ProductType.Stock)) 40 { 41 bool productInStock = product.StockLevel > 0 || product.NeverOutOfstock; 42 43 if (!productInStock) 44 { 45 string notifiedMessage = Model.Item.GetString("NotifiedMessage"); 46 string notifiedMessageId = $"NotifiedMessage_item_{Model.Item.SystemName.ToLower()}_{product.Id}_{product.VariantId.Replace(".", "_")}"; 47 48 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 49 horizontalAlign = horizontalAlign == "center" ? "justify-content-center" : horizontalAlign; 50 horizontalAlign = horizontalAlign == "end" ? "justify-content-end" : horizontalAlign; 51 horizontalAlign = horizontalAlign == "full" ? "" : horizontalAlign; 52 53 string flexFill = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "flex-fill" : ""; 54 string fullWidth = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "w-100" : ""; 55 56 bool notificationRegisteredForUser = BackInStockRegisteredForUser(product); 57 58 <div class="d-flex flex-row w-100 @horizontalAlign @fullWidth item_@Model.Item.SystemName.ToLower()"> 59 <div class="@horizontalAlign @fullWidth @(notificationRegisteredForUser ? "" : "d-none")" id="@notifiedMessageId"> 60 @notifiedMessage 61 </div> 62 63 @if (!notificationRegisteredForUser) 64 { 65 66 string notifyIcon = Model.Item.GetString("Icon"); 67 string notifyLabel = !notifyIcon.Contains("_none") ? "<span class=\"icon-2\">" + ReadFile(notifyIcon) + "</span>" : ""; 68 notifyLabel += " " + Translate("Notify me when available"); 69 70 string buttonSize = Model.Item.GetRawValueString("ButtonSize", "regular"); 71 string inputSize = string.Empty; 72 73 switch (buttonSize) 74 { 75 case "small": 76 inputSize = " input-group-sm"; 77 buttonSize = " btn-sm"; 78 break; 79 case "regular": 80 buttonSize = string.Empty; 81 break; 82 case "large": 83 inputSize = " input-group-lg"; 84 buttonSize = " btn-lg"; 85 break; 86 } 87 88 string modalId = $"modal_item_{Model.Item.SystemName.ToLower()}_{product.Id}_{product.VariantId.Replace(".", "_")}"; 89 string formId = $"NotificationForm_item_{Model.Item.SystemName.ToLower()}_{product.Id}_{product.VariantId.Replace(".", "_")}"; 90 string notificationButtonId = $"NotificationButton_item_{Model.Item.SystemName.ToLower()}_{product.Id}_{product.VariantId.Replace(".", "_")}"; 91 string notificationOnClick = !Pageview.IsVisualEditorMode ? $"swift.BackInStockNotification.SubmitNotification('{formId}', '{modalId}', '{notifiedMessageId}', '{notificationButtonId}')" : ""; 92 93 string productPage = $"Default.aspx?ID={GetPageIdByNavigationTag("ProductDetailPage")}"; 94 95 <div class="d-flex @horizontalAlign @fullWidth js-input-group"> 96 <div class="input-group input-primary-button-group flex-nowrap@(inputSize)"> 97 <button type="button" class="btn btn-primary @(buttonSize) @flexFill" id="@notificationButtonId" data-bs-toggle="modal" data-bs-target="#@modalId"> 98 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 99 @notifyLabel 100 </span> 101 </button> 102 </div> 103 </div> 104 105 <div class="modal fade" id="@modalId" tabindex="-1" aria-labelledby="label_@modalId" aria-hidden="true"> 106 <div class="modal-dialog modal-dialog-centered"> 107 <div class="modal-content"> 108 <div class="modal-header"> 109 <h5 class="modal-title" id="label_@modalId">@Translate("Back in Stock")</h5> 110 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="@Translate("Close")"></button> 111 </div> 112 <div class="modal-body"> 113 <form name="@product.Id" id="@formId" method="post" action="@productPage"> 114 <input type="hidden" name="ProductID" value="@product.Id" /> 115 <input type="hidden" name="VariantID" value="@product.VariantId" /> 116 <input type="hidden" name="LanguageID" value="@product.LanguageId" /> 117 <input type="hidden" name="CartCmd" value="createnotificationforthisproduct" /> 118 <div class="m-2"> 119 @Translate("Send me an email when the product is in stock.") 120 </div> 121 <div class="form-floating m-2"> 122 <input class="form-control" type="text" id="NotificationEmail" value="@(Pageview.User != null ? Pageview.User.Email : "")" name="NotificationEmail" placeholder="@Translate("Email")" required="required" aria-required="aria-required" /> 123 <label for="NotificationEmail" class="form-label">@Translate("Email")</label> 124 </div> 125 </form> 126 </div> 127 <div class="modal-footer"> 128 <button type="button" class="btn btn-primary" onclick="@notificationOnClick">@Translate("Submit")</button> 129 </div> 130 </div> 131 </div> 132 </div> 133 } 134 </div> 135 } 136 } 137 else if (Pageview.IsVisualEditorMode) 138 { 139 <div class="alert alert-dark m-0">@Translate("Back in stock notification will be shown here")</div> 140 } 141

Product Details

Error executing template "Designs/Swift/Paragraph/Swift_RelatedProducts.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_7c449ec64f92411bb9c389f8a3f95c7c.Execute() in D:\dynamicweb.net\Solutions\Nextech\superhome.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Paragraph\Swift_RelatedProducts.cshtml:line 164
   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.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Core 3 @using Dynamicweb.Ecommerce.ProductCatalog 4 5 @{ 6 ProductViewModel product = null; 7 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 8 { 9 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 10 } 11 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 12 { 13 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 14 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 15 16 if (productList?.Products is object) 17 { 18 product = productList.Products[0]; 19 } 20 } 21 22 string title = Model?.Item?.GetRawValueString("Title", Translate("Products")); 23 string campaignValues = string.Join(",", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 24 25 //Styling 26 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h3"); 27 string subtitleFontSize = Model.Item.GetRawValueString("SubtitleFontSize", "fs-5"); 28 string buttonStyle = Model.Item.GetRawValueString("ButtonStyle", ""); 29 buttonStyle = buttonStyle == "primary" ? " btn-primary" : buttonStyle; 30 buttonStyle = buttonStyle == "secondary" ? " btn-secondary" : buttonStyle; 31 buttonStyle = buttonStyle == "link" ? " btn-link" : buttonStyle; 32 string maxWidth = Model.Item.GetRawValueString("TextReadability", ""); 33 maxWidth = maxWidth == "max-width-on" ? " mw-75ch" : maxWidth; 34 maxWidth = maxWidth == "max-width-off" ? "" : maxWidth; 35 36 string generalTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("GeneralTheme")) ? " theme " + Model.Item.GetRawValueString("GeneralTheme").Replace(" ", "").Trim().ToLower() : ""; 37 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 38 string imageTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : ""; 39 40 //Link generation 41 string pageId = !string.IsNullOrEmpty(Model.Item.GetRawValueString("ProductSliderServicePage")) ? Model.Item.GetLink("ProductSliderServicePage").PageId.ToString() : ""; 42 if (string.IsNullOrEmpty(pageId)) 43 { 44 pageId = GetPageIdByNavigationTag("ProductSliderService").ToString(); 45 } 46 47 string url = "/Default.aspx?ID=" + pageId; 48 if (!url.Contains("LayoutTemplate", StringComparison.OrdinalIgnoreCase)) 49 { 50 url += url.Contains("?") ? "&LayoutTemplate=Designs/Swift/Swift_PageClean.cshtml" : "?LayoutTemplate=Designs/Swift/Swift_PageClean.cshtml"; 51 } 52 if (Pageview.IsVisualEditorMode) 53 { 54 url += "&VisualEdit=True"; 55 } 56 57 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 58 if (isLazyLoadingForProductInfoEnabled) 59 { 60 url += "&getproductinfo=true"; 61 } 62 63 //Source type 64 string sourceType = Model.Item.GetRawValueString("RelationType", "trending"); 65 IList<string> relateFromGroupIds = new List<string> { }; 66 IList<string> relateFromProductVariantIds = new List<string> { }; 67 IList<string> relateFromProductIds = new List<string> { }; 68 bool hasVariants = false; 69 70 //--- VARIANTS --- 71 if (sourceType == "variants" && Model.Item.GetValue<ProductListViewModel>("ProductsToRelateToVariants") is ProductListViewModel productsToRelateToVariants) 72 { 73 foreach (var productSelection in productsToRelateToVariants.Products) 74 { 75 relateFromProductIds.Add(productSelection.Id); 76 } 77 } 78 79 //--- MOST SOLD --- 80 if (sourceType == "most-sold" && Model.Item.GetValue<IList<ProductGroupViewModel>>("GroupsToRelateToMostSold") is IList<ProductGroupViewModel> groupsToRelateToMostSold) 81 { 82 foreach (var fromGroup in groupsToRelateToMostSold) 83 { 84 relateFromGroupIds.Add(fromGroup.Id); 85 } 86 } 87 88 //--- TRENDING --- 89 if (sourceType == "trending" && Model.Item.GetValue<IList<ProductGroupViewModel>>("GroupsToRelateToTrending") is IList<ProductGroupViewModel> groupsToRelateToTrending) 90 { 91 foreach (var fromGroup in groupsToRelateToTrending) 92 { 93 relateFromGroupIds.Add(fromGroup.Id); 94 } 95 } 96 97 //--- LATEST --- 98 if (sourceType == "latest" && Model.Item.GetValue<IList<ProductGroupViewModel>>("GroupsToRelateToLatest") is IList<ProductGroupViewModel> groupsToRelateToLatest) 99 { 100 foreach (var fromGroup in groupsToRelateToLatest) 101 { 102 relateFromGroupIds.Add(fromGroup.Id); 103 } 104 } 105 106 //--- FREQUENTLY BOUGHT --- 107 if (sourceType == "frequently" && Model.Item.GetValue<ProductListViewModel>("ProductsToRelateTo") is ProductListViewModel productsToRelateTo) 108 { 109 foreach (var fromProduct in productsToRelateTo.Products) 110 { 111 relateFromProductIds.Add(fromProduct.Id); 112 } 113 } 114 115 //--- SELECTED PRODUCTS --- 116 if ((sourceType == "selected" || sourceType == "frequently") && Model.Item.GetValue<ProductListViewModel>("Products") is ProductListViewModel products) 117 { 118 hasVariants = products.Products.Any(p => !string.IsNullOrEmpty(p.VariantId)); 119 foreach (var productSelection in products.Products) 120 { 121 if (hasVariants) 122 { 123 if (!string.IsNullOrEmpty(productSelection.VariantId)) 124 { 125 relateFromProductVariantIds.Add($"{productSelection.Id} {productSelection.VariantId}"); 126 } 127 else 128 { 129 relateFromProductVariantIds.Add($"{productSelection.Id}"); 130 } 131 } 132 relateFromProductIds.Add($"{productSelection.Id}"); 133 } 134 } 135 136 //--- RELATED PRODUCTS --- 137 if (sourceType == "related-products" && Model.Item.GetValue<ProductListViewModel>("ProductsToRelateTo2") is ProductListViewModel selectedRelationProduct) 138 { 139 if (selectedRelationProduct.Products.Any()) 140 { 141 product = selectedRelationProduct.Products.FirstOrDefault(); 142 } 143 144 if (product?.RelatedGroups != null) 145 { 146 foreach (var group in product.RelatedGroups) 147 { 148 foreach (var relatedProduct in group.Products) 149 { 150 if (!string.IsNullOrEmpty(relatedProduct.VariantId)) 151 { 152 relateFromProductVariantIds.Add($"{relatedProduct.ProductId} {relatedProduct.VariantId}"); 153 } 154 else 155 { 156 relateFromProductVariantIds.Add($"{relatedProduct.ProductId}"); 157 } 158 } 159 } 160 } 161 } 162 163 //Create group id collection and products id collection strings 164 string groupIds = product is object ? product.PrimaryOrDefaultGroup.Id : string.Join(",", relateFromGroupIds); 165 string productVariantIds = relateFromProductVariantIds.Count > 0 ? string.Join(",", relateFromProductVariantIds) : ""; 166 string productIds = product is object && relateFromProductIds.Count == 0 ? product.Id : string.Join(",", relateFromProductIds); 167 168 //Set the parameters to the url 169 string linkParameters = ""; 170 linkParameters += sourceType != "related-products" && sourceType != "frequently" && sourceType != "selected" ? "&GroupId=" + groupIds : ""; 171 linkParameters += !string.IsNullOrEmpty(productIds) && sourceType != "most-sold" && sourceType != "trending" && sourceType != "latest" && sourceType != "frequently" && sourceType != "related-products" ? "&MainProductId=" + productIds : ""; 172 linkParameters += !string.IsNullOrEmpty(productVariantIds) && sourceType == "related-products" ? "&ProductVariantId=" + productVariantIds : ""; 173 linkParameters += sourceType == "variants" ? "&IsVariant=true" : ""; 174 linkParameters += sourceType == "latest" ? "&SortBy=Created" : ""; 175 linkParameters += sourceType == "most-sold" ? "&SortBy=OrderCount" : ""; 176 linkParameters += sourceType == "trending" ? "&SortBy=OrderCountGrowth" : ""; 177 linkParameters += !string.IsNullOrEmpty(productIds) && sourceType == "frequently" ? $"&BoughtWithProductIds=[{productIds}]" : ""; 178 var productListPageId = GetPageIdByNavigationTag("Shop"); 179 string link = "/Default.aspx?ID=" + productListPageId + linkParameters; 180 181 // Slider settings (documentation: swiffyslider.com/configuration) 182 string navigationStyle = $"{Model.Item.GetRawValueString("NavigationStyle", "slider-nav-round")}"; 183 string navigationPlacement = $"{Model.Item.GetRawValueString("NavigationPlacement", "slider-nav-on-slides")}"; 184 string indicatorStyle = $"{Model.Item.GetRawValueString("IndicatorStyle", "slider-indicators-hidden")}"; 185 string revealSlides = Model.Item.GetRawValueString("RevealSlides", "no-reveal") == "reveal" ? "slider-item-reveal" : string.Empty; 186 string navigationAlwaysVisible = (Model.Item.GetBoolean("NavigationAlwaysVisible")) ? "slider-nav-visible" : string.Empty; 187 string navigationVisibleOnTouch = (Model.Item.GetBoolean("NavigationVisibleOnTouch")) ? "slider-nav-touch" : string.Empty; 188 string navigationShowScrollbar = (Model.Item.GetBoolean("NavigationShowScrollbar")) ? "slider-nav-scrollbar" : string.Empty; 189 string navigationSmall = (Model.Item.GetBoolean("NavigationSmall")) ? "slider-nav-sm" : string.Empty; 190 string navigationInvertColors = (Model.Item.GetBoolean("NavigationInvertColors")) ? "slider-nav-dark" : string.Empty; 191 string navigationSlideEntirePage = (Model.Item.GetBoolean("NavigationSlideEntirePage")) ? "slider-nav-page" : string.Empty; 192 string navigationNoLoop = (Model.Item.GetBoolean("NavigationNoLoop")) ? "slider-nav-noloop" : string.Empty; 193 string indicatorsOutsideSlider = (Model.Item.GetBoolean("IndicatorsOutsideSlider") && indicatorStyle != string.Empty) ? "slider-indicators-outside" : string.Empty; 194 string indicatorsHighlightActive = (Model.Item.GetBoolean("IndicatorsHighlightActive")) ? "slider-indicators-highlight" : string.Empty; 195 string indicatorsInvertColors = (Model.Item.GetBoolean("IndicatorsInvertedColors")) ? "slider-indicators-dark" : string.Empty; 196 string indicatorsVisibleOnSmallDevices = (Model.Item.GetBoolean("IndicatorsVisibleOnSmallDevices")) ? "slider-indicators-sm" : string.Empty; 197 198 bool productsFound = true; 199 if (string.IsNullOrEmpty(groupIds) && string.IsNullOrEmpty(productIds) && string.IsNullOrEmpty(productVariantIds)) 200 { 201 if (Pageview.IsVisualEditorMode) 202 { 203 productIds = product.Id; 204 sourceType = "selected"; 205 } 206 else 207 { 208 productsFound = false; 209 } 210 } 211 } 212 213 @*Container element for the request*@ 214 @if (productsFound) 215 { 216 <form method="post" action="@url" id="RelatedProductsForm_@Model.ID" data-response-target-element="RelatedProducts_@Model.ID" data-preloader="inline" data-update-url="false" class="item_@Model.Item.SystemName.ToLower()"> 217 <input type="hidden" name="ModelID" value="@Model.ID"> 218 <input type="hidden" name="SourceType" value="@sourceType"> 219 220 @*--- SLIDER SETTINGS ---*@ 221 <input type="hidden" name="NavigationStyle" value="@navigationStyle"> 222 <input type="hidden" name="NavigationPlacement" value="@navigationPlacement"> 223 <input type="hidden" name="IndicatorStyle" value="@indicatorStyle"> 224 <input type="hidden" name="RevealSlides" value="@revealSlides"> 225 <input type="hidden" name="NavigationAlwaysVisible" value="@(navigationAlwaysVisible)"> 226 <input type="hidden" name="NavigationVisibleOnTouch" value="@(navigationVisibleOnTouch)"> 227 <input type="hidden" name="NavigationShowScrollbar" value="@(navigationShowScrollbar)"> 228 <input type="hidden" name="NavigationSmall" value="@(navigationSmall)"> 229 <input type="hidden" name="NavigationInvertColors" value="@(navigationInvertColors)"> 230 <input type="hidden" name="NavigationNoLoop" value="@(navigationNoLoop)"> 231 <input type="hidden" name="NavigationSlideEntirePage" value="@(navigationSlideEntirePage)"> 232 <input type="hidden" name="IndicatorsOutsideSlider" value="@(indicatorsOutsideSlider)"> 233 <input type="hidden" name="IndicatorsHighlightActive" value="@(indicatorsHighlightActive)"> 234 <input type="hidden" name="IndicatorsInvertColors" value="@(indicatorsInvertColors)"> 235 <input type="hidden" name="IndicatorsVisibleOnSmallDevices" value="@(indicatorsVisibleOnSmallDevices)"> 236 237 @*--- VARIANTS ---*@ 238 @if (sourceType == "variants") 239 { 240 <input type="hidden" name="isVariant" value="true"> 241 <input type="hidden" name="MainProductID" id="MainProductID_@Model.ID" value="@productIds"> 242 } 243 244 @*--- MOST SOLD ---*@ 245 @if (sourceType == "most-sold") 246 { 247 <input type="hidden" name="SortBy" value="OrderCount"> 248 if (groupIds != "") 249 { 250 <input type="hidden" name="GroupId" value="@groupIds"> 251 } 252 } 253 254 @*--- TRENDING ---*@ 255 @if (sourceType == "trending") 256 { 257 <input type="hidden" name="SortBy" value="OrderCountGrowth"> 258 if (groupIds != "") 259 { 260 <input type="hidden" name="GroupId" value="@groupIds"> 261 } 262 } 263 264 @*--- FREQUENTLY BOUGHT ---*@ 265 @if (sourceType == "frequently" && !string.IsNullOrEmpty(productIds)) 266 { 267 <input type="hidden" name="BoughtWithProductIds" value="[@productIds]"> 268 } 269 @if (sourceType != "frequently" && hasVariants) 270 { 271 <input type="hidden" name="ProductVariantId" value="@productVariantIds"> 272 } 273 274 @*--- LATEST ---*@ 275 @if (sourceType == "latest") 276 { 277 <input type="hidden" name="SortBy" value="Created"> 278 <input type="hidden" name="GroupId" value="@groupIds"> 279 } 280 281 @*--- SELECTED PRODUCTS ---*@ 282 @if (sourceType == "selected" && !string.IsNullOrEmpty(productIds) && !hasVariants) 283 { 284 <input type="hidden" name="MainProductId" id="MainProductID_@Model.ID" value="@productIds"> 285 } 286 @if (sourceType == "selected" && hasVariants) 287 { 288 <input type="hidden" name="ProductVariantId" value="@productVariantIds"> 289 } 290 291 @*--- RELATED PRODUCTS ---*@ 292 @if (sourceType == "related-products") 293 { 294 <input type="hidden" name="ProductVariantId" id="MainProductID_@Model.ID" value="@productVariantIds"> 295 } 296 297 @* General parameters *@ 298 <input type="hidden" name="Link" value="@link"> 299 <input type="hidden" name="HideTitle" value="@Model.Item.GetString("HideTitle")"> 300 301 @if (Model.Item.GetInt32("ProductsCount") != 0) 302 { 303 <input type="hidden" name="PageSize" value="@Model.Item.GetInt32("ProductsCount")"> 304 } 305 <input type="hidden" name="HeadingTitle" id="RelatedProductsTitle_@Model.ID" value="@title"> 306 @if (!string.IsNullOrEmpty(Model.Item.GetString("Subtitle"))) 307 { 308 <input type="hidden" name="Subtitle" value="@Model.Item.GetString("Subtitle")"> 309 } 310 @if (!string.IsNullOrEmpty(Model.Item.GetString("LinkText"))) 311 { 312 <input type="hidden" name="LinkText" value="@Model.Item.GetString("LinkText")"> 313 } 314 @if (!string.IsNullOrEmpty(Model.Item.GetString("ImageAspectRatio"))) 315 { 316 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 317 ratio = ratio != "0" ? ratio : ""; 318 <input type="hidden" name="ImageAspectRatio" value="@ratio"> 319 } 320 @if (!string.IsNullOrEmpty(Model.Item.GetString("Layout"))) 321 { 322 <input type="hidden" name="Layout" value="@Model.Item.GetRawValueString("Layout")"> 323 } 324 @if (titleFontSize != "") 325 { 326 <input type="hidden" name="TitleFontSize" value="@titleFontSize"> 327 } 328 @if (subtitleFontSize != "") 329 { 330 <input type="hidden" name="SubtitleFontSize" value="@subtitleFontSize"> 331 } 332 @if (buttonStyle != "") 333 { 334 <input type="hidden" name="ButtonStyle" value="@buttonStyle"> 335 } 336 @if (generalTheme != "") 337 { 338 <input type="hidden" name="GeneralTheme" value="@generalTheme"> 339 } 340 @if (theme != "") 341 { 342 <input type="hidden" name="Theme" value="@theme"> 343 } 344 @if (imageTheme != "") 345 { 346 <input type="hidden" name="ImageTheme" value="@imageTheme"> 347 } 348 @if (!string.IsNullOrEmpty(Model.Item.GetString("ContentPadding"))) 349 { 350 string contentPadding = Model.Item.GetRawValueString("ContentPadding"); 351 <input type="hidden" name="ContentPadding" value="@contentPadding"> 352 } 353 <input type="hidden" name="TextReadability" value="@maxWidth"> 354 <input type="hidden" name="ParentColumnSize" id="ParentColumnSize_@Model.ID" value="12"> 355 356 <input type="hidden" name="SaleBadgeType" value="@Model.Item.GetRawValue("SaleBadgeType")"> 357 <input type="hidden" name="SaleBadgeCssClassName" value="@Model.Item.GetRawValue("SaleBadgeDesign")"> 358 <input type="hidden" name="NewBadgeCssClassName" value="@Model.Item.GetRawValue("NewBadgeDesign")"> 359 <input type="hidden" name="NewPublicationDays" value="@Model.Item.GetInt32("NewPublicationDays")"> 360 361 @if (campaignValues != string.Empty) 362 { 363 <input type="hidden" name="CampaignBadgesValues" value="@campaignValues"> 364 } 365 </form> 366 367 <script type="module" src="/Files/Templates/Designs/Swift/Assets/js/swiffy-slider.js"></script> 368 <script> 369 window.addEventListener("load", () => { 370 swift.AssetLoader.Load('/Files/Templates/Designs/Swift/Assets/css/swiffy-slider.min.css', 'css'); 371 }); 372 </script> 373 374 if (Pageview.IsVisualEditorMode) 375 { 376 <div class="alert alert-info" role="alert"> 377 <span>@Translate("Product slider: Edit this column to configure")</span> 378 </div> 379 } 380 381 if (sourceType != "related-products") 382 { 383 <div class="w-100 h-100"> 384 <div id="@Model.ID" class="user-select-none" style="scroll-margin-top:var(--header-height,150px)"></div> 385 <div id="RelatedProducts_@Model.ID" class="h-100 swift_product_slider_container"></div> 386 </div> 387 } 388 else if (product?.RelatedGroups != null) 389 { 390 @* Create multiple slider containers, if type is Product relation *@ 391 <div class="grid w-100 h-100@(generalTheme)" style="grid-row-gap: 4rem"> 392 <div id="@Model.ID" class="user-select-none" style="scroll-margin-top:var(--header-height,150px)"></div> 393 @foreach (var group in product.RelatedGroups) 394 { 395 <div id="RelatedProducts_@(Model.ID)_@group.Id" class="g-col-12 h-100 swift_product_slider_container"></div> 396 } 397 </div> 398 } 399 400 @* Initialize *@ 401 if (sourceType != "related-products") 402 { 403 <script type="module"> 404 if (document.querySelector("#RelatedProducts_@Model.ID").closest("[data-col-size]")) { 405 document.querySelector("#ParentColumnSize_@Model.ID").value = document.querySelector("#RelatedProducts_@Model.ID").closest("[data-col-size]").getAttribute("data-col-size"); 406 } 407 swift.PageUpdater.Update(document.querySelector("#RelatedProductsForm_@Model.ID")).then(function () { 408 setTimeout(function() { 409 const isVisualEditor = @(Converter.ToString(Pageview.IsVisualEditorMode).ToLowerInvariant()); 410 const productSliderContainer = document.querySelector(".swift_product_slider_container"); 411 412 if (productSliderContainer && productSliderContainer.innerHTML !== "") { 413 productSliderContainer.classList.remove("d-none"); 414 } 415 else if (!isVisualEditor) { 416 productSliderContainer.closest("[class*=column]").classList.add("d-none"); 417 } 418 }, 150); 419 }); 420 </script> 421 } 422 else if (product?.RelatedGroups != null) 423 { 424 @* Create multiple sliders, if type is Product relation *@ 425 foreach (var group in product.RelatedGroups) 426 { 427 IList<string> fromProductIds = new List<string> { }; 428 429 foreach (var relatedProduct in group.Products) 430 { 431 if (!string.IsNullOrEmpty(relatedProduct.VariantId)) 432 { 433 fromProductIds.Add($"{relatedProduct.ProductId} {relatedProduct.VariantId}"); 434 } 435 else 436 { 437 fromProductIds.Add($"{relatedProduct.ProductId}"); 438 } 439 } 440 <script type="module"> 441 document.querySelector("#ParentColumnSize_@Model.ID").value = document.querySelector("#RelatedProducts_@(Model.ID)_@group.Id").closest("[data-col-size]").getAttribute("data-col-size"); 442 document.querySelector("#MainProductID_@Model.ID").value = "@string.Join(",", fromProductIds)"; 443 document.querySelector("#RelatedProductsTitle_@Model.ID").value = "@group.Name"; 444 document.querySelector("#RelatedProductsForm_@Model.ID").setAttribute("data-response-target-element", "RelatedProducts_@(Model.ID)_@group.Id"); 445 446 swift.PageUpdater.Update(document.querySelector("#RelatedProductsForm_@Model.ID")); 447 </script> 448 } 449 } 450 } 451
Error executing template "/Designs/Swift/Paragraph/PreviouslyViewed_ProductPage_Carousel.cshtml"
System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) ---> System.ComponentModel.Win32Exception (0x80004005): The network path was not found
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.Open()
   at Dynamicweb.Data.DatabaseConnectionProvider.CreateConnection(Boolean open)
   at Dynamicweb.Data.Database.CreateConnection()
   at Dynamicweb.Data.Database.CreateDataReader(CommandBuilder commandBuilder, IDbConnection connection, IDbTransaction transaction, Int32 commandTimeout)
   at Dynamicweb.Ecommerce.Products.ProductRepository.GetProductsBySql(CommandBuilder query, Boolean doRefactoring, Boolean bulkFill, Boolean useAssortments)
   at Dynamicweb.Ecommerce.Products.ProductService.GetByProductIDs(String[] productIds, Boolean doRefactoring, String productLanguageId, Boolean bulkFill, Boolean useAssortments)
   at CompiledRazorTemplates.Dynamic.RazorEngine_fbe304534a4a4ae6a6d4cd8392b98c59.Execute() in D:\dynamicweb.net\Solutions\Nextech\superhome.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\Paragraph\PreviouslyViewed_ProductPage_Carousel.cshtml:line 72
   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()
ClientConnectionId:00000000-0000-0000-0000-000000000000
Error Number:53,State:0,Class:20

1 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2 3 @using System.Linq; 4 @using System.Web; 5 @using Dynamicweb.Core; 6 @using System; 7 @using System.Web; 8 @using System.Collections.Generic; 9 @using Dynamicweb.Rapido.Blocks.Components.General; 10 @using Dynamicweb.Rapido.Blocks; 11 @using Dynamicweb.Rapido.Services; 12 @using RaptorRecommendation.Recommendations; 13 @using NextechDWAddIn.Common; 14 @using Dynamicweb.Security.UserManagement; 15 @using Dynamicweb.Environment; 16 @using System.Globalization 17 @using NextechDWAddIn.Helpers 18 @using Dynamicweb.Ecommerce.ProductCatalog 19 @using Dynamicweb.Core.Encoders 20 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 21 @using Dynamicweb.Ecommerce 22 @using Dynamicweb.Caching 23 @using Dynamicweb 24 @using Dynamicweb.Ecommerce.Products 25 26 @{ 27 28 29 //Standard Swift to get the product object.. 30 ProductViewModel productVM = null; 31 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 32 { 33 productVM = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 34 } 35 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 36 { 37 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 38 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 39 40 if (productList?.Products is object) 41 { 42 productVM = productList.Products[0]; 43 } 44 } 45 //..Standard Swift to get the product object 46 47 48 //https://doc.dynamicweb.com/forum/ecommerce-standard-features/ecommerce-standard-features/recently-viewed-products-list-is-not-populated 49 //First in your product detail template add a string array to session: 50 IEnumerable<Product> youHaveSeenTheseProductsList = null; 51 if (Context.Current.Session["youHaveSeenTheseProductsList"] is null && productVM != null) 52 { 53 Context.Current.Session.Add("youHaveSeenTheseProductsList", new string[] { productVM.Id }); 54 } 55 else 56 { 57 var productIds = ((string[])Dynamicweb.Context.Current.Session["youHaveSeenTheseProductsList"]).ToList(); 58 /* 59 foreach (var pId in productIds) 60 { 61 Logger.Instance.Log(ErrorLevel.DebugInfo, "PreviouslyViewed_ProductPage_Carousel.cshtml pId: " + pId); 62 } 63 */ 64 productIds.Add(productVM.Id); 65 Context.Current.Session["youHaveSeenTheseProductsList"] = productIds.ToArray(); 66 } 67 68 //And then fetch them something like this: 69 if (Context.Current.Session["youHaveSeenTheseProductsList"] != null) 70 { 71 var productIds = (string[])Dynamicweb.Context.Current.Session["youHaveSeenTheseProductsList"]; 72 youHaveSeenTheseProductsList = Dynamicweb.Ecommerce.Services.Products.GetByProductIDs(productIds, false, Dynamicweb.Ecommerce.Common.Context.LanguageID, true, true); 73 } 74 75 76 77 78 79 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService")); 80 string isGuestUser = Pageview.User != null ? "0" : "1"; 81 82 //CS NT The path to the tutorial 83 //https://www.jqueryscript.net/slider/Fully-Responsive-Flexible-jQuery-Carousel-Plugin-slick.html 84 //Good slick example 85 //https://codepen.io/vilcu/pen/ZQwdGQ 86 87 88 //bool showCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToCartButton"); 89 90 string currentLanguageTwoLetter = ExecutingContext.GetCulture(true).TwoLetterISOLanguageName; 91 string baseCategoryBasedOnLanguage = "/Default.aspx?ID=" + CommonFunctions.GetPageIdByNavigationTag("Shop",currentLanguageTwoLetter) + "&"; 92 93 94 95 var PS = new Dynamicweb.Ecommerce.Products.ProductService(); 96 string imagePrefix = "/Admin/Public/GetImage.ashx?width=150&amp;height=150&amp;crop=5&FillCanvas=True&DoNotUpscale=true&amp;Compression=75&amp;image="; 97 98 var shopId = string.Empty; 99 if (Pageview != null && Pageview.Area != null) 100 { 101 shopId = Pageview.Area.EcomShopId; 102 } 103 104 string productId = productVM != null ? productVM.Id : ""; 105 //Previously Viewed 106 string CarouselID1 = "3"; 107 string CarouselDetails1 = Translate("Previously Viewed"); 108 string SliderDescription1 = "slider slider-nav"; 109 110 List<string> finalIds1 = new List<string>(); 111 112 bool skipLoop = false;//CS NT if the only item is the current item then skip loop 113 foreach (LoopItem loopProd in GetLoop("eCom:Related.YouHaveSeenTheseProducts")) 114 { 115 if((GetLoop("eCom:Related.YouHaveSeenTheseProducts").Count == 1) && (loopProd.GetString("Ecom:Product.ID") == GetString("Ecom:Product.ID"))) 116 { 117 skipLoop = true; 118 }else 119 { 120 finalIds1.Add(loopProd.GetString("Ecom:Product.ID")); 121 } 122 } 123 if (youHaveSeenTheseProductsList != null && youHaveSeenTheseProductsList.Count() > 0) 124 { 125 foreach (var tP in youHaveSeenTheseProductsList) 126 { 127 if((youHaveSeenTheseProductsList.Count() == 1) && (productVM.Id == tP.Id)) 128 { 129 skipLoop = true; 130 }else 131 { 132 finalIds1.Add(tP.Id); 133 } 134 } 135 } 136 string[] arrayOfIDs1 = finalIds1.ToArray(); 137 138 139 140 141 142 int maxItemsToShow = 16; 143 int prodsCounter = 0; 144 int prodsCounter1 = 0; 145 146 var cartLoop = Dynamicweb.Ecommerce.Common.Context.Cart != null && Dynamicweb.Ecommerce.Common.Context.Cart.OrderLines != null ? Dynamicweb.Ecommerce.Common.Context.Cart.OrderLines : null; 147 int newBadgePublicationDays = CommonFunctions.GetNewBadgePublicationDays(); 148 } 149 150 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 151 152 @using System.Linq; 153 @using System.Web; 154 @using Dynamicweb.Core; 155 @using System; 156 @using System.Web; 157 @using System.Collections.Generic; 158 @using Dynamicweb.Rapido.Blocks.Components.General; 159 @using Dynamicweb.Rapido.Blocks; 160 @using Dynamicweb.Rapido.Services; 161 @using RaptorRecommendation.Recommendations; 162 @using NextechDWAddIn.Common; 163 @using Dynamicweb.Security.UserManagement; 164 @using Dynamicweb.Environment; 165 @using System.Globalization 166 @using NextechDWAddIn.Helpers 167 @using Dynamicweb.Ecommerce.ProductCatalog 168 @using Dynamicweb.Core.Encoders 169 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 170 171 @{ 172 } 173 174 175 @helper RenderAddToCartNT(Dynamicweb.Ecommerce.Products.Product product) 176 { 177 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService")); 178 string variantName = Dynamicweb.Ecommerce.Services.Variants.GetVariantName(product.VariantId); 179 bool anonymousUser = Pageview.User == null; 180 //string showLoginModalOrAddToCart = anonymousUser ? "showLoginModal();" : "swift.Cart.Update(event)"; 181 string showLoginModalOrAddToCart = "swift.Cart.Update(event)"; 182 //bool favoritesSelector = true; 183 string PageviewCurrentParagraphID = (Pageview != null && Pageview.CurrentParagraph != null) ? Pageview.CurrentParagraph.ID.ToString() : ""; 184 //string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : product.DefaultUnitId; 185 string unitId = product.DefaultUnitId; 186 187 188 189 //CS NT..Google tag manager new fields 190 191 string itemCategory = ""; 192 string itemCategory2 = ""; 193 string itemCategory3 = ""; 194 string itemCategory4 = ""; 195 string itemCategory5 = ""; 196 197 string shopId = (Pageview is object && Pageview != null) ? Pageview.Area.EcomShopId : ""; 198 var defaultProductGroup = product.GetDefaultGroupByShopId(shopId); 199 string PrimaryOrDefaultGroupId = defaultProductGroup != null ? defaultProductGroup.Id : ""; 200 201 202 var prodCategories = CommonFunctions.GetProductCategories(Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(PrimaryOrDefaultGroupId)); 203 if (prodCategories != null && prodCategories.Count >= 1) 204 { 205 prodCategories.Reverse(); 206 for (int i = 0; i < prodCategories.Count; i++) 207 { 208 if (i == 0) 209 { 210 itemCategory = prodCategories[i]; 211 } 212 else if (i == 1) 213 { 214 itemCategory2 = prodCategories[i]; 215 } 216 else if (i == 2) 217 { 218 itemCategory3 = prodCategories[i]; 219 } 220 else if (i == 3) 221 { 222 itemCategory4 = prodCategories[i]; 223 } 224 else if (i == 4) 225 { 226 itemCategory5 = prodCategories[i]; 227 } 228 } 229 } 230 231 //..CS NT 232 233 bool isPhoneOrder = false; 234 string brand = ""; 235 if (product.ProductFieldValues != null && product.ProductFieldValues.Count > 0) 236 { 237 foreach (var pf in product.ProductFieldValues) 238 { 239 if (pf.ProductField.Name == "PhoneOrders" && pf.Value != null && !string.IsNullOrWhiteSpace(pf.Value.ToString())) 240 { 241 isPhoneOrder = pf.Value.ToString() == "1" ? true : false; 242 } 243 else if (pf.ProductField.Name == "Brand" && pf.Value != null && !string.IsNullOrWhiteSpace(pf.Value.ToString())) 244 { 245 brand = pf.Value.ToString(); 246 } 247 } 248 } 249 250 if (isPhoneOrder) 251 { 252 253 <div class="w-100" style="text-align: center;"> 254 <button id="PhoneOrderBtn" class="PhoneOrderBtnNT"><a href="tel:+77777545" style="height: auto !important;"> @Translate("Phone Order") <i class="fas fa-phone"></i></a></button> 255 </div> 256 } 257 else 258 { 259 <div class="d-flex justify-content-center w-100 js-input-group "> 260 <form method="post" action="@url" class="w-100" style="z-index: 1"> 261 <input type="hidden" name="redirect" value="false"> 262 <input type="hidden" name="ProductId" value="@product.Id"> 263 <input type="hidden" name="ProductName" value="@HtmlEncoder.HtmlEncode(product.Name)"> 264 <input type="hidden" name="ProductVariantName" value="@variantName"> 265 <input type="hidden" name="ProductCurrency" value="@Dynamicweb.Ecommerce.Common.Context.Currency.Code"> 266 <input type="hidden" name="ProductPrice" value="@product.Price.PriceWithVAT"> 267 <input type="hidden" name="ProductReferer" value="component_ProductAddToCart"> 268 <input type="hidden" name="cartcmd" value="add"> 269 <input type="hidden" id="Unit_@(product.Id)_@product.VariantId.Replace(".", "_")" name="UnitID" value="@unitId" /> 270 271 @*CS NT..*@ 272 <input type="hidden" name="brand" value="@brand"> 273 <input type="hidden" name="itemCategory" value="@itemCategory"> 274 <input type="hidden" name="itemCategory2" value="@itemCategory2"> 275 <input type="hidden" name="itemCategory3" value="@itemCategory3"> 276 <input type="hidden" name="itemCategory4" value="@itemCategory4"> 277 <input type="hidden" name="itemCategory5" value="@itemCategory5"> 278 @*..CS NT*@ 279 280 <input type="submit" class="d-none" onclick="event.preventDefault(); swift.Cart.Update(event)"> @* Fix for enterKey should not redirect to minicart page *@ 281 282 @if (!product.NeverOutOfStock) 283 { 284 <input type="hidden" name="Stock" value="@product.Stock"> 285 286 <template class="js-out-of-stock-notice"> 287 <div class="modal-header"> 288 <h1 class="modal-title fs-5">@Translate("Stock limit")</h1> 289 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="@Translate("Close")"></button> 290 </div> 291 <div class="modal-body"> 292 @Translate("There are not enough products in stock. The product might be sold out or discontinued. Please adjust the quantity.") 293 </div> 294 </template> 295 } 296 297 298 <div class="d-flex flex-row w-100"> 299 300 301 <button type="button" onclick="@showLoginModalOrAddToCart" class="btn btn-primary flex-fill js-add-to-cart-button" style="white-space: nowrap;/*margin-right: 2rem;margin-left: 2rem;*/" 302 title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)_@PageviewCurrentParagraphID"> 303 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 304 @Translate("Add to cart") 305 </span> 306 </button> 307 308 309 </div> 310 </form> 311 </div> 312 } 313 } 314 315 316 @helper RenderAddToCart_QuantitySelectorNT(Dynamicweb.Ecommerce.Products.Product product) 317 { 318 319 try 320 { 321 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService")); 322 string variantName = Dynamicweb.Ecommerce.Services.Variants.GetVariantName(product.VariantId); 323 bool anonymousUser = Pageview.User == null; 324 string showLoginModalOrAddToCart = anonymousUser ? "showLoginModal();" : "swift.Cart.Update(event)"; 325 //bool favoritesSelector = true; 326 string PageviewCurrentParagraphID = (Pageview != null && Pageview.CurrentParagraph != null) ? Pageview.CurrentParagraph.ID.ToString() : ""; 327 //string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : product.DefaultUnitId; 328 string unitId = product.DefaultUnitId; 329 330 double? stepQty = product.PurchaseQuantityStep > 0 ? product.PurchaseQuantityStep : 1; 331 double? minQty = product.PurchaseMinimumQuantity > 0 ? product.PurchaseMinimumQuantity : 1; 332 double? valueQty = minQty > stepQty ? minQty : stepQty; 333 bool isStockType = product.Type == Dynamicweb.Ecommerce.Products.ProductType.Stock; 334 bool neverOutOfStock = product.NeverOutOfStock; 335 bool setMaxQty = isStockType && !neverOutOfStock; 336 //cs nt 337 long stockLocationID = Dynamicweb.Ecommerce.Common.Context.StockLocation is object ? Dynamicweb.Ecommerce.Common.Context.StockLocation.ID : 0; 338 double? maxQty = null; 339 double? productStock = product.Stock; 340 341 if (setMaxQty && productStock > 0) 342 { 343 maxQty = productStock; 344 } 345 string subId = product.Id + "_" + product.VariantId.Replace(".", "_") + "_MiniCart"; 346 347 <div class="d-flex justify-content-end w-100 js-input-group "> 348 <form method="post" action="@url" class="d-flex justify-content-end" style="z-index: 0"> 349 <input type="hidden" name="redirect" value="false"> 350 <input type="hidden" name="ProductId" value="@product.Id"> 351 <input type="hidden" name="ProductName" value="@HtmlEncoder.HtmlEncode(product.Name)"> 352 <input type="hidden" name="ProductVariantName" value="@variantName"> 353 <input type="hidden" name="ProductCurrency" value="@Dynamicweb.Ecommerce.Common.Context.Currency.Code"> 354 <input type="hidden" name="ProductPrice" value="product.Price"> 355 <input type="hidden" name="ProductReferer" value="component_ProductAddToCart"> 356 <input type="hidden" name="cartcmd" value="add"> 357 358 <input type="hidden" id="Unit_@(product.Id)_@product.VariantId.Replace(".", "_")" name="UnitID" value="@unitId" /> 359 360 <button type="button" id="decreaseQtyButton" onclick="decreaseQtyButtonMiniCart_OnClick('@subId')" class="decrease_IncreaseQuantityButton_miniCart">-</button> 361 <input id="Quantity_@subId" name="Quantity" value="@valueQty" step="@stepQty" min="@minQty" max="@maxQty" class="form-control swift_quantity-field" style="min-width: 60px; max-width: 100px; z-index: 1" type="number" onKeyDown="CheckCharacter_OnlyDigits()"> 362 <button type="button" id="increaseQtyButton" onclick="increaseQtyButtonMiniCart_OnClick('@subId')" class="decrease_IncreaseQuantityButton_miniCart">+</button> 363 364 <input type="submit" class="d-none" onclick="event.preventDefault(); swift.Cart.Update(event)"> @* Fix for enterKey should not redirect to minicart page *@ 365 366 @if (!product.NeverOutOfStock) 367 { 368 <input type="hidden" name="Stock" value="@productStock"> 369 370 <template class="js-out-of-stock-notice"> 371 <div class="modal-header"> 372 <h1 class="modal-title fs-5">@Translate("Stock limit")</h1> 373 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="@Translate("Close")"></button> 374 </div> 375 <div class="modal-body"> 376 @Translate("There are not enough products in stock. The product might be sold out or discontinued. Please adjust the quantity.") 377 </div> 378 </template> 379 } 380 381 382 <div class="d-flex flex-row w-100"> 383 384 385 <button type="button" onclick="@showLoginModalOrAddToCart" class="btn btn-primary flex-fill js-add-to-cart-button" style="white-space: nowrap;margin-right: 2rem;" 386 title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)_@PageviewCurrentParagraphID"> 387 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 388 @Translate("Add to cart") 389 </span> 390 </button> 391 392 393 <template class="js-min-quantity-warning"> 394 <div class="modal-header"> 395 <h1 class="modal-title fs-5">@Translate("The product could not be added to the cart")</h1> 396 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 397 </div> 398 <div class="modal-body"> 399 @Translate("The quantity is not valid. You must buy at least") @product.PurchaseMinimumQuantity 400 </div> 401 </template> 402 403 </div> 404 </form> 405 </div> 406 } 407 catch (Exception ex) 408 { 409 <div id="catchError">@ex.Message + @ex.StackTrace</div> 410 } 411 412 413 } 414 415 416 417 @if (arrayOfIDs1.Length > 0) 418 { 419 <div class="productPageHorizontalCarousel grid gap-0 superhome" id="productPageHorizontalCarousel3" style="visibility:hidden;"> 420 @*<h4 class="u-no-margin productPageHorizontalCarouselTitle titleWithLines"> <!--<a href=""> </a>--></h4>*@ 421 @if (!string.IsNullOrWhiteSpace(@CarouselDetails1)) 422 { 423 <p class="u-no-margin g-col-12 header-lead-carousel productPageHorizontalCarouselDescription">@CarouselDetails1</p> 424 } 425 <div class="productsCarousel g-col-12"> 426 <div class="@SliderDescription1@CarouselID1" style="max-width: 100vw;"> 427 @*@foreach (var product in masterProducts1)*@ 428 @foreach (var product_str in arrayOfIDs1) 429 { 430 try 431 { 432 var product = PS.GetProductById(product_str, "", Pageview.Area.EcomLanguageId.ToString()); 433 if(product.IsVariantMaster || !string.IsNullOrWhiteSpace(product.VariantId)) 434 { 435 continue; 436 } 437 if(maxItemsToShow <= prodsCounter1) 438 { 439 continue; 440 } 441 prodsCounter1 = prodsCounter1 + 1; 442 443 string noStockErrorBaseId = "error-noStock-message"; 444 string stockSpanId = "stockSpan"; 445 string maxQtyErrorBaseId = "error-maxQty-message"; 446 string prodId = product.Id;// GetString("Ecom:Product.ID"); 447 string quantityId = "Quantity" + CarouselID1 + "_" + prodId; 448 string QuickAddSpan = "QuickAdd_Span_" + CarouselID1 + "_" + prodId; 449 string AddedToCartSpan = "AddedToCart_Span_" + CarouselID1 + "_" + prodId; 450 string prodName = product.Name;// GetString("Ecom:Product.Name"); 451 string prodNumber = product.Number;// GetString("Ecom:Product.Number"); 452 453 string prodMaxQty = ""; 454 string discountPercentage = ""; 455 string originalPrice = ""; 456 string onOffer = ""; 457 string comparisonPrice = ""; 458 foreach (var prodCustomField in product.ProductFieldValues) 459 { 460 if (prodCustomField.ProductField.SystemName == "MaxQty") 461 { 462 prodMaxQty = prodCustomField.Value.ToString(); 463 } 464 if (prodCustomField.ProductField.SystemName == "DiscountPercentage") 465 { 466 discountPercentage = prodCustomField.Value.ToString(); 467 } 468 if (prodCustomField.ProductField.SystemName == "OriginalPrice") 469 { 470 originalPrice = prodCustomField.Value.ToString(); 471 } 472 if (prodCustomField.ProductField.SystemName == "OnOffer") 473 { 474 onOffer = prodCustomField.Value.ToString(); 475 } 476 if (prodCustomField.ProductField.SystemName == "ComparisonPrice" && !string.IsNullOrWhiteSpace(prodCustomField.Value.ToString())) 477 { 478 comparisonPrice = "€" + CommonFunctions.HandleComparisonPriceAccordingToLaw(prodCustomField.Value.ToString()); 479 } 480 } 481 originalPrice = (originalPrice == "0") ? "" : ( onOffer == "Yes" ? "€" + originalPrice : ""); 482 483 484 bool onlyMono = string.IsNullOrWhiteSpace(originalPrice) && !string.IsNullOrWhiteSpace(discountPercentage) && discountPercentage.Contains("Super") ? true : false; 485 486 long stockLocationID = Dynamicweb.Ecommerce.Common.Context.StockLocation is object ? Dynamicweb.Ecommerce.Common.Context.StockLocation.ID : 0; 487 double stockQuantity = product.Stock; 488 bool isOutOfStock = stockQuantity <= 0; 489 string outOfStockCss = isOutOfStock ? "outOfStockNT" : ""; 490 DateTime createdDate = product.Created; //!return DateTime.Now if NULL 491 492 //CS NT 20211206 AllowSubstitute changes 493 string allowSubOLValue ="1"; 494 if(cartLoop != null) 495 { 496 foreach (var i in cartLoop.Where(x => x.ProductId == prodId)) 497 { 498 //CS NT 20211206 499 foreach (var a in i.OrderLineFieldValues) 500 { 501 if (a.OrderLineFieldName == "AllowSubstitute") 502 { 503 allowSubOLValue = a.Value != null ? a.Value.ToString() : "" ; 504 } 505 } 506 } 507 } 508 string productImage_CS = "/Files/Images/Products/" + product.Number.Trim() + ".jpg&AlternativeImage=/Images/missing_image.jpg"; 509 var primaryGroup = product.GetDefaultGroupByShopId(shopId); 510 //var productLink = "Default.aspx?ID=" + Dynamicweb.Context.Current.Request["ID"] + "&GroupID=" + primaryGroup.Id + "&ProductID=" + product.IdUrlEncoded; 511 var productLink = baseCategoryBasedOnLanguage + "GroupID=" + primaryGroup.Id + "&ProductID=" + product.IdUrlEncoded; 512 513 <div id="Product" class="grid__col-3 product-list__grid-item dw-mod productPageHorizontalProductInCarousel @outOfStockCss" > 514 515 <div class="grid__cell product-list__grid-item__image dw-mod "> 516 <a href="@productLink" onclick="Scroll.SavePosition(event)" class="u-block u-position-relative"> 517 <img class="grid__cell-img grid__cell-img--centered b-lazy b-loaded" src="@imagePrefix@productImage_CS" alt="@prodName"> 518 </a> 519 @if(onlyMono) 520 { 521 <div class="position-absolute" style="bottom:0;right:0;"> 522 <img style="width: 50px;" src="/Admin/Public/GetImage.ashx?Width=100&Height=90&Crop=5&DoNotUpscale=True&FillCanvas=True&Image=/Files/Images/General/SUPER LABEL ΜΟΝΟ.png&AlternativeImage=/Images/missing_image.jpg" alt="Only Mono Price" title="" data-image="/Files/Images/SUPER LABEL ΜΟΝΟ.png"> 523 </div> 524 }else if(!string.IsNullOrWhiteSpace(discountPercentage)) 525 { 526 <div class="position-absolute top-0 left-0 stickers-container stickers-container--bottom-right dw-mod"> 527 <div class="stickers-container__tag--sale">@discountPercentage</div> 528 </div> 529 } 530 @if((createdDate.AddDays(newBadgePublicationDays) > DateTime.Now)) 531 { 532 <div class="position-absolute top-0 right-0 p-2 p-lg-3 ps-0 ps-lg-0 fs-6"> 533 <span class="h7"><span class="badge new-nt rounded-0"></span></span> 534 </div> 535 } 536 </div> 537 538 <div class="horizontalCarouselDetailsBlock"> 539 <a href="@productLink" onclick="Scroll.SavePosition(event)" title="@prodName "> 540 <span class="horizontalCarouselProductName"><span>@product.Name</span></span> 541 </a> 542 <div class="item-number dw-mod">@product.Number</div> 543 @*CS NT Aligned OriginalPrice, Price, ComparisonPrice 20240605*@ 544 <div class="fs-5 m-0 d-flex flex-wrap flex-column align-items-center" style="row-gap: 0 !important" > 545 <div class="fs-5 m-0 m-0 w-100 align-items-center align-items-center"style="height:30px;"> 546 @if(!string.IsNullOrWhiteSpace(originalPrice)) 547 { 548 <span class="text-decoration-line-through-with-color-nt opacity-75 original-price-nt before-price" style="">&nbsp; @originalPrice &nbsp;</span> 549 } 550 </div> 551 <span class=" p-0"> 552 <span class="text-price">@product.Price</span> 553 <span class="opacity-75" style="font-size:14px;line-height: 2;">@comparisonPrice</span> 554 </span> 555 </div> 556 557 <p id="allowSubOLValue_Paragraph_@prodId" hidden>@Translate("Allow Substitute in Cart") <span id="allowSubOLValue_Span_@prodId">@allowSubOLValue</span></p> 558 <div class="error-noStock-message" style="display:none" id="@noStockErrorBaseId@prodId"> 559 <br /> 560 <div class="error-block-nextech">@Translate("Available stock is") <span id="@stockSpanId@prodId"></span></div> 561 </div> 562 563 <div class="error-maxQty-message" style="display:none" id="@maxQtyErrorBaseId@prodId"> 564 <br /> 565 <div class="error-block-nextech">@Translate("The maximum quantity you can buy is") @prodMaxQty</div> 566 </div> 567 568 <div class="buttons-collection buttons-collection--center"> 569 @if(!isOutOfStock) 570 { 571 @*CS NT Add to cart button With quantity 572 <button class=" btn--condensed btn btn--primary dw-mod" id="CartButton_@prodId" onclick="ProductAddToCart(event, { id: '@prodId',variantId: '',unitId: '',productInfo: {&quot;link&quot;:&quot;&quot;,&quot;image&quot;:&quot;%2fFiles%2fImages%2fEcom%2fProducts%2f@prodNumber.jpg&quot;,&quot;name&quot;:&quot;@prodName&quot;,&quot;variantName&quot;:&quot;&quot;,&quot;unitName&quot;:&quot;&quot;,&quot;googleImpression&quot;:null},quantity: parseFloat(document.getElementById('@quantityId').value)}, @CarouselID1,@isGuestUser);" type="button"> 573 <i class="fal fa-shopping-bag u-flex--align-center"></i> 574 </button> 575 *@ 576 577 @RenderAddToCartNT(product) 578 @*CS NT QUICK ADD 579 <input id="@quantityId" name="@quantityId" min="1" value="1" type="number" class=" dw-mod" hidden data-qtyincart="0" data-maxqty="@prodMaxQty" data-id="" > 580 581 <button class="btn btn-primary js-add-to-cart-button" style="border-radius: 25px;" id="CartButton_@prodId" onclick="ProductAddToCart(event, { id: '@prodId',variantId: '',unitId: '',productInfo: {&quot;link&quot;:&quot;&quot;,&quot;image&quot;:&quot;%2fFiles%2fImages%2fEcom%2fProducts%2f@prodNumber.jpg&quot;,&quot;name&quot;:&quot;@prodName&quot;,&quot;variantName&quot;:&quot;&quot;,&quot;unitName&quot;:&quot;&quot;,&quot;googleImpression&quot;:null},quantity: 1}, @CarouselID1,@isGuestUser);" type="button"> 582 <span id="@QuickAddSpan">@Translate("Add to cart")</span><span id="@AddedToCartSpan" hidden>@Translate("Added")</span> 583 </button> 584 *@ 585 586 @*CS NT HIDE Add to cart button With quantity -> 587 <div class="buttons-collection buttons-collection--center"> 588 <button type="button" id="decreaseQtyButton" onclick="decreaseQtyButton_HorizontalCarousel_OnClick('@prodId','@CarouselID1')" class="decrease_IncreaseQuantityButton_VerticalCarousel">-</button> 589 <input type="number" class=" u-pull--right use-btn-primary-height verticalCarouselQuantityInput" id="@quantityId" name="@quantityId" value="1" min="1" data-qtyincart="" data-id="@prodId" data-productId="@prodId" > 590 <button type="button" id="increaseQtyButton" onclick="increaseQtyButton_HorizontalCarousel_OnClick('@prodId','@CarouselID1')" class="decrease_IncreaseQuantityButton_VerticalCarousel">+</button> 591 592 <button class=" btn--condensed btn btn--primary u-full-width dw-mod" id="CartButton_@prodId" onclick="ProductAddToCart(event, { id: '@prodId',variantId: '',unitId: '',productInfo: {&quot;link&quot;:&quot;&quot;,&quot;image&quot;:&quot;%2fFiles%2fImages%2fEcom%2fProducts%2f@prodNumber.jpg&quot;,&quot;name&quot;:&quot;@prodName&quot;,&quot;variantName&quot;:&quot;&quot;,&quot;unitName&quot;:&quot;&quot;,&quot;googleImpression&quot;:null},quantity: parseFloat(document.getElementById('@quantityId').value)}, @CarouselID1,@isGuestUser); " type="button"> 593 @Translate("Add to cart") 594 </button> 595 </div> 596 *@ 597 598 }else 599 { 600 <div class="outOfStockDiv_Carousel">@Translate("Out of stock")</div> 601 } 602 </div> 603 </div> 604 605 </div> 606 607 } 608 catch (Exception ex) 609 { 610 Logger.Instance.Log(ErrorLevel.DebugInfo, "RaptorRecommendation.Recommendations.AvailableLoops.GetOverAllTopSelling_Loop() ex: " + ex.Message + " Stack: " + ex.StackTrace); 611 prodsCounter1 = prodsCounter1 - 1; 612 } 613 } 614 </div> 615 </div> 616 </div> 617 618 <script type="text/javascript"> 619 $(document).ready(function () { 620 621 $('.slider-nav' + @CarouselID1).slick({ 622 slidesToShow: 8, 623 slidesToScroll: 4, 624 dots: true, 625 focusOnSelect: false, 626 autoplay: false, 627 autoplayspeed: 2000, 628 arrows: true, 629 prevArrow:"<button type='button' class='slick-prev'><span class='fa fa-angle-left'></span></button>", 630 nextArrow:"<button type='button' class='slick-next'><span class='fa fa-angle-right'></span></button>", 631 responsive: [ 632 { 633 breakpoint: 1024, 634 settings: { 635 slidesToShow: 8, 636 slidesToScroll: 4, 637 infinite: true, 638 dots: false, 639 arrows: false, 640 autoplay: true, 641 autoplayspeed: 2000 642 } 643 }, 644 { 645 breakpoint: 600, 646 settings: { 647 slidesToShow: 2, 648 slidesToScroll: 2, 649 arrows: false 650 } 651 }, 652 { 653 breakpoint: 480, 654 settings: { 655 slidesToShow: 2, 656 slidesToScroll: 2, 657 arrows: false 658 659 } 660 }, 661 { 662 breakpoint: 360, 663 settings: { 664 slidesToShow: 2, 665 slidesToScroll: 2, 666 arrows: false 667 } 668 } 669 // You can unslick at a given breakpoint now by adding: 670 // settings: "unslick" 671 // instead of a settings object 672 ] 673 674 }); 675 676 $('a[data-slide]').click(function (e) { 677 e.preventDefault(); 678 var slideno = $(this).data('slide'); 679 $('.slider-nav' + @CarouselID1).slick('slickGoTo', slideno - 1); 680 }); 681 682 $('#productPageHorizontalCarousel3').css('visibility','inherit'); 683 }); 684 685 </script> 686 } 687 688 689 690 691 <script type="text/javascript"> 692 function decreaseQtyButton_HorizontalCarousel_OnClick(id,carouselId){ 693 $('#Quantity' + carouselId + '_' + id).val( function(i, oldval) { 694 if(parseInt( oldval, 10) == 0) 695 return 0; 696 else 697 return parseInt( oldval, 10) - 1; 698 }); 699 700 }; 701 702 function increaseQtyButton_HorizontalCarousel_OnClick(id,carouselId){ 703 console.log('increaseQtyButton_HorizontalCarousel_OnClick id: ' + id + ' carouselId: ' + carouselId); 704 $('#Quantity' + carouselId + '_' + id).val( function(i, oldval) { 705 return parseInt( oldval, 10) + 1; 706 }); 707 }; 708 </script>