3

I have a readymade library(dll) given to me, which has important data, i m able to take that data into Datatable and successfully displaying it on a GridView.

Now my further task is the Data what it is displaying in GridView should be filterable, meaning if i click on any column on a row it should filtered results of similar columns.

This is my GridView Result

HeaderCol1        HeaderCol2       HeaderCol3      HeaderCol4 
Name1              Info1            ID1              Time1
Name2              Info2            ID2              Time2
Name1              Info3            ID3              Time3
Name3              Info2            ID4              Time4
Name4              Info4            ID3              Time5
Name5              Info5            ID5              Time5

Now what i want is if i click on Name1 it should show

HeaderCol1        HeaderCol2       HeaderCol3      HeaderCol4 
Name1              Info1            ID1              Time1
Name1              Info3            ID3              Time3

And if i click on Info2 it should show

HeaderCol1        HeaderCol2       HeaderCol3      HeaderCol4 
Name2              Info2            ID2              Time2
Name3              Info2            ID4              Time4

I think my question is clear now. How can i achieve this? Thanks in advance

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
N Khan
  • 366
  • 1
  • 6
  • 15
  • 1
    Can you try to elaborate this more: _"the Data what it is displaying in GridView inturn has data in it. How to get that?"_ – Tim Schmelter Nov 08 '12 at 10:39
  • 1
    One approach: use a `FormView` or `DetailsView` to display the detail informations about that person. You can use the `GridView's` [`SelectedIndexChanged`](http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.selectedindexchanged.aspx) event therefore. – Tim Schmelter Nov 08 '12 at 10:42
  • @TimSchmelter, I mean the data which is displayed in GridView has clickable data in it, if i click on any of the column it should show data binded to it. Suppose if i click col1 of Row1 which is a name field it should show me new table with person details. – N Khan Nov 08 '12 at 10:54
  • 1
    That's not the way ASP.NET (or web in general) works. If the first column contains the person, what do the other columns contain? Maybe you're showing unrelated (or simply too much) informations in one row. I would just list persons in this grid. You can show detail informations about that person when the user clicks on the **row**. – Tim Schmelter Nov 08 '12 at 10:58
  • @TimSchmelter sorry, actually i mean to filter that data i m displaying in GridView. Say i have same person in col1 many a times in the table, so when i click on Name1, the Table shld be filtered for Name1 like HeaderCol1 HeaderCol2 HeaderCol3 HeaderCol4 Name1 Info1 ID1 Time1 Name1 Info3 ID3 Time3 Name1 Info9 ID9 Time9 are you getting me now? – N Khan Nov 09 '12 at 07:42
  • 1
    Then you might want edit your question to provide better sample data and also to update your reuirement. – Tim Schmelter Nov 09 '12 at 07:56

2 Answers2

1

So you want to filter a GridView's DataSource by a value of a cell the user clicked on. These are multiple tasks in one, i'll try to explain all.

The major task is to enable that every cell in the GridView reacts on a user's click, handling that click-event on serverside and get somehow the value from that cell.

I've used a DataTable in following example, replace it with your type of datasource. If you need to add custom events/controls to GridViewRows the best place is RowCreated since this is called on every postback not only on databinding. Note that you don't have the DataItem at this stage.

protected void gridView1_RowCreated(Object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        for(int i = 0; i < e.Row.Cells.Count; i++)
        {
            TableCell cell = e.Row.Cells[i];
            cell.ToolTip = "Click to filter by this value";
            string js = string.Format("var txt=document.getElementById('{0}');txt.value='{1} {2}';{3}"
                , TxtFilter.ClientID, e.Row.RowIndex, i
                , ClientScript.GetPostBackClientHyperlink(TxtFilter, null));
            cell.Attributes["onclick"] = js;
        }
    }
}

As you can see i've added the clientside onclick event to each cell. I'm using a hidden TextBox(display:none) with AutoPostBack=true to store the row and cell the user has clicked. Now you're able to handle and process the click event on serverside.

protected void FilterGrid(object sender, EventArgs e)
{
    TextBox txtFilter = (TextBox)sender;
    string[] parts = txtFilter.Text.Split();
    int row = int.Parse(parts[0]);
    int col = int.Parse(parts[1]);
    gridView1.DataSource = GetData(row, col);
    gridView1.DataBind();
}

