Kendo UI MVC Grid row selecting - kendo-ui

I need to execute a History push state to some Action on Grid click...
I looked the API, and I think the Events Change its the right place to do that...
So, thats the code i´d like to put in there
"window.History.pushState(null, null," + "'" + Url.Action("Edit", "MyController") + "/' + Id);"
I used that on a similar JS Grid and works fine, but I dont know how to do that with Kendo UI MVC Wrapper...
I intend to use that directly on Grid definition, so I dont have to create any JS method... Something like that :
.Events(events => events.Change(x => "window.History.pushState..."))
Is that possible? How get the ID and declare Url.Action there?
Thanks

The docs for the "change" event have an example of how to get the data item for the selected row(s).
The MVC helper expects the string name of a JS function to be passed to events.Change() but I think you can define a function there too.
So something like:
#{
var url = Url.Action("Edit", "MyController");
}
...
.Events(events => events.Change(x => #"function (changeEvent) {
var selectedRows = this.select();
var dataItem;
var numSelectedRows = selectedRows.length;
for (var i = 0; i < numSelectedRows ; i++) {
dataItem = this.dataItem(selectedRows[i]);
selectedDataItems.push(dataItem);
window.History.pushState(null, null, """ + url + #"/"" + dataItem.Id);
}
}"))
I don't have a Kendo MVC project open in front of me to verify the syntax, but that should be pretty close, or at least get you pointed in the right direction.

Related

KendoUI for jQuery - Chart dataBound event does not work

Here's a simplified example of my data:
[{"Name": "Bob", "Count":3}, {"Name": "Steve", "Count":5}]
What I want is a chart title of: Total FOO: 8. So the title must be based on the data. The data is AJAX and this is an ASP.NET MVC application.
In my CSHTML I have:
.DataSource(ds => ds.Read(read => read.Action("MeMethodName", "MyControllerName")))
.Events(events => events.DataBound("setChartTitle('chartName', 'Total FOO')"))
Here's the crazy hack I had to do:
function setChartTitle(name, title) {
let chart = $("#" + name).data("kendoChart");
if (chart) {
let ds = chart.dataSource;
let total = 0;
for (let i = 0; i < ds.data().length; i++) {
total += ds.data()[i].Count;
}
chart.options.title.text = title + ": " + total;
chart.refresh();
} else if (arguments.length < 3) {
// Data source was not found and this was initiated through Kendo. Wait and try again but only once
setTimeout(function () {
sumEntityCount(name, title, "stop");
}, 500);
}
}
This is really bad.
Accessing the kendoChart returns undefined, yet the chart itself called this. This is why I need to check if (chart) above.
This leads to a hacky ELSE block I added where I can call this again with a 500 ms delay. This alone is a bug as 500ms is a random number and may not be enough. I can't ship like this.
To prevent recursion I call the same function with a different parameter.
If the values are found, then I can't just set the chart options. I need to call refresh which redraws everything.
Questions:
Why is the kendoChart data undefined initially? Why has Telerik called dataBound when there's nothing there?!
Isn't there a dataBinding event? I don't want to do this after the fact nor do I want to refresh the whole thing.
The chart itself is passed in when you declare a basic function without calling it:
.events(events => events.Render("someFunction"))
Then declare your function:
function someFunction(sender) {
// sender.chart is what I want
}
But you cannot pass any arguments here. Which means I can't use it.
The hack is to do the following:
.Events(events => events.Render("function(sender) { someFunction(sender, 'param1', 'param2', 'param3'); }"))
This gives it an actual function instead of calling a function. Kendo passes in the sender as expected and you can pass it along with new parameters to your JavaScript.
I also switched to using Render instead of DataBound.

How to determine which row or control is making a DropDownList Read Data call

I have a DropDownListFor control inside a Kendo grid, and I need the value of another element in that row in order to pass a parameter to the DropDownList's server-side read method. It's a similar setup to the example here.
Here is the code which defines the DropDownListFor:
#(Html.Kendo().DropDownListFor(m => m)
.Name("LinkIdentifier")
.OptionLabel("---Select Form, etc.---")
.DataValueField("ID")
.DataTextField("Name")
.AutoBind(false)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("LinkTypeIdentifierDdl", "Alerts").Type(HttpVerbs.Post).Data("getCurrentLinkType");
}).ServerFiltering(true);
})
)
And here is the javascript function which is called in .Data:
function getCurrentLinkType() {
var grid = $("#linkGrid").data("kendoGrid");
var data = grid.dataSource.data();
var dataItem = data[0];
var valueForParameter = dataItem.SomeValue
//--snipped for brevity
}
The problem above is data[0]. It only points to the first row in the grid, which won't be correct if editing any other row. If I use a javascript debugger within this method and look at "this", it's the AJAX call which is referenced, not the dropdown control. I can't specify ".Data("getCurrentLinkType(this)")" as the method.
So, how can I determine which row/control has made the call to getCurrentLinkType?
There is no context passed from the Grid to the DropDownList to the Data function, so you need to figure it out yourself.
I have found 2 ways.
1:
// If your grid is single Selectable(), use the current selection
var dataItem = grid.dataItem(grid.select());
2:
// If your grid is not Selectable or is multi Selectable, get the row/tr closest to the editor and then get the dataItem from that
var dataItem = grid.dataItem($("#LinkIdentifier").closest("tr"));

How to prepend items in kendo mobile ui at listview. I am using kendo v2013.1.319

I have try this
$("#divPostList").data("kendoMobileListView").prepend("...");
but it gives error prepend: prepend is not a function
prepend method has an array as argument. You should use:
$("#divPostList").data("kendoMobileListView").prepend([ "..." ]);
But this is not available in v2013.1.319, Can you use the latest release? If you need to stay on v2013.1.319 you need to do something like:
// Get reference to the listview
var listview = $("#divPostList").data("kendoMobileListView");
// Get reference to the datasource
var ds = listview.dataSource;
// Get original data
var old = ds.data();
// New items + old
var prepended = $.merge([ "Prepended 1", "Prepended 2" ], old);
// Send prepended to listview
ds.data(prepended);
You can see it running here : http://dojo.telerik.com/#OnaBai/ONiY
But of course, upgrading Kendo UI version makes it much easier.

Ajax from telerik mvc treeviewitem

I am trying to work with telerik MVC TreeView. i have three levels in the treeview. On clicking on the 3rd level tree view item, i need to load a view without page refresh.
I tried to use item.Url. But the entire page refreshes and treeview disappears.
I have a treeview in "Menu" partial view and it is called by _layout.cshtml
#(Html.Telerik().TreeView()
.Name("TreeView")
.ShowLines(false)
.BindTo(Model, mappings =>
{
mappings.For<AdminTool.Web.Models.ProjectModel>(binding => binding
.ItemDataBound((item, project) =>
{
item.Text = project.Name;
})
.Children(project => project.ApiModels));
mappings.For<AdminTool.Web.Models.ApiModel>(binding => binding
.ItemDataBound((item, api) =>
{
item.Text = api.Name;
item.Value = api.Id;
})
.Children(api => api.ApiMethods));
mappings.For<AdminTool.Web.Models.ApiMethodModel>(binding => binding
.ItemDataBound((item, apimethod) =>
{
item.Text = apimethod.Name;
item.Url = Url.Action("ApiMethodById", "ApiMethod", new { id= apimethod.Id });
}));
})
)
Thanks in advance!
I would recommend using jQuery for this. What you would do it the following:
1) Have whatever location you want this to load to be placed inside a tag with some id on it (e.g. 'myDiv')
2) Write a jQuery function that on the click of you third level item (e.g. apiMethodID) to run a function that will call the controller action that you're looking for, and to post that to myDiv. You might want to try something like the following:
$(document).ready(function()){
$('#apiMethodID').click(function(){
var value = $('#apiMethodID').val();
var url = "/ApiMethod/ApiMethodById";
$.get(url, { apiMethodId: value }, function(data){
$('#myDiv').html(data);
});
})
}
$.get here will actually call your controller method. You should be able to debug that fact to make sure that it works.
3) Make sure that the controller action that you going to returns a PartialView, otherwise you're going to re-render the whole page inside of that div.
Let me know if that works.

Telerik Grid Master / Detail - display expand only if detail data exists

I have to display data using the telerik grid (master / detail) .
Is there a possibility to show the expand icon only if data exists for the master record? And how can i get this done?
Thanks in advance
On client-side:
<script>
function hidePlusSign(e) {
var row = e.row;
var dataItem = e.dataItem;
if (!dataItem.Expression) {
$('a.t-icon', e.row.cells).css('display', 'none');
}
}
</script>
...
.DetailView(d => d.ClientTemplate("<# if (expression) { #>" +
Html.Telerik().Grid<Details>...ToHtmlString()
+ "<# } #>")
.ClientEvents(e => e.OnRowDataBound("hidePlusSign"))
...
replace "Expression" with your condition.
On server-side:
I think you get the idea. The template is easier and for hiding the plus sign use the RowAction.

Resources