This website is no longer actively supported
Written by John DeVight on 18 May 2011 02:54
Last Updated by John DeVight on 15 Mar 2013 20:42
Download TelerikBuilderExtensions.cs
Overview
Last week I wrote a wiki page MVC 3 Razor : Creating Custom HTML Helpers about extending the HTML Helpers to be able to render controls read-only. I also needed to extend the Telerik MVC controls to render the Telerik MVC controls read-only as well. I took a look at the Telerik.Web.Mvc.dll assembly using .NET Reflector and looked to see how Telerik extended the HTML Helper with their ViewComponentFactory, what we usually see as the Html.Telerik() method. The ViewComponentFactory creates an instance of a ViewComponentBuilder to "build" the control. The ViewComponentBuilder has a method called Render that renders the component as a control on the page.
Since I wanted to be able to render the Telerik controls as read-only, I overloaded the Render method to take a parameter of bool that indicates whether the control is editable or not.
Overloading the Render Method for the DropDownList Control
The class that derives from ViewComponentBuilder to render the DropDownList control is the DropDownListBuilder. If the DropDownList control is editable, the DropDownListBuilder.Render method is executed. If it is read-only, then the System.Web.Mvc.TagBuilder class is used to create a read-only input control. The DropDownListBuilder is used to get the Name and Value for the DropDownList control.
Here is the code:
namespace Telerik.Web.Mvc.UI
{
using Fluent;
public static class TelerikBuilderExtensions
{
public static void Render(this DropDownListBuilder dropDownListBuilder, bool editable)
{
if (editable)
{
dropDownListBuilder.Render();
}
else
{
TagBuilder tagBuilder = new TagBuilder("input");
tagBuilder.MergeAttribute("type", "text");
tagBuilder.MergeAttribute("id", dropDownListBuilder.ToComponent().Name, true);
tagBuilder.MergeAttribute("value", dropDownListBuilder.ToComponent().Value, true);
tagBuilder.MergeAttribute("class", "readOnly", true);
tagBuilder.MergeAttribute("readonly", "read-only", true);
dropDownListBuilder.ToComponent().ViewContext.Writer.Write(tagBuilder.ToString());
}
}
}
}
Loading a Partial View That Contains a Grid Using jQuery.ajax
I recently posted an articles about loading a partial view that contains a Telerik Grid and other Telerik Controls. I started thinking about wrapping the calls to Render(), WriteInitializationScript() and creating the hidden element in an extension method. Turns out that it was pretty easy to do. I extended the Builder class for each control by adding a RenderAjax method that encapsulates the Render() and WriteInitializationScript() methods as well as the creation of the hidden element with the jQuery call to create the jQuery objects for each control. I still needed to use eval to evaluate the string in the hidden field to execute the jQuery to create the jQuery object for the control, but I still haven't given up the idea of coming up with a solution for this!
RenderAjax Extension Method for the Grid
Here is the code to extend the Grid:
namespace Telerik.Web.Mvc.UI
{
using Fluent;
public static class TelerikBuilderExtensions
{
public static void RenderAjax<T>(this GridBuilder<T> grid) where T : class
{
grid.Render();
StringWriter sw = new StringWriter();
grid.ToComponent().WriteInitializationScript(sw);
TagBuilder tagBuilder = new TagBuilder("input");
tagBuilder.MergeAttribute("type", "hidden");
tagBuilder.MergeAttribute("id", string.Format("{0}_Create_tGrid", grid.ToComponent().Name));
tagBuilder.MergeAttribute("value", sw.GetStringBuilder().ToString());
grid.ToComponent().ViewContext.Writer.Write(tagBuilder.ToString());
}
}
}
Here is an example of implementing the RenderAjax extension method in the parital view:
@{
Html.Telerik().Grid<TelerikMvcApplication.Models.WikiPage>()
.Name("WikiPageGrid")
.Columns(columns =>
{
columns.Bound(c => c.Title);
columns.Bound(c => c.Url);
columns.Bound(c => c.DateCreated);
columns.Bound(c => c.Id).Hidden(true);
columns.Command(commands =>
{
commands.Edit();
}).Width(100);
})
.DataKeys(keys =>
{
keys.Add(c => c.Id);
})
.DataBinding(dataBinding => dataBinding.Ajax().Select("GetWikiPages", "Home")
.Update("UpdateWikiPages", "Home")
)
.Pageable(paging =>
paging.PageSize(5)
.Style(GridPagerStyles.NextPreviousAndNumeric)
.Position(GridPagerPosition.Bottom)
)
.Footer(true)
.RenderAjax();
}
Here is the javascript code to make the jQuery.ajax call to get the partial view and execute the jQuery code in the hidden field using the eval function:
$.ajax({
url: '/Home/GetTabThree/',
contentType: 'application/html; charset=utf-8',
type: 'GET',
dataType: 'html'
})
.success(function(result) {
$('#IndexTabStrip').data('tTabStrip').addTab({ text: 'Tab Three', html: result });
// evaluate the text in the hidden field to create the "tGrid".
eval($('#WikiPageGrid_Create_tGrid').val());
});
TelerikBuilderExtensions.cs Extension Methods
The TelerikExtensions.cs contains the following extension methods:
- Render(this DropDownListBuilder dropDownListBuilder, bool editable)
- Render(this DatePickerBuilder datePickerBuilder, bool editable)
- RenderAjax<T>(this GridBuilder<T> grid)
- RenderAjax(this ComboBoxBuilder comboBoxBuilder)
- RenderAjax(this DatePickerBuilder datePickerBuilder)
Need to Extend the Telerik HTML Helper?
I'll be adding more to this wiki page as I extend other Telerik components. However, if you have a need to extend the ViewComponentBuilder for a control, leave me a comment and I'll see what I can do.