data-bind not working in List View template within Grid detail template - kendo-ui

I need help using a Kendo UI list view which lives within a grid row detail template.
here is something I have done so far.
<div id="grid">
</div>
<script type="text/x-kendo-template" id="gridDetailTemplate">
<div class='grid-edit'>
<div class='edit-list'></div>
</div>
</script>
<script type="text/x-kendo-template" id="editItemtemplate">
<div class='edit-Item'>
#if(Type=='string'){#
<ul><li><b>#:Name#</b></li><li><input class='inputString' value='#:DataVal()#'/></li></ul>
#}else if(Type=='number'){#
<ul><li><b>#:Name#</b></li><li><input class='inputNumber' data-role='numerictextbox' data-type='number' value='#:DataVal()#'/></li></ul>
#}else if(Type=='date'){#
<ul><li><b>#:Name#</b></li><li><input class='inputDate' data-role='datepicker' value='#:kendo.toString(DataVal(),'MM/dd/yyyy')#'/></li></ul>
#}else if(Type=='boolean'){Name #<input type='checkbox'/>
#}#
</div>
</script>
<script type="text/javascript">
$(document).ready(function () {
$.get("http://localhost:4916/DataAttribute", function (data, status) {
var selFields = new Object();
$.each(data, function (index, elem) {
selFields[elem.Name] = new Object();
selFields[elem.Name]["type"] = elem.Type;
});
$("#grid").kendoGrid({
dataSource: {
type: "json",
transport: {
read: { url: "http://localhost:4916/Deal",
dataType: "json"
}
},
schema: {
data: "Data", total: "Total",
model: {
fields: selFields
}
}
},
height: 430,
filterable: true,
sortable: true,
pageable: false,
detailTemplate: kendo.template($("#gridDetailTemplate").html()),
detailInit: detailInit,
columns: [{
field: "SecurityName",
title: "Security Name",
width: 250
},
{
field: "DateOfAcquisition",
title: "Date Of Acquisition",
width: 120,
format: "{0:MM/dd/yyyy}"
}, {
field: "Acres",
title: "Acres",
width: 120
}
]
});
});
});
function detailInit(e) {
$.get("http://localhost:4916/DataAttribute", function (data, status) {
var detailRow = e.detailRow;
detailRow.find(".edit-list").kendoListView({
dataSource: {
data: data,
schema: {
model: {
DataVal: function () {
switch (this.get("Type")) {
case "number"
}
if (e.data[this.get("Name")])
return e.data[this.get("Name")];
else
return '';
}
}
}
},
template: kendo.template($("#editItemtemplate").html())
});
});
}
</script>
My code gets dynamic field list and binds it to the data source for grid.
Then, in the detailInit event, I find the div within row detail and convert it into kendo UI list, for which the template have been created.
Now, when I use data-bind="value: DataVal()" ,it doesn't pick up the values of List data source. It works the way I have done i.e. value="#: DataVal() #". But, data-role does not convert the fields to specified types which are datepicker and numericinput in my case.
I believe that data-role not being used is caused due to same issue as data-bind not being read.
Can anyone help me out with this? Also, feel free to suggest any alternate ways and general code improvements. I am an ASP.NET developer and usually don't work on pure html and javascript.
PS: I would be happy to provide the context on what I am trying to achieve here if anyone is interested.
Thanks in advance.

If you can rig up a jsFiddle or jsBin example that would help debug the issue.
However, try removing the parenthesis:
data-bind="value: DataVal"
Kendo should detect that DataVal is a function and call it on its own.

I experienced a similar situation in a listview template. I created a JSFiddle to demonstrate:
http://jsfiddle.net/zacharydl/7L3SL/
Oddly, the solution is to wrap the contents of the template in a div. It looks like your template already has this, so YMMV.
<div id="example">
<div data-role="listview" data-template="template" data-bind="source: array"></div>
</div>
<script type="text/x-kendo-template" id="template">
<!--<div>-->
<div>method 1: #:field#</div>
<div>method 2: <span data-bind="text: field"></span></div>
<input data-role="datepicker" />
<!--</div>-->
</script>
var model = kendo.observable({
array: [
{ field: 'A'},
{ field: 'B'}
]
});
kendo.bind($('#example'), model);

