This is a migrated thread and some comments may be shown as answers.

Challanging RadGrid Setup

4 Answers 96 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Kori
Top achievements
Rank 2
Kori asked on 21 Aug 2009, 04:54 PM
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

4 Answers, 1 is accepted

Sort by
0
BaiH
Top achievements
Rank 1
answered on 26 Aug 2009, 12:57 PM
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
0
Kori
Top achievements
Rank 2
answered on 26 Aug 2009, 06:25 PM
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.
0
BaiH
Top achievements
Rank 1
answered on 28 Aug 2009, 03:11 PM
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
0
Kori
Top achievements
Rank 2
answered on 28 Aug 2009, 04:50 PM
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.
Tags
Grid
Asked by
Kori
Top achievements
Rank 2
Answers by
BaiH
Top achievements
Rank 1
Kori
Top achievements
Rank 2
Share this question
or