Kendo TreeList with checkboxes on ASPNET Mvc - asp.net-mvc

I'm using Kendo (and I've almost never used it before) in an ASPNET Mvc application and I need to create a TreeList with checkboxes: checking a father should check all children and unchecking a child should uncheck the father (and the grandfather, and so on).
The tree in itself works well: I've added a column with custom template and I'm using (successfully) the onClick event to get the value of the checkbox, but I can't figure out how to "bind" that value to the node of the tree (to reach every child and check it).
Here the code:
#(Html.Kendo().TreeList<TreeElem>()
.Name("treelist")
.Columns(col =>{
col.Add().Field(f => f.NodeDescription).Title("TREE LIST");
col.Add().Template("<input type='checkbox' data-bind='checked: checked' onClick='onCheck(event)'/>").Width(55);
})
.DataSource(source => source.Read(read => read.Action("GetData", "TreeController"))
.Model(m => {
m.Id(f => f.NodeId);
m.ParentId(f => f.ParentId);
m.Field(f => f.NodeDescription);
})
)
)
In the javascript:
function onCheck(e) {
console.log(e.target.checked); //print true/false according to the checkbox
console.log($("#treelist").data('kendoTreeList').dataSource.data()); //print the complete node list
//Other stuffs
}
I would like to get the right node from data() (or view()) according to the checkbox selected. Every node has references to his children and father, so the recursive function should be easy after that.
I've looked for and tried a lot of solutions but with almost no result, any idea?
Thanks

Related

Convert/Hide a MVC Core Html control behind a simple custom control with model binding

I have this dropdown
#(Html.Kendo().DropDownListFor(m => m.Letter.LetterTypeId)
.Size(ComponentSize.Medium).Rounded(Rounded.Medium).FillMode(FillMode.Outline)
.OptionLabel("Select RL Type *")
.HtmlAttributes(new { style = "width: 100%" })
.DataValueField(nameof(LookupLetterTypeModel.Id))
.DataTextField(nameof(LookupLetterTypeModel.Name))
.Filter(FilterType.Contains)
.Height(400)
.DataSource(source =>
{
source.Read(read => { read.Action("GetLookupLetterTypes", "Api"); })
.ServerFiltering(false);
})
.Events(e => { e.Select("LetterTypeId_OnSelect"); })
)
Is there a way in Core MVC to turn this control into a custom control that should only allow me to get or set the selected value (no need for the data object)? For all internal JS, the component will handle internally. It just needs to update the parent Model will be bound to. I'm looking at ViewComponent approach, but the code to invoke the view component is not that interesting, and the issue of binding a Model's property remains an issue.
I'm hoping to hide the significant markup of Kendo's Dropdown behind a simple tag-helper syntax for invoking my custom control.

How to move SignalR connection scripts to the bottom of the page on Kendo UI MVC grid