Related

Simple Kendo DropDownList binding in window

I have a form with a DropDownList inside a Kendo window and I want to bind existing data to it. Examples for this abound and I've done it in other situations before, but this one (which seems like it should be really easy) is escaping me because I can't seem for the life of me to get the DropDownList to show the correct value. I figure I must be missing something really simple, but I haven't done Kendo in over a year, and looking at my previous work isn't helping me either.
Extremely simplified code:
<button onclick="OnButtonClick();">Click Me</button>
<div id="form-window"></div>
<script type="text/x-kendo-template" id="form-template">
<div class="form-group">
<label for="Url">URL</label>
<input name="Url" type="text" value="#= Url #" required="required" />
</div>
<div class="form-group">
<label for="HttpVerb">HTTP verb</label>
<input name="HttpVerb" data-bind="value:HttpVerb" data-source="httpVerbsDataSource" data-value-field="verb" data-text-field="verb" data-role="dropdownlist" />
</div>
</script>
<script type="text/javascript">
var formWindow = $("#form-window")
.kendoWindow({
title: "Form",
modal: true,
visible: false,
resizable: false,
scrollable: false,
width: 500,
actions: ["Close"],
open: function () {
kendo.init($("#form-window"));
}
}).data("kendoWindow");
var formTemplate = kendo.template($("#form-template").html());
var httpVerbsDataSource = new kendo.data.DataSource({
data: [
{ verb: "GET" },
{ verb: "POST" },
{ verb: "PUT" }
]
});
function OnButtonClick(e) {
var dataItem = {
Url: "abcdef",
HttpVerb: "POST"
};
var windowContent = formTemplate(dataItem);
formWindow.content(windowContent);
formWindow.center().open();
}
</script>
When I click the button, the window opens and the form text field is populated correctly, and the DropDownList has properly been bound to the data source, but the value in my data item is not selected.
JS Bin: https://jsbin.com/wariyorilo/edit?html,js,output
What am I missing? Thanks in advance.

How to programatically expand a node of Kendo treeview

