1-888-365-2779
+1-888-365-2779
Try Now
More in this section

Forums / Developing with Sitefinity / Ordering module builder data by the choices column

Ordering module builder data by the choices column

6 posts, 0 answered
  1. Dan Sorensen
    Dan Sorensen avatar
    256 posts
    Registered:
    13 Aug 2010
    16 Apr 2012
    Link to this post
    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').
  2. Andrew
    Andrew avatar
    6 posts
    Registered:
    16 Mar 2012
    19 Sep 2012
    Link to this post
    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;
    }

  3. Richard Baugh
    Richard Baugh avatar
    201 posts
    Registered:
    22 Aug 2012
    21 Sep 2012
    Link to this post
    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.
  4. Dan Sorensen
    Dan Sorensen avatar
    256 posts
    Registered:
    13 Aug 2010
    11 Apr 2013 in reply to Richard Baugh
    Link to this post
    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.
  5. Dan Sorensen
    Dan Sorensen avatar
    256 posts
    Registered:
    13 Aug 2010
    11 Apr 2013 in reply to Dan Sorensen
    Link to this post
    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"));
  6. Pavel Benov
    Pavel Benov avatar
    341 posts
    Registered:
    14 Mar 2016
    12 Apr 2013
    Link to this post
    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
6 posts, 0 answered