Challanging RadGrid Setup

5 posts, 0 answers
  1. kfrancis
    kfrancis avatar
    69 posts
    Member since:
    Dec 2008

    Posted 21 Aug 2009 Link to this post

    Hey,

    I have a unique set of features I need to try an implement and I'm just wondering what might be possible ways to implement these features. The features are as follows:

    Dynamically Creating Enum Image Columns

    Part of the data I need to display, certain columns may be of a Enum that I need to display different images for. Let's just say the enum set is as follows:

    Unknown = unknown.png
    Red = red.png
    Yellow = yellow.png
    Green = green.png
    NotAvailable = notavailable.png

    I also don't know the names of the columns before hand, which is why everything has to be created dynamically. I have potentially implemented this using a custom ITemplate class that the column class inherits GridTemplateColumn - but it seems messy? I could be wrong, this could be the best way to do this. 

    Dynamic Hover Information

    I also need to show different information if you were to hover over different data. For example, if the user were to hover over an item in one of the columns in the first feature (Dynamically Creating Enum Image Columns) then I want to show a dynamic histogram graph using some other data that I can obtain using the information about the item I'm currently hovering over.

    Another case is an item not in an image column, let's say it's a customer name - when I hover over that I want to dynamically show more information about that customer in a tooltip like popup (not modal, but inline)

    Expanding Columns with Subcolumns

    Another part of my challange, is to find a way for the user to click on possibly an imagebutton in the header of a column and for that column to expand into a subset of columns.

    Let's say I have the following columns, noticing that the 'B' column has an optional button to allow the user to expand it:
    A | B (+) | C | D

    After it's expanded, I would like the following
    A | B1 | B2 | B3 | C | D

    How could I go about doing that? It's not like a seperate grid, but a modification to the columns. Is there a way to do this slickly (animated possibly?). A postback is probably required (due to the dynamic nature of the columns I'm guessing).

    Anyways, anyone up for helping me figure this all out?

    Thanks,
    Kori
  2. BaiH
    BaiH avatar
    83 posts
    Member since:
    Aug 2008

    Posted 26 Aug 2009 Link to this post

    Hi Kori,

    Dynamically Creating Enum Image Columns
    By me the template column solution is most suitable in cases like yours.

    Dynamic Hover Information
    You should check this online demo.

    Expanding Columns with Subcolumns
    A possible solution could be to set columns display from the server to false and then show them client-side when the button is clicked.

    --BH
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. kfrancis
    kfrancis avatar
    69 posts
    Member since:
    Dec 2008

    Posted 26 Aug 2009 Link to this post

    Hey BH,

    Dynamically Created Image Columns
    Here's what I have for that:
    Public Class WorkflowElementColumn 
        Inherits GridTemplateColumn 
     
        Public Class WorkflowElementHeaderTemplate 
            Implements ITemplate 
            Public column As WorkflowElementColumn = Nothing 
            Private headerText As String = String.Empty 
     
            Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.InstantiateIn 
                Dim lbl As New Label() 
                lbl.ID = Me.column.UniqueName & "_lbl" 
                lbl.Text = Me.headerText 
                container.Controls.Add(lbl) 
     
                Dim imgBtn As New ImageButton() 
                imgBtn.ID = Me.column.UniqueName & "_img" 
                imgBtn.ImageUrl = "~/Images/add16.png" 
                'AddHandler imgBtn.Click, AddressOf imgBtn_Click 
                container.Controls.Add(imgBtn) 
            End Sub 
     
            Public Sub New(ByVal headerText As String
                Me.headerText = headerText 
            End Sub 
        End Class 
     
        Public Class WorkflowElementItemTemplate 
            Implements ITemplate 
            Public column As WorkflowElementColumn = Nothing 
     
            Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.InstantiateIn 
                Dim image As New Image() 
                image.ID = Me.column.UniqueName 
                container.Controls.Add(image) 
                AddHandler image.DataBinding, AddressOf image_DataBinding 
            End Sub 
     
            Private Sub image_DataBinding(ByVal sender As ObjectByVal e As EventArgs) 
                Dim dataItem As GridDataItem = CType(CType(sender, Control).NamingContainer, GridDataItem) 
                If dataItem IsNot Nothing Then 
                    Dim image As Image = CType(sender, Image) 
                    image.Width = Unit.Parse("24px"
                    image.Height = Unit.Parse("24px"
                    Dim value As String = DataBinder.Eval(dataItem.DataItem, Me.column.DataField).ToString() 
                    If Not String.IsNullOrEmpty(value) Then 
                        image.ImageUrl = "~/images/" & value & ".png" 
                    End If 
                End If 
            End Sub 
     
        End Class 
     
        Public Sub New(ByVal headerText As String
            Dim EITemplate As New WorkflowElementItemTemplate() 
            EITemplate.column = Me 
            Me.ItemTemplate = EITemplate 
     
            Dim EHTemplate As New WorkflowElementHeaderTemplate(headerText) 
            EHTemplate.column = Me 
            Me.HeaderTemplate = EHTemplate 
        End Sub 
     
        Public Sub New() 
            Dim EITemplate As New WorkflowElementItemTemplate() 
            EITemplate.column = Me 
            Me.ItemTemplate = EITemplate 
        End Sub 
     
    End Class 

    And for the data:
    Private fieldList As List(Of String) = Nothing 
     
        Protected Sub Page_Load(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Load 
     
            fieldList = New List(Of String)() 
            fieldList.Add("A"
            fieldList.Add("B_$G"
            fieldList.Add("B_sub1"
            fieldList.Add("B_sub2"
            fieldList.Add("B_sub3"
            fieldList.Add("C"
     
            If Not Me.IsPostBack Then 
                CreateGrid() 
            End If 
     
        End Sub 
     
        Private Sub CreateGrid() 
            Me.gvWorkflow.MasterTableView.Columns.Clear() 
     
            Dim dt As DataTable = CreateTestDataTable() 
            Dim dc As New DataConverterDataTable(dt) 
     
            Dim boundColumn As GridBoundColumn 
            For index As Integer = 0 To dc.DataTable.Columns.Count - 1 
                Dim columnName As String = dc.DataTable.Columns(index).ColumnName 
                If fieldList.Contains(columnName) Then 
                    Dim headerText As String 
                    Dim elementColumn As WorkflowElementColumn 
                    If columnName.Contains("_$G"Then 
                ' if group item column, fix the header name
                        headerText = columnName.Replace("_$G"""
                        elementColumn = New WorkflowElementColumn(headerText) 
                    Else 
                        headerText = columnName 
                        elementColumn = New WorkflowElementColumn() 
                        elementColumn.HeaderText = columnName 
                    End If 
     
                    With elementColumn 
                        .DataField = columnName 
                        .ItemStyle.Width = Unit.Parse("30px"
                        .ItemStyle.HorizontalAlign = HorizontalAlign.Center 
                        .HeaderStyle.HorizontalAlign = HorizontalAlign.Center 
                    End With 
                    Me.gvWorkflow.MasterTableView.Columns.Add(elementColumn) 
                ElseIf columnName = "Name" Then 
                    boundColumn = New GridBoundColumn() 
                    With boundColumn 
                        .DataField = columnName 
                        .HeaderText = columnName 
                        .ItemStyle.Width = Unit.Parse("125px"
                    End With 
                    Me.gvWorkflow.MasterTableView.Columns.Add(boundColumn) 
                Else 
                    boundColumn = New GridBoundColumn() 
                    With boundColumn 
                        .DataField = columnName 
                        .HeaderText = columnName 
                    End With 
                    If columnName <> "ID" Then 
                        Me.gvWorkflow.MasterTableView.Columns.Add(boundColumn) 
                    End If 
                End If 
            Next 
     
            Me.gvWorkflow.DataSource = dt 
            Me.gvWorkflow.DataBind() 
        End Sub 
     
        Private Function CreateTestDataTable() As DataTable 
            Dim dt As New DataTable 
     
            dt.Columns.Add("Name"GetType(String)) 
            dt.Columns.Add("ID"GetType(Guid)) 
            dt.Columns.Add("A"GetType(String)) 
            dt.Columns.Add("B_$G"GetType(String)) ' use the group column identifier?
            dt.Columns.Add("C"GetType(String)) 
     
            dt.Rows.Add("James Smith", Guid.NewGuid(), "Red""Yellow""Green"
            dt.Rows.Add("John Smith", Guid.NewGuid(), "Yellow""Green""Red"
            dt.Rows.Add("Jane Smith", Guid.NewGuid(), "Green""Red""Yellow"
     
            Return dt 
        End Function 

    As you can see, I have a template for the header that shows an ImageButton - not sure how to do the "show the columns on client-side" thing.
  5. BaiH
    BaiH avatar
    83 posts
    Member since:
    Aug 2008

    Posted 28 Aug 2009 Link to this post

    Hi,

    You should add few lines of javascript in order to handle the button's click client event and use the Grid's client methods to show/hide columns. Check this:

    grids declaration
    <telerik:RadGrid runat="server" ID="RadGrid1" DataSourceID="SqlDataSource1" AutoGenerateColumns="false"
                <MasterTableView> 
                    <Columns> 
                        <telerik:GridTemplateColumn DataField="CustomerID"
                            <HeaderTemplate> 
                                CustomerID 
                                <input type="button" value="Expand" onclick='toggleColumns(event,"<%# Container.OwnerTableView.ClientID %>")' /> 
                            </HeaderTemplate> 
                            <ItemTemplate> 
                                <%#Eval("CustomerID") %> 
                            </ItemTemplate> 
                        </telerik:GridTemplateColumn> 
                        <telerik:GridBoundColumn DataField="Address" HeaderText="Address" Display="false" /> 
                        <telerik:GridBoundColumn DataField="City" HeaderText="City" Display="false" /> 
                        <telerik:GridBoundColumn DataField="CompanyName" HeaderText="Company Name" /> 
                        <telerik:GridBoundColumn DataField="ContactName" HeaderText="Contact Name" /> 
                        <telerik:GridBoundColumn DataField="ContactTitle" HeaderText="Contact Title" /> 
                    </Columns> 
                </MasterTableView> 
            </telerik:RadGrid> 

    expand/collapse button handler
    <script type="text/javascript"
                function toggleColumns(e,tableViewId) {  
                    var tableView=$find(tableViewId);                 
                    if(!this.expanded) { 
                        this.value = "Collapse"
                        tableView.showColumn(getColumnIndexByUniqueName(tableView, "Address")); 
                        tableView.showColumn(getColumnIndexByUniqueName(tableView, "City")); 
                        this.expanded=true
                    } else { 
                        this.value = "Expand"
                        tableView.hideColumn(getColumnIndexByUniqueName(tableView, "Address")); 
                        tableView.hideColumn(getColumnIndexByUniqueName(tableView, "City")); 
                        this.expanded=false
                    } 
                } 
                 
                function getColumnIndexByUniqueName(tableView, uniqueName){ 
                    var columnIndex = -1; 
                    for(var i=0, len = tableView.get_columns().length; i < len; i++) 
                    { 
                        if(tableView.get_columns()[i].get_uniqueName().toUpperCase() == uniqueName.toUpperCase()) 
                        { 
                            columnIndex = i; 
                            break
                        } 
                    } 
                    return columnIndex; 
                } 
            </script> 

    Yes I know it is not your exact scenario but this will do for "illustration" purpose and today my head is on fire :(

    --BH
  6. kfrancis
    kfrancis avatar
    69 posts
    Member since:
    Dec 2008

    Posted 28 Aug 2009 Link to this post

    Hey BH,

    Well - that 'sort of' works. When they hide however, the layout of the grid is all messed up.
    The other thing I attempted, was to just set the CssClass of the sub items and then use jQuery to show them with .toggle()

    Which ever works functionally the best, is the best solution of course. But it would look amazing if the subcolumns faded-in - in a cascading way. Boom boom boom :)

    Anyways, appreciate the advice BH.
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017