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
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
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
0
BaiH
Top achievements
Rank 1
answered on 26 Aug 2009, 12:57 PM
Hi Kori,
Dynamic Hover Information
You should check this online demo.
--BH
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 Object, ByVal 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 Object, ByVal 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
expand/collapse button handler
Yes I know it is not your exact scenario but this will do for "illustration" purpose and today my head is on fire :(
--BH
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 :)
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.