Thursday 22 May 2008

DynamicData - Limit the Filter Fields

Articles in this Series

Limit the Filter Fields

Below is the attribute and helper class.

using System;
using System.Linq;
using System.Web.DynamicData;

/// <summary>
/// attribute to suppress an MetaChildColumn or MetaParetnColumn in the 
/// filter repeater
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class HideInFilterAttribute : System.Attribute
{
    // this property is required to work with "AllowMultiple = true" ref David Ebbo
    // As implemented, this identifier is merely the Type of the attribute. However, 
    // it is intended that the unique identifier be used to identify two 
    // attributes of the same type.
    public override object TypeId { get { return this; } }

    /// <summary>
    /// Constructor
    /// </summary>
    public HideInFilterAttribute()
    {
    }
}

/// <summary>
/// Permissions Attributes Helper Extension Methods
/// </summary>
public static class HideInFilterAttributesHelper
{
    public static Boolean ContainsHideInFilter(this MetaColumn column)
    {
        // thanks to Marcin Dobosz for this really elegant code
        return column.Attributes.OfType<HideInFilterAttribute>().FirstOrDefault() != null;
    }
}
Listing 1

Sample metadata

[MetadataType(typeof(OrderMetadata))]
public partial class Order
{
}

public class OrderMetadata
{
    // entities
    [HideInFilter]
    public Object Employee { get; set; }
}
Listing 2

And in the code on the page (i.e. List.aspx.cs) an OnItemDataBound="FilterRepeater_ItemDataBound" is added to the FilterRepeater.

<asp:FilterRepeater 
    ID="FilterRepeater" 
    runat="server" 
    onitemdatabound="FilterRepeater_ItemDataBound" >
Listing 3

In the OnItemDataBound method I check for the metadata using the helper method (which make the code more readable) and set the e.Item.Visible = false.

protected void FilterRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    var column = e.Item.DataItem as MetaColumn;
    if (column != null)
    {
        if (column.ContainsHideInFilter())
            e.Item.Visible = false;
    }
}
Listing 4

Now just by adding metadata to any field (MetaForeignKeyColumn or MetaChildrenColumn), then that filter field can be hidden.

12 comments:

Anonymous said...

Hello, many thanks for your work. I have a question, how would I have to modify this code to hide the filters by role?

Thanks in advance.

Stephen J. Naughton said...

Hi there Anonymous, e-mail me and I'll send you a sample that workes by roles.

Steve :)

mbendahan said...

Hi Steve...
Could you send mee too?

Stephen J. Naughton said...

Hi Chelo send me an e-mail and I'll sent it to you also.

Steve

Bob said...

Im using a DD4 site, I take it this was written for an different version. I'm getting the error

'System.Web.DynamicData.QueryableFilterRepeater' does not have a public property named 'OnItemDataBound'.

What do I need to change for this to work?

Stephen J. Naughton said...

yes this was written for either DDv1 or the old future project, if you look at my http://csharpbits.notaclue.net/2011/06/more-nuget.html Dynamic Data Extensions this has filter ordering etc.

Bob said...

I wish to disable the dropdown list for on of the foreign keys, I have this

[Filter(Hidden=true)]
public object Customer { get; set; }

But doesn't work, is what I'm doing ok?

Stephen J. Naughton said...

Bob, this is too cumbersom to solve these issue just e-mail me direct.

P.S. always state which version of .Net + Service Pack you are running and version of Visual Studio if relavent.

Steve

Unknown said...

Hello Steve,

Please send us an application.
Email id: samirjikadia@gmail.com

Best Regards,
Samir

James Manning said...

In case anyone else runs across this post, in the 2012 bits for dynamic data there is now built-in support for this - specifically, you can add [Display(AutoGenerateFilter = false)] and it works great!

http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute.autogeneratefilter.aspx

Stephen J. Naughton said...

Hi James, this does not work with DD 4 or 4.5 as the filter system is completly different.

Steve

LA Guy said...

Hi Steve and James,

I have a .Net 4.5 Dyn Data project
and the AutoGenerateFilter parameter works to hide or show the Filter Dropdown.

//[Display(Name = "Site ID", Order = 8, AutoGenerateFilter=false )]
[Display(Name = "Site ID", Order = 8, AutoGenerateFilter = true)]
public Site Site { get; set; }

Thanks for all your hard work.

Best, LA Guy