SitePoint Sponsor

User Tag List

Results 1 to 25 of 25
  1. #1
    always learning . . .
    Join Date
    Nov 2003
    Location
    UK
    Posts
    821
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Alphabet filter for GridView

    Currently I have a GridView on a page with edit/delete functionality enabled. For the Data Source I am using an ObjectDataSource.

    I have say 300 items in this list. 10 per page with paging.

    It would take too long to navigate to the middle to change an item beggining with the letter "m", but even more importantly be annoying.

    What I ask is how does one go about creating an Alphabet filter A to Z so when a letter is pressed the GridView uses this argument to filter all items beginning with the letter pressed???

    Thanks all, I have tried looking online but found nothing. May be in the wrong place?
    Last edited by Tezler; Feb 4, 2007 at 14:48.

  2. #2
    always learning . . .
    Join Date
    Nov 2003
    Location
    UK
    Posts
    821
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    No one with previous experience in doing this? Like a phone contact filter or something like that where letters of the alphabet filters/pages the results?

  3. #3
    SitePoint Mentor NightStalker-DNS's Avatar
    Join Date
    Jul 2004
    Location
    Cape Town, South Africa
    Posts
    2,878
    Mentioned
    47 Post(s)
    Tagged
    0 Thread(s)
    U can do it with a SQL query string:

    select [column] from [table] where [column] like 'm%'

    That will return every entry that starts with m.

  4. #4
    always learning . . .
    Join Date
    Nov 2003
    Location
    UK
    Posts
    821
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    whilst I know the SQL above will work and return the correct data. The question was more about the implementation into the application and GridView.

    Knowing the current setup is:

    DataTable
    BusinessLogic

    The GridView is populated using an ObjetcDataSource who's source is the BusinessLogic.

    Question is how I go about firstly creating the alphabet, using the querystring to change the data, etc.

  5. #5
    always learning . . .
    Join Date
    Nov 2003
    Location
    UK
    Posts
    821
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So I found the FilterExpression property
    Code:
    DataSourceTeamsAdmin.FilterExpression = "TeamName LIKE 'b%'";
    This works super. At the moment I use a button and onClick set the above.

    What would be the best way to create an alphabet of buttons? That do not look like buttons each with a click event. They could even fire the same event but pass in the argument of the letter.

    Any one with ideas? ALSO paging the records loses the filtered state. How can I persist the filtered stage whilst paging?

  6. #6
    always learning . . .
    Join Date
    Nov 2003
    Location
    UK
    Posts
    821
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Any one with experience for keeping the data filtered while paging?

  7. #7
    SitePoint Guru pufa's Avatar
    Join Date
    Oct 2004
    Location
    Portugal, Lisboa
    Posts
    947
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    string[] alphabet = {"a", "b", "c" ...};

    repeater with a link button...

    <repeater id="xpto"...>
    <ItemTemplate>
    <asp:LinkButton .... CommandArgument="... bind the letter here... " CommandName="GridFilterClick"
    </ItemTemplate>
    </repeater>

    protected void GridFilterClick(object sender, CommandEventArgs e)
    {
    string letter = e.CommandArgument as string;
    if (letter != null)
    {
    // 1 .Validate letter
    // 2 .Store current letter in ViewState for reference in other postback events.
    // 3 .Pass letter as parameter to ObjectDataSource
    // 4 .Fire the ObjectDataSource and get the records from database.
    }

    }


    this would avoid having to load all records into a DataTable to filter the data with filter expressions.
    Last edited by pufa; Feb 6, 2007 at 19:40.
    Ciao, Rui...

  8. #8
    always learning . . .
    Join Date
    Nov 2003
    Location
    UK
    Posts
    821
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That makes sense when reading but since I am new it's the implementation that seems to be the blur.

    I like and will use the way you use a repeater to create the alphabet.

    Also I understand that on click the command fires the GridFilterClick.

    How to store the letter in viewstate and still use this on different postback events like paging is still confusing me. Not sure how to go about this. Also the passing letter as parameter I do not know how to action. Do you have further details of how this is implemented?

  9. #9
    always learning . . .
    Join Date
    Nov 2003
    Location
    UK
    Posts
    821
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Can someone please explain in a little more detail how this is wired up?

    1) How is the alphabet array wired to the repeater?

    2) How do I pass the letter as a parameter to the ObjectDataSource?

    3) Following which how do you manually fire the ObjectDataSource (I mean how an earth does it know what it's firing from by BLL)?


    Help hugley appreciated :-)

  10. #10
    SitePoint Addict inverse.chi's Avatar
    Join Date
    May 2006
    Location
    Oxford, UK | Durham, UK
    Posts
    243
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I am working on a program that has exactly what you are describing, although i didn't make the program and i'm not that good at programming. but the programmer used labels for each of the letters and then using an objectdatasource linked to the gridview. Which links upto a class which pulls the data down using a stored procedure.

    I hope that helps.

  11. #11
    ALT.NET - because we need it silver trophybronze trophy dhtmlgod's Avatar
    Join Date
    Jul 2001
    Location
    Scotland
    Posts
    4,836
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Stuck together a simple example for you:

    aspx
    Code:
    <asp:Repeater ID="rptAlpha" runat="server" OnItemCommand="rptAlpha_ItemCommand">
                    <ItemTemplate>
                    <asp:LinkButton ID="lbAlpha" runat="server" CommandArgument='<%# Container.DataItem.ToString() %>'><%#Container.DataItem.ToString() %></asp:LinkButton>
                    </ItemTemplate>
                </asp:Repeater>
                <br />
                <asp:GridView ID="GridView1" runat="server" DataSourceID="ObjectDataSource1">
                </asp:GridView>
                <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" OldValuesParameterFormatString="original_{0}"
                    OnSelecting="ObjectDataSource1_Selecting" SelectMethod="Load" TypeName="Your.TypeName.Here">
                    <SelectParameters>
                        <asp:Parameter Name="Filter" Type="Object" />
                    </SelectParameters>
                </asp:ObjectDataSource>
    aspx.cs
    Code:
    protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack)
                return;
            
            BindAlphaRepeater();
        }
    
        private void BindAlphaRepeater()
        {
            string[] alphabet = {"a", "b", "c", "d", "e" };
    
            rptAlpha.DataSource = alphabet;
            rptAlpha.DataBind();
        }
    
        protected void rptAlpha_ItemCommand(object source, RepeaterCommandEventArgs e)
        {
            string filterleter = e.CommandArgument as string;
    
            if (filterleter == null)
                return;
    
            ViewState["filterletter"] = filterleter;
    
            GridView1.DataBind();
        }
    
        protected void ObjectDataSource1_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
        {
            // This is designed to return null, you might want to change it to a default value
            e.InputParameters["Filter"] = ViewState["filterletter"] as string     
        }
    
        protected void Button1_Click(object sender, EventArgs e)
        {
            Response.Write("Paging click");
            GridView1.DataBind();
        }

  12. #12
    always learning . . .
    Join Date
    Nov 2003
    Location
    UK
    Posts
    821
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Cheers dhtmlgod.

    Helps loads.

  13. #13
    always learning . . .
    Join Date
    Nov 2003
    Location
    UK
    Posts
    821
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    Line 1272:            this.Adapter.SelectCommand = this.CommandCollection[1];
    Line 1273:            if ((TeamName == null)) {
    Line 1274:                throw new System.ArgumentNullException("TeamName");
    Line 1275:            }
    Line 1276:            else {
    I am getting a
    Value cannot be null.
    Parameter name: TeamName
    Is this to do with the default null?

    I am not sure what that line is doing.

    Code:
    protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack)
                return;
    
            BindAlphaRepeater();
        }
    
        private void BindAlphaRepeater()
        {
            string[] alphabet = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
            rptAlpha.DataSource = alphabet;
            rptAlpha.DataBind();
        }
    
        protected void rptAlpha_ItemCommand(object source, RepeaterCommandEventArgs e)
        {
            string filterleter = e.CommandArgument as string;
    
            if (filterleter == null)
                return;
    
            ViewState["filterletter"] = filterleter;
    
            GridViewTeamsAdmin.DataBind();
        }
    
        protected void ObjectDataSource1_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
        {
            // This is designed to return null, you might want to change it to a default value
            e.InputParameters["letter"] = ViewState["filterletter"] as string;
        }
    Code:
    <asp:Repeater ID="rptAlpha" runat="server" OnItemCommand="rptAlpha_ItemCommand">
            <ItemTemplate>
            <asp:LinkButton ID="lbAlpha" runat="server" CommandArgument='<%# Container.DataItem.ToString() %>'><%#Container.DataItem.ToString() %></asp:LinkButton>
            </ItemTemplate>
        </asp:Repeater>
        
        <asp:ObjectDataSource ID="DataSourceTeamsAdmin" runat="server" 
        SelectMethod="GetTeamsByStartingLetter" DeleteMethod="DeleteTeam" 
        UpdateMethod="UpdateTeam" InsertMethod="AddTeam"
        TypeName="TeamsBLL" OldValuesParameterFormatString="team{0}">
            <SelectParameters>
                <asp:Parameter Name="letter" Type="String" />
            </SelectParameters>
            <DeleteParameters>
                <asp:Parameter Name="teamID" Type="Int32" />
            </DeleteParameters>
            <UpdateParameters>
                <asp:Parameter Name="teamName" Type="String" />
                <asp:Parameter Name="teamID" Type="Int32" />
            </UpdateParameters>
            <InsertParameters>
                <asp:Parameter Name="teamName" Type="String" />
            </InsertParameters>
        </asp:ObjectDataSource>
        
        <asp:GridView ID="GridViewTeamsAdmin" runat="server" ShowHeader="False"
        AutoGenerateColumns="False" DataKeyNames="ID" GridLines="None"
        DataSourceID="DataSourceTeamsAdmin" AllowPaging="True">
            <Columns>
    
            </Columns>
        </asp:GridView>

  14. #14
    ALT.NET - because we need it silver trophybronze trophy dhtmlgod's Avatar
    Join Date
    Jul 2001
    Location
    Scotland
    Posts
    4,836
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This line here:
    Code:
    // This is designed to return null, you might want to change it to a default value
    e.InputParameters["letter"] = ViewState["filterletter"] as string;
    One solution might be:
    Code:
    if ((TeamName == null))
       TeamName = "a default value";

  15. #15
    always learning . . .
    Join Date
    Nov 2003
    Location
    UK
    Posts
    821
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don't get what TeamName is though. Where is TeamTeam in the code supplied? Am I missing something?

  16. #16
    ALT.NET - because we need it silver trophybronze trophy dhtmlgod's Avatar
    Join Date
    Jul 2001
    Location
    Scotland
    Posts
    4,836
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Can you post code from the file you had TeamName in? Its from code you posted...

  17. #17
    ALT.NET - because we need it silver trophybronze trophy dhtmlgod's Avatar
    Join Date
    Jul 2001
    Location
    Scotland
    Posts
    4,836
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ack, my bad, didn't read the code you posted properly! It appears that your object needs a TeamName parameter with the select command.

  18. #18
    always learning . . .
    Join Date
    Nov 2003
    Location
    UK
    Posts
    821
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So
    Code:
    <SelectParameters>
           <asp:Parameter Name="letter" Type="String" />
    </SelectParameters>
    Becomes
    Code:
    <SelectParameters>
           <asp:Parameter Name="TeamName" Type="String" />
    </SelectParameters>
    This I don't get because GetTeamsByStartingLetter(String letter) is the method in the BLL. It's this method which is assigned to the selectmethod is it not?

    Doing the above change results in
    ObjectDataSource 'DataSourceTeamsAdmin' could not find a non-generic method 'GetTeamsByStartingLetter' that has parameters: TeamName.

  19. #19
    always learning . . .
    Join Date
    Nov 2003
    Location
    UK
    Posts
    821
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think it all works except on first load the select event does not have a starting letter. How do I in your example on first load set the parameter to "A"?

    Could this be the problem?

    It just errors when passing null all the way throguh the BLL to the DAL


    Well hard coding the below to = a&#37; in the BLL proves that null is being passed in. How can I avoid this and set it to "a" from the off?
    Code:
     [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, false)]
        public Snooker.TeamsDataTable GetTeamsByStartingLetter(string letter)
        {
            return Adapter.GetTeamsByStartingLetter("a%");
        }

  20. #20
    ALT.NET - because we need it silver trophybronze trophy dhtmlgod's Avatar
    Join Date
    Jul 2001
    Location
    Scotland
    Posts
    4,836
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You just need to change this:
    Code:
    string inputvalue = ViewState["filterletter"] == null ? "a&#37;" : (string)ViewState["filterletter"];
    e.InputParameters["letter"] = inputvalue;

  21. #21
    always learning . . .
    Join Date
    Nov 2003
    Location
    UK
    Posts
    821
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Brill that works a treat.

    Can you explain how that works? How does the line evaluate? Just so I can understand what I am using.

  22. #22
    SitePoint Author silver trophybronze trophy
    wwb_99's Avatar
    Join Date
    May 2003
    Location
    Washington, DC
    Posts
    10,633
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    That is just a terniary operator, and it is merely syntactic sugar. It translates to:

    Code:
    string inputvalue=null;
    if (ViewState["filterletter"]==null)
    {
       inputvalue="a&#37;";
    }
    else
    {
      inputvalue=(string)ViewState["filterletter"];
    }
    Now, I, myself, would wrap that ViewState call in a protected property. But I am a fanatic at times.

  23. #23
    ALT.NET - because we need it silver trophybronze trophy dhtmlgod's Avatar
    Join Date
    Jul 2001
    Location
    Scotland
    Posts
    4,836
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by wwb_99 View Post
    But I am a fanatic at times.
    A good way to be! Always plan for the worst

  24. #24
    always learning . . .
    Join Date
    Nov 2003
    Location
    UK
    Posts
    821
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Cool, I get it. BUT now you mention "protected property". How and benefits?

  25. #25
    ALT.NET - because we need it silver trophybronze trophy dhtmlgod's Avatar
    Join Date
    Jul 2001
    Location
    Scotland
    Posts
    4,836
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Basically moving the code for returning the filter letter from the method body into a property. This is a good idea if your going to be using the FilterLetter around the page, or at a later date might change where the filter later is stored. Basically, you add something like this to the top of your page:
    Code:
    protected string FilterLetter
        {
            get
            {
                if (ViewState["filterletter"] == null)
                {
                    return "a&#37;";
                }
                else
                {
                    return (string)ViewState["filterletter"];
                }
            }
            set
            {
                ViewState["filterletter"] = value;
            }
        }
    Then change this:
    Code:
    string inputvalue = ViewState["filterletter"] == null ? "a%" : (string)ViewState["filterletter"];
    e.InputParameters["letter"] = inputvalue;
    to
    Code:
    e.InputParameters["letter"] = FilterLetter;
    and
    Code:
    ViewState["filterletter"] = filterleter;
    to
    Code:
    FilterLetter = filterleter;


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •