From 5b0329b9233e5c72942fec26182067b2fe66fe9d Mon Sep 17 00:00:00 2001 From: Marcus Gesing Date: Fri, 2 Oct 2020 13:06:02 +0200 Subject: [PATCH] Hidden attribute options (in progress) --- .../Migrations/MigrationsConfiguration.cs | 6 +++ .../UI/Choices/ChoiceModel.cs | 4 +- .../Controllers/ProductController.cs | 3 ++ .../Models/Catalog/ProductModel.cs | 11 +++-- .../Product/_CreateOrUpdate.Attributes.cshtml | 16 +++---- .../Controllers/CatalogHelper.cs | 42 ++++++++++--------- .../Shared/ChoiceTemplates/Choice.Box.cshtml | 2 +- .../ChoiceTemplates/Choice.CheckRadio.cshtml | 2 +- .../ChoiceTemplates/Choice.Dropdown.cshtml | 4 +- .../ChoiceTemplates/Choice.Radio.cshtml | 2 +- 10 files changed, 53 insertions(+), 39 deletions(-) diff --git a/src/Libraries/SmartStore.Data/Migrations/MigrationsConfiguration.cs b/src/Libraries/SmartStore.Data/Migrations/MigrationsConfiguration.cs index f2b3f57aa9..65861a20dd 100644 --- a/src/Libraries/SmartStore.Data/Migrations/MigrationsConfiguration.cs +++ b/src/Libraries/SmartStore.Data/Migrations/MigrationsConfiguration.cs @@ -599,6 +599,12 @@ können aber nicht bearbeitet werden. Die Texte dieser Informationen können üb "Nicht verfügbare Attribut-Kombinationen ausblenden", "Specifies whether to hide unavailable attribute combinations on product detail pages. By default, they are disabled.", "Legt fest, ob nicht verfügbare Attribut-Kombinationen auf Produktdetailseiten ausgeblendet werden sollen. Standardmäßig werden sie deaktiviert."); + + builder.AddOrUpdate("Admin.Catalog.Products.ProductVariantAttributes.Attributes.Fields.CustomData", + "Custom data", + "Benutzerdefinierte Daten", + "Specifies user-defined data. For free usage, e.g. for individual shop extensions.", + "Legt benutzerdefinierte Daten fest. Zur freien Verwendung, z.B. bei individuellen Shop-Erweiterungen."); #region Media diff --git a/src/Presentation/SmartStore.Web.Framework/UI/Choices/ChoiceModel.cs b/src/Presentation/SmartStore.Web.Framework/UI/Choices/ChoiceModel.cs index a460705a03..a1c2dbb58a 100644 --- a/src/Presentation/SmartStore.Web.Framework/UI/Choices/ChoiceModel.cs +++ b/src/Presentation/SmartStore.Web.Framework/UI/Choices/ChoiceModel.cs @@ -23,11 +23,13 @@ protected ChoiceModel() public string TextPrompt { get; set; } + public string CustomData { get; set; } + public bool IsRequired { get; set; } public bool IsDisabled { get; set; } - public bool IsHidden { get; set; } + //public bool IsHidden { get; set; } /// /// Allowed file extensions for customer uploaded files diff --git a/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs b/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs index ddc59a5607..5756fb7e73 100644 --- a/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs +++ b/src/Presentation/SmartStore.Web/Administration/Controllers/ProductController.cs @@ -2864,6 +2864,7 @@ public ActionResult ProductVariantAttributeList(GridCommand command, int product ProductAttribute = _productAttributeService.GetProductAttributeById(x.ProductAttributeId).Name, ProductAttributeId = x.ProductAttributeId, TextPrompt = x.TextPrompt, + CustomData = x.CustomData, IsRequired = x.IsRequired, AttributeControlType = x.AttributeControlType.GetLocalizedEnum(_localizationService, _workContext), AttributeControlTypeId = x.AttributeControlTypeId, @@ -2907,6 +2908,7 @@ public ActionResult ProductVariantAttributeInsert(GridCommand command, ProductMo // Use ProductAttribute property (not ProductAttributeId) because appropriate property is stored in it. ProductAttributeId = int.Parse(model.ProductAttribute), TextPrompt = model.TextPrompt, + CustomData = model.CustomData, IsRequired = model.IsRequired, // Use AttributeControlType property (not AttributeControlTypeId) because appropriate property is stored in it. AttributeControlTypeId = int.Parse(model.AttributeControlType), @@ -2934,6 +2936,7 @@ public ActionResult ProductVariantAttributeUpdate(GridCommand command, ProductMo // Use ProductAttribute property (not ProductAttributeId) because appropriate property is stored in it. pva.ProductAttributeId = int.Parse(model.ProductAttribute); pva.TextPrompt = model.TextPrompt; + pva.CustomData = model.CustomData; pva.IsRequired = model.IsRequired; // Use AttributeControlType property (not AttributeControlTypeId) because appropriate property is stored in it. pva.AttributeControlTypeId = int.Parse(model.AttributeControlType); diff --git a/src/Presentation/SmartStore.Web/Administration/Models/Catalog/ProductModel.cs b/src/Presentation/SmartStore.Web/Administration/Models/Catalog/ProductModel.cs index f27de3d34d..fedd63d72c 100644 --- a/src/Presentation/SmartStore.Web/Administration/Models/Catalog/ProductModel.cs +++ b/src/Presentation/SmartStore.Web/Administration/Models/Catalog/ProductModel.cs @@ -634,7 +634,6 @@ public class TierPriceModel : EntityModelBase public class ProductVariantAttributeModel : EntityModelBase { public int ProductId { get; set; } - public int ProductAttributeId { get; set; } [SmartResourceDisplayName("Admin.Catalog.Products.ProductVariantAttributes.Attributes.Fields.Attribute")] @@ -645,6 +644,10 @@ public class ProductVariantAttributeModel : EntityModelBase [AllowHtml] public string TextPrompt { get; set; } + [SmartResourceDisplayName("Admin.Catalog.Products.ProductVariantAttributes.Attributes.Fields.CustomData")] + [AllowHtml] + public string CustomData { get; set; } + [SmartResourceDisplayName("Admin.Catalog.Products.ProductVariantAttributes.Attributes.Fields.IsRequired")] public bool IsRequired { get; set; } @@ -653,9 +656,9 @@ public class ProductVariantAttributeModel : EntityModelBase public string AttributeControlType { get; set; } public int AttributeControlTypeId { get; set; } - //we don't name it DisplayOrder because Telerik has a small bug - //"if we have one more editor with the same name on a page, it doesn't allow editing" - //in our case it's category.DisplayOrder + // We don't name it DisplayOrder because Telerik has a small bug + // "if we have one more editor with the same name on a page, it doesn't allow editing" + // in our case it's category.DisplayOrder. [SmartResourceDisplayName("Common.DisplayOrder")] public int DisplayOrder1 { get; set; } diff --git a/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdate.Attributes.cshtml b/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdate.Attributes.cshtml index dc129ba889..6718e4e302 100644 --- a/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdate.Attributes.cshtml +++ b/src/Presentation/SmartStore.Web/Administration/Views/Product/_CreateOrUpdate.Attributes.cshtml @@ -66,20 +66,16 @@ .Columns(columns => { columns.Bound(x => x.ProductAttribute) - .Width("16%"); - columns.Bound(x => x.AttributeControlType) - .Width("16%"); - columns.Bound(x => x.TextPrompt) - .Width("16%"); + .Width("15%"); + columns.Bound(x => x.AttributeControlType); + columns.Bound(x => x.TextPrompt); + columns.Bound(x => x.CustomData); columns.Bound(x => x.IsRequired) - .Width("10%") - .ClientTemplate(@Html.SymbolForBool("IsRequired")) + .ClientTemplate(Html.SymbolForBool("IsRequired")) .Centered(); columns.Bound(x => x.DisplayOrder1) - .Width("10%") .Centered(); columns.Bound(x => x.ViewEditUrl) - .Width("16%") .ClientTemplate( "<#= ViewEditText #>" + "" @@ -91,7 +87,7 @@ commands.Edit().Localize(T); commands.Delete().Localize(T); }) - .Width("20%") + .Width("15%") .HtmlAttributes(new { align = "right" }); }) .ToolBar(commands => commands.Insert() ) diff --git a/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs b/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs index 3d22bd571b..1afe28bf74 100644 --- a/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs +++ b/src/Presentation/SmartStore.Web/Controllers/CatalogHelper.cs @@ -783,6 +783,7 @@ public ProductDetailsModel PrepareProductDetailModel( Name = attribute.ProductAttribute.GetLocalized(x => x.Name), Description = attribute.ProductAttribute.GetLocalized(x => x.Description), TextPrompt = attribute.TextPrompt, + CustomData = attribute.CustomData, IsRequired = attribute.IsRequired, AttributeControlType = attribute.AttributeControlType, AllowedFileExtensions = _catalogSettings.FileUploadAllowedExtensions @@ -1032,7 +1033,7 @@ public ProductDetailsModel PrepareProductDetailModel( foreach (var attribute in model.ProductVariantAttributes) { var updatePreSelection = selectedValueIds.Any() && selectedValueIds.Intersect(attribute.Values.Select(x => x.Id)).Any(); - var hideAttribute = true; + //var hideAttribute = true; foreach (ProductDetailsModel.ProductVariantAttributeValueModel value in attribute.Values) { @@ -1058,30 +1059,33 @@ public ProductDetailsModel PrepareProductDetailModel( value.IsDisabled = true; value.IsHidden = product.HideUnavailableAttributes; - // Set title attribute for unavailable option. - if (product.DisplayStockAvailability && availabilityInfo.IsOutOfStock && availabilityInfo.IsActive) + if (!value.IsHidden) { - value.Title = product.BackorderMode == BackorderMode.NoBackorders || product.BackorderMode == BackorderMode.AllowQtyBelow0 - ? res["Products.Availability.OutOfStock"] - : res["Products.Availability.Backordering"]; - } - else - { - value.Title = res["Products.Availability.IsNotActive"]; + // Set title attribute for unavailable option. + if (product.DisplayStockAvailability && availabilityInfo.IsOutOfStock && availabilityInfo.IsActive) + { + value.Title = product.BackorderMode == BackorderMode.NoBackorders || product.BackorderMode == BackorderMode.AllowQtyBelow0 + ? res["Products.Availability.OutOfStock"] + : res["Products.Availability.Backordering"]; + } + else + { + value.Title = res["Products.Availability.IsNotActive"]; + } } } - if (!value.IsDisabled && !value.IsHidden) - { - hideAttribute = false; - } + //if (!value.IsDisabled && !value.IsHidden) + //{ + // hideAttribute = false; + //} } - if (hideAttribute) - { - attribute.IsHidden = true; - attribute.IsRequired = false; - } + //if (hideAttribute) + //{ + // attribute.IsHidden = true; + // attribute.IsRequired = false; + //} } } } diff --git a/src/Presentation/SmartStore.Web/Views/Shared/ChoiceTemplates/Choice.Box.cshtml b/src/Presentation/SmartStore.Web/Views/Shared/ChoiceTemplates/Choice.Box.cshtml index 8ed4d36f5d..c56613be99 100644 --- a/src/Presentation/SmartStore.Web/Views/Shared/ChoiceTemplates/Choice.Box.cshtml +++ b/src/Presentation/SmartStore.Web/Views/Shared/ChoiceTemplates/Choice.Box.cshtml @@ -4,7 +4,7 @@ @{ var controlId = Model.BuildControlId(); - var items = Model.Values ?? new List(); + var items = Model.Values.Where(x => !x.IsHidden) ?? Enumerable.Empty(); }
diff --git a/src/Presentation/SmartStore.Web/Views/Shared/ChoiceTemplates/Choice.CheckRadio.cshtml b/src/Presentation/SmartStore.Web/Views/Shared/ChoiceTemplates/Choice.CheckRadio.cshtml index ffeb3f7613..c994cb3dac 100644 --- a/src/Presentation/SmartStore.Web/Views/Shared/ChoiceTemplates/Choice.CheckRadio.cshtml +++ b/src/Presentation/SmartStore.Web/Views/Shared/ChoiceTemplates/Choice.CheckRadio.cshtml @@ -5,7 +5,7 @@ @{ var controlId = Model.BuildControlId(); - var items = Model.Values ?? new List(); + var items = Model.Values.Where(x => !x.IsHidden) ?? Enumerable.Empty(); var type = Model.AttributeControlType == AttributeControlType.Checkboxes ? "checkbox" : "radio"; // TODO: (mc) Replace .checkbox with .form-check } diff --git a/src/Presentation/SmartStore.Web/Views/Shared/ChoiceTemplates/Choice.Dropdown.cshtml b/src/Presentation/SmartStore.Web/Views/Shared/ChoiceTemplates/Choice.Dropdown.cshtml index 621147b98e..8804008679 100644 --- a/src/Presentation/SmartStore.Web/Views/Shared/ChoiceTemplates/Choice.Dropdown.cshtml +++ b/src/Presentation/SmartStore.Web/Views/Shared/ChoiceTemplates/Choice.Dropdown.cshtml @@ -4,7 +4,7 @@ @{ var controlId = Model.BuildControlId(); - var items = Model.Values ?? new List(); + var items = Model.Values.Where(x => !x.IsHidden) ?? Enumerable.Empty(); }