I have a Kendo treeview that is built as below codes (see below). Each tree node has a unique data id field (that is employee Id).
I would like to have a text box ( <input type="text" ... /> ) and a button ( <input type="button" ... /> ) so user can input some id and when she hit the button, the button click event handler will let the treeview expand the node whose id matches the input id. How can I do that? Thank you very much.
Details of click event handler or the button:
function buttonExpand_onClick()
{
var id = $("textboxEmployeeId").val();
// ???
// how can I do the following code lines to expand the node with id of "id" to see all its children?
}
Details of the existing Kendo treeview building codes:
<div id="treeviewEmployee">
</div>
<script id="treeview-template" type="text/kendo-ui-template">
#: item.text #
</script>
$(function(
{
var defaultRootSelectedId = 1; // 1 is employee id of the root employee on first loading
$.ajax({
url: '/Employee/AjaxGetEmployeeNodes/?id=' + defaultRootSelectedId,
type: 'GET',
dataType: 'json',
async: false,
success: function (data, textStatus, xhr) {
$("#reeviewEmployee").kendoTreeView({
template: kendo.template($("#treeview-template").html()),
dataSource: data,
select: treeview_onSelect
});
_treeview = $("#treeviewEmployee").data("kendoTreeView");
},
error:
function (xhr, textStatus, errorThrown) {
alert(textStatus);
}
});
});
You can access the datasource on the treeview and find the node by id. I would also like to add that the treeView has a 'findByText()' method as well, in case that is what you want.
HTML
<script id="treeTemplate" type="text/x-kendo-template">
#: item.text #
</script>
<div id="content">
<div id="form">
<label>Node ID:
<input id="nodeId" type="text"/>
</label>
<button id="expandNodeBtn">Expand Node</button>
</div>
<h2>TreeView</h2>
<div id="treeView"/>
</div>
JAVASCRIPT
(function ($) {
$(document).ready(function () {
$("#treeView").kendoTreeView({
dataSource: [
{
text: 'one with id 1',
id: 1,
items: [
{
text: 'one-child-1',
id: 2
},
{
text: 'one-child-2',
id: 3
}
]
},
{
text: 'two with id 4',
id: 4,
items: [
{
text: 'two-child-1',
id: 5
},
{
text: 'two-child-2',
id: 6
}
]
}
]
});
$("#expandNodeBtn").on("click", function(e) {
var val = $("#nodeId").val();
console.log('val: ' + val);
var treeView = $("#treeView").data('kendoTreeView');
var dataSource = treeView.dataSource;
var dataItem = dataSource.get(val); // find item with id = 5
var node = treeView.findByUid(dataItem.uid);
treeView.expand(node);
});
});
})(jQuery);
JSFiddle
I also put together a JSFiddle sample for you to play with: http://jsfiddle.net/jsonsee/D35Q6/
Slightly related, but I came here looking for an answer to this question: How to expand the whole branch when clicking to a parent node in angular treeview? Since I didnt find any answers, I post my solution here. Hope it helps someone.
html
<div id="treeview" kendo-tree-view="tree" k-options="options" k-on-change="selectItem(dataItem)">
</div>
controller
$scope.options = {
dataSource: dummyData,
template: $scope.treeItemTemplate
}
$scope.treeItemTemplate = "<button ng-click='expandRoot(dataItem)'>Blow up</button>";
$scope.expandRoot = function expandRoot(dataItem) {
dataItem.expanded = true;
if (dataItem.hasChildren) {
dataItem.load()
var children = dataItem.children.data();
children.forEach(function (c) {
c.expanded = true;
$scope.expandRoot(c)
});
}
}

Implementing DoJo enhanced Grid with Json

I have been trying to implement DoJo Enhanced Grid with Json and I have not been successful thus far.
This is what I have done so far;
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:util="urn:jsptagdir:/WEB-INF/tags/util" xmlns:spring="http://www.springframework.org/tags" version="2.0">
<jsp:output omit-xml-declaration="yes"/>
<spring:url value="/students/listdata" var="mydatasource"/>
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("dojox.grid.EnhancedGrid");
dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
dojo.require("dijit.form.Button");
dojo.require("dojo.data.ItemFileReadStore");
dojo.addOnLoad(function() {
dojo.parser.parse();
loadGrid(dataGrid);
});
function loadGrid(dataGrid) {
dojo.xhrGet({
url: "${mydatasource}",
load: function(data, ioArgs) {
dataGrid.setStore(
new dojo.data.ItemFileReadStore(
{data: {items : data}})
);
},
error: function(error) {
console.log("loading of grid data failed. Exception...", error);
}
});
}
</script>
<util:panel id="titlePane" title="Course List">
<div id="addButton" dojoType="dijit.form.Button">
Add
</div>
<div id="deleteButton" dojoType="dijit.form.Button">
Delete
</div>
<div id="grid" jsId="dataGrid" dojoType="dojox.grid.EnhancedGrid"
structure ="[
{ field: 'id', name: 'ID', width: '55px' },
{ field: 'firstName', name: 'First Name', width: '230px' },
{ field: 'lastName', name: 'Last Name', width: '50px' },
{ field: 'gender', name: 'Gender', width: '145px'}
]"
autoWidth="true"
autoHeight="true"
plugins="{indirectSelection: true}"
selectionMode="single">
</div>
</util:panel>
As you can see, I am getting the Json String via the AJAX call by DOJO. The grid is generating however, it is not being populated with data. Only two check boxes comes up in the grid...
Is there anything that I'm doing wrongly?
I have never used the EnhancedGrid, but for a regular grid I did this by creating the store declaratively, attaching its ID to the grid (via store=... attribute in the HTML), and then when I wanted to refresh the grid with new store info, called:
grid.setStore(...,null,null);
found out the problem to the grid not loading data.
Actually I needed to handle the data as a Json String.
below is copy of the code that works:
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("dojox.grid.EnhancedGrid");
dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
dojo.require("dijit.form.Button");
dojo.require("dojo.data.ItemFileReadStore");
dojo.addOnLoad(function() {
dojo.parser.parse();
loadGrid(dataGrid);
});
function loadGrid(dataGrid) {
dojo.xhrGet({
url: "${mydatasource}",
handleAs: "json",
load: function(data, ioArgs) {
dataGrid.setStore(
new dojo.data.ItemFileReadStore(
{data: {items : data}})
);
},
error: function(error) {
console.log("loading of grid data failed. Exception...", error);
}
});
}
</script>

