on Customization user able to click view
_variantDropdown
@model ProductViewModel @using Sana.Commerce.Catalog; @using Sana.Commerce.Shop @using Sana.Commerce.Customization.ExtendedModels @{ var variants = Model.Product.Variants; var firstGroup = Model.Product.VariantComponents.FirstOrDefault(); var showPrices = Shop.UserAbilities.Has(AbilityTo.ViewPrices); var showStock = Shop.UserAbilities.Has(AbilityTo.ViewStock); var type = Shop.Settings.ActionPricesPresentationType; // scope not defined //var selectedVarientId = variants.Where(x => ((ExtendedProductVariant)x).IsSelectedVariant == true).FirstOrDefault(); var showListPrice = showPrices && (type.iEquals(WebsiteSettings.ActionPricePresentationModes.BaseAndSalesPrice) || type.iEquals(WebsiteSettings.ActionPricePresentationModes.BaseAndSalesPriceDiscountPercentage) || type.iEquals(WebsiteSettings.ActionPricePresentationModes.BaseAndSalesPriceDiscountAmount)); var showDiscountAmount = showPrices && (type.iEquals(WebsiteSettings.ActionPricePresentationModes.SalesPriceDiscountAmount) || type.iEquals(WebsiteSettings.ActionPricePresentationModes.BaseAndSalesPriceDiscountAmount)); var showDiscountPercent = showPrices && (type.iEquals(WebsiteSettings.ActionPricePresentationModes.BaseAndSalesPriceDiscountPercentage) || type.iEquals(WebsiteSettings.ActionPricePresentationModes.SalesPriceDiscountPercentage)); } @if (firstGroup == null) { @DropdownFormRow("variantId", showPrices, showListPrice, showDiscountAmount, showDiscountPercent, showStock, null, variants, "withoutgroup") } else if (Model.Product.VariantComponents.Count == 1) { @DropdownFormRow("variantId", showPrices, showListPrice, showDiscountAmount, showDiscountPercent, showStock, firstGroup, variants, "single") } else { string ddId = "c" + Next(); @DropdownFormRow(ddId, showPrices, showListPrice, showDiscountAmount, showDiscountPercent, showStock, firstGroup, variants, "multifirst") var combinations = InitialCombinations(firstGroup, variants); foreach (var group in Model.Product.VariantComponents.Skip(1).Take(Model.Product.VariantComponents.Count - 2)) { ddId = "c" + Next(); @DropdownFormRow(ddId, showPrices, showListPrice, showDiscountAmount, showDiscountPercent, showStock, group, variants, "multimiddle", combinations) combinations = ExpandCombinations(combinations, group); } var lastGroup = Model.Product.VariantComponents.Last(); @DropdownFormRow("variantId", showPrices, showListPrice, showDiscountAmount, showDiscountPercent, showStock, lastGroup, variants, "multilast", combinations) } @helper DropdownFormRow(string ddId, bool showPrices, bool showListPrice, bool showDiscountAmount, bool showDiscountPercent, bool showStock, IVariantComponentGroup group, IProductVariantCollection variants, string mode, IList<dynamic> combinations = null) { <div class="form-row row-variant"> <div class="control"> <div class="label"> <label for="@ddId">@VariantComponentGroupName(group)</label> </div> <div class="field"> <div class="ddlb ddlb-component"> @if (mode == "withoutgroup") { <select name="@ddId" id="@ddId"> @Html.Each(variants, @<option value="@item.Id" data-price="@GetPrice(item, showPrices)" data-listprice="@GetListPrice(item, showListPrice)" data-inventory="@When(showStock, item.Inventory.ToString())" data-image-tags="@TagBuilder.CreateSanitizedId('v' + item.Id)" data-discount-percentage="@GetDiscountPercantage(item, showDiscountPercent)" data-discount-amount="@GetDiscountAmount(item, showDiscountAmount)" data-available-sales-agreement-lines="@item.AvailableSalesAgreementLines.ToJson().ToHtmlString()" @When(!item.IsOrderable, "data-not-orderable")> @item.Title.Or(item.Id) </option>) </select> } else if (mode == "single") { <select name="@ddId" id="@ddId"> @Html.Each(group.Items.Select(i => variants.FirstOrDefault(v => v.Components.Match(group.Id, i.Id))).Where(v => v != null), @<option value="@item.Id" data-price="@GetPrice(item, showPrices)" data-listprice="@GetListPrice(item, showListPrice)" data-inventory="@When(showStock, item.Inventory.ToString())" data-image-tags="@TagBuilder.CreateSanitizedId('v' + item.Id) @TagBuilder.CreateSanitizedId('v' + item.Components[group.Id])" data-discount-percentage="@GetDiscountPercantage(item, showDiscountPercent)" data-discount-amount="@GetDiscountAmount(item, showDiscountAmount)" data-available-sales-agreement-lines="@item.AvailableSalesAgreementLines.ToJson().ToHtmlString()" @When(!item.IsOrderable, "data-not-orderable")> @group.Items[item.Components[group.Id]].Name </option>) </select> } else if (mode == "multifirst") { // 3.3 issue Set selected drop down var selectedVarient = variants.Where(x => ((ExtendedProductVariant)x).IsSelectedVariant == true).FirstOrDefault(); if (selectedVarient != null) { var selectedVarientComponent = group.Items.FilterByVariants(new List<IProductVariant>() { selectedVarient }).FirstOrDefault(); var comId = selectedVarientComponent.Id; @Html.DropDownList(ddId, group.Items.FilterByVariants(variants).Select(c => new SelectListItem { Value = c.Id, Text = c.Name, Selected = (c.Id == comId) })) } else { @Html.DropDownList(ddId, group.Items.FilterByVariants(variants).Select(c => new SelectListItem { Value = c.Id, Text = c.Name })) } } else if (mode == "multimiddle") { <select name="@ddId" id="@ddId"> @foreach (var scope in combinations) { var selectedVarient = variants.Where(x => ((ExtendedProductVariant)x).IsSelectedVariant == true).FirstOrDefault(); if (selectedVarient != null) { var selectedVarientComponent = group.Items.FilterByVariants(new List<IProductVariant>() { selectedVarient }).FirstOrDefault(); var comId = selectedVarientComponent.Id; var ss = (IList<IProductVariant>)scope.Variants; //var selectedVarientComponent = group.Items.FilterByVariants(new List<IProductVariant>() { selectedVarient }).FirstOrDefault(); } var items = group.Items.FilterByVariants((IList<IProductVariant>)scope.Variants); <optgroup label="@scope.Text" data-scope="@scope.Key"> @Html.Each(items, @<option value="@scope.Key @item.Id">@item.Name</option>) </optgroup> } </select> } else if (mode == "multilast") { var selectedVarient = variants.Where(x => ((ExtendedProductVariant)x).IsSelectedVariant == true).FirstOrDefault(); if (selectedVarient != null) { } <select name="@ddId" id="@ddId"> @foreach (var scope in combinations) { var vars = (IList<IProductVariant>)scope.Variants; <optgroup label="@scope.Text" data-scope="@scope.Key"> @foreach (var item in group.Items) { var variant = vars.FirstOrDefault(v => v.Components.Match(group.Id, item.Id)); if (variant != null) { var selectedValue = ""; //if (variant.Id == selectedVarient.Id) //{ // selectedValue = "selected"; //} <option @selectedValue value="@variant.Id" data-price="@GetPrice(variant, showPrices)" data-listprice="@GetListPrice(variant, showListPrice)" data-inventory="@When(showStock, variant.Inventory.ToString())" data-image-tags="@TagBuilder.CreateSanitizedId('v' + variant.Id) @variant.Components.Values.Select(v => TagBuilder.CreateSanitizedId('v' + v)).JoinWith(" ")" data-discount-percentage="@GetDiscountPercantage(variant, showDiscountPercent)" data-discount-amount="@GetDiscountAmount(variant, showDiscountAmount)" data-available-sales-agreement-lines="@variant.AvailableSalesAgreementLines.ToJson().ToHtmlString()" @When(!variant.IsOrderable, "data-not-orderable")> @item.Name </option> } } </optgroup> } </select> } </div> </div> </div> </div> } @functions { string GetPrice(Sana.Commerce.Catalog.IProductVariant variant, bool showPrices) { if (!showPrices) return null; return variant.Price.FormatAsPrice(); } string GetListPrice(Sana.Commerce.Catalog.IProductVariant variant, bool showPrices) { if (!showPrices) return null; if (variant.ListPrice == null) return string.Empty; return variant.ListPrice.Value.FormatAsPrice(); } string GetDiscountPercantage(Sana.Commerce.Catalog.IProductVariant variant, bool showPrices) { if (!showPrices) return null; return ProductExtensions.DiscountPercentage(variant.Price, variant.ListPrice, Shop.CommerceContext.CurrencyId).ToHtmlString(); } string GetDiscountAmount(Sana.Commerce.Catalog.IProductVariant variant, bool showPrices) { if (!showPrices) return null; return ProductExtensions.DiscountAmount(variant.Price, variant.ListPrice, Shop.CommerceContext.CurrencyId).ToHtmlString(); } IHtmlString VariantComponentGroupName(IVariantComponentGroup group) { return group == null ? Sana.SimpleText("Variant") : Sana.SimpleText("Product_VariantComponent_" + group.Id, group.Name); } IList<dynamic> InitialCombinations(IVariantComponentGroup group, IList<IProductVariant> variants) { return ExpandCombinations(new[] { new { Key = string.Empty, Variants = variants } }, group); } IList<dynamic> ExpandCombinations(IList<dynamic> current, IVariantComponentGroup group) { var result = new List<dynamic>(); foreach (var parent in current) { var variants = (IList<IProductVariant>)parent.Variants; foreach (var item in group.Items.FilterByVariants(variants)) { result.Add(new { Key = parent.Key != string.Empty ? parent.Key + ' ' + item.Id : item.Id, Text = parent.Key != string.Empty ? parent.Text + '-' + item.Name : item.Name, Variants = variants.Where(v => v.Components.Match(group.Id, item.Id)).ToArray() }); } } return result; } }
Ticket 93818: [Holz Pichler] 3.3. Item variants – “range value” attributes.