BYGGERI - Telefon: 6341 1240
INDUSTRI/VVS - Telefon: 6341 1230
Exception in template (Designs\StandardWebshop\eCom/Product/Product.cshtml): System.Exception: Error Running ExecuteReader: Transaction (Process ID 205) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction., Sql: "SELECT
	                    -- Object columns
	                    O.DefinitionKey
	                    ,O.LastModified AS OjectLastModified
	                    ,O.ObjectId
	                    ,O.XmlObjectId
	                    ,O.ShopId
	                    ,O.LanguageId

	                    -- Value columns
	                    ,V.LastModified AS ValueLastModified
	                    ,V.XmlReferenceObjectId
	                    ,V.XmlReferenceObjectKey
	                    ,V.ValueId
	                    ,V.[Text]
                        ,V.FieldKey
                        ,V.SortOrder

                    FROM [LWI_Spec_Objects] AS O
                    JOIN [LWI_Spec_Values] AS V ON
	                    V.ShopId = O.ShopId
	                    AND V.LanguageId = O.LanguageId
	                    AND V.XmlObjectKey = O.DefinitionKey
	                    AND V.XmlObjectId = O.XmlObjectId
                    WHERE
                        O.DefinitionKey IN ('Product')
                        AND O.XmlObjectId IN ('NE 50 3')
                        AND O.ShopId IN ('SHOP1')
                        AND O.LanguageId IN ('LANG1')
                    ORDER BY O.DefinitionKey, O.LanguageId, O.ShopId, O.XmlObjectId
                    ", Params: '' ---> System.Data.SqlClient.SqlException: Transaction (Process ID 205) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at Glimpse.Ado.AlternateType.GlimpseDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at NLWI.Platforms.Dynamicweb9.Database.ADatabaseRepository.ExecuteReader(String query, Object[] ps)
   --- End of inner exception stack trace ---
   at NLWI.Platforms.Dynamicweb9.Database.ADatabaseRepository.ExecuteReader(String query, Object[] ps)
   at NLWI.Platforms.Dynamicweb9.Specs.Repositories.SpecificationRepository.GetSpecificationObjects(HashSet`1 keys) in D:\VSO Agents\00TFS01-norriq-ip\_work\3\s\src\NLWI.Platforms.Dynamicweb9.Specs\Repositories\SpecificationRepository.cs:line 265
   at NLWI.Platforms.Dynamicweb9.Specs.Services.CachedSpecificationService.b__12_1(HashSet`1 k) in D:\VSO Agents\00TFS01-norriq-ip\_work\3\s\src\NLWI.Platforms.Dynamicweb9.Specs\Services\CachedSpecificationService.cs:line 91
   at NLWI.Core.Platform.Caching.DictionaryCaching.GetOrInsert[TKey,TVal](HashSet`1 keys, Func`2 buildCacheKey, Func`2 lookupMethod, CacheOptions cacheOptions)
   at NLWI.Platforms.Dynamicweb9.Specs.Services.CachedSpecificationService.GetSpecificationObjects(HashSet`1 specificationObjectIdentifiers) in D:\VSO Agents\00TFS01-norriq-ip\_work\3\s\src\NLWI.Platforms.Dynamicweb9.Specs\Services\CachedSpecificationService.cs:line 88
   at NLWI.Platforms.Dynamicweb9.Specs.Services.CachedProductSpecificationService.GetProductSpecifications(Dictionary`2 autoIdMappings) in D:\VSO Agents\00TFS01-norriq-ip\_work\3\s\src\NLWI.Platforms.Dynamicweb9.Specs\Services\CachedProductSpecificationService.cs:line 64
   at NLWI.Platforms.Dynamicweb9.Specs.Services.CachedProductSpecificationService.GetProductSpecifications(HashSet`1 productAutoIds) in D:\VSO Agents\00TFS01-norriq-ip\_work\3\s\src\NLWI.Platforms.Dynamicweb9.Specs\Services\CachedProductSpecificationService.cs:line 59
   at NLWI.Platforms.Dynamicweb9.Specs.Services.CachedProductSpecificationService.GetProductSpecifications(Int64 productAutoId) in D:\VSO Agents\00TFS01-norriq-ip\_work\3\s\src\NLWI.Platforms.Dynamicweb9.Specs\Services\CachedProductSpecificationService.cs:line 91
   at NLWI.Platforms.Dynamicweb9.Specs.ProductSpecificationExtensionMethods.GetProductSpecifications(Int32 autoId) in D:\VSO Agents\00TFS01-norriq-ip\_work\3\s\src\NLWI.Platforms.Dynamicweb9.Specs\ProductSpecificationExtensionMethods.cs:line 48
   at NLWI.Platforms.Dynamicweb9.Specs.ProductSpecificationExtensionMethods.GetProductSpecifications[T](RazorTemplateBase`1 page) in D:\VSO Agents\00TFS01-norriq-ip\_work\3\s\src\NLWI.Platforms.Dynamicweb9.Specs\ProductSpecificationExtensionMethods.cs:line 24
   at CompiledRazorTemplates.Dynamic.eddcadafcdbffffe.Execute()
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context)
   at RazorEngine.Templating.TemplateService.Run(ITemplate template, DynamicViewBag viewBag)
   at RazorEngine.Templating.TemplateService.Parse(String razorTemplate, Object model, DynamicViewBag viewBag, String cacheName)
   at RazorEngine.Razor.Parse[T](String razorTemplate, T model, String cacheName)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
@using System.Web @using NORRIQ.Universal.Extensions @using NORRIQ.Common8.Context @using System.Web.Mvc.Html @using Newtonsoft.Json @using NORRIQ.Common8.Ecom @using NORRIQ.Common8.Factory @using NORRIQ.FavoriteList.Models @using NORRIQ.FavoriteList.Services @using NORRIQ.Common8.Razor; @using Dynamicweb.Ecommerce.Common; @using Dynamicweb.Ecommerce.Products @using NLWI.Platforms.Dynamicweb9.Extensions @using NLWI.Platforms.Dynamicweb9.Specs; @using NLWI.Platforms.Dynamicweb9.Specs.ViewModels @using NORRIQ.Universal.SessionStorage @using StandardWebshop.CustomCode @using StandardWebshop.CustomCode.ContactForm @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @{ // EcomMedia settings var image = NORRIQ.EcomMedia.Frontend.GetProductMedia(this); var docs = NORRIQ.EcomMedia.Frontend.GetProductMedia(this); //XPI var specs = this.GetProductSpecifications(); var SpecImages = specs.GetAllByKey("Image"); var SpecVideos = specs.GetAllByKey("YouTubeLinks"); // Product var ProductCurrency = Context.Currency.Symbol; var Productsheet = Translate("Productsheet", "Datablad"); //var isProductB2C = NORRIQ.Common8.Factory.ObjectFactory.GetInstance<NORRIQ.Common8.Context.AreaItemSettings>().GetCurrentAreaValue<string>("B2CShopping"); // Related products //var Columns = "col-xs-12 col-sm-4 col-md-3"; var ListMode = ObjectFactory.GetInstance<AreaItemSettings>().GetCurrentAreaValue<string>("ShowRelateproductsAsSlider"); // List mode var mode = ObjectFactory.GetInstance<TemporarilySettings>().GetAndUpdate("listmode") ?? "" + Pageview.Area.Item["ProductlistMode"] + ""; //Favortites var ProductAvailableFavoriteLists = (List<NORRIQ.FavoriteList.Models.FavoriteItemList>)GetValue("NIQ:FavoriteListsAvailable"); var ProductFavoriteListsWithProduct = (List<NORRIQ.FavoriteList.Models.FavoriteItemList>)GetValue("NIQ:FavoritListsWithProduct"); var ProductIsFavorite = ProductFavoriteListsWithProduct.Any(); var ProductListId = ProductAvailableFavoriteLists.Any() ? ProductAvailableFavoriteLists.First().Id : 0; var ProductFavoriteTitle = Translate("Add to you favoriteliste"); string productId = GetString("Ecom:Product.ID"); string variantId = GetString("Ecom:Product.VariantID"); string languageId = GetString("Ecom:Product.LanguageID"); var productKey = new ProductKey(productId, variantId ?? "", languageId); var contractFormService = ObjectFactory.GetInstance<ProductContactFormParagraphResolver>(); string contactFormParagraphId = contractFormService.GetContactParagraphLink(productKey); var currentProduct = Dynamicweb.Ecommerce.Services.Products.GetProductById(productId, variantId, languageId); var group = currentProduct != null && currentProduct.Groups.FirstOrDefault() != null ? currentProduct.Groups.FirstOrDefault() : null; var tableListView = group != null ? group.ProductGroupFieldValues.FirstOrDefault(x => x.ProductGroupField.SystemName == "TableListView") : null; var tableListViewColumnString = tableListView != null ? tableListView.Value.ToString() : null; var tableListColumns = tableListViewColumnString != null ? tableListViewColumnString.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToList() : null; var tableSpecs = new List<ProductSpecification>(); if (tableListColumns != null && tableListColumns.Any()) { foreach (string header in tableListColumns) { var spec = specs.GetByKey(header); if (spec != null) { tableSpecs.Add(spec); } } } } <section class="" itemscope itemtype="http://schema.org/Product"> <div class="row"> <div class="col-xs-12 col-sm-6 product-media"> @if (specs.GetAllByKey("Image").Any()) { <text>@if (SpecImages.Any()) { <div class="product-images" id="product-images"> @foreach (var images in SpecImages) { <a class="product-image mfp-image" data-image-type="image" href="/Admin/Public/GetImage.ashx?Width=1000&amp;Height=1000&amp;Crop=5&amp;Compression=80&amp;Image=/Files/Images/XPI/@(images.Value)"> <img itemprop="image" class="img-responsive" src="/Admin/Public/GetImage.ashx?Width=400&amp;Height=400&amp;Crop=5&amp;Compression=80&amp;Image=/Files/Images/XPI/@(images.Value)" alt="@images.Caption" /> </a> } @foreach (var video in SpecVideos) { <a class="product-image mfp-iframe" data-image-type="video" href="@GetYouTubeLink(video.Value)"> <img itemprop="image" width="400" class="img-responsive" src="@GetYouTubeImageUrl(video.Value)" /> </a> } </div> if (SpecImages.Count() > 0 || SpecImages.Any() && SpecVideos.Any()) { <div id="product-images-thumbs" class="product-thumbs"> @foreach (var images in SpecImages) { <div class="product-thumb"> <div class="product-thumb-inner" data-thumb-type="image"> <img class="img-responsive" src="/Admin/Public/GetImage.ashx?Width=110&amp;Height=110&amp;Crop=5&amp;Compression=80&amp;Image=/Files/Images/XPI/@(images.Value)" alt="@images.Caption" /> </div> </div> } @foreach (var video in SpecVideos) { <div class="product-thumb"> <div class="product-thumb-inner" data-thumb-type="video"> <img class="img-responsive" src="@GetYouTubeImageUrl(video.Value)" alt="@video.Caption" /> </div> </div> } </div> } } else { <div class="product-images"> <div class="product-image"> <div class="product-image-inner"> <img class="img-responsive" src="/Admin/Public/GetImage.ashx?&amp;Width=400&amp;Height=400&amp;Crop=5&amp;Compression=80&amp;Image=/Files/Images/Ecom/default.png" alt="@Translate("No image","No image")" /> </div> </div> </div> } @functions { string GetYouTubeLink(string url) { var uri = new UriBuilder(url).Uri; var query = HttpUtility.ParseQueryString(uri.Query); var videoId = query["v"]; return "https://www.youtube.com" + uri.AbsolutePath + "?v=" + videoId; } string GetYouTubeImageUrl(string url) { var uri = new UriBuilder(url).Uri; //var uri = new Uri(url); var query = HttpUtility.ParseQueryString(uri.Query); var videoId = query["v"]; if (string.IsNullOrEmpty(videoId)) { return "https://img.youtube.com/vi/" + uri.AbsolutePath.Replace("/", "") + "/0.jpg"; } return "https://img.youtube.com/vi/" + videoId + "/0.jpg"; } } </text> } else { <text>@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @if (image.GetImages().Count() > 1 || image.GetImages().Any() && !String.IsNullOrEmpty(GetString("Ecom:Product:Field.YoutubeVideoID")) || !String.IsNullOrEmpty(GetString("Ecom:Product:Field.VimeoVideoID"))) { <div class="product-images" id="product-images"> @foreach (var images in image.GetImages()) { <a class="product-image mfp-zoom" href="/Admin/Public/GetImage.ashx?Width=1000&amp;Height=1000&amp;Crop=5&amp;Compression=80&amp;Image=@(images.Url)"> <img itemprop="image" class="img-responsive" src="/Admin/Public/GetImage.ashx?Width=400&amp;Height=400&amp;Crop=5&amp;Compression=80&amp;Image=@(images.Url)" alt="@GetString("Ecom:Product.Name")" /> </a> } @if (!String.IsNullOrEmpty(GetString("Ecom:Product:Field.YoutubeVideoID"))) { var YoutubeSrc = "https://www.youtube-nocookie.com/embed/" + GetString("Ecom:Product:Field.YoutubeVideoID") + "?rel=0"; <div class="product-image"> <iframe src="@YoutubeSrc" width="640" height="360" frameborder="0" allowfullscreen></iframe> </div> } @if (!String.IsNullOrEmpty(GetString("Ecom:Product:Field.VimeoVideoID"))) { var VimeoSrc = "https://player.vimeo.com/video/" + GetString("Ecom:Product:Field.VimeoVideoID") + "?byline=0"; <div class="product-image"> <iframe src="@VimeoSrc" width="640" height="360" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe> </div> } </div> <div id="product-images-thumbs" class="product-thumbs"> @foreach (var images in image.GetImages()) { <div class="product-thumb"> <div class="product-thumb-inner" data-thumb-type="image"> <img class="img-responsive" src="/Admin/Public/GetImage.ashx?Width=110&amp;Height=110&amp;Crop=5&amp;Compression=80&amp;Image=@(images.Url)" alt="@GetString("Ecom:Product.Name")" /> </div> </div> } @if (!String.IsNullOrEmpty(GetString("Ecom:Product:Field.YoutubeVideoID"))) { <div class="product-thumb"> <div class="product-thumb-inner" data-thumb-type="video"> <span class="product-thumb-play"><i class="icon-youtube icon-5x" aria-hidden="true"></i></span> </div> </div> } @if (!String.IsNullOrEmpty(GetString("Ecom:Product:Field.VimeoVideoID"))) { <div class="product-thumb"> <div class="product-thumb-inner" data-thumb-type="video"> <span class="product-thumb-play"><i class="icon-vimeo icon-5x" aria-hidden="true"></i></span> </div> </div> } </div> } else { <div class="product-images product-images-single"> <a class="product-image mfp-zoom" href="/Admin/Public/GetImage.ashx?Width=1000&amp;Height=1000&amp;Crop=5&amp;Compression=80&amp;Image=@(image.GetFirstImage().Url)"> <img class="img-responsive" alt="@GetString("Ecom:Product.Name")" src="/Admin/Public/GetImage.ashx?Width=400&amp;Height=400&amp;Crop=5&amp;Compression=80&amp;Image=@(image.GetFirstImage().Url)" /> </a> </div> }</text> } </div> <div class="col-xs-12 col-sm-6 product-data "> <h1 itemprop="name" class="title-styled"> @GetString("Ecom:Product.Name") </h1> @*@if (Pageview.Security.UserLoggedIn) { <div class="product-detail async-price" data-product-key='@(this.GetJsonPriceKey())' data-product-retail-price='@(this.GetJsonRetailPrice())'> <div class="product-info"> <span class="product-number"> <span class="name"> @Translate("Product Number", "Product Number"): </span> <span class="value"> @GetString("Ecom:Product.Number") </span> </span> <span class="product-stock async-price-stock"> <i class="icon-async icon-pulse"></i> </span> </div> <div class="product-offer"> <div class="product-price-info"> <p class="product-price async-price-total"> <i class="icon-async icon-pulse"></i> </p> </div> <p class="product-price-type"> @Translate("Unitprice without VAT", "Unitprice without VAT") </p> @if (GetLoop("VariantGroups").Any()) { <text>@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using StandardWebshop.CustomCode.ViewModels.Variants; @using Newtonsoft.Json; @{ var variants = this.GetVariantTree(); var settings = new JsonSerializerSettings { Converters = new List<JsonConverter> { new VariantDimensionTreeNodeJsonConverter() }, Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; string variantsJson = JsonConvert.SerializeObject(variants, settings); } <div id="variant-container"> <div data-bind="foreach: { data: Dimensions, as: 'DimensionValues' }"> <label for="selecta">@Translate("variant_label", "Variant")</label> <select class="form-control" data-bind="disable: !DimensionValues.length, options: DimensionValues, optionsText: 'OptionName', value: $root.SelectedVariants[$index()], optionsCaption: DimensionValues.length ? '@Translate("variant_chose_variant", "Vælg variant")' : '@Translate("variant_chose_previous_variant", "Vælg forrige variant")'" id="selecta"></select> </div> </div> <!-- Build the JSON object --> <script append="true"> var globalVariantTree = @variantsJson; $(document).ready(function () { var variantControl = new AppStart.VariantControl({ VariantTree: @variantsJson, $variantContainer: $('#variant-container') }); variantControl.Render(); var variantControl = new AppStart.VariantSelectionHandler(AppStart.VariantSelectionHandlerModes.ReloadOnVariantSelected); }) </script></text> } <div class="product-buying"> <form class="form-inline" id="prodform_@GetString("Ecom:Product:Page.ID")" name="prodform_@GetString("Ecom:Product:Page.ID")" method="post" action="@GetGlobalValue("Global:Pageview.Url.Raw")"> @GetString("Ecom:Product.Form.Clean") <label for="quantity" class="sr-only">@Translate("Qty", "Qty")</label> <div class="input-group input-group-lg"> <input name="quantity" id="quantity" value="1" type="text" class="form-control" autocomplete="off" /> <span class="input-group-btn"> <button class="btn btn-primary" role="button" type="submit" @((GetLoop("VariantGroups").Any() && String.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) ? "disabled=\"disabled\"" : ""))> <i class="icon-minicart" aria-hidden="true"></i> <span class="product-added-text">@Translate("Add to cart", "Add to cart")</span> </button> </span> </div> </form> @if (!GetLoop("VariantGroups").Any()) { <div class="product-favorite"> <a href="javascript:void(0)" class="js-favorite-toggle" )" data-favorite-list-id="@ProductListId" data-is-favorite="@(ProductIsFavorite ? "true" : "false")" data-product-id="@(GetString("Ecom:Product.ID"))" data-product-language-id="@(GetString("Ecom:Product.LanguageID"))" data-product-variant-id="@(GetString("Ecom:Product.VariantID"))"> @if (ProductIsFavorite) { <i class="icon-favorite-added"></i> @Translate("Remove favorite", "Remove favorite") } else { <i class="icon-favorite"></i> @Translate("Make favorite", "Make favorite") } </a> </div> } </div> </div> </div> }*@ <div><div class="product-detail"> <div class="product-info"> <span class="product-number"> <span class="name"> @Translate("Product Number", "Product Number"): </span> <span class="value"> @GetString("Ecom:Product.Number") </span> </span> <span class="pull-rightXXX"> @*<a class="" rel="nofollow" href="@Navigation.GetUrlByNavigationTag("productsheet")?GroupID=@GetString("Ecom:Product.PrimaryOrFirstGroupID")&amp;ProductID=@GetString("Ecom:Product.ID")&amp;VariantID=@GetString("Ecom:Product.VariantID")&amp;PDF=true&amp;Filename=@GetString("Ecom:Product.Name")_@(GetString("Ecom:Product.Number")).pdf"><i class="icon-print" aria-hidden="true"></i> @Translate("Print PDF")</a>*@ </span> @*<span class="product-stock"> <i class="icon-stock @GetString("Ecom:Product:Stock.DeliveryUnit")" aria-hidden="true"></i> <span class="stock-label-text">@GetString("Ecom:Product:Stock.Text")</span> </span>*@ </div> <div class="product-offer"> @*<div class="product-price-info"> <p class="product-price"> <span class="product-currency">@GetString("Ecom:Product.Currency.Code")</span> @GetString("Ecom:Product.Price.PriceWithVAT") </p> </div>*@ @if (GetLoop("VariantGroups").Any()) { <text>@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using StandardWebshop.CustomCode.ViewModels.Variants; @using Newtonsoft.Json; @{ var variants = this.GetVariantTree(); var settings = new JsonSerializerSettings { Converters = new List<JsonConverter> { new VariantDimensionTreeNodeJsonConverter() }, Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; string variantsJson = JsonConvert.SerializeObject(variants, settings); } <div id="variant-container"> <div data-bind="foreach: { data: Dimensions, as: 'DimensionValues' }"> <label for="selecta">@Translate("variant_label", "Variant")</label> <select class="form-control" data-bind="disable: !DimensionValues.length, options: DimensionValues, optionsText: 'OptionName', value: $root.SelectedVariants[$index()], optionsCaption: DimensionValues.length ? '@Translate("variant_chose_variant", "Vælg variant")' : '@Translate("variant_chose_previous_variant", "Vælg forrige variant")'" id="selecta"></select> </div> </div> <!-- Build the JSON object --> <script append="true"> var globalVariantTree = @variantsJson; $(document).ready(function () { var variantControl = new AppStart.VariantControl({ VariantTree: @variantsJson, $variantContainer: $('#variant-container') }); variantControl.Render(); var variantControl = new AppStart.VariantSelectionHandler(AppStart.VariantSelectionHandlerModes.ReloadOnVariantSelected); }) </script></text> } @*<div class="product-buying"> <form class="form-inline" id="prodform_@GetString("Ecom:Product:Page.ID")" name="prodform_@GetString("Ecom:Product:Page.ID")" method="post" action="@GetGlobalValue("Global:Pageview.Url.Raw")"> @GetString("Ecom:Product.Form.Clean") <label for="quantity" class="sr-only">@Translate("Qty")</label> <div class="input-group input-group-lg"> <input name="quantity" id="quantity" value="1" type="text" class="form-control" autocomplete="off" /> <span class="input-group-btn"> <button class="btn btn-primary" role="button" type="submit" @((GetLoop("VariantGroups").Any() && String.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) ? "disabled=\"disabled\"" : ""))> <i class="icon-minicart" aria-hidden="true"></i> <span class="product-added-text">@Translate("Add to cart")</span> </button> </span> </div> </form> </div>*@ </div> </div></div> </div> <div class="col-xs-12 col-sm-6 product-tabs"> <ul class="nav nav-tabs product-nav-tabs" role="tablist"> @if (!String.IsNullOrWhiteSpace(GetString("Ecom:Product.LongDescription")) || specs.GetByKey("ProductDescription").Value != null) { <li role="presentation" class="active"> <a href="#desc" aria-controls="desc" role="tab" data-toggle="tab"> @Translate("Description", "Description") </a> </li> } @if (specs.GetByGroup("Specifikationer").Any()) { <li role="presentation"> <a href="#specs" aria-controls="specs" role="tab" data-toggle="tab"> @Translate("Specifications") </a> </li> } @if (docs.HasItem("Documents") || specs.GetAllByKey("Datablad").Any() || specs.GetAllByKey("Sikkerhedsdatablad").Any()) { <li role="presentation"> <a href="#docs" aria-controls="docs" role="tab" data-toggle="tab"> @Translate("Documents") </a> </li> } @if (!string.IsNullOrWhiteSpace(contactFormParagraphId)) { <li role="presentation"> <a href="#product-contact-me" aria-controls="docs" role="tab" data-toggle="tab"> @Translate("Contact Me") </a> </li> } </ul> <div class="tab-content product-tab-content"> @if (!String.IsNullOrWhiteSpace(GetString("Ecom:Product.LongDescription")) || specs.GetByKey("ProductDescription").Value != null) { <div role="tabpanel" class="tab-pane active" id="desc" itemprop="description"> @GetString("Ecom:Product.LongDescription") @specs.GetByKey("ProductDescription").Value </div> } @if (specs.GetByGroup("Specifikationer").Any()) { <div role="tabpanel" class="tab-pane" id="specs"> <table class="table table-striped"> <tbody> @foreach (var spec in specs.GetByGroup("Specifikationer").GroupBy(a => a.Key)) { <tr> <td> @spec.First().Caption </td> <td> @String.Join(", ", spec.Select(a => a.Value)) </td> </tr> } </tbody> </table> </div> } @if (docs.HasItem("Documents") || specs.GetAllByKey("Datablad").Any() || specs.GetAllByKey("Sikkerhedsdatablad").Any()) { <div role="tabpanel" class="tab-pane" id="docs"> @if (docs.HasItem("Documents")) { foreach (var item in docs.GetItems("Documents")) { <p> <a href="@item.Url"> @item.Url.Split('/').Last() </a> <small>(@item.FileSizeInMb)</small> </p> } } @foreach (var specFile in specs.GetAllByKey("Datablad")) { var name = Translate(specFile.Caption); <p> <a download="@name" href="/Files/Images/XPI/@(specFile.Value)" title="@name"> @specFile.GetReferenceSpecification().GetByKey("OriginalFilename").Value </a> </p> } @foreach (var specFile in specs.GetAllByKey("Sikkerhedsdatablad")) { var name = Translate(specFile.Caption); <p> <a download="@name" href="/Files/Images/XPI/@(specFile.Value)" title="@name"> @specFile.GetReferenceSpecification().GetByKey("OriginalFilename").Value </a> </p> } </div> } @if (!string.IsNullOrWhiteSpace(contactFormParagraphId)) { <div role="tabpanel" class="tab-pane" id="product-contact-me" data-product-name="@GetString("Ecom:Product.Name")" data-product-number="@GetString("Ecom:Product.Number")"> <p>@Translate("ContactMeMessage", "Hvis du har spørgsmål til produktet, udfyld nedenstående formular og vi vender tilbage hurtigst muligt.")</p> @RenderParagraphContent(int.Parse(contactFormParagraphId)) <p class="error hidden" id="error-message">@Translate("SubmitFormerror-message", "Noget gik galt, forsøg venligst igen.")</p> </div> } </div> </div> @if (tableSpecs.Any()) { <div class="col-xs-12 product-specs"> <h2 class="title-styled"> @Translate("Specifications") </h2> <table class="table table-condensed productlist-table js-product-table plpx-table"> <thead> <tr> @foreach (var spec in tableSpecs) { <th> <strong>@spec.Caption</strong> </th> } </tr> </thead> <tbody> <tr> @foreach (var spec in tableSpecs) { <td> @String.Join(", ", spec.Value) </td> } </tr> </tbody> </table> </div> } <div class="col-xs-12 product-related"> @if (GetLoop("ProductRelatedGroups").Any()) { foreach (var grp in GetLoop("ProductRelatedGroups")) { if (grp.GetLoop("RelatedProducts").Any()) { var RelatedRow = "productlist-grid-flex"; if (grp.GetLoop("RelatedProducts").Count > 4) { RelatedRow = "slick-middle-arrow slick-flex related-product-slider"; } <h2 class="title-styled"> @grp.GetString("Ecom:Product:RelatedGroup.Name") </h2> <div class="@RelatedRow" id="slide-products-@grp.GetString("Ecom:Product:RelatedGroup.GroupID")"> @foreach (var product in grp.GetLoop("RelatedProducts")) { if (Pageview.Security.UserLoggedIn) { <text>@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using NLWI.Platforms.Dynamicweb9.Extensions; @{ // Image takes from either DW or XPI var media = NORRIQ.EcomMedia.Frontend.GetProductMedia(product); var ProductSpecs = product.GetProductSpecifications(); var Image = ProductSpecs.GetAllByKey("Image").Any() ? "/Files/Images/XPI/" + ProductSpecs.GetByKey("Image").Value : media.GetFirstImage().Url; // Favoritelist var availableFavoriteLists = (List<NORRIQ.FavoriteList.Models.FavoriteItemList>)product.GetValue("NIQ:FavoriteListsAvailable"); var favoriteListsWithProduct = (List<NORRIQ.FavoriteList.Models.FavoriteItemList>)product.GetValue("NIQ:FavoritListsWithProduct"); var isFavorite = favoriteListsWithProduct.Any(); var listId = availableFavoriteLists.Any() ? availableFavoriteLists.First().Id : 0; var favoriteLabel = isFavorite ? Translate("Remove from favorites") : Translate("Add to favorites"); } <div class="@(String.IsNullOrEmpty(Pageview.CurrentParagraph.Item["ProductlistGrid"].ToString()) ? Pageview.Area.Item["ProductlistGrid"] : Pageview.CurrentParagraph.Item["ProductlistGrid"]) async-price js-favProduct" data-product-display="flex" data-product-key='@(product.GetJsonPriceKey())' data-product-retail-price='@(product.GetJsonRetailPrice())'> <div class="productlist-grid-product@(product.GetInteger("Products.LoopCounter") < 7 ? " in-view" : "") hvr-glow"> <a class="productlist-grid-image" href="@product.GetString("NIQ:ProductUrl")"> <img src="/Admin/Public/GetImage.ashx?Width=200&amp;Height=200&amp;Crop=5&amp;Compression=80&amp;Image=@Image" class="img-responsive" alt="@product.GetString("Ecom:Product.Name")" /> </a> <a href="@product.GetString("NIQ:ProductUrl")" class="productlist-grid-name"> <span>@product.GetString("Ecom:Product.Name")</span> </a> <div class="productlist-grid-info"> <span class="productlist-grid-number"> @Translate("Product Number") <span itemprop="sku">@product.GetString("Ecom:Product.Number")</span> </span> <span class="productlist-grid-stock async-price-stock" itemprop="availability"></span> </div> <div class="productlist-grid-offer"> <span class="productlist-grid-price async-price-total" itemprop="price"> <span class="icon-async icon-pulse"></span> </span> @if (!product.GetLoop("VariantGroups").Any()) { <form class="form" id="prodform_@product.GetString("Ecom:Product.Number")" name="prodform_@product.GetString("Ecom:Product.Number")" method="post" action="@GetGlobalValue("Global:Pageview.Url.Raw")"> @product.GetString("Ecom:Product.Form.Clean") <button role="button" type="submit" class="btn btn-primary"> <span class="product-added-text">@Translate("Add to cart")</span> </button> </form> } else { <a href="@product.GetString("NIQ:ProductUrl")" class="btn btn-info"> @Translate("Choose Variant") </a> } </div> @if (!product.GetLoop("VariantGroups").Any()) { <div class="productlist-grid-buttons"> <a href="javascript:void(0)" class="js-favorite-toggle productlist-grid-favorite" title="@favoriteLabel" data-favorite-list-id="@listId" data-is-favorite="@(isFavorite ? "true" : "false")" data-product-id="@(product.GetString("Ecom:Product.ID"))" data-product-language-id="@(product.GetString("Ecom:Product.LanguageID"))" data-product-variant-id="@(product.GetString("Ecom:Product.VariantID"))"> <i class="icon-favorite-toggle" aria-hidden="true"></i> <span class="sr-only">@favoriteLabel</span> </a> </div> } </div> </div> </text> } else { <text>@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @{ // Image takes from either DW or XPI var media = NORRIQ.EcomMedia.Frontend.GetProductMedia(product); var ProductSpecs = product.GetProductSpecifications(); var Image = ProductSpecs.GetAllByKey("Image").Any() ? "/Files/Images/XPI/" + ProductSpecs.GetByKey("Image").Value : media.GetFirstImage().Url; } <div class="@(String.IsNullOrEmpty(Pageview.CurrentParagraph.Item["ProductlistGrid"].ToString()) ? Pageview.Area.Item["ProductlistGrid"] : Pageview.CurrentParagraph.Item["ProductlistGrid"])" data-product-display="flex"> <div class="productlist-grid-product@(product.GetInteger("Products.LoopCounter") < 7 ? " in-view" : "") hvr-glow" itemscope itemtype="http://schema.org/Product"> <a class="productlist-grid-image" href="@product.GetString("NIQ:ProductUrl")" itemprop="url"> <img src="/Admin/Public/GetImage.ashx?Width=200&amp;Height=200&amp;Crop=5&amp;Compression=80&amp;Image=@Image" class="img-responsive" alt="@product.GetString("Ecom:Product.Name")" itemprop="image" /> </a> <a href="@product.GetString("NIQ:ProductUrl")" class="productlist-grid-name" itemprop="url"> <span itemprop="name">@product.GetString("Ecom:Product.Name")</span> </a> <span class="productlist-grid-number"> @Translate("Varenr.") <span itemprop="mpn">@product.GetString("Ecom:Product.Number")</span> </span> @* Include if shop has B2C shopping *@ @*<div class="productlist-grid-info"> <span class="productlist-grid-number"> @Translate("Product Number") <span itemprop="mpn">@product.GetString("Ecom:Product.Number")</span> </span> <span class="productlist-grid-stock"> <i class="icon-stock @product.GetString("Ecom:Product:Stock.DeliveryUnit")" aria-hidden="true"></i> <span itemprop="availability" href="http://schema.org/InStock" class="stock-label-text">@product.GetString("Ecom:Product:Stock.Text")</span> </span> </div> <div class="productlist-grid-offer" itemprop="offers" itemscope itemtype="http://schema.org/Offer"> <span class="productlist-grid-price"> <meta itemprop="priceCurrency" content="@product.GetString("Ecom:Product.Currency.Code")" /> <span itemprop="price"> @product.GetString("Ecom:Product.Price.PriceWithVAT") </span> </span> @if (!product.GetLoop("VariantGroups").Any()) { <form class="form" id="prodform_@product.GetString("Ecom:Product:Page.ID")" name="prodform_@product.GetString("Ecom:Product:Page.ID")" method="post" action="@GetGlobalValue("Global:Pageview.Url.Raw")"> @product.GetString("Ecom:Product.Form.Clean") <button role="button" type="submit" class="btn btn-primary"> <span class="product-added-text">@Translate("Add to cart")</span> </button> </form> } else { <a href="@product.GetString("NIQ:ProductUrl")" class="btn btn-info"> @Translate("Choose Variant") </a> } </div>*@ </div> </div></text> } } </div> } } } </div> </div> </section> <script append="true"> $(document).ready(function () { var pdp = new AppStart.Product({ $asyncTemplate: $("#async-price"), productPrimaryImage: '#product-images', productImgThumb: '#product-images-thumbs', $productImages: $('.product-images'), $asyncPrices: $('.async-price'), $relatedProducts: $('.related-product-slider'), qtySelector: '.qty-input', isLoggedIn: @Pageview.Security.UserLoggedIn.ToString().ToLower() }); pdp.init(); }); </script> @if (Pageview.Security.UserLoggedIn) { <script append="true"> $(document).ready(function () { var favorite = new AppStart.Favoritelist({ isFavoriteMode: false, $allFavoriteIcons: $('.js-favorite-toggle'), $productParent: $(), defaultFavoriteName: "Favorites" }); favorite.init(); }); </script> <script id="async-price" type="text/x-jsrender"> <div data-target=".async-price-unit"> {{if NetUnitPrice.PriceWithoutVat != UnitPrice.PriceWithoutVat}} {{>UnitPrice.PriceWithoutVat.formatMoney(2,',','.')}} {{/if}} </div> <div data-target=".async-price-stock"> {{if Inventory > 1 }} <i class="icon-stock icon-green" title="{{>Inventory}}"></i> <span class="stock-label-text">@Translate("In Stock")</span> {{else Inventory == 1}} <i class="icon-stock icon-yellow" title="{{>Inventory}}"></i> <span class="stock-label-text">@Translate("Few in stock")</span> {{else}} <i class="icon-stock icon-red" title="0"></i> <span class="stock-label-text">@Translate("Out of stock")</span> {{/if}} </div> <div data-target=".async-price-total"> {{>NetUnitPrice.PriceWithoutVat.formatMoney(2,',','.')}} {{if error != null }} <i class="icon-warning" title="@Translate("There was a technical problem so your specific price could not be calculated. The price you see is retail price.")"></i> {{/if}} </div> </script> <script type="text/x-jsrender" id="autoaddfeedbackloading"> <i class="icon-async icon-pulse"></i> </script> <script type="text/x-jsrender" id="autoaddfeedbacksuccess"> <i class="icon-added" title="@Translate("Product added to cart")"></i> </script> <script type="text/x-jsrender" id="autoaddfeedbackerror"> {{if error == "badinput"}} <i class="icon-warning" title="@Translate("Please enter a numerical value")"></i> {{else error == "servererror"}} <i class="icon-warning" title="@Translate("An server error occured your cart was not updated")"></i> {{else}} <i class="icon-warning"></i> {{/if}} </script> }