How to make content item selectable sortable in widget
I have created on widget and defined one content item selector property called links
now when i select multiple activities it displays as a list in UI. Here is example:
now when i change order like moving last link to first it does not change order in ui. when delete all and select again with new order then it shows with new order. but i want to apply the changes when i change the order. It is working in my page template . but not in widget. So is there anything that i am missing. Here is the code responsible
var bannerGuids = vm?.Properties?.SelectedNavigationItems.Select(i => i.Identifier).ToList();
var query = new ContentItemQueryBuilder()
.ForContentType(NavigationItem.CONTENT_TYPE_NAME, config => config
.WithLinkedItems(3)
.Where(where => where
.WhereIn(nameof(IContentQueryDataContainer.ContentItemGUID), bannerGuids)));
IEnumerable<NavigationItem> SelectedNavigationItems = await _contentQueryExecutor.GetMappedResult<NavigationItem>(query);
model.NavigationItems = SelectedNavigationItems.ToList();
Environment
Xperience by Kentico version: [30.5.3]
.NET version: [8]
Answers
You have to order the query results based on the order of the GUID values in the widget property.
SQL doesn't have a simple way to do that ordering in the database.
Okay, so what i understand is that i have to do that in backend while retrieving the data. Something like this:
model.NavigationItems = SelectedNavigationItems.OrderBy(x => bannerGuids.IndexOf(x.SystemFields.ContentItemGUID)).ToList();
One more thing i want to know that why i have to do it with widget property and not page template content types ??
When retrieving content by content item directly (with IContentRetriever
or ContentItemQueryBuilder
) you are asking Xperience to build the graph of linked items and populate all them.
From this API example, if the CandyStore
content type has many linked items Xperience will auto populate those when querying for the CandyStore
(assuming you set the query depth for linked items correctly with .WithLinkedItems(X)
).
This means Xperience will order the linked content items for you because it's already doing all the linked querying and model hydration.
If instead you have a widget property using the combined content selector, it's not returning populated content items - it returns an array of ContentItemGUID
. It's your responsibility to query for them.
At no point in your query have you told Xperience "these results need to be in a specific order", right?? SQL doesn't magically know that you want a set of rows returned in a specific order. It's your responsibility to tell it that using a SQL ORDER BY
clause.
But SQL requires that ORDER BY
to be a specific column or computed value the result set. There's no good way to do this when passing an array of values for the WHERE IN
part of the SQL query.
The content items returned from your query where you passed the ContentItemGUID
array will have all their linked content items in the correct order, but that's because Xperience knows those are supposed to be in that order. WHERE IN
doesn't imply any specific order in any dialect of SQL.
By the way, this is the exact same topic you asked about previously 😄.
To answer this question, you have to login first.