Ordering module builder data by the choices column
I am sharing this solution to sort results by the Module Builder's 'choices' type because it works and may be useful to you. I am interested in feedback and suggestions if you have a better method.
I have built a custom user control to output this dynamic module data that uses OrderBy for the choices field. Here is the relevant code:
// req'd for GetValue()
using
Telerik.Sitefinity.Model;
// This is Module Builder boiler plate code needed to access the custom module:
DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager();
Type jobOpeningType = TypeResolutionService.ResolveType(
"Telerik.Sitefinity.DynamicTypes.Model.JobOpenings.JobOpening"
);
// First thing we're doing is making sure that we're not getting any duplicates
and only getting published items.var jobs = dynamicModuleManager.GetDataItems(jobOpeningType).Where(i => i.Status == ContentLifecycleStatus.Live && i.Visible ==
true
).ToList();
// This foreach loops over all published jobs and sorts them by "Category" - our choices column.
// Sorting a dropdown in a custom module is awkward.
// "Category" (the choice column) must be resolved before it can be sorted.
// To resolve it, you must use Sitefinity's GetValue(), which returns a String[] (of choices).
// Then you need to grab the first string in the array with the appropriate
casts and methods.// This works because we only allow 1 choice to be selected.
foreach
(var job
in
jobs.OrderBy(j => (
string
)((Array)j.GetValue(
"Category"
)).GetValue(0)))
// job is now filtered for currently published and is sorted by the choices column
// YOU MAY DO SOMETHING WITH job HERE
// If you need the string value of "Category" (the choice) as string,
// you will need to repeat the process above:
string
Category = (
string
)((Array)job.GetValue(
"Category"
)).GetValue(0);
I'm glad I found this... I needed to do something similar -- limiting the result set of a dynamic module based on a choices column. I looked around the net for over 30 minutes and tried several different approaches at the retrieval level but nothing seemed to work. I finally resorted to returning the full data set and checking for each record in the result set before adding it to a list that gets returned from the method. I pasted my code below in case it can provide help to anyone.
public
static
List<Course> Search(
string
category)
Course course =
new
Course();
var dynamicModuleManager = DynamicModuleManager.GetManager();
Type type = TypeResolutionService.ResolveType(course.TYPE_NAME);
var items = dynamicModuleManager.GetDataItems(type).Where(item => item.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live);
if
(!
string
.IsNullOrEmpty(category))
// Ideally this would be done in the query but it doesn't work.
// For Time being, doing this in Foreach loop below until an actual solution can be found.
// items = items.Where(((string)((Array)item.GetValue("Category")).GetValue(0)) == category);
List<Course> list =
new
List<Course>();
foreach
(DynamicContent item
in
items)
// Only add content to result set if category matches
if
(
string
.IsNullOrEmpty(category) || ((
string
)((Array)item.GetValue(
"Category"
)).GetValue(0)) == category)
list.Add(
new
Course(item));
return
list;
Andrew,
Could you not use the following to filter out the data:
if (!string.IsNullOrEmpty(category))
items = items.Where(item => item.GetValue<
string
[]>("Category").Contains(category));
Has anyone come up with a better way of sorting items by the choice selected? I am surprised I have not found more information on this topic considering 'choice' is a useful field in Module Builder.
I have found that converting the IQueryable() to an IEnumerable() by using .ToList() makes sorting by choice much easier. I understand there are drawbacks to doing that, but it provides the opportunity to use .FirstOrDefault() to sort by the selected choice.
var myCollection = dynamicModuleManager.GetDataItems(jobOpeningType)
.Where(x => x.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live)
.ToList()
// Very, very important for sorting choices -- allows First() and FirstOrDefault()
.OrderBy(j => (
string
)j.GetValue<
string
[]>(
"Category"
).FirstOrDefault())
.ThenBy(z => z.GetValue<
string
>(
"Title"
));
Hi guys,
Thank you for sharing your observations with the community. I am sure other users will find those really helpful. As a token of appreciation I have adjusted your Telerik points accordingly.
Kind regards,