I have been looking all over for the answer and think I am missing something simple. I have a kendo grid where I want one of the columns to be a link to another page with the id as a route parameter. However, the value in the column cells are the bound values and are unchanged by my template. Any insights to this will be appreciated.
#(Html.Kendo().Grid((IEnumerable<ProviderAccess>)Model.Providers)
.Name("grants-grid")
.Columns(columns =>
{
columns.Bound(a => a.ProviderName);
columns.Bound(a => a.HasAccess);
columns.Bound(a => a.ProviderId).ClientTemplate("#= toggleLink(data) #");
})
.Scrollable()
)
<script>
function toggleLink(access) {
var action = '#Url.Action("Toggle", "Access")';
var html = kendo.format("<a href='{0}/{1}'>Toggle...</a>",
action,
access.ProviderId
);
return html;
}
</script>
ClientTemplate isn't using when Kendo Grid is binded to a dataSource on server side like your code.
You should use Template method of columns like below
columns.Template(p => "<a href='..../Toggle/Access/" + p.ProviderId + "'>Click</a>");
dataSource.Server() will let you use a custom.template
dataSource.Ajax() will let you use ClientTemplate
Figuring that out was really frustrating... They are not interchangeable one of the other will work depending on ajax or Server
<%: Html.Kendo().Grid((List<RadCarePlus.V2.Web.Models.GetMeSomeData>) ViewData["Mydata"])
.Name("Grid")
.Columns(columns =>
{
columns.Template(c => "<a href='ImplementationDetails?EpisodeID=" + c.EpisodeID + "'>" + c.EpisodeID + "</a>").Title("Testing").Width(140);
//columns.Bound(c => c.EpisodeID).Width(140);
columns.Bound(c => c.AuthStatus).Width(190);
columns.Bound(c => c.CPTCode).Width(100);
columns.Bound(c => c.inscarrier).Width(110);
columns.Bound(c => c.CreatedOn).Width(160);
//columns.Template(c => "<a href='ImplementationDetails?EpisodeID=" + c.EpisodeID + "'>" + c.EpisodeID + "</a>");
//columns.Template(c => c.EpisodeID).Title("Testing").ClientTemplate("<a href='ImplementationDetails?EpisodeID=#= EpisodeID#'>#= EpisodeID #</a>");
})
.Pageable(pageable=> pageable.ButtonCount(5))
.Sortable(sortable => sortable.AllowUnsort(false))
.DataSource(dataSource => dataSource.Server().PageSize(5)
)
%>
Related
i'm new to kendo UI and currently learning about custom editor.
My Problem is i managed to get my editor template working in edit mode and populate the data just fine, but somehow it won't save the value to the display grid
I Retreive all my data from API.
UPDATE:
i've managed to properly save the value from the custom editor template to the controller and it works just fine, but using clientTemplate won't display the correct value from what i select in the dropdown, and only show a string
DropDown Only Display A String
my setup code is like this
#( Html.Kendo().Grid<SalesOrderDetailVM>()
.Name("list-detail")
.Columns(columns =>
{
columns.Bound(c => c.Product).ClientTemplate("\\#=Product.ProductId\\#").Title("Products");
columns.Bound(c => c.Quantity);
columns.Bound(c => c.UnitPrice);
})
.Editable(GridEditMode.InCell)
.ToolBar(tool =>
{
tool.Create();
tool.Save();
}
)
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(false)
.Batch(true)
.Model(model =>
{
model.Id(p => p.ProductId);
model.Field(p => p.Product);
})
.Create(act => act.Action("DetailCell_Create","SalesOrder"))
)
)
DDLProduct.cshtml:
#model AAF.WEB.MVC.ViewModels.ProductVM
#(
Html.Kendo().DropDownListFor(m => m)
.DataValueField("ProductId")
.DataTextField("ProductName")
.OptionLabel("Select Product")
.BindTo((System.Collections.IEnumerable)ViewData["products"])
)
Edit Mode
DisplayMode / Out of Product Edit Mode
Use template method to acheive dropdown with kendo grid.
GridForeignKey.cshtml - it should placed in shared folder or EditorTemplates
#model object
#(
Html.Kendo().DropDownListFor(m => m)
.BindTo((SelectList)ViewData[ViewData.TemplateInfo.GetFullHtmlFieldName("") + "_Data"])
)
In your kendo grid please change like below
#( Html.Kendo().Grid<AAF.WEB.MVC.ViewModels.SalesOrderDetailVM>()
.Name("list-detail")
.Columns(columns =>
{
columns.Bound(c => c.Id)
columns.ForeignKey(c => c.ProductId, (System.Collections.IEnumerable)ViewData["Products"], "ProductId", "ProductName").Title("Products");
columns.Bound(c => c.Quantity);
columns.Bound(c => c.UnitPrice);
})
.Editable(GridEditMode.InCell)
.ToolBar(tool =>
{
tool.Create();
tool.Save();
}
)
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(false)
)
)
You can set the products data to view data. using this method you can save the product id.
Thanks
Okay after i frustrated for many hours, finally found the solution
the solution is to add a defaultvalue to the passed model in the grid
.Model(model =>
{
model.Id(p => p.ProductId);
model.Field(p => p.Product).DefaultValue(
ViewData["defaultProduct"] as ProductVM
);
})
and pass the data from the controller
// Function that get data from API
ViewData["products"] = products;
ViewData["defaultProduct"] = products.First();
Assuming I have the below table:
#Html.Kendo().Grid(Model).Name("Staff").Columns(x =>
{
x.Bound(y => y.StaffId);
x.Bound(y => y.FirstName);
x.Bound(y => y.LastName);
x.Bound(y => y.Email);
x.Bound(y => y.Phone);
x.Command(y => y.Custom("Edit").Action("edit", "controller", new { id = ????? }));
}).Sortable().Scrollable().Pageable(x=> x.PageSizes(true)).Filterable()
How can I pass the primary key value (StaffId in this case) associated to the row to the object route values similar to the way it is done by Visual Studio auto-scaffold?
I do not know if you can pass ID using Command.Custom the way you are attempting right now.
If you prefer this way, you can define a JS method and fetch selected row in that and perform an AJAX operation to manipulate the data.
So in your case you can instead define command as:
columns.Command(command => command.Custom("Edit").Click("editRow"));
and in script tag, you can define method that read and send data to server:
function editRow(e) {
e.preventDefault();
try {
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
var searchId = dataItem.Id;
var searchName = dataItem.Name;
var model = { searchId: searchId };
$.ajax({
url: '#Url.Action("BindLeftMenu")',
contentType: 'application/json; charset=utf-8',
type: 'POST',
dataType: 'html',
data: JSON.stringify(model)
})
.success(function (resultMenu) {
$("#driversummaryarea").show();
})
.error(function (xhr, status) {
$("div.overlay").hide();
});
}
catch (e) {
alert(e.message);
}
}
Now there are 2 other ways you can modify grid data:
Use default commands e.g. Edit(). A demo is shown here. Simple and easy but limiting i.e. less control from JS.
Use ClientTemplate - Very powerful as offers full control over display and capturing data in JS.
For example with ClientTemplate you can define a grid like below. Notice how we are passing model Id parameter in ClientTemplate as raw html.
Once you define ClientTemplate, you can define the JS functions fnEditUser as shown above and perform operation on grid data.
HTML
#(Html.Kendo().Grid<Eda.RDBI.Web.Models.OrganizationUserViewModel>()
.Name("organizationUserViewModelGrid")
.Columns(columns =>
{
columns.Bound(p => p.FirstName).Filterable(true).Title("Name").Groupable(false).ClientTemplate("<a class='lnkEditUser' href='javascript:void(0)' onclick='fnEditUser(#=Id#)' > #=FirstName# </a>").Width(200);
columns.Bound(p => p.EMail).Width(200);
columns.Bound(p => p.Role)
.ClientTemplate("<span>#=Role#</span> <span>#=IsDriverSearchAllowed ? ' (DS)' : ''#</span>");
columns.Bound(p => p.IsActive).Title("Active")
.ClientTemplate("<input type='checkbox' #=IsActive ? checked='checked':'' # class='chkbx' onclick='return false'/>");
columns.Bound(p => p.Id).Title(string.Empty).ClientTemplate("<a class='btn btn-default' href='javascript:void(0)' onclick='fnDeleteUser(#=Id#)'>Delete</a>").Filterable(false).Sortable(false);
})
.Sortable(sortable => sortable.AllowUnsort(false))
.Scrollable()
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(50)
.Model(model => model.Id(p => p.Id))
.Read(read => read.Action("GetUsersForOrganization", "OrganizationUser"))
)
.Scrollable(scrollable => scrollable.Virtual(true))
)
This works for me. If you're not doing any AJAX, you might be able to just move the anchor into Template and not use ClientTemplate. I'm using bootstrap buttons, but you could replace that code with your own styles or the kendo styles.
This is the code that inserts your id: #= Id # - it should be a field from your Model. See http://docs.telerik.com/kendo-ui/framework/templates/overview
#Html.Kendo().Grid(Model).Name("Staff").Columns(x =>
{
x.Bound(y => y.StaffId);
x.Bound(y => y.FirstName);
x.Bound(y => y.LastName);
x.Bound(y => y.Email);
x.Bound(y => y.Phone);
x.Template(#<text></text>).Title(string.Empty).Width(40)
.ClientTemplate(#"<a href='" + Url.Action("Edit") + "?id=#= Id #' class='btn btn-info btn-xs' title='Modify this'>Edit</a>");
}).Sortable().Scrollable().Pageable(x=> x.PageSizes(true)).Filterable()
After playing with the grid over and over, I could finally solve the problem. Here you go:
x.Bound(y => y.Title).Template(y=> "Click Me")
I am using kendo ui with asp.net mvc. I want to change the group header coloumn dynamically. Please suggest solution.My code is shown below.
<div id="dvPayrollReportGrid" class="kendo-responsive-grid-content">
#(Html.Kendo().Grid<CyberPayBO.Models.PayrollReportModel>()
.Name("gridpayrollreport")
.Columns(columns =>
{
columns.Bound(payroll => payroll.CompanyCode).Title("").Hidden(true).Filterable(false).ClientTemplate("<input type='hidden' id='hdnCompanyCode' value='#=CompanyCode#'>");
columns.Bound(payroll => payroll.CompanyCode).Title("Action").Filterable(false).ClientTemplate("View || <span class='CompanyNameLink DeleteLink' onclick='DeletePayrollReport(this.id)' id='#=ID#'>Del</span> | <img src='../Images/pdf.gif' id='PayrollImage'/>").Sortable(false);
columns.Bound(payroll => payroll.CheckDate).Format("{0:dd/MM/yyyy}");
columns.Bound(payroll => payroll.FromDate).Format("{0:dd/MM/yyyy}");
columns.Bound(payroll => payroll.ToDate).Format("{0:dd/MM/yyyy}");
columns.Bound(p => p.StoredFile).ClientTemplate("#if (StoredFile.toLowerCase().indexOf('.pdf')>-1) {#"
+ " "
+ "#} else { #" + ""
+ "# } #" + "#=StoredFile#");
columns.Bound(payroll => payroll.CheckDate).Title("Payroll Reports").Hidden(Convert.ToBoolean(PayrollReportColumn)).ClientTemplate("<span style='color:red'>Payroll Report</span>");
columns.Bound(payroll => payroll.CreatedDate).Title("Created At").Format("{0:dd/MM/yyyy HH:mm tt}");
})
.Pageable(pageable => pageable
.Messages(messages => messages.Display("Payroll Reports {0} - {1} of {2}"))
)
.Sortable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(PageSize)
.Read(read => read.Action("PayrollReport_Read", "PayrollReport"))
.Group(groups =>
{
groups.Add(payroll => payroll.CompanyName);
})
)
)
</div>
i am grouping by the company name, and by default it is giving me company name as header in result. I want the header to be dynamic and display the company code instead.I am getting ouput as CompanyName: AAA TEST 1 in header, but i want ouput as 004:AAA Test 1., where 004 is company code.
I found the solution to it by using ClientGroupHeader Template
columns.Bound(payroll => payroll.Company).ClientGroupHeaderTemplate("#=value#").Hidden(true);
Here company is combination of CompanyCode and CompanyName and which i bind from repository. Finally grouping on Company gives me the desired result.
To Achieve this you need to return a new column in your backend With the class of the data you want to group by since Kendo doesn't let you group by anonymous type yet. the End the end of your Action will look something like this
...
var query = db.PayrollReportModel.Select(payroll=> new PayrollReportModel()
{
payroll.CompanyCode
...
grouper = new GrouperClass()
{
CompanyCode = payroll.CompanyCode,
CompanyName = payroll.CompanyName
}
});
DataSourceResult result = await query.ToDataSourceResultAsync(request);
}
For your View
<div id="dvPayrollReportGrid" class="kendo-responsive-grid-content">
#(Html.Kendo().Grid<CyberPayBO.Models.PayrollReportModel>()
.Name("gridpayrollreport")
.Columns(columns =>
{
columns.Bound(payroll => payroll.grouper).Hidden(true).ClientGroupHeaderTemplate("#=value.CompanyCode#-#=value.CompanyName#");
columns.Bound(payroll => payroll.CompanyCode).Title("Action").Filterable(false).ClientTemplate("View || <span class='CompanyNameLink DeleteLink' onclick='DeletePayrollReport(this.id)' id='#=ID#'>Del</span> | <img src='../Images/pdf.gif' id='PayrollImage'/>").Sortable(false);
columns.Bound(payroll => payroll.CheckDate).Format("{0:dd/MM/yyyy}");
columns.Bound(payroll => payroll.FromDate).Format("{0:dd/MM/yyyy}");
columns.Bound(payroll => payroll.ToDate).Format("{0:dd/MM/yyyy}");
columns.Bound(p => p.StoredFile).ClientTemplate("#if (StoredFile.toLowerCase().indexOf('.pdf')>-1) {#"
+ " " + "#} else { #" + "" + "# } #" + "#=StoredFile#");
columns.Bound(payroll => payroll.CheckDate).Title("Payroll Reports").Hidden(Convert.ToBoolean(PayrollReportColumn)).ClientTemplate("<span style='color:red'>Payroll Report</span>");
columns.Bound(payroll => payroll.CreatedDate).Title("Created At").Format("{0:dd/MM/yyyy HH:mm tt}");
})
.Pageable(pageable => pageable
.Messages(messages => messages.Display("Payroll Reports {0} - {1} of{2}"))
)
.Sortable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(PageSize)
.Read(read => read.Action("PayrollReport_Read", "PayrollReport"))
.Group(groups =>
{
groups.Add(payroll => payroll.grouper);
})
)
)
</div>
Hope this helps
I have added new menu, new controller and new view in my nop.Admin project. What i want is to bind Edit link inside Rad grid in nop.Admin. my code is.
#(Html.Telerik().Grid<Nop.Admin.Models.AuthorizeWorkshops.RegistrationModel>()
.Name("ProductRegistration-grid")
.Columns(columns =>
{
columns.Bound(x => x.RegisteredProducts.Make);
columns.Bound(x => x.RegisteredProducts.Model);
columns.Bound(x => x.RegisteredProducts.Year);
columns.Bound(x => x.RegisteredProducts.CC);
columns.Bound(x => x.RegisteredProducts.AuthorizedWorkshop);
columns.Bound(x => x.RegisteredProducts.PurchaseDate);
columns.Bound(x => x.RegisteredProducts.InoiceNo);
columns.Bound(x => x.RegisteredProducts.SerialNo);
columns.Bound(x => x.RegisteredProducts.Id)
.Template(x => Html.ActionLink(T("Admin.Common.Edit").Text, "Edit", new { Id = x.RegisteredProducts.Id }))
.ClientTemplate("" + T("Admin.Common.Edit").Text + "")
.Width(50)
.Centered()
.HeaderTemplate(T("Admin.Common.Edit").Text)
.Filterable(false);
})
.Pageable(settings => settings.PageSize(gridPageSize).Position(GridPagerPosition.Both))
.DataBinding(dataBinding => dataBinding.Ajax().Select("List", "ProductRegistration"))
.EnableCustomBinding(true))
**if i exclude following code**
columns.Bound(x => x.RegisteredProducts.Id)
.Template(x => Html.ActionLink(T("Admin.Common.Edit").Text, "Edit", new { Id = x.RegisteredProducts.Id }))
.ClientTemplate("" + T("Admin.Common.Edit").Text + "")
.Width(50)
.Centered()
.HeaderTemplate(T("Admin.Common.Edit").Text)
Rad Grid in View works fine and return me all records. **but if i continue with same** i get following error.
Uncaught ReferenceError: Id is not defined
Please Help me for this issue. thanks.
It took my 5 hours to identify that what was issue behind the scene. Actaully i was using model which was returning multiple models. so i just replaced
.ClientTemplate("" + T("Admin.Common.Edit").Text + "")
** WITH **
.ClientTemplate("" + T("Admin.Common.Edit").Text + "")
and it worked.
Thanks GOD.
I am working in an MVC 3.0 application. In my project I used Telerk mvc grid for data listing. I made grid edit mode as "InCell". In my grid, there are two columns "Facts" & "Actions". When I press "Facts" column it changed into edit mode with textbox. Also in Ipad, keypad get displayed automatically. There after when I press "Actions" column, it changed into edit mode but Ipad keypad hides. If I am pressing same "Actions" column or any other column again, Ipad keypad get displayed. But in the online demo of telerik mvc grid batch editing (http://demos.telerik.com/aspnet-mvc/razor/grid/editingbatch) it seems working. I am using telerik version 2012.2.607 in my project. My code for grid listing looks like.
#(Html.Telerik().Grid<AnswerQuestionVM>()
.Name("GridQuestions")
.DataKeys(keys =>
{
keys.Add(p => p.QuestionID);
})
.Columns(columns =>
{
columns.Bound(p => p.QuestionNumber).Format("{0:0.00}").HtmlAttributes(new { style = "text-align:center;" }).Title("#").Width("5%").ReadOnly();
columns.Bound(p => p.QuestionName).Title("Question Name").Width("43%").ReadOnly();
columns.Bound(p => p.Facts).Width("8%");
columns.Template(#<text></text>).ClientTemplate("<img src='" + #Url.Content("~/images/help.gif") + "' name='help' alt='help' title='<#=FactOptions#>' />");
columns.Bound(p => p.Actions).Width("8%");
columns.Template(#<text></text>).Width("2%").ClientTemplate("<img src='" + #Url.Content("~/images/help.gif") + "' name='help' alt='help' title='<#=ActionOptions#>' />");
columns.Template(#<text></text>).Title("Skip").Width("3%").ClientTemplate(
"<# if(Skip==false) {#>" +
"<input type='checkbox' style='cursor:pointer;' class='skipClass' />" +
"<#} else{#>" +
"<input type='checkbox' style='cursor:pointer;' class='skipClass' checked='checked' />" +
"<# } #>"
);
columns.Bound(p => p.Note).Title("Note").Width("26%");
})
.Editable(editing => editing.Mode(Telerik.Web.Mvc.UI.GridEditMode.InCell))
.KeyboardNavigation( navigation => navigation.EditOnTab(true))
.ClientEvents(e => e.OnSave("OnSave"))
.DataBinding(dataBinding =>
{
dataBinding.Ajax().Select("GetQuestion", "AnswerQuestion", new { Area = "question", ajax = true }).Enabled(true);
})
.Scrollable(scrolling => scrolling.Enabled(false))
.Sortable(sorting => sorting.Enabled(true))
.Pageable(paging => paging.Enabled(true))
.Filterable(filtering => filtering.Enabled(true))
.Groupable(grouping => grouping.Enabled(false))
.Footer(true)
)
Please tell what I am missing in my code. Any help will be appreciated.