I could create a grid with telerik mvc
<% Html.Telerik().Grid(Model)
.Name("ProductGrid")
.Columns(columns => {
columns.Bound(h => h.ProductName).Width("34%");
columns.Bound(h => h.Description).Width("60%");
columns.Bound(h => h.ProductID).Format(Html.ImageLink("Edit", "Products", new { Id = "{0}" }, "/Content/images/icon_edit.gif", "", new { Id = "edit{0}" }, null).ToString()).Encoded(false).Title("").Sortable(false).Width("3%");
columns.Bound(h => h.ProductID).Format(Html.ImageLink("Delete", "Products", new { Id = "{0}" }, "/Content/images/icon_delete.gif", "", new { onclick = string.Format("return confirm('Are you sure to delete this add on?');") },null).ToString()).Encoded(false).Title("").Sortable(false).Width("3%");
})
.EnableCustomBinding(true)
.DataBinding(databinding => databinding.Ajax().Select("_Index", "ProductGrid"))
.Pageable(settings => settings.Total((int)ViewData["TotalPages"])
.PageSize(10))
.Sortable()
.Render(); %>
but I need to add a serial number column in telerik grid.How can i do this?
I think the best way is to use template column like this.
<%
var sn = 0;
Html.Telerik().Grid(Model).Name("Grid").HtmlAttributes(new { style = "width:auto" })
.EnableCustomBinding(true)
.Columns(columns =>
{
columns.Template(c=> {%> <%: ++sn %> <% }).Title("S/N");
columns.Bound(c => c.CustomerNumber);
columns.Bound(c => c.Narration);
})
.Render(); %>
This way you don't have to be adding serial number property to your view models.
Hope this help?
I think the best way to do this is to add a SerialNumber column to your Product class which is your model and than just add another bound column to the grid like this:
columns.Bound(h => h.SerialNumber)
If you pass a List of Products you can populate the SerialNumber column like this:
List<Product> products = GetList(); // Your method to get data here
int counter = 1;
products.ForEach(x => x.SerialNumber = counter++);
If you want to support consistent numbers with paging you have to calculate yourself the initial value of the counter valuable. For this purpose you must have the current page and page size.
In MVC Web Grid
use this calculation
grid.Column(header: "#",
format: item => item.WebGrid.Rows.IndexOf(item) + 1 + Math.Round(Convert.ToDouble(grid.TotalRowCount / grid.PageCount) / grid.RowsPerPage) * grid.RowsPerPage * grid.PageIndex),
Related
I need to use multiselect list in kendo grid (inline editing) so that user can select multiple values from the list per row.
Following are my requirements:
At the time of display, kendo grid should show comma separated list of all the selected values.
At the time of Add, kendo grid should show multiselect list and allow to select multiple values.
At the time of Edit, kendo grid should show multiselect list with already selected values. User should be able to modify the select and add/remove items from the list.
When user clicks on update/save button, selected values from multiselect list should be available in code behind (in update ajax action) along with id of row.
Following what I do as of now:
I am taking an approach similar to using a drop down list in kendo inline grid.
I have created an Editor Template for displaying multiselect at the time of add/edit.
Following is the code:
#model List<Namespace.CompanyConnector>
#using Kendo.Mvc.UI
#(Html.Kendo().MultiSelectFor(c=>c)
.Name("company_connector_id")
.DataTextField("connector_name")
.DataValueField("company_connector_id")
.Placeholder("Select connector...")
.AutoBind(false)
.Value((List<int>)ViewData["SelectedValues"])
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetCompanyConnectors", "BrandConnector");
})
.ServerFiltering(true);
})
)
#Html.ValidationMessageFor(m => m)
Explanation: I bind a list of model class to the multiselect and set data source in the read action. For selecting the selected values at the time of edit, I have created a function that returns the ids of selected values and put that in View Data in the read action.
I've used this Editor template in my Index page as following code:
#{Html.Kendo().Grid<Cee.DomainObjects.DomainObjects.BrandConnector>()
.Name("BrandConnectorGrid")
.Filterable()
.Events(e => e.Edit("onEdit"))
.DataSource(dataSource => dataSource
.Ajax()
.Events(e => e.Error("error_handler").RequestEnd("onRequestEnd"))
.ServerOperation(false)
.Model(model =>
{
model.Id(p => p.brand_id);
model.Field(e => e.CompanyConnectorList).DefaultValue(new
List<Cee.DomainObjects.DomainObjects.CompanyConnector>());
})
.Read(read => read.Action("_AjaxBinding", "BrandConnector",new{companyID = 0 }).Type(HttpVerbs.Post))
.Update(update => update.Action("_UpdateBinding", "BrandConnector").Type(HttpVerbs.Post)))
.Columns(columns =>
{
columns.Bound(c => c.brand_connector_id).Width(0).Hidden(true);
columns.Bound(c => c.company_id).Width(0).Hidden(true);
columns.Bound(c => c.brand_id).Width(0).Hidden(true);
columns.Bound(u => u.brand_name).Title("Brand").Width("18%").HtmlAttributes(new { #class = "brkWord", #readonly = "readonly" });
columns.ForeignKey(u => u.connector_name, Model.CompanyConnectorList, "company_connector_id", "connector_name").Title("Connector").Width
("16%").HtmlAttributes(new { #class = "brkWord" }).EditorTemplateName("company_connector_id");
columns.Command(p => p.Edit().Text("Edit").HtmlAttributes(new { #title = "Edit" })).Width("16%").Title("Edit");
})
.Editable(editable => editable.Mode(GridEditMode.InLine).CreateAt(GridInsertRowPosition.Top))
.Pageable(pageable => pageable.Refresh(true).PageSizes(GlobalCode.recordPerPageList).ButtonCount(GlobalCode.PageSize).Input(true).Numeric(true))
.HtmlAttributes(new { #class = "dynamicWidth" })
.Sortable(sorting => sorting.Enabled(true))
.Render();
}
Explanation: I've used ForeignKey. Bound it to the string column "connector_name". Connector_name is a comma separated list of IDs that I send from controller. Editor template is used here.
Issue: It works fine at the time of View/Display in Index but Edit does not show selected value. Also we do not get updated value in code behind on update click.
Is this correct way of implementing multiselect list or do I need to bind a collection property as a column in grid?
If I bind a collection property as a column then how would I be able to show comma separated string at the time of display?
Try below code:
function onEdit(e) {
var multiselect = $("#YourMutliselectDropdown").data("kendoMultiSelect");
var IDArray = [];
$(e.model.propertyName).each(function (index) {
var ID = e.model.propertyName[index].id;
IDArray.push(ID);
});
multiselect.value(IDArray);
}
I assume that propertyName is List of your collection and it contains id as property.
try it:
c.Bound(p => p.CompanyConnectorList).ClientTemplate("#= connectorsToString(data)#").EditorTemplateName("company_connector_id");
and js:
function connectorsToString(data) {
var list = data.company_connector_id;
var result = "";
for (var i = 0; i < list.length; i++) {
result += list[i].Name + ';';
}
return result;
}
I am using Kendo() grid in my application which has binding with an model.
I want to provide Upload control in Grid against each row. Please see razor view design as follows
#(Html.Kendo().Grid<Model>()
.Name("Grid")
.Columns(col =>
{
col.Template(#<text></text>).ClientTemplate("<a Title='Export' href='" + Url.Action("Export", "RouteFileExport", new { Id = "#= RouteScheduleID #", routeID = "#= RouteID #" }) + "'><img src=" + #Url.Content("~/Content/images/download.png") + "></a>").Title("Export");
col.Template(#<text>#(Html.Kendo().Upload()
.Name("attachments<#= ID #>")
.HtmlAttributes(new { id = "attachments<#= ID #>" })
.Multiple(false)
.Async(async => async
.Save("Save", "Controller", new { folder = "<#= ID #>" })
.AutoUpload(true)
)
)</text>).Title("Import");
col.Command(command =>
{
command.Destroy();
command.Custom("Unlock");
command.Custom("Notification");
}
);
})
With above design i am not able to get the upload control displayed inside grid. Its displaying BLANK column.
Please let me know how can i achieve upload against each kendo grid row.
Thanks
Are you looking for a custom button in the last column? If you use the custom command buttons it can be linked to JQuery or a controller action like below:
columns.Command(cmd => cmd.Custom("Upload").Text("Upload").Click("UploadJqueryScript")).Width(75);
columns.Command(cmd => cmd.Custom("Upload").Action("UploadMethod", "Controller")).Width(75);
Have you tried these options?
I have a grid where first 2 columns are bound with ForeignKey (Category and Product). The value of the first dropdown dictates the value of the second. How can I reload the values of the second dropdown after the first dropdown value changes?
#(Html.Telerik().Grid<Order>().HtmlAttributes(new { style = "width: 700px" })
.Name("grdOrders")
.ToolBar(tb => tb.Insert())
.DataBinding(binding => binding.Ajax()
.Select("GetOrders", "Home")
.Update("UpdateOrder", "Home")
.Insert("InsertOrder", "Home")
.Delete("DeleteOrder", "Home"))
.DataKeys(keys => keys.Add(o => o.OrderID))
.Columns(cols =>
{
cols.Bound(c => c.OrderID).Width(100).ReadOnly();
cols.Bound(c => c.Name);
cols.ForeignKey(c => c.ItemCategoryID, (System.Collections.IEnumerable)ViewData["Categories"],
"ItemCategoryID", "CategoryName").Title("dbCategory").Width(300);
cols.ForeignKey(c => c.ItemID, (System.Collections.IEnumerable)ViewData["dbItems"],
"ItemID", "ItemName").Width(200).Title("Item");
cols.Command(cmd =>
{
cmd.Edit().ButtonType(GridButtonType.Image);
cmd.Delete().ButtonType(GridButtonType.Image);
}).Title("Commands").Width(100);
})
Having the same problem, i found this:
"Dependent Drop Down in Grid"
http://www.telerik.com/community/forums/aspnet-mvc/grid/dependent-drop-down-in-grid.aspx
There is a full explanation for PopUp mode, however only a description of the solution for Inline mode (which, unfortunately, is too difficult for me to follow).
Hi i am new in asp.net mvc and telerik controls. How can i get o.Id value when i click on row?
<%= Html.Telerik().Grid(Model)
.Name("RolesGrid")
.DataKeys(keys => keys.Add(o => o.Id))
.Selectable()
.Columns(columns =>
{
columns.Bound(o => o.Name);
columns.Bound(o => o.Description);
})
.Pageable()
.ClientEvents(events => events
.OnRowSelect("onRowSelect"))
%>
in js code:
function onRowSelect(e) {
var ordersGrid = $('#RolesGrid').data('tGrid');
var row = e.row;
var dataItem = ordersGrid.dataItem(row);
alert(dataItem);
}
But dataItem is null and there is no id value in generated html file. Thanks and sorry for my bad english
So after all i have the best way to get id is:
bind onRowSelect function to your grid
write next code in onRowSelect
var dataItem = jQuery('#MyGridId').data('tGrid').dataItem(e.row);
alert(dataItem['Id']);
dataItem is a map witch have all properties of grid model so you get all you want
Thats all, thanks
From telerik grid demo.
You have to put the Id in the telerik grid as a hidden column.
// ...
.DataKeys(keys => keys.Add(o => o.Id))
.Selectable()
.Columns(columns =>
{
columns.Bound(o => o.Id).Hidden();
columns.Bound(o => o.Name);
columns.Bound(o => o.Description);
})
// ...
.ClientEvents(events => events.OnRowSelect("onRowSelect"))
It will render a
<td style="display: none; ...">...</td>
And then you get it like this:
function onRowSelect(e) {
var id = e.row.cells[0].innerHTML;
// ...
}
Notes:
I know, it's ugly.
I don't know why the telerik forces you to call the .DataKeys(...) method if there's no documented way to get the value for the key defined.
If you use grouping or some other feature it gets trickier, as the hidden column position varies depending on the grouping arrangement.
I found a slightly more elegant way to do this that borrows off of mmutilva's answer.
Start by putting in the hidden column and the change event in the same way:
.DataKeys(keys => keys.Add(o => o.Id))
.Selectable()
.Columns(columns =>
{
columns.Bound(o => o.Id).Hidden();
columns.Bound(o => o.Name);
columns.Bound(o => o.Description);
})
.ClientEvents(events => events.OnRowSelect("onRowSelect"))
But then in the javascript function, there is a better way to actually select the object and then the hidden row:
function onRowSelect(e) {
var grid = e.sender;
var currentitem = grid.dataItem(this.select());
var Id = currentitem.Id;
//then do whatever with the ID variable
}
Source
Change the function onRowSelect to this:
function onRowSelect(sender, args){...}
The sender will be the grid, and from the args you can determine which item was selected.
Look to the Telerik help site for detailed info on how to get the data using the Client Side API:
http://www.telerik.com/help
I have the following legacy code that I would like to mimic, with all action links inside one column. However, I can't seem to get the Razor syntax right. How should I express this in Razor?
The ASPX column template is like this:
.Columns(column =>
{
column.Template(o =>
{%>
<%= Html.ActionLink("Edit", "Edit", new{ id = o.DeviceID}) %> |
<%= Html.ActionLink("Delete", "Delete", new { id = o.DeviceID })%>
<%});
I have only been able to get three separate columns using Razor without complaints about syntax etc. as below:
.Columns(columns =>
{
columns.Template(o => #Html.ActionLink("Edit", "Edit", new { id = o.ProductId })).Width(50);
columns.Template(o => #Html.ActionLink("Details", "Details", new { id = o.ProductId })).Width(50);
columns.Template(o => #Html.ActionLink("Delete", "Delete", new { id = o.ProductId })).Width(50);
How can I define one template column that contains all three action links using Razor syntax?
EDIT: In trying the following small adaptation of Mike's answer below, I get the error "Only assignment, call, increment, decrement, and new object expressions can be used as a statement":
columns.Template(o => #<text>#Html.ActionLink("Edit", "Edit", new { id = o.CampaignId }) |
#Html.ActionLink("Delete", "Delete", new { id = o.CampaignId })
</text>).Width(100);
Here is a quick sample showing both bound columns and a template column:
Sample #1 using #<text></text> syntax
#(Html.Telerik().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(m => m.UserName);
columns.Bound(m => m.Email);
columns.Template(#<text> #Html.ActionLink("Edit", "Edit", new { id = item.UserId} ) |
#Html.ActionLink("Delete", "Delete", new { id = item.UserId)
</text>).Width(100);
})
)
Sample #2 using an Action delegate
#(Html.Telerik().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(m => m.UserName);
columns.Bound(m => m.Email);
columns.Template(m => #Html.ActionLink("Edit", "Edit", new { id = m.UserId} ) + " | " +
#Html.ActionLink("Delete", "Delete", new { id = m.UserId)
).Width(100);
})
)
Hope that helps, if didn't already figure it out. :)
UPDATE - added the implicitly defined "item" parameter in code sample above. It shows how to get the Model properties within the Telerik control template.
UPDATE#2 - korchev showed the "#item.someProperty" syntax within his code sample. The # symbol is not needed in our case since we are within an extension method, but doesn't hurt to leave it for clarity.
UPDATE#3 - added Sample #2 code sample
If you are binding with ajax, the format has to look something more like this:
c.Bound(i => i.Name).ClientTemplate(#Html.ActionLink("<#= Name #>", "[Action]", "[Controller]", new { Id = "<#= Id #>" }, new { Area = "[Area]" }).ToHtmlString())
See here for more info: http://www.telerik.com/forums/kendo-mvc-grid-actionlink-column
columns.Template(#Html.ActionLink("Edit", "Edit", new {id = #item.id }));
Check ScottGu's blog posts with regard to Razor for what #item is.
columns.Command(commands => {
commands.Custom("Update").Text(Resource.Edit)
.ButtonType(GridButtonType.BareImage) .SendState(true).SendDataKeys(true).HtmlAttributes(new { id = "popUp"})
Action("Gallery_Bar_EditOrAddTranslate", "Administration").Ajax(false);
commands.Custom("Update").Text(Resource.Edit)
.ButtonType(GridButtonType.BareImage) .SendState(true).SendDataKeys(true).HtmlAttributes(new { id = "popUp"}) Action("Gallery_Bar_EditOrAddTranslate", "Administration").Ajax(false); }).Width("5%").Title(Resource.Coomand);
This will generate something like action Link
the id id = m.UserId you can show like DataKeys:
.Name("GridName") .DataKeys(key =>
{
key.Add(c => c.UserId).RouteKey("userId");
})
at the post method you will have :
public ActionResult xxx(int userId)
{
}
I had a print button I needed to put in the Header row, that I chose to put in the same column as, but above where the Update button goes. I was able to do it just fine in Razor like this:
columns.Command(command => {command.Edit(); }).Width(100).HeaderTemplate(i => #Html.ActionLink("Print Grid", "OutputAgencies", "Admin", new { #class = "k-button" }) );
This is where "Print Grid" was for display on my linkbutton, "OutputAgencies" was a method in my controller, and "AdminController" was the name of my controller.