I have a kendo grid on a view with signalr connection to back end. It is currently working fine, however, I would like to move the script tag to the bottom of the generated page with a razor #section block.
<script>
var dataCollectionHub;
var hubStart;
$(function () {
dataCollectionHub = $.connection.dataCollectionHub;
hubStart = $.connection.hub.start();
});
</script>
#(Html.Kendo().Grid<ViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.Name);
})
.DataSource(
dataSource => dataSource
.SignalR()
.AutoSync(true)
.Transport(tr => tr
.Promise("hubStart")
.Hub("dataCollectionHub")
.Client(c => c
.Read("read")
.Create("create")
.Update("update")
.Destroy("destroy")
)
.Server(s => s.Read("read")))
.Schema(schema => schema
.Model(model =>
{
model.Id("Id");
model.Field("Id", typeof(int)).Editable(false);
model.Field("Name", typeof(string)).Editable(false);
})
)
)
)
The problem is that the grid requires the variables to be defined before itself because I get the following error:
Uncaught Error: The "promise" option must be set.
at new init (http://localhost:61683/Scripts/kendo/kendo.all.min.js:31:9317)
at Object.oe.create (http://localhost:61683/Scripts/kendo/kendo.all.min.js:28:13869)
at new init (http://localhost:61683/Scripts/kendo/kendo.all.min.js:27:22769)
at Function.ie.create (http://localhost:61683/Scripts/kendo/kendo.all.min.js:28:14660)
at init._dataSource (http://localhost:61683/Scripts/kendo/kendo.all.min.js:53:11752)
at new init (http://localhost:61683/Scripts/kendo/kendo.all.min.js:51:10176)
at HTMLDivElement.<anonymous> (http://localhost:61683/Scripts/kendo/kendo.all.min.js:26:4691)
at Function.each (http://localhost:61683/Scripts/jquery-1.12.3.js:370:19)
at jQuery.fn.init.each (http://localhost:61683/Scripts/jquery-1.12.3.js:137:17)
at jQuery.fn.init.e.fn.(anonymous function) [as kendoGrid] (http://localhost:61683/Scripts/kendo/kendo.all.min.js:26:4668)
Is there any way to move the script tag to bottom of the grid without breaking it?
What you're probably after is the Deferring-Feature of Kendo UI. Usually, the Scripts are generated immediately and all variables and JavaScript methods must exist during the initialization.
Update your script:
#(Html.Kendo().Grid<ViewModel>()
.Name("grid")
.Deferred() // Add this to your script
.....
Then move your script to the page bottom, and right after that, put the line:
#Html.Kendo().DeferredScripts();
Please note that deferred initialization might have some drawbacks. You might run into some timing issues when you access the Widgets in JavaScript, they will now be initialized later, also you might notice some FOUC effects.

Kendo Grid filterMenuInit.checkSource.view() empty in ASP.Net MVC

With a Kendo Grid defined in ASP.NET, with columns set as multi filterable
.Filterable(ftb => ftb.Multi(True))
I have defined the filterMenuInit event like so:
.Events(ev => ev.FilterMenuInit("filterMenuInit"))
Using the canonical js example for sorting the entries in a filter dropdown on a Kendo Grid,
function filterMenuInit(e) {
var filterMultiCheck = this.thead.find("[data-field=" + e.field + "]").data("kendoFilterMultiCheck")
filterMultiCheck.container.empty();
filterMultiCheck.checkSource.sort({ field: e.field, dir: "asc" });
filterMultiCheck.checkSource.data(filterMultiCheck.checkSource.view().toJSON());
filterMultiCheck.createCheckBoxes();
}
I have encountered the following issue - filterMultiCheck.checkSource.view() is always empty, causing the .toJSON() call to fail.
A grid defined totally in js (sadly NOT an option with this particular grid), within the same environment (Kendo Tab on Kendo Window) does not have this issue.
Has anyone any helpful clues?
This may or may not be an option for you, but setting ServerOperation to false in the DataSource solved this for me.
.Events(e => e.FilterMenuInit("filterMenuInit"))
.DataSource(d => d
.Ajax()
.ServerOperation(false)
.Read(...)
)

How to bind a Kendo MultiSelect helper via external event

I have a MVC Kendo MultiSelect helper that I want to set up but NOT retrieve the data for until an external event if fired. Im using it in a cascading capacity with a drop down list and don't what to show any values to select until the dropDownList has a selected value. Everything is working fine except this one annoyance.
#(Html.Kendo().MultiSelect()
.Name("productMultiSelect")
.DataTextField("Name")
.DataValueField("Id")
.Filter(FilterType.Contains)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetProducts", "OrderProductAdmin3");
});
})
I tried setting the AutoBind property to false but the MultiSelect helper still did and initial DataBind.
I think I can use code like this to data bind it when the external event is fired
var productMultiSelect = $("#productMultiSelect").data("kendoMultiSelect");
if (!DataBound) {
productMultiSelect.dataBind();
DataBound = true;
}
Thank you for your help.
Earl
I'm just going to show and hide it as appropriate.

Kendo UI for MVC Grid How do I hide the ID column

I would like to hide the ID column of a Kendo grid but still be able to reference it for other actions. I tried making the Width = 0 but that only makes it really wide.
#(Html.Kendo().Grid(Model)
.Name("LineItems")
.Columns(columns =>
{
columns.Bound(o => o.ID).Width(1);
columns.Bound(o => o.Ui).Width(20);
columns.Bound(o => o.QtyOrdered).Width(20);
columns.Bound(o => o.Nomenclature).Width(200);
columns.Bound(o => o.QtyShipped).Width(140);
columns.Bound(o => o.QtyReceived).Width(200);
columns.Bound(o => o.Hazmat).Width(50);
})
Edit on June 26
OK I was able to get a reasonable solution based on a post from the Kendo forum. As long as the ID is defined in the datasource, the column does not have to be defined in the grid. You still have access to the ID value. I wrote a quick snippet to prove it and it returns the ID without the ID column in the grid.
<script>
$(document).ready(function () {
$("#btn").on("click", function () {
var grid = $("#LineItems").data("kendoGrid");
var data = grid.dataSource.data();
$.each(data, function (i, item) {
alert(item.ID);
});
});
});
</script>
Hidden columns are supported since the Q2 2012 release. You can now use the Hidden() setting.
You can make the column hidden via the Hidden() method. Is this okey for you?
It looks like in the current version its not supported, they do have a page where you can vote to get this feature added to Kendo. They may have started working on it since the status does say 'started' about 13 hours ago.
http://kendo.uservoice.com/forums/127393-kendo-ui-feedback/suggestions/2804580-ability-to-show-hide-columns-in-grid
In the meantime it looks like some users might have some suggestions in this post by setting the style of that column to display:none
http://www.kendoui.com/forums/ui/grid/hide-columns-in-grid-kendo.aspx

Resources