Hi i am using KEndo Ajax Grid in my MVC project. I am using a htmlhlper in my grid to simply go into the new page but i am getting the error "mvc.HTMLHelper does not contain a definition for ActionLink and the best extension method overload"
My Code
<%: Html.Kendo().Grid<KendoGridAjaxEditing2.Models.ProductViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(product => product.CustomerID).Width(100);
columns.Bound(product => product.CustomerName).Template(c => #Html.ActionLink(c.CustomerID, "ViewDetails", new { id = c.CustomerID }));
columns.Bound(product => product.CustomerLastName).Width(250);
columns.Bound(product => product.Customerage).Width(250);
columns.Command(commands =>
{
commands.Edit(); // The "edit" command will edit and update data items
commands.Destroy(); // The "destroy" command removes data items
}).Title("Commands").Width(200);
})
.ToolBar(toolbar => toolbar.Create()) // The "create" command adds new data items
.Editable(editable => editable.Mode(GridEditMode.InLine)) // Use inline editing mode
.DataSource(dataSource =>
dataSource.Ajax()
.Model(model =>
{
model.Id(product => product.CustomerID); // Specify the property which is the unique identifier of the model
model.Field(product => product.CustomerID).Editable(false); // Make the ProductID property not editable
})
.Create(create => create.Action("Products_Create", "Home")) // Action invoked when the user saves a new data item
.Read(read => read.Action("Products_Read", "Home")) // Action invoked when the grid needs data
.Update(update => update.Action("Products_Update", "Home")) // Action invoked when the user saves an updated data item
.Destroy(destroy => destroy.Action("Products_Destroy", "Home")) // Action invoked when the user removes a data item
)
.Pageable()
%>
Help needed thanks
How to use action links is covered here.
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();
I have a Kendo Grid which has a popup editable template,
If possible i would like to pass the model (the model of the row, or at least its Id) to the editable template
Grid
#(Html.Kendo().Grid<Client>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.Name).Width(140);
columns.Bound(c => c.Status);
columns.Bound(c => c.ProcesingStyle);
columns.Bound(c => c.ArchiveDays);
columns.Command(command =>
{
command.Edit().Text(" ");
command.Destroy().Text(" "); ;
}).Width(90);
})
.ToolBar(toolbar => toolbar.Create().Text("New"))
.Editable(editable => editable
.Mode(GridEditMode.PopUp)
.TemplateName("Client").AdditionalViewData(new { Client = Model })
.Window(w => w.Title("Site")))
.HtmlAttributes(new { style = "height: 380px;" })
.Scrollable()
.Sortable()
.Selectable()
.Resizable(resize => resize.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
.Events(events => events.Change("onChange"))
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("Get", "Clients"))
.Model(model => model.Id(p => p.Id))
.Create(update => update.Action("Create", "Clients"))
.Update(update => update.Action("Update", "Clients"))
.Destroy(update => update.Action("Destroy", "Clients"))
)
)
Template
#model Client
#(Html.Kendo().ComboBoxFor(m => m.Plan)
.DataTextField("Name")
.DataValueField("Id")
.Placeholder("Select Plan...")
.HtmlAttributes(new { style = "width:300px" })
.Filter(FilterType.Contains)
.MinLength(3)
.DataSource(source =>
source.Read(read =>
read.Action("GetPlans", "Plans",new {ClientId = Model.Id}))))
Everything works fine except i need to use the Id of the row/model inside the template, in particular , i need the to pass the model.Id (which is the id of the model of the row), to the action on the Combobox in the template, so i can filter the data correctly
This is the offending line in the grid,
.TemplateName("Client").AdditionalViewData(new { Client = Model })
The result is the Model inside the template is always null, im not sure how to pass the data i need to the template
Is there anyway i can do this, or should i be looking at a different approach?
The way I got around this was to put a JavaScript function in the original view as seen below:
function getClientId() {
var row = $(event.srcElement).closest("tr");
var grid = $(event.srcElement).closest("[data-role=grid]").data("kendoGrid");
var dataItem = grid.dataItem(row);
if (dataItem)
return { clientId: dataItem.Id }
else
return { clientId: null }
}
And reference it from my editor template:
.DataSource(source => source.Read(read => read.Action("GetPlans", "Plans").Data("getClientId"))))
Note : I'm pretty sure you cant run JavaScript from a EditorTemplate so it needed to be housed in the original view.
I know this is a really old question, but for those who are wondering why this doesn't work:
.TemplateName("Client").AdditionalViewData(new { Client = Model })
This code doesn't work because the only data you can pass through this method is static data. You can pass specific strings or numbers, like "Hello World", and that would work fine. For dynamic data with kendo, I've learned that it really depends on the situation, and your solution here works well.
I have a Kendo grid set up for client-side only. Whenever I add a row, then edit it, then cancel - it gets removed. Multiple questions have been asked here and on the Kendo forums about this same issue, and all the suggestions point to incorrect setup of the model's ID.
Well, in my case the ID seems to be set up correctly. I am assigning a new ID to the model in the onGridSave() javascript event, like this:
var _curId = 1;
function onGridSave(e) {
var newId = _curId++;
e.model.set('id', newId);
e.model.set('EncryptedIngredientId', newId);
}
And when I look at the data in the grid after having added multiple rows, all of their IDs are unique - from 1 to n.
But when I cancel an edit, in the onGridChange() event the action is "remove", and the cancelled row is removed. This happens for new rows as well as for edited rows, while it should only be the case for new rows.
The grid is set up as follows:
#(Html.Kendo().Grid<IngredientViewModel>(Model.ServerData)
.Name("IngredientsGrid")
.Editable(editable => editable.Mode(GridEditMode.InLine).Enabled(true))
.BindTo(Model.DataAfterEdit ?? Model.ServerData)
.DataSource(ds => ds
.Ajax()
.ServerOperation(false)
.Events(ev => ev.Change("onGridChange").Error("onGridError"))
.Model(m => {
m.Id(p => p.EncryptedIngredientId);
m.Field(p => p.EncryptedIngredientId).DefaultValue(Guid.NewGuid().ToString());
m.Field(p => p.PercentInfo).DefaultValue(new PercentInfoViewModel());
})
.Read("IngGrid_Read", "Company") // <-- dummy action that doesn't exist in controller
.Update("IngGrid_Update", "Company") // <-- dummy action that doesn't exist in controller
.Create("IngGrid_Create", "Company") // <-- dummy action that doesn't exist in controller
.Destroy("IngGrid_Destroy", "Company")) // <-- dummy action that doesn't exist in controller
.ToolBar(tbar => tbar.Create())
.Columns(c => {
c.AutoGenerate(false);
c.Bound(m => m.CasNumber);
c.Bound(m => m.IngredientName);
c.Bound(m => m.PercentInfo).ClientTemplate("#= makePercentageDisplayString(data.PercentInfo) #").Width(180);
c.Bound(m => m.ReachRegNumber);
c.Bound(m => m.ReachSvhc);
c.Bound(m => m.RohsSubstance);
c.Bound(m => m.Prop65Substance);
c.Command(command => {
command.Edit();
command.Destroy();
}).Width(200);
})
.Events(evt => {
evt.Save("onGridSave");
evt.Edit("onGridEdit");
})
)
What am I doing wrong?
When you declare this dummy actions, Kendo is trying to save data after you edit your cell. It perform create action but doesn't have correct response from the server so it believe that request was fail. Because of that it trying to remove row after you click cancel, cuz it can't find it in their dataSource.
If it gonna be just local grid as you said, the solution is add .Batch(true) on you grid dataSource config to prevent update action after you change cell.
If you wanna save your edited data on the server you should implement Update, Create and Destroy action correctly.
I also asked my question here:
http://www.telerik.com/forums/mvc---inline-client-side-grid---clicking-cancel-removes-row-probably-not-the-model-id-issue-#qn5VWKCX9kmpZnLuTzDveQ
It turns out this is not supported when using MVC wrappers, however it could be done using JavaScript. Since I didn't want to lose the type safety of C#, I implemented the CRUD actions on the controller and store rows in the session.
The only 2 things I had to change in my grid definition were: set .ServerOperation(true) instead of false; and remove the .BindTo(...) call. Resulting code looks like this:
#(Html.Kendo().Grid<IngredientViewModel>(Model.ServerData)
.Name("IngredientsGrid")
.Editable(editable => editable.Mode(GridEditMode.InLine).Enabled(true))
.DataSource(ds => ds
.Ajax()
.ServerOperation(true)
.Events(ev => ev.Change("onGridChange").Error("onGridError"))
.Model(m => {
m.Id(p => p.EncryptedIngredientId);
m.Field(p => p.EncryptedIngredientId).DefaultValue(Guid.NewGuid().ToString());
m.Field(p => p.PercentInfo).DefaultValue(new PercentInfoViewModel());
})
.Read("IngGrid_Read", "Company") // <-- dummy action that doesn't exist in controller
.Update("IngGrid_Update", "Company") // <-- dummy action that doesn't exist in controller
.Create("IngGrid_Create", "Company") // <-- dummy action that doesn't exist in controller
.Destroy("IngGrid_Destroy", "Company")) // <-- dummy action that doesn't exist in controller
.ToolBar(tbar => tbar.Create())
.Columns(c => {
c.AutoGenerate(false);
c.Bound(m => m.CasNumber);
c.Bound(m => m.IngredientName);
c.Bound(m => m.PercentInfo).ClientTemplate("#= makePercentageDisplayString(data.PercentInfo) #").Width(180);
c.Bound(m => m.ReachRegNumber);
c.Bound(m => m.ReachSvhc);
c.Bound(m => m.RohsSubstance);
c.Bound(m => m.Prop65Substance);
c.Command(command => {
command.Edit();
command.Destroy();
}).Width(200);
})
.Events(evt => {
evt.Save("onGridSave");
evt.Edit("onGridEdit");
})
)
I want to show radio button in kendo Grid column. I have tried so many methods. Its showing only header in row not showing radio button. I am working in MVC4
My code :
#(Html.Kendo().Grid<razor.Core.BOL.TRD_OrderItem>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(item => item.OrderId).Hidden(true);
columns.Template(item => #Html.RadioButton("Approve", true, false, new { #id = "Approve" })).Title("Approve");
columns.Bound(m => m.MatchType).Title("Match Type");
columns.Bound(item => item.OrderDate).Format("{0:MM/dd/yyyy}").Title("Date");
columns.Bound(item => item.OrderType).Title("Sell");
columns.Bound(item => item.Description).Title("Ask");
columns.Bound(item => item.OrderAmount).Title("Total");
columns.Bound(item => item.OrderStatus).Title("Status");
})
.Pageable()
.Sortable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Model(model =>
{
model.Id(m => m.OrderId);
})
.Read(read => read.Action("GetOrderOption", "Order", new { OrderId = ViewBag.OrderId}))
))
Thanks,
S Somu
In my case the radio button was bound to the model, so you should add a field to save the radiobutton value (Approved), so following your example I added my radio button column with:
columns.Bound(item => item.Approved).Template(#<text></text>).ClientTemplate("<input type='radio' name='ItemList[#= index(data)#].Approved' value='true' />").Title("Approve");
Where ItemList is the name of your List of TRD_OrderItem in your model.
Also you will need to add this javascript function that is used to get the index for the radiobutton name field:
function index(dataItem) {
var data = $("#Grid").data("kendoGrid").dataSource.data();
return data.indexOf(dataItem);
}
I have a Grid with Employes. There is a Edit button and the edit mode is set to Popup. In the EditorTemplate of the entity I want to edit, there is another grid that has a history of Salary with a incell or inline edit mode.
Both grids uses Ajax datasources. The problem is with the inner grid binding. The controller action feeding a Json result to the ajax call requires the ID of the employe we are editing to return the appropriate Salary history. However, Kendo UI ASP.NET MVC wrapper will render some sort of template of the editor before knowing which employee we want to edit, then it will edit it when we are requesting the popup.
How can I feed the Employe ID in the Read Ajax call?
Main Grid
#(Html.Kendo().Grid<MyProject.Business.Models.EmployeDTO>().Name("EmployeGrid")
.ToolBar(toolbar => toolbar.Create())
.Columns(cols =>
{
cols.Bound(o => o.someData).Title("Some Data");
cols.Bound(o => o.moreData).Title("More Data");
cols.Command(o =>
{
o.Edit();
o.Destroy();
}).Title(" ");
})
.Editable(editor => editor
.Mode(GridEditMode.PopUp)
.Window(window => window.Draggable().Resizable().HtmlAttributes(new { #style = "width:700px;" })))
.Sortable()
.Filterable()
.Groupable()
.DataSource(datasource => datasource
.Ajax()
.Model(model => model.Id(o => o.id))
.Read(read => read.Action("GetAll", "EmployesAjax"))
.Update(update => update.Action("Update", "EmployesAjax"))
.Create(create => create.Action("Create", "EmployesAjax"))
.Destroy(destroy => destroy.Action("Destroy", "EmployesAjax"))
)
)
Inner Grid (In Views/Shared/EditorTemplates/EmployeDTO.cshtml)
#Html.Kendo().Grid<MyProject.Business.Models.SalairyDTO>().Name("SalaryGrid")
.Columns(cols =>
{
cols.Bound(o => o.someInfo).Title("Some Info");
})
.DataSource(datasource => datasource
.Ajax()
.Model(model =>
{
model.Id(o => o.id);
model.Field(o => o.employe_id).DefaultValue(Model.id);
})
// NEED THE ID HERE
.Read(read => read.Action("GetByEmployeId", "SalairyAjax", new { id = "" }))
.Update(update => update.Action("Update", "SalairyAjax"))
.Create(create => create.Action("Create", "SalairyAjax"))
.Destroy(destroy => destroy.Action("Destroy", "SalairyAjax"))));
Basically I would suggest you to Set the AutoBind option to false of the inner Grid and use the edit event of the outer Grid to perform a read request and pass the value as additional parameter.
Here is an example:
function onEditOfEmployeGrid(e){
$('#SalaryGrid').data().kendoGrid.dataSource.read({id:e.model.EmployeeID})
}
You could simply pass the value from the grid using addtionaldata parameter within the grid. the RouteID on the (left side) can then be referenced within the Grid Popup Editor using ViewData["RouteID"]. I hope that helps
.Editable(editable => editable.Mode(GridEditMode.PopUp)
.TemplateName("busStop")
.DisplayDeleteConfirmation(true)
.Window(window => window.Modal(true).Resizable().Draggable())
.AdditionalViewData(new { RouteID = Model.RouteID }))