Extend Umbraco Backoffice Member Search to include additional custom properties
Hello, I am trying to extend the search capabilities of the backoffice members search to include the additional custom fields I have added to the members.
This is the backoffice search that I want to modify
Right now when I enter a search string, the only fields it searches are the default Name, Username, and Email fields. I would like the search to also return matching strings in fields like First Name, Last Name, and Company, which are all custom fields I have created.
I was trying to follow this guide https://dev.to/skttl/how-to-customize-searching-in-umbraco-list-views-1knk that someone had recommended, but my implementation of it is not working. I had to modify a few parts of the example they gave to update to my Umbraco version (v 13.2.2), so I am unsure if it was something I did that caused this not to work or if this is the wrong way to go about this in general.
In any case, is there a way to extend the backoffice member search to include custom fields? I am using the latest Umbraco version (v 13.2.2)
This is the only way I can think to do it, as the search is actioned directly against the database and is't 'pluggable' easily with a different implementation.
Soren's technique relies on being able to intercept the request in angularJS and replace it with the results from his own apicontroller results...
if it's still possible to do that interception step in V13, then it should still be possible to take that approach.
Otherwise, you could create your own custom dashboard, but it's a lot of work when you just want to search by another field, and particularly when there is a mechanism to add extra search fields for members to the main backoffice search!
As far as I know it should still be possible. Like I said, i've had to modify a few things from the example. One of those modifications that I am having trouble with is the intercepter.js file, where the request url is redirected. In his code, he has the following
if (request.url.indexOf("backoffice/UmbracoApi/Content/GetChildren?id=") > -1)
Which works for him because the Content section of the Backoffice. I have tried replacing it with
if (request.url.indexOf("backoffice/UmbracoApi/Members/GetChildren?id=") > -1)
But this does not seem to work.
Any idea on what the correct request url would be/how to find it? I'm currently looking through the backoffice Member Controller and the GetPagedResults and GetListNodeDisplay functions look promising, but I am not sure that they are the correct requests for this
Marc, thank you. Your method of using the dev tools to find the request url helped me find the correct solution.
To give the original question an official answer, you can follow Soren's guide with a few alterations
The correct url request for a member search is "backoffice/umbracoapi/member/GetPagedResults", you need to replace the parts in the javascript intercepter that say "backoffice/UmbracoApi/Content/GetChildren?id=" with "backoffice/umbracoapi/member/GetPagedResults".
For searching the member list, you need to implement a Custom MemberSearchController, instead of a ListViewSearchController. The function in the original MemberSearchController you need to replace is GetPagedResults.
Mine looks like the following
public PagedResult<MemberBasic> GetPagedResultsCustom(
int pageNumber = 1,
int pageSize = 100,
string orderBy = "username",
Direction orderDirection = Direction.Ascending,
bool orderBySystemField = true,
string filter = "",
string? memberTypeAlias = null)
{
if (pageNumber <= 0 || pageSize <= 0)
{
throw new NotSupportedException("Both pageNumber and pageSize must be greater than zero");
}
//Add search logic here, the default is
//IMember[] members = _memberService.GetAll(
// pageNumber - 1,
// pageSize,
// out var totalRecords,
// orderBy,
// orderDirection,
// orderBySystemField,
// memberTypeAlias,
// filter).ToArray();
//if (totalRecords == 0)
//{
// return new PagedResult<MemberBasic>(0, 0, 0);
//}
if (totalRecords == 0)
{
return new PagedResult<MemberBasic>(0, 0, 0);
}
var pagedResult = new PagedResult<MemberBasic>(totalRecords, pageNumber, pageSize)
{
Items = members.Select(x => _umbracoMapper.Map<MemberBasic>(x)).WhereNotNull()
};
return pagedResult;
}
Hope this helps anyone looking to implement this functionality in the future, and again thank you Marc for showing me the cool trick with the Network dev tools
Extend Umbraco Backoffice Member Search to include additional custom properties
Hello, I am trying to extend the search capabilities of the backoffice members search to include the additional custom fields I have added to the members.
This is the backoffice search that I want to modify
Right now when I enter a search string, the only fields it searches are the default Name, Username, and Email fields. I would like the search to also return matching strings in fields like First Name, Last Name, and Company, which are all custom fields I have created.
I was trying to follow this guide https://dev.to/skttl/how-to-customize-searching-in-umbraco-list-views-1knk that someone had recommended, but my implementation of it is not working. I had to modify a few parts of the example they gave to update to my Umbraco version (v 13.2.2), so I am unsure if it was something I did that caused this not to work or if this is the wrong way to go about this in general.
In any case, is there a way to extend the backoffice member search to include custom fields? I am using the latest Umbraco version (v 13.2.2)
Hi Matthew
This is the only way I can think to do it, as the search is actioned directly against the database and is't 'pluggable' easily with a different implementation.
Soren's technique relies on being able to intercept the request in angularJS and replace it with the results from his own apicontroller results...
if it's still possible to do that interception step in V13, then it should still be possible to take that approach.
Otherwise, you could create your own custom dashboard, but it's a lot of work when you just want to search by another field, and particularly when there is a mechanism to add extra search fields for members to the main backoffice search!
regards
Marc
As far as I know it should still be possible. Like I said, i've had to modify a few things from the example. One of those modifications that I am having trouble with is the intercepter.js file, where the request url is redirected. In his code, he has the following
Which works for him because the Content section of the Backoffice. I have tried replacing it with
But this does not seem to work.
Any idea on what the correct request url would be/how to find it? I'm currently looking through the backoffice Member Controller and the GetPagedResults and GetListNodeDisplay functions look promising, but I am not sure that they are the correct requests for this
Hi Matthew
What I've found sometimes works is:
go to the page with the functionality you sneakily want to intercept.
open chrome dev tools and on the Network tab, filter requests by Fetch/XHR.
Then clear all the existing list of requests
And then perform the activity you want to intercept, eg do the member search...
Then you should see the request being made in the browser, I think for a Member search it might be this:
regards
Marc
Marc, thank you. Your method of using the dev tools to find the request url helped me find the correct solution.
To give the original question an official answer, you can follow Soren's guide with a few alterations
The correct url request for a member search is "backoffice/umbracoapi/member/GetPagedResults", you need to replace the parts in the javascript intercepter that say "backoffice/UmbracoApi/Content/GetChildren?id=" with "backoffice/umbracoapi/member/GetPagedResults".
For searching the member list, you need to implement a Custom MemberSearchController, instead of a ListViewSearchController. The function in the original MemberSearchController you need to replace is GetPagedResults.
Mine looks like the following
int pageNumber = 1, int pageSize = 100, string orderBy = "username", Direction orderDirection = Direction.Ascending, bool orderBySystemField = true, string filter = "", string? memberTypeAlias = null) { if (pageNumber <= 0 || pageSize <= 0) { throw new NotSupportedException("Both pageNumber and pageSize must be greater than zero"); }
}
Hope this helps anyone looking to implement this functionality in the future, and again thank you Marc for showing me the cool trick with the Network dev tools
is working on a reply...