Loading a partial view in jquery.dialog

I am a completely new to mvc and trying to create a dummy application to learn mvc 3.
I have worked my way through the music store example and now I am trying to extend it slightly into a more real world application.
With the example whenever you want to any new item you are redirected to the Create view which is fine however I want instead of doing a full page post back I want to use the jquery.dialog to open a modal popup which will allow the user to insert a new item.
so far I have
<script type="text/javascript">
$(function () {
$('#dialog').dialog({
autoOpen: false,
width: 400,
resizable: false,
title: "hi there",
modal: true,
buttons: {
"Close": function () {
$(this).dialog("close");
}
}
});
$('#my-button').click(function () {
$('#dialog').dialog('open');
});}); </script>
<div id="dialog" title="Create Album" style="overflow: hidden;">
#Html.Partial("_CreateAlbumPartial")</div>
Problems with this is the partial view is loaded everytime not through ajax and I dont really know where I should be placing the partial view. Shoukld it be in the shared location or in the folder with the other views?
How do I update the controller class to cater for the partial view?
Sorry if these are easy to do, im 3 days into mvc :)
Try something like this:
<script type="text/javascript">
$(function () {
$('#dialog').dialog({
autoOpen: false,
width: 400,
resizable: false,
title: 'hi there',
modal: true,
open: function(event, ui) {
//Load the CreateAlbumPartial action which will return
// the partial view _CreateAlbumPartial
$(this).load("#Url.Action("CreateAlbumPartial")");
},
buttons: {
"Close": function () {
$(this).dialog("close");
}
}
});
$('#my-button').click(function () {
$('#dialog').dialog('open');
});
});
</script>
<div id="dialog" title="Create Album" style="overflow: hidden;">
We used the open function which is triggered when the dialog is opened and inside we send an AJAX request to a controller action which would return the partial:
public ActionResult CreateAlbumPartial()
{
return View("_CreateAlbumPartial");
}
To improve Darin answer, we can move the div loading code in the button click event.
In this way all position's alghorithms of the dialog works on the new text, and so the dialog is placed correctly.
<script type="text/javascript">
$(function () {
$('#dialog').dialog({
autoOpen: false,
width: 400,
resizable: false,
title: 'hi there',
modal: true,
buttons: {
"Close": function () {
$(this).dialog("close");
}
}
});
$('#my-button').click(function () {
//Load the CreateAlbumPartial action which will return
// the partial view _CreateAlbumPartial
$('#dialog').load("#Url.Action("CreateAlbumPartial")",
function (response, status, xhr) {
$('#dialog').dialog('open');
});
});
});
</script>
<div id="dialog" title="Create Album" style="overflow: hidden;">

Using dijit.filteringselect in a Spring MVC environment

