Ordering module builder data by the choices column

Posted by Community Admin on 04-Aug-2018 19:14

Ordering module builder data by the choices column

All Replies

Posted by Community Admin on 16-Apr-2012 00:00

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 don't like ordering so late on looped output, but I had trouble with it working on retrieval. 

This might be simplified if there was an extension method that resolved the 1st item in the choices string array. It could be named something like .GetFirstValue('choices_column').

Posted by Community Admin on 19-Sep-2012 00:00

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.

Thanks for the informative post!

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;

Posted by Community Admin on 21-Sep-2012 00:00

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));

I haven't tested this out. Just seems that if you should be able to cast the GetValue call as a sting array and then check to see if the array contains your value.

Posted by Community Admin on 11-Apr-2013 00:00

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.

Posted by Community Admin on 11-Apr-2013 00:00

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"));

Posted by Community Admin on 12-Apr-2013 00:00

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,
Pavel Benov
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

This thread is closed