Pass values of kendo grid to popup window - kendo-ui

I have implemented a kendo grid and context menu in my MVC5 page. I open a window on click of the Update Status menu. I need to retrieve the requestid and couple of other fields from the selected row in the pop up window. I would also need to show a drop down control with values. Whats the best way of doing it
Grid
div class="requestgrid" id="requestGrid">
#(Html.Kendo().Grid<CC.GRP.MCRequest.ViewModels.RequestViewModel>()
.Name("GridRequest")
.Columns(columns => {
columns.Bound(o => o.RequestID).Width("100px");
columns.Bound(o => o.CountryCode).Width("100px");
columns.Bound(o => o.SalesOffice).Width("100px");
columns.Bound(o => o.CustomerNumber).Width("120px");
columns.Bound(o => o.ProjectName).Width("120px");
columns.Bound(o => o.ProjectContent).Width("120px");
columns.Bound(o => o.ContractStartDate).Width("140px");
columns.Bound(o => o.Priority).Width("120px");
columns.Bound(o => o.NameOfResponsiblePerson).Width("170px");
columns.Bound(o => o.Status).Width("100px");
columns.Bound(o => o.CreatedBy).Width("110px");
columns.Bound(o => o.CreatedDate).Width("110px");
columns.Bound(o => o.ModifiedBy).Width("110px");
})
//.ToolBar(toolbar => toolbar.Create())
//.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Pageable()
.Sortable()
.Filterable()
.Scrollable()
.Groupable()
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Single)
.Type(GridSelectionType.Row))
.Events(events => events
.Change("onChange")
)
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(t => t.RequestID))
//.Create(update => update.Action("Team_Create", "Admin"))
.Read(read => read.Action("Requests_Read", "Request"))
//.Update(update => update.Action("Team_Update", "Admin"))
)
)
Context Menu
#(Html.Kendo().ContextMenu()
.Name("RequestMenu")
.Target("#GridRequest")
.Filter("tr")
.Orientation(ContextMenuOrientation.Vertical)
.Animation(animation =>
{
animation.Open(open =>
{
open.Fade(FadeDirection.In);
open.Duration(500);
});
})
.Items(items =>
{
items.Add()
.Text("Edit");
items.Add()
.Text("Update Status");
})
.Events(e =>
{
e.Select("onSelect");
})
)
Javascript
function onSelect(e) {
var grid = $("#GridTeam").data("kendoGrid");
var requestId;
switch ($(e.item).children(".k-link").text()) {
case "Edit":
var grid = $("#GridRequest").data("kendoGrid");
var column = grid.columns[0];
var selectedBackup = grid.dataItem(grid.select());
requestId = selectedBackup.id;
window.location.href = '#Url.Action("EditRequest", "Request", new { id = "_id_", status="Edit" })'.replace('_id_', requestId);
break;
case "Update Status":
//alert("Work in progress");
//$('#window1').data('kendoWindow').center().open();
var myWindow = $("#window");
//e.preventDefault();
//var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
//kendo.bind($("#window"), dataItem);
myWindow.kendoWindow({
width: "400px",
height: "180px",
title: "Update Request Status",
modal: true,
visible: false,
actions: ["Minimize", "Maximize", "Close"],
}).data("kendoWindow");
myWindow.data("kendoWindow").center().open();
}

You're doing it almost right, only by two details:
If you bind the contextMenu's target to the grid's container, you'll never be sure which row user did clicked. I suggest you to bind to your grid's rows(TR) instead, e.g. #GridRequest tbody tr;
I'm afraid e.currentTarget doesn't exists or returns undefined in that context. You should use e.target which will point to the clicked row if you did what I suggested above. Then you could get your dataItem as follows:
grid.dataItem(e.target);
Check out this demo with my suggestions working.

Related

How to access a Model property in a TreeView on Telerik MVC TreeView (Kendo UI)

How do I access the ID property of the model when I select one of the treeview nodes? (I want to display the details based on ID next to the treeview)
#(Html.Kendo().TreeView()
.Name("OrganizationTree")
.HtmlAttributes(new { #class = "demo-section" })
.DataTextField("Name")
.DragAndDrop(true)
.ExpandAll(true)
.Events(events => events
.Select("onOrgSelect")
.Drop("onOrgDrop")
)
.DataSource(dataSource => dataSource
.Model(m=> m
.Id("ID")
.HasChildren("HasChildren")
)
.Read(read => read
.Action("Organizations_Read", "Organizations")
)
)
)
Here's the javascript function:
function onOrgSelect(e)
{
var id = $("#" + e.node.id).?????;
GetOrganization(id);
}
Check the common operations topic here.
function onSelect(e) { // this refers to the TreeView object var dataItem = this.dataItem(e.node);
console.log("Selected node with id=" + dataItem.id);
}
$("#treeview").kendoTreeView({ dataSource: [ { id: 1, text: "Item 1", items: [ { id: 3, text: "Item 3" } ] }, { id: 2, text: "Item 2" } ], select: onSelect });

Kendo grid error missing when scrolling

I have simple kendo grid with scrolling. It shows 20 items at the beginning and when scrolling it gets dynamically more data and add to the grid.
Normally when getting data for first page when grid is loading, when dataService throws exception like this:
return new HttpStatusCodeResult((int)HttpStatusCode.ServiceUnavailable, this.T("System Error - retrying.").Text);
and my js method binded in configuration
Events(events => events.Error("acc.mp.gridErrorDialog"))
catch it and display proper message.
The problem is with next page, when grid is getting more data.
I have seen that is happend when I toucht the scroll and scroll like 3 rows (even thought page size is 20), grid is trying to get data to the buffer to show them when I scroll 20 items.
But when error happens in this operation, the same like in first query, Kendo grid is not showing it immediately (becuse I didn't scrool yet 20 rows only it keeps its in his buffer) and nothing happen, and when I scroll to 20 rows spinner shows and all frezes. Method acc.mp.gridErrorDialog is not fired.
Grid initialization:
public static GridBuilder<T> InitializeGrid<T>(this GridBuilder<T> gridBuilder, string gridName, string dataBindAction, string controllerName, object routeValues) where T : class
{
if (gridBuilder == null)
{
throw new ArgumentNullException("gridBuilder");
}
return
gridBuilder
.Name(gridName)
.TableHtmlAttributes(new { Class = "styled", cellpadding = "0", border = "0", margin = "0" })
.HtmlAttributes(new { Class = "dynamicGridHeight" })
.AutoBind(false)
.DataSource(
dataSource =>
dataSource.Ajax()
.PageSize(ModelPortfolioConfigurationManager.GridPageSize)
.ServerOperation(true)
.Events(events => events.Error("acc.mp.gridErrorDialog"))
.Read(read => read.Action(dataBindAction, controllerName, AddAntispinnerParameter(routeValues))));
}
and grid:
#(Html.Kendo()
.Grid<ValidatedClientAccountViewModel>()
.InitializeGrid(Naming.GridId(GridType.Upper), "GetClients, "ModelClients", new { modelTemplateId = Model.ModelId })
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(o => o.AccountId)))
.ToolBar(toolBar => toolBar.Template(
#<text>
<script type="text/javascript">
acc.mp.utils.bindLiveSearch($("##Naming.GridId(GridType.Upper) input[name='txtSearch']"), function () { $("##Naming.GridId(GridType.Upper) button[name='btnSearch']").click(); });
acc.mp.utils.searchGridFocus($("##Naming.GridId(GridType.Upper) input[name='txtSearch']"));
</script>
</text>))
.Columns(columns =>
{
columns.Bound(o => o.AccountId)
.ClientTemplate(ClientTemplates.UpperGridRowSelection)
.HtmlAttributes(new { style = "text-align: center" })
.HeaderTemplate(ClientTemplates.SelectAllCheckBox("cbLinkAll"))
.HeaderHtmlAttributes(new { style = "text-align: center" })
.Filterable(true)
.Sortable(false)
.Width(35);
columns.Bound(o => o.ClientReferenceNumber).Title(accountReference).HeaderHtmlAttributes(new { title = accountReference });
})
.EnableScrollingAndPaging(ModelPortfolioConfigurationManager.GridPageSize)
.Sortable()
.Events(events =>
{
events.DataBinding("acc.mp.clientAccounts.upperGrid.dataBinding");
events.DataBound("acc.mp.clientAccounts.upperGrid.dataBound");
events.Change("acc.mp.clientAccounts.upperGrid.rowSelect");
})
)
this is a bug in kendo, You can track the status of the issue here https://github.com/telerik/kendo-ui-core/issues/749

How can i highlight the Kendo grid cell by color change after update

I am using Kendo Ui Grid with MVC and SignalR. I can successfully perform the CRUD operations on grid using SignalR. I would like to notify clients by highlighting(By changing cell color) the updated cell. How can I achieve this with the following code:
#(Html.Kendo().Grid<Webapplication1.Models.ShipViewModel>()
.Name("ShipGrid")
.Columns(c =>{
c.Bound(m => m.Id).Hidden();
c.Bound(m => m.LocationViewModel)
.Title("Location1");
c.Bound(m => m.Location2ViewModel)
.Title("Location2");
c.Bound(m => m.boxSent);
c.Command(p =>
{
p.Edit().Text(" ").UpdateText(" ").CancelText(" ");
p.Destroy().Text(" ").HtmlAttributes(new { #title = "Cancel" });
});
})
.ToolBar(toolbar =>
{
toolbar.Create().Text("").HtmlAttributes(new { #title = "Add" });
})
.Editable(editable => editable
.DisplayDeleteConfirmation("DELETE.")
.Mode(Kendo.Mvc.UI.GridEditMode.PopUp)
.TemplateName("abcEditor")
)
.Events(events =>
{
events.Edit("edit");
})
.DataSource(dataSource => dataSource
.SignalR()
.Transport(tr => tr
.Promise("hubStart")
.Hub("mainHub")
.Client(c => c.Read("abc_Read").Create("abc_Insert").Update("abc_Update").Destroy("abc_Delete"))
.Server(s => s.Read("abc_Read").Create("abc_Insert").Update("abc_Update").Destroy("abc_Delete")))
.Schema(schema => schema
.Model(m => {
m.Id(p => p.Id);
m.Field(p => p.Location1ViewModel).DefaultValue(ViewData["DefaultLocation1"] as Webapplication1.Models.Location1ViewModel);
m.Field(p => p.Location2ViewModel).DefaultValue(ViewData["DefaultLocation2"] as Webapplication1.Models.DeliveryLocationViewModel);
})
)
)
)
I would like to Highlight the cell that is being updating here. Something like stock market data flashing. How can I achieve this?
I've done similar kind of thing. I don't know if that helps you. In your default view model add a extra property, say "Updated" as a boolean. Now every time you have update a row, put "Updated" as a true.
And in kendo grid add a new dataBound event.
.Events(events => events.DataBound("onDataBound"))
Now on JS use something like the following;
function onDataBound(arg) {
var itemsInActivityGrid = $("#ShippingGrid").data().kendoGrid.dataSource.data().length;
for (i = 0; i < itemsInActivityGrid; i++) {
if ($("#ShippingGrid").data().kendoGrid.dataSource.data()[i].Updated == true) {
$("#ShippingGrid .k-grid-content tr[data-uid='" + $("#ShippingGrid").data().kendoGrid.dataSource.data()[i].uid + "']").css("background-color", "orange");
}
}
}
Update: I don't know your logic. As far as you put on comments, you want to do something like online share dealing sites. Anyway, as far as I could, if you want to highlight individual cell in a row, add another extra field say "Column" along with "Updated"; it could be a string. Here you mark which cell you want to put the back ground colour from the backend. Say we've got it's value as "2".
for (i = 0; i < itemsInActivityGrid; i++)
{
var TableUID = $("#ShippingGrid").data().kendoGrid.dataSource.data()[i].uid;
var TableToColour = $("#ShippingGrid .k-grid-content tr[data-uid='" + TableUID + "']").parent().parent()[0];
var ColumnToColor = $("#ShippingGrid").data().kendoGrid.dataSource.data()[i].Column;
$(TableToColour.rows[0].cells[" + ColumnToColor + "]).select().attr("style","background-color:blue")
}
In case, you need to highlight multiple cells on the same row, in Column send something like "1,2,3,5"; where 1, 2, 3 and 5 represents the column numbers on the same row. And after ColumnToColor do some string parsing, put it into a for loop or something and colour;
Hope this helps. Thank you.
I have achieved this as below and its working fine:
in my .cshtml page
myHub.client.highlightRow = function (id) {
var data = $("#MyGrid").data("kendoGrid").dataSource.data();
for (var i = 0; i < data.length; i++) {
var dataItem = data[i];
if (dataItem.id == id) {
//alert(dataItem.uid);
$("#MyGrid").data("kendoGrid").tbody.find("tr[data-uid=" + dataItem.uid + "]").effect("highlight", { color: "#f35800" }, 3000);
}
}
};
And in my update/insert method in my SignalR Hub class:
Clients.Others.highlightRow(mygridViewModel.Id);

Change text globalization "The field X must be a number." in KendoGrid for not int values using View Model

I'm using Kendo UI 2013.2.716, specifically KendoGrid, C#, Visual Studio 2010, I need to change the globalization of the message "The field X must be a number." as seen in the image and put it in another language.
If I inspect the element in Chrome I see:
I tried doing this:
ViewModel
namespace Test.Models
{
public class TestModel
{
...
[DisplayName("Pos")]
[IsNumberAttribute(ErrorMessage = "Ingrese un número.")]
public int Pos { get; set; }
}
}
namespace Test.Models.CustomValidator
{
[AttributeUsage(AttributeTargets.Property)]
public class IsNumberAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
try
{
int numeroTemp;
bool esNumero = int.TryParse((string)value, out numeroTemp);
return esNumero;
}
catch (Exception)
{
return base.IsValid(value);
}
}
}
}
But it did not work, still in English :(
In my View I have this:
#(Html.Kendo().Grid<Test.Models.TestModel>(Model)
.Name("titulo")
.Columns(columns =>
{
...
columns.Bound("Pos").Filterable(false);
columns.Bound("Edad").Title("Edad").ClientTemplate("#=window.TestMantenedor.Valida(edad)#").Width(500);
})
.ToolBar(toolbar =>
{
toolbar.Create().Text("Agregar");
toolbar.Save().SaveText("Modificar").CancelText("Cancelar");
})
.Editable(editable =>
{
editable.DisplayDeleteConfirmation(false);
editable.Mode(GridEditMode.InCell);
})
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Batch(true)
.Model(model =>
{
...
model.Field(p => p.Edad).DefaultValue(true);
})
.Create("Create", "Test", new { id = id })
.Events(events => events.Error("error_handler"))
.Events(events => events.RequestEnd("success_handler"))
)
.Filterable(filterable => filterable.Messages(messages =>
{
messages.Info("Mostrar plantillas en estado");
messages.Filter("Filtrar");
messages.Clear("Borrar");
messages.IsTrue("Valido");
messages.IsFalse("No valido");
})
)
.Pageable(p => p
.Messages(m => m
.Display("Mostrando {0}-{1} de {2} registros")
.Empty("No se encontraron registros")
.First("Ir a la primera página")
.Last("Ir a la última página")
.Next("Ir a la página siguiente")
.Previous("Ir a la página anterior")
)
)
)
Any help?
Finally, after 3 days trying a lot of stuff, also try the solutions of
How to change 'data-val-number' message validation in MVC while it is generated by #Html helper
#(Html.Kendo().Grid<Test.TestModel>(Model)
.Name("listado")
.Columns(columns =>
{
columns.Bound("idElementColumn").Filterable(false);
...
}
And at least, in the end of View I put:
<script type="text/javascript">
$("#listado").on("click", function (e) {
$(".k-grid #idElementColumn").attr('data-val-number', 'Ingrese un número.');
});
</script>

Kendo grid update - update click of any row shows 1st row details

I am facing an issue with Kendo grid inline editing, The issue is even though I update any row, 1st row data is displayed in grid, Any help on this?
Before update
After update.
Interestingly the object I return from the controller does have the correct data
Controller code
[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken]
[ActionSessionState(System.Web.SessionState.SessionStateBehavior.Required)]
[OutputCache(Duration = 0, VaryByParam = "none")]
public ActionResult _SaveBatchEditingintegrate([DataSourceRequest] DataSourceRequest request)
{
var UPObj = SessionFacade.UserProfile as UserProfile;
try
{
IntegrationRate objInteg = new IntegrationRate();
TryUpdateModel(objInteg);
if (objInteg.PeriodID != 0)
{
var Integrationrate = (from p in _draftManagecompany.IntegrationRates where p.PeriodID == objInteg.PeriodID select p).First();
TryUpdateModel(Integrationrate);
if (Integrationrate.Rate > 100) //set 100 as default
{
Integrationrate.Rate = 100;
}
}
LoadResourceJSArray();
}
catch (Exception ex)
{
// Adding related additional information along with exception object
//ExceptionLogger.Log(ex, "Period ID", id);
ExceptionLogger.Log(ex, "User Profile Info", UPObj);
// Handle exception with BubbleExceptionPolicy
if (exManager.HandleException(ex, "BubbleExceptionPolicy"))
throw; // Not to include the ex, as the previous stack trace to be maintained
}
//_draftManagecompany.IntegrationRates contains updated value in the correct order
return Json(_draftManagecompany.IntegrationRates.ToDataSourceResult(request));
}
cshtml code:
#{ var integrateGrid = Html.Kendo()
.Grid(Model.Company.IntegrationRates)
.Name("Gridintegrate")
.EnableCustomBinding(true) // Enable custom binding
.BindTo(Model.Company.IntegrationRates)
.Events(events =>
{
events.Change("DataBound_Integ");
})
.ToolBar(
commands =>
{
//commands.Insert().ButtonType(GridButtonType.BareImage).ImageHtmlAttributes(new { style = "visibility:hidden" });
}
)
.Columns(columns =>
{
columns.Bound(p => p.PeriodID).Visible(false);
columns.Bound(p => p.Month).Width(150);
columns.Bound(p => p.Rate).Format("{0:0.00}%").Width(100);
columns.Command(commands =>
{
commands.Edit().HtmlAttributes(new { #id = "btn_IntRateEdit" });
}).Width(150).Title(gridTitle);
})
.HtmlAttributes(new { style = "height: 380px;" })
.Scrollable()
.Editable(editable => editable.Mode(GridEditMode.InLine))
.DataSource(dataSource => dataSource.Ajax()
//.Batch(true)
.Read(read => read.Action("_AjaxBindingintegrate", "Company"))
.Update(update => update.Action("_SaveBatchEditingintegrate", "Company"))
.Model(model =>
{
model.Id(c => c.PeriodID);
model.Field(c => c.Month).Editable(false);
}
)
.Events(events =>
{
events.Error("CheckSessionExistsOnTelerik");
})
);
//.Pageable(paging => paging.Style(GridPagerStyles.NextPreviousAndNumeric | GridPagerStyles.PageSizeDropDown).PageSize(20, new int[3] { 20, 50, 100 })).ToComponent();
var culture = System.Globalization.CultureInfo.InvariantCulture;
//integrateGrid.Localization = new GridControlLocalization(culture);
integrateGrid.Render();
}
I think I see the problem here. From what I can tell when you complete the update you are returning the entire data set back on the update ie June, january, February etc.
On the update all you have to do is return the item you have updated back to the grid
So in your example change the return json to the following:
Return json(new { IntegrationRate}.toDataSourceResult(request,modelState),jsonbehaviour.allowget);
This then should sort out your issue.
Because you are returning the entire data set back it is rendering the first row as the expected result.
As you say you see the data saving correctly behind the scenes. So you know an error is not being thrown.

Resources