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,