// replace with your DAL, used a DataTable for testing
private DataTable GetData(int rowIndex = -1, int colIndex = -1)
{
    DataTable tblData = getDataSource(); 
    if (rowIndex > -1 && colIndex > -1)
    {
        var field = tblData.Columns[colIndex];
        var row = tblData.Rows[rowIndex];
        var value = row[field];
        // now use Linq-To-DataSet to filter the table, remember to add 'using System.Linq'
        tblData = tblData.AsEnumerable()
            .Where(r => !r.IsNull(field) && r[field].Equals(value))
            .CopyToDataTable();
    }

    return tblData;
}

Here's the aspx of my sample page:

<asp:TextBox ID="TxtFilter" runat="server" style="display:none" AutoPostBack="true" OnTextChanged="FilterGrid" />
<asp:GridView ID="gridView1" runat="server" AutoGenerateColumns="False" OnRowCreated="gridView1_RowCreated"  >
   <Columns>
       <asp:TemplateField HeaderText="HeaderCol1">
            <ItemTemplate>
                <asp:Label ID="LblHeaderCol1" runat="server" Text='<%#Eval("HeaderCol1") %>' />
            </ItemTemplate>
       </asp:TemplateField>
       <asp:TemplateField HeaderText="HeaderCol2">
            <ItemTemplate>
                <asp:Label ID="LblHeaderCol2" runat="server" Text='<%#Eval("HeaderCol2") %>' />
            </ItemTemplate>
       </asp:TemplateField>
       <asp:TemplateField HeaderText="HeaderCol3">
            <ItemTemplate>
                <asp:Label ID="LblHeaderCol3" runat="server" Text='<%#Eval("HeaderCol3") %>' />
            </ItemTemplate>
       </asp:TemplateField>
       <asp:TemplateField HeaderText="HeaderCol4">
            <ItemTemplate>
                <asp:Label ID="LblHeaderCol4" runat="server" Text='<%#Eval("HeaderCol4") %>' />
            </ItemTemplate>
       </asp:TemplateField>
  </Columns>
</asp:GridView>
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Sorry i dear i got struck here as i m a beginner, what is DAL? and where is the definition for getDataSource() – N Khan Nov 11 '12 at 05:43
  • if i refract a separate method for my datasource as private void GetDataSource() { kmmiscc.flexlicusage flus = new kmmiscc.flexlicusage(); flus.InitializeConStringE("user id=uid;password=[break]eRkLhQ4DaGzVUjV7YxaCfA==[break];data source=testdb", 10, 1, "C:/flexlic.log"); DataTable dt = flus.GetCurrentLicUsed("1.2.3.4", "%", "%"); MyDataGrid.DataSource = dt; MyDataGrid.DataBind(); } and then when i give it in GetData() method DataTable tbldata = GetDataSource(); Its shows cannot convert void to DataTable – N Khan Nov 11 '12 at 05:55
  • Now if i want the filtered result to be displayed in new page as a child page of current page? How can i? – N Khan Nov 11 '12 at 10:43
  • @rNoorullaKhan: Please ask another question since it's not related to this and it's not possible to help via comments. – Tim Schmelter Nov 11 '12 at 10:47
  • Okay fine i will be posting as new question – N Khan Nov 11 '12 at 10:59
  • please check the new question here [http://stackoverflow.com/questions/13330577/filter-a-datatable] – N Khan Nov 11 '12 at 17:37
0

1) Create new pages (.aspx files) that display the details of the person etc.

2) In your current GridView you have to use HyperLinkField instead of simple BoundField:

      <asp:hyperlinkfield datatextfield="UnitPrice"
        datatextformatstring="{0:c}"
        datanavigateurlfields="ProductID"
        datanavigateurlformatstring="~\yourNewPage.aspx?ProductID={0}"          
        headertext="HeaderCol1"
        target="_blank" />

This will now render a hyperlink that, when clicked, will open the details in a new page.

Knaģis
  • 20,827
  • 7
  • 66
  • 80
  • Guys sorry, actually i mean to filter that data i m displaying in GridView. Say i have same person in col1 many a times in the table, so when i click on Name1, the Table shld be filtered for Name1 like HeaderCol1 HeaderCol2 HeaderCol3 HeaderCol4 Name1 Info1 ID1 Time1 Name1 Info3 ID3 Time3 Name1 Info9 ID9 Time9 are you getting me now? – N Khan Nov 09 '12 at 07:37
  • Do the same as above - just do not create a new page but redirect to the same page with ?PersonId=234 in the query string. Then in this page when you load the data, filter it by person. – Knaģis Nov 09 '12 at 08:26