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.