I am trying to code two filteringselects which should both change according to data entered into any of the forms.
So data entered into fs1 should trigger changes in fs2.
Data entered into fs2 should trigger changes in fs1.
I am in a spring environment which in my case means that the dojo code is in a jsp file and the filtering select fields are populated through a Controller class on the server side using #ModelAttribute annotations to make the data available as a variable in the jsp file.
I have the relation data on the Java side so it's available through the controller.
Here is what confuses me at the moment.
I am new to DOJO and the documentation on the DOJO support site is a little hard to grasp for me. I would like to see a conceptual list of what is needed to accopmplish and connect the separate stores of my filteringselects.
When there is a change in one of the filteringselects, how do I inform the controllerclass of the changes and send the data that remains in the filteringselect?
This question could also be read as: how can I call a method with input parameters that hold the data available in the edited filteringselect?
I suggest we work on this in two incremental parts:
Get the first FilteringSelect's onChange event working
Wire them up to use server data stores
The following code sample takes a Dojo Campus' codependent FilteringSelect example and simplifies it so that its data stores are local. It shows how to programmatically instantiate two FilteringSelects with the second being dependent on the first by an onChange event handler.
Can you please try running it and let me know if you get it working?
Once we get your first FilteringSelect triggering filtering on the second, I will edit to add an explanation on how to convert them to use server side data stores.
<html>
<head>
<title>Test File</title>
<link type="text/css" rel="stylesheet" href="dijit/themes/tundra/tundra.css"/>
</head>
<body class="tundra">
<label for="state">State:</label>
<input id="state">
<label for="city">City:</label>
<input id="city">
<script type="text/javascript" src="dojo/dojo.js"
djConfig="isDebug: true, parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dijit.form.FilteringSelect");
dojo.require("dojo.data.ItemFileReadStore");
dojo.addOnLoad(function() {
var cityJson = {
label: 'name',
items: [{ name: 'Albany', state: 'NY' },
{ name: 'New York City', state: 'NY' },
{ name: 'Buffalo', state: 'NY' },
{ name: 'Austin', state: 'TX' },
{ name: 'Houston', state: 'TX' }]
};
var stateJson = {
identifier: 'abbreviation',
label: 'name',
items: [ { name: 'New York', abbreviation: 'NY' },
{ name: 'Texas', abbreviation: 'TX' } ]
};
new dijit.form.ComboBox({
store: new dojo.data.ItemFileReadStore({
data: cityJson
}),
autoComplete: true,
query: {
state: "*"
},
style: "width: 150px;",
required: true,
id: "city",
onChange: function(city) {
dijit.byId('state').attr('value', (dijit.byId('city').item || {
state: ''
}).state);
}
},
"city");
new dijit.form.FilteringSelect({
store: new dojo.data.ItemFileReadStore({
data: stateJson
}),
autoComplete: true,
style: "width: 150px;",
id: "state",
onChange: function(state) {
dijit.byId('city').query.state = state || "*";
}
},
"state");
});
</script>
</body>
</html>
in the namespace of the jsp:
xmlns:springform="http://www.springframework.org/tags/form"
sample form:
<springform:form action="#" >
<label for="country">Country:</label>
<springform:select id="country" path="country" items="${countryList}" itemLabel="country" itemValue="id"/>
<div id="citySelectDiv"></div>
</springform:form>
javascript code:
<script type="text/javascript">
<![CDATA[
dojo.require("dojo.parser");
dojo.require("dojo.data.ItemFileReadStore");
function countryChanged(dataFromServer){
//convert json to dojo filteringSelect options
var options = {
identifier: 'id',
label: 'city',
items: dataFromServer
};
var cityStore =new dojo.data.ItemFileReadStore({data : options});
// create Select widget, populating its options from the store
if (!dijit.byId("citySelectDiv")) {
//create city selction combo
new dijit.form.FilteringSelect({
name: "citySelectDiv",
store: cityStore,
searchAttr : "city",
}, "citySelectDiv");
}else{
//if already created the combo before
dijit.byId('citySelectDiv').set('value',null);
dijit.byId('citySelectDiv').store = cityStore;
}
}
Spring.addDecoration(new Spring.ElementDecoration({
elementId : "country",
widgetType : "dijit.form.FilteringSelect",
widgetAttrs : {
promptMessage: "Select a Country",
required : true,
onChange : function(){
var xhrArgs = {
url: "ajax/country/" +dijit.byId('country').get('value'),
handleAs: 'json',
load: function(dataFromServer) {
countryChanged(dataFromServer);
}
};
//make the ajax call
dojo.xhrGet(xhrArgs);
}
}
}));
Sample Controller method:
#ResponseBody
#RequestMapping("/ajax/country/{country}")
public List<City> clientSelection(#PathVariable("country") String country ) {
log.info("Country = {} ",country);
return cityService.findCitiesByCountry(country);
}

Resources