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