Dear Dynamicweb,
Is there a way where we can create custom-selector like product-group-selector as in pic, and in there data are taken from outside dynamicweb?
Thanks
Best Regards,
Oliver
Dear Dynamicweb,
Is there a way where we can create custom-selector like product-group-selector as in pic, and in there data are taken from outside dynamicweb?
Thanks
Best Regards,
Oliver
Hi
Yes, you can implement a selector provider:
https://doc.dynamicweb.dev/api/Dynamicweb.CoreUI.Editors.Selectors.SelectorProviderBase.html
Here is an example of our provider for the above selector:
public class ProductGroupSelectorProvider : SelectorProviderBase<string>, IProductGroupSelectorProvider, ISelectorProviderWithLinkValue { private const int ColumnCount = 1; private static NavigationNodePath BasePath => new(typeof(ProductsArea).FullName); public Icon LinkIcon { get => Icon.Folder; } public string LinkType { get => "product-group"; } public string LinkName { get => "Product group"; } public bool ShowShops { get; set; } = true; public bool ShowChannels { get; set; } = true; public bool ShowWarehouses { get; set; } = true; public bool ShowDataStructures { get; set; } = true; public bool ShowDataModels { get; set; } = true; public bool AllowShopSelection { get; set; } = true; public List<string>? UnselectableGroupIds { get; set; } public List<string>? HiddenGroupIds { get; set; } public ProductGroupSelectorProvider() : base(ColumnCount) { } public override SelectorDefinitionModel GetDefinition() { return new() { ColumnCount = ColumnCount, Heading = AllowShopSelection ? "Select" : "Select group" }; } protected override UiComponentBase? GetColumnContent(int columnIndex) => columnIndex switch { 1 => GetGroupList(), _ => null }; private ShowScreen GetGroupList() { return new ShowScreen { Value = typeof(TreeScreen), Query = new GroupNavigationByPathQuery { Path = BasePath.Path, DisplayState = NavigationComponentDisplayState.Minimal, ShowShops = ShowShops, ShowChannels = ShowChannels, ShowWarehouses = ShowWarehouses, ShowDataStructures = ShowDataStructures, ShowDataModels = ShowDataModels, AllowShopSelection = AllowShopSelection, ShouldReturnValueAsLink = true, UnselectableGroupIds = UnselectableGroupIds, HiddenGroupIds = HiddenGroupIds }, Load = ShowScreen.LoadMethod.Inline }; } public override IEnumerable<SelectedItem>? GetSelectedItems(IEnumerable<string> selectedValues) { if (selectedValues is not null) { var query = new ProductCatalogGroupByIdQuery(); return selectedValues.Select(groupId => { if (string.IsNullOrWhiteSpace(groupId)) return new SelectedItem() { Id = groupId, Name = groupId, IsInvalid = true }; query.Id = groupId; var group = query.GetModel(); return GetSelectedItemFromGroup(groupId, group?.Name ?? groupId); }); } return null; } internal static SelectedItem GetSelectedItemFromGroup(string groupId, string groupName) => new() { Id = groupId, Name = groupName, Link = $"groupid={groupId}", DisplayName = $"{groupName} (ID: {groupId})", }; public void ConfigureForLink(Link link) { ShowChannels = true; ShowWarehouses = true; } }
Then we create the selector like this:
public static Selector CreateProductGroupSelector(ProductGroupSelectorOptions? options) { options ??= new(); var provider = AddInManager.GetInstance<IProductGroupSelectorProvider>() ?? throw new InvalidOperationException($"Unable to resolve instance of {typeof(IProductGroupSelectorProvider).FullName}."); provider.ShowShops = options.ShowShops; provider.ShowChannels = options.ShowChannels; provider.ShowWarehouses = options.ShowWarehouses; provider.ShowDataStructures = options.ShowDataStructures; provider.ShowDataModels = options.ShowDataModels; provider.AllowShopSelection = options.AllowShopSelection; provider.UnselectableGroupIds = options.UnselectableGroupIds; provider.HiddenGroupIds = options.HiddenGroupIds; var selector = CreateSelectorByProvider(provider as SelectorProviderBase<string>, options?.Hint, options?.Explanation, options?.Multiselect, Icons.Icon.Archive); if (!string.IsNullOrEmpty(options?.Value)) selector.SetValue(options.Value); bool multiselect = options?.Multiselect ?? false; selector.EmptyStateText = multiselect ? "Select product groups" : "Search product group"; selector.Hint = options?.Hint ?? (multiselect ? "Search or browse for product groups" : "Search or browse for a product group"); selector.EmptyStateSearchText = "Search product groups"; return selector; }
And use it like this:
public override EditorBase? GetEditor(string propertyName, PageDataModel? model) => propertyName switch { nameof(model.NavigationUseEcomGroups) => new Checkbox() { ReloadOnChange = true }, nameof(model.NavigationProvider) => CreateNavigationProviderSelect(), nameof(model.NavigationParentType) => CreateNavigationParentTypeSelect(), nameof(model.NavigationGroups) => SelectorBuilder.CreateProductGroupSelector(new() { Multiselect = true }), nameof(model.NavigationShopId) => EditorHelper.GetShopEditor(), nameof(model.NavigationMaxLevels) => CreateNavigationMaxLevelsSelect(), nameof(model.NavigationProductPage) => SelectorBuilder.CreatePageSelector(areaId: model?.AreaId), _ => null };
Hello,
Thank you Nicolai.
Best Regards,
Oliver
You must be logged in to post in the forum