More in this section
Forums / Module Builder / Dynamically filtering content on hierarchical categories

Dynamically filtering content on hierarchical categories

The forums are in read-only mode. In case that you want to directly contact the Progress Sitefinity team use the support center. In our Google Plus group you can find more than one thousand Sitefinity developers discussing different topics. For the Stack Overflow threads don’t forget to use the “Sitefinity” tag.
2 posts, 0 answered
  1. Andy
    Andy avatar
    0 posts
    Registered:
    29 Jan 2016
    26 Sep 2016
    Link to this post

    Our solution calls for a number of dynamic content items with a hierarchical category field containing any number of taxons.

    The hierarchical structure is separated into n category groups.  For example: Size { Large, Medium, Small } and Color { Red Green Blue }.

    The UI allows a user to select any number of these to filter the content. eg. Large + Red + Green should return anything Large & Red or Large & Green. The selected taxons are returned to the server as a 2D array of Guids (the above selection would be [[Large], [Red, Green]]).

    I have been able to filter by a single filter group, but when I try to add a second filter group no results are returned even though I have content that should fit the criteria. My code is:

    [HttpPost]
    [RelativeRoute("GetProducts")]
    public JsonResult GetProducts(ProductListRequest request)
    {
        var products = GetProducts();
        products = FilterProducts(products, request);
     
        var response = new ProductListResponse(request.Page, ProductsPerPage);
        response.AllProductsCount = products.Count();
     
        if (request.Page >= 0)
        {
            products = products.Skip(request.Page * ProductsPerPage).Take(ProductsPerPage);
        }
     
        response.Products = products;
     
        return Json(response);
    }
     
    public static IQueryable<DynamicContent> GetProducts()
    {
        DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager("OpenAccessProvider");
        Type productType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.MyModule.Product");
        return dynamicModuleManager.GetDataItems(productType).Where(p => p.Status == ContentLifecycleStatus.Live);
    }
     
    public static IQueryable<DynamicContent> FilterProducts(IQueryable<DynamicContent> products, ProductListRequest request)
    {
        if (request.FilterList == null) return products;
     
        foreach (Guid[] filterlist in request.FilterList.Where(x => x != null))
        {
            products = FilterByCategory(products, filterlist);
        }
     
        return products;
    }
     
    private static IQueryable<DynamicContent> FilterByCategory(IQueryable<DynamicContent> products, Guid[] categories)
    {
        if (categories.Any())
        {
            products = products.Where(p => p.GetValue<TrackedList<Guid>>("Category").Any(g => categories.Contains(g)));
        }
     
        return products;
    }

     

    Here is an example of a filter against 2 taxon groups which returns no results: 

    {Extent<Telerik.Sitefinity.DynamicTypes.Model.MyModel.Product>().Where(re-p => (re-p.ApplicationName == OpenAccessProvider.ApplicationName)).Where(re-p => (Convert(Convert(Convert(Convert(Convert(Convert(Convert(re-p.Status))))))) == 2)).Where(re-p => re-p.FieldValue("Category").Any(g => value(SitefinityWebApp.MyApp.Products+<>c__DisplayClass3_0).categories.Contains(g))).Where(re-p => re-p.FieldValue("Category").Any(g => value(SitefinityWebApp.MyApp.Products+<>c__DisplayClass3_0).categories.Contains(g)))}

    Please help me understand why this is not working.

  2. Andy
    Andy avatar
    0 posts
    Registered:
    29 Jan 2016
    26 Sep 2016 in reply to Andy
    Link to this post

    Just an update. I have found that using the IEnumerable.Where() works, but the IQueryable.Where() does not. I am guessing this is a result of deferred execution, trying to mix the IEnumerable Guid[] with the IQueryable content collection. 

    I am not keen on the idea of resolving the IQueryable to an IEnumerable to get this to work, so I would be interested to learn if anybody has solved this in any other ways.

2 posts, 0 answered