RadGrid and the Lists Module
For a clients' site I'm working on, I've used the Lists module as an employee directory. I've added some custom fields to the Lists, such as First Name, Last Name, Email, Department, Phone number, etc. Three of the custom fields are of the type "classification".
On the front end I'm wanting to use the Telerik RadGrid component in an user control to display this directory information.
The directory ascx code is as follows...
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Directory.ascx.cs" Inherits="Directory" EnableViewState="True" ViewStateMode="Enabled" %>
<
telerik:RadAjaxLoadingPanel
runat
=
"server"
ID
=
"RadAjaxLoadingPanel1"
>
</
telerik:RadAjaxLoadingPanel
>
<
telerik:RadAjaxPanel
runat
=
"server"
ID
=
"RadAjaxPanel1"
LoadingPanelID
=
"RadAjaxLoadingPanel1"
>
<
div
class
=
"filterDiv"
>
<
telerik:RadFilter
runat
=
"server"
ID
=
"RadFilter1"
FilterContainerID
=
"RadGrid1"
ShowApplyButton
=
"false"
/>
</
div
>
<
telerik:RadGrid
runat
=
"server"
ID
=
"RadGrid1"
ShowGroupPanel
=
"True"
AutoGenerateColumns
=
"false"
PageSize
=
"10"
AllowPaging
=
"true"
AllowSorting
=
"true"
AllowFilteringByColumn
=
"true"
OnItemCommand
=
"RadGrid1_ItemCommand"
Skin
=
"Outlook"
GroupingEnabled
=
"true"
>
<
MasterTableView
IsFilterItemExpanded
=
"false"
GroupLoadMode
=
"Client"
CommandItemDisplay
=
"top"
>
<
CommandItemTemplate
>
<
telerik:RadToolBar
runat
=
"server"
ID
=
"RadToolBar1"
OnButtonClick
=
"RadToolBar1_ButtonClick"
>
<
Items
>
<
telerik:RadToolBarButton
Text
=
"Apply filter"
CommandName
=
"FilterRadGrid"
ImageUrl="<%#GetFilterIcon() %>" ImagePosition="Right" />
</
Items
>
</
telerik:RadToolBar
>
</
CommandItemTemplate
>
<
Columns
>
<
telerik:GridCalculatedColumn
UniqueName
=
"Name"
SortExpression
=
"LastName"
HeaderText
=
"Name"
DataFields
=
"LastName, FirstName"
Expression
=
'0 + ", " + 1'
HeaderButtonType
=
"TextButton"
>
</
telerik:GridCalculatedColumn
>
<
telerik:GridBoundColumn
DataField
=
"Jobtitle"
HeaderText
=
"Title"
HeaderButtonType
=
"TextButton"
SortExpression
=
"Jobtitle"
/>
<
telerik:GridBoundColumn
DataField
=
"Email"
HeaderText
=
"Email"
HeaderButtonType
=
"TextButton"
SortExpression
=
"Email"
/>
<
telerik:GridBoundColumn
DataField
=
"Phone"
HeaderText
=
"Phone"
HeaderButtonType
=
"TextButton"
SortExpression
=
"Phone"
/>
<
telerik:GridBoundColumn
DataField
=
"Room"
HeaderText
=
"Room #"
HeaderButtonType
=
"TextButton"
SortExpression
=
"Room"
/>
</
Columns
>
</
MasterTableView
>
<
ClientSettings
AllowColumnsReorder
=
"true"
AllowDragToGroup
=
"true"
EnableRowHoverStyle
=
"true"
AllowGroupExpandCollapse
=
"True"
ReorderColumnsOnClient
=
"True"
ColumnsReorderMethod
=
"Reorder"
>
<
Animation
AllowColumnReorderAnimation
=
"true"
AllowColumnRevertAnimation
=
"true"
ColumnReorderAnimationDuration
=
"2000"
/>
<
Selecting
AllowRowSelect
=
"true"
/>
</
ClientSettings
>
<
GroupingSettings
ShowUnGroupButton
=
"true"
/>
</
telerik:RadGrid
>
</
telerik:RadAjaxPanel
>
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Web;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
Telerik.Sitefinity;
using
Telerik.Sitefinity.GenericContent.Model;
using
Telerik.Sitefinity.Modules.Events;
using
Telerik.Sitefinity.Events.Model;
using
Telerik.Web.UI;
using
Telerik.Web;
public
partial
class
Directory : System.Web.UI.UserControl
protected
void
Page_Load(
object
sender, EventArgs e)
RadGrid1.DataSource = App.WorkWith().ListItems().Where(itm => itm.Parent.Title ==
"Directory"
).Publihed().Get();
protected
void
RadGrid1_ItemCommand(
object
source, GridCommandEventArgs e)
if
(e.CommandName ==
"FilterRadGrid"
)
RadFilter1.FireApplyCommand();
protected
void
RadToolBar1_ButtonClick(
object
sender, RadToolBarEventArgs e)
//
protected
string
GetFilterIcon()
return
SkinRegistrar.GetWebResourceUrl(Page,
typeof
(RadGrid),
string
.Format(
"Telerik.Web.UI.Skins.0.Grid.Filter.gif"
, RadGrid1.Skin));
Hello Kevin,
The reason for the Classification fields breaking the page is that a Classification field returns a TrackedList<Guid> of guids for the taxons of the selected taxonomy. This cannot be bound to a data column. What I can suggest here is create a new class that has the required properties from the ListItems and firstly pass the properties from the items of the List with the fluent API to objects of this class and then create a collection of these objects and bind the grid to it. For the classification you will have a property, which gets the GUID from the field and using our API selects the taxon with that GUID. I think this implementation will also fix the other two problems - with the filter not working and the pager too.
Can you please try this and see if it works for you?
Svetoslav,
I don't want to come off sounding like an idiot, but I'm not totally sure I understand what you're telling me to do. Can you give me an example?
Hi Kevin,
For the problem with the pager, I forgot to tell you that it is probably a ViewState issue, so try turning on the viewstate of the page and this should fix the problem.
For the Classification fields, what I meant is that this field holds a list of GUIDs (IDs) of all the classifications that are applied to the relevant list item. So, a simple Eval and the name of the classification field won't do the trick. You can do this:
var list = item.GetValue<TrackedList<Guid>>(
"Category"
);
var list = DataExtensions.GetValue<TrackedList<Guid>>(blog,
"Categories"
);
TaxonomyManager mng = TaxonomyManager.GetManager();
List<
string
> resultList =
new
List<
string
>();
foreach
(var item
in
list)
var taxon = mng.GetTaxon(item);
resultList.Add(taxon.Title);
Just an FYI; here's what we implemented...
directory.ascx...
<%@ Control Language="C#" Debug="true" AutoEventWireup="true" CodeFile="Directory.ascx.cs" Inherits="Directory" EnableViewState="True" ViewStateMode="Enabled" %>
<
telerik:RadAjaxLoadingPanel
runat
=
"server"
ID
=
"RadAjaxLoadingPanel1"
>
</
telerik:RadAjaxLoadingPanel
>
<
telerik:RadAjaxPanel
runat
=
"server"
ID
=
"RadAjaxPanel1"
LoadingPanelID
=
"RadAjaxLoadingPanel1"
>
<
div
class
=
"filterDiv"
>
<
telerik:RadFilter
runat
=
"server"
ID
=
"RadFilter1"
FilterContainerID
=
"RadGrid1"
ShowApplyButton
=
"false"
>
</
telerik:RadFilter
>
</
div
>
<
telerik:RadGrid
runat
=
"server"
ID
=
"RadGrid1"
ShowGroupPanel
=
"True"
AutoGenerateColumns
=
"false"
PageSize
=
"10"
AllowPaging
=
"true"
AllowSorting
=
"true"
AllowFilteringByColumn
=
"true"
OnItemCommand
=
"RadGrid1_ItemCommand"
Skin
=
"Outlook"
GroupingEnabled
=
"true"
>
<
MasterTableView
IsFilterItemExpanded
=
"false"
GroupLoadMode
=
"Client"
CommandItemDisplay
=
"top"
>
<
CommandItemTemplate
>
<
telerik:RadToolBar
runat
=
"server"
ID
=
"RadToolBar1"
OnButtonClick
=
"RadToolBar1_ButtonClick"
>
<
Items
>
<
telerik:RadToolBarButton
Text
=
"Apply filter"
CommandName
=
"FilterRadGrid"
ImageUrl="<%#GetFilterIcon() %>" ImagePosition="Right" />
</
Items
>
</
telerik:RadToolBar
>
</
CommandItemTemplate
>
<
Columns
>
<
telerik:GridBoundColumn
DataField
=
"Name"
HeaderText
=
"Name"
HeaderButtonType
=
"TextButton"
SortExpression
=
"Name"
/>
<
telerik:GridBoundColumn
DataField
=
"Jobtitle"
HeaderText
=
"Title"
HeaderButtonType
=
"TextButton"
SortExpression
=
"Jobtitle"
/>
<
telerik:GridBoundColumn
DataField
=
"Email"
HeaderText
=
"Email"
HeaderButtonType
=
"TextButton"
SortExpression
=
"Email"
/>
<
telerik:GridBoundColumn
DataField
=
"Phone"
HeaderText
=
"Phone"
HeaderButtonType
=
"TextButton"
SortExpression
=
"Phone"
/>
<
telerik:GridBoundColumn
DataField
=
"Categories"
HeaderText
=
"Categories"
HeaderButtonType
=
"TextButton"
SortExpression
=
"Categories"
/>
<
telerik:GridBoundColumn
DataField
=
"Department"
HeaderText
=
"Department"
HeaderButtonType
=
"TextButton"
SortExpression
=
"Department"
/>
<
telerik:GridBoundColumn
DataField
=
"Building"
HeaderText
=
"Building"
HeaderButtonType
=
"TextButton"
SortExpression
=
"Building"
/>
<
telerik:GridBoundColumn
DataField
=
"Room"
HeaderText
=
"Room #"
HeaderButtonType
=
"TextButton"
SortExpression
=
"Room"
/>
</
Columns
>
</
MasterTableView
>
<
ClientSettings
AllowColumnsReorder
=
"true"
AllowDragToGroup
=
"true"
EnableRowHoverStyle
=
"true"
AllowGroupExpandCollapse
=
"True"
ReorderColumnsOnClient
=
"True"
ColumnsReorderMethod
=
"Reorder"
>
<
Animation
AllowColumnReorderAnimation
=
"true"
AllowColumnRevertAnimation
=
"true"
ColumnReorderAnimationDuration
=
"2000"
/>
<
Selecting
AllowRowSelect
=
"true"
/>
</
ClientSettings
>
<
GroupingSettings
ShowUnGroupButton
=
"true"
/>
</
telerik:RadGrid
>
</
telerik:RadAjaxPanel
>
using
System;
using
System.Data;
using
System.Data.SqlClient;
using
System.Collections;
using
System.Collections.Generic;
using
System.Linq;
using
System.Web;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
Telerik.Sitefinity;
using
Telerik.Sitefinity.GenericContent.Model;
using
Telerik.Sitefinity.Modules.Events;
using
Telerik.Sitefinity.Events.Model;
using
Telerik.Web.UI;
using
Telerik.Web;
public
partial
class
Directory : System.Web.UI.UserControl
protected
void
Page_Load(
object
sender, EventArgs e)
Hashtable buildings =
new
Hashtable(),
categories =
new
Hashtable(),
departments =
new
Hashtable();
StockHashTable(
ref
buildings,
"SELECT * FROM sf_list_items_building a INNER JOIN sf_taxa b ON a.val=b.id"
);
StockHashTable(
ref
categories,
"SELECT * FROM sf_list_items_categories a INNER JOIN sf_taxa b ON a.val=b.id"
);
StockHashTable(
ref
departments,
"SELECT * FROM sf_list_items_department a INNER JOIN sf_taxa b ON a.val=b.id"
);
DataTable myDataTable =
new
DataTable();
DataColumn[] cols =
new
DataColumn[8];
cols[0] =
new
DataColumn(
"Name"
);
cols[1] =
new
DataColumn(
"Jobtitle"
);
cols[2] =
new
DataColumn(
"Email"
);
cols[3] =
new
DataColumn(
"Phone"
);
cols[4] =
new
DataColumn(
"Categories"
);
cols[5] =
new
DataColumn(
"Department"
);
cols[6] =
new
DataColumn(
"Building"
);
cols[7] =
new
DataColumn(
"Room"
);
myDataTable.Columns.Add(cols[0]);
myDataTable.Columns.Add(cols[1]);
myDataTable.Columns.Add(cols[2]);
myDataTable.Columns.Add(cols[3]);
myDataTable.Columns.Add(cols[4]);
myDataTable.Columns.Add(cols[5]);
myDataTable.Columns.Add(cols[6]);
myDataTable.Columns.Add(cols[7]);
string
ConnString = @
"Data Source=(local)\SQLEXPRESS;UID=choose;Password=guTrut56"
;
SqlConnection conn =
new
SqlConnection(ConnString);
conn.Open();
SqlCommand cmd =
new
SqlCommand(
"SELECT * FROM sf_list_items a INNER JOIN sf_lists b ON a.parent_id=b.content_id WHERE b.url_name_='directory' AND a.visible='1'"
, conn);
SqlDataReader rdr = cmd.ExecuteReader();
while
(rdr.Read())
myDataTable.LoadDataRow(
new
object
[] rdr[
"last_name"
] +
", "
+ rdr[
"first_name"
], rdr[
"job_title"
], rdr[
"email"
], rdr[
"phone"
], categories[rdr[
"content_id"
].ToString()], departments[rdr[
"content_id"
].ToString()], buildings[rdr[
"content_id"
].ToString()], rdr[
"room"
] ,
true
);
rdr.Close();
conn.Close();
RadGrid1.DataSource = myDataTable;
//Bldg Query
//Categories Query
//Department
public
void
StockHashTable(
ref
Hashtable ht,
string
qryString)
string
ConnString = @
"Data Source=(local)\SQLEXPRESS;UID=choose;Password=guTrut56"
;
SqlConnection conn =
new
SqlConnection(ConnString);
conn.Open();
SqlCommand cmd =
new
SqlCommand(qryString, conn);
SqlDataReader rdr = cmd.ExecuteReader();
while
(rdr.Read())
if
(ht[rdr[
"content_id"
].ToString()] !=
null
)
ht[rdr[
"content_id"
].ToString()] +=
", "
+ rdr[
"title_"
].ToString();
else
ht[rdr[
"content_id"
].ToString()] = rdr[
"title_"
].ToString();
rdr.Close();
conn.Close();
protected
void
RadGrid1_ItemCommand(
object
source, GridCommandEventArgs e)
if
(e.CommandName ==
"FilterRadGrid"
)
RadFilter1.FireApplyCommand();
protected
void
RadToolBar1_ButtonClick(
object
sender, RadToolBarEventArgs e)
//
protected
string
GetFilterIcon()
return
SkinRegistrar.GetWebResourceUrl(Page,
typeof
(RadGrid),
string
.Format(
"Telerik.Web.UI.Skins.0.Grid.Filter.gif"
, RadGrid1.Skin));
Hello Kevin,
Thank you for the shared code, it will be really helpful for the community! I updated your Telerik points.
Greetings,Just an FYI on what my code does...
First we created an employee/staff directory using the Lists module. To do this we customized Lists to add some new fields. We added a first name field, a last name field, a phone field, an email field, a job title field, employee category field which is a classifications field. As well, we added a building and a department classification field. Of course your field names can vary. Once the Lists module was customized and populated, we created a user control called "directory", added the control to the widget toolbar, and then added it to a page.
So far all is working well. Thanks for the assistance.