Kendo Listbox selection generates duplicate entries in separate listbox - kendo-ui

When you click Role1 in the top listbox it will display Person 1 and Person 2 once. Every subsequent click on Role1 or Role2 generates an additional duplicate in the listbox below it. Why is that? I tried all possible permutations of the parts in KH_ClearKendoListbox to get the listbox cleared
before proceeding but that did not seem to help. The other reference to this issue on Stack Overflow suggested to use setDataSource but that did not help either. I am stuck and would love to know why this is happening in this scenario and how this might be solved so there is only one set of two items in the bottom listbox at all times.
<html>
<head runat="server">
<script type="text/javascript">
$(document).ready(function () {
var initDS;
var rolesDS = initDS = new kendo.data.DataSource({
data: [{ id1: 3, name1: "Role1" },
{ id1: 4, name1: "Role2" }]
});
$("#lstRoles").kendoListBox({
dataValueField: "id1",
dataTextField: "name1",
dataSource: rolesDS,
change: onChangeRoles,
}).data("kendoListBox");
function onChangeRoles(e) {
KH_ClearKendoListbox($("#lstIndividuals"));
initDS = new kendo.data.DataSource({
data: [{ id2: 3, name2: "Person 1" },
{ id2: 4, name2: "Person 2" }]
});
$("#lstIndividuals").kendoListBox({
dataValueField: "id2",
dataTextField: "name2",
}).data("kendoListBox").setDataSource(initDS);
}
function KH_ClearKendoListbox(lst) {
var listBox = lst.data("kendoListBox");
if (listBox === undefined) return;
var itemcount = listBox.dataSource._data.length;
for (var i = 0; i < itemcount; i++)
listBox.remove(listBox.items().first());
listBox.refresh();
listBox.clearSelection();
listBox.destroy();
}
});
</script>
</head>
<body>
<form id="form2" runat="server"
style="background-color: cornflowerblue">
<div class="container" style="padding:30px">
<select id="lstRoles" style="width: 265px"></select>
<br />
<select id="lstIndividuals" style="width:
265px; height: 233px">
</select>
</div>
</form>
</body>
</html>

Pulling the definition of the listbox out of the on change event and then just setting the data inside the onchange event did the trick. So this is answered :)
$(document).ready(function () {
var rolesDS = initDS = new kendo.data.DataSource({
data: [
{ id1: 3, name1: "Role1" },
{ id1: 4, name1: "Role2" }
]
});
$("#lstRoles").kendoListBox({
dataValueField: "id1",
dataTextField: "name1",
dataSource: rolesDS,
change: onChangeRoles,
}).data("kendoListBox");
var ds;
var listbox = $("#lstIndividuals").kendoListBox({
dataValueField: "id2",
dataTextField: "name2",
dataSource: ds
}).data("kendoListBox");
function onChangeRoles(e) {
var list = $("#lstRoles").data("kendoListBox");
var selectedRow = list.select();
var selectedData = e.sender.dataSource._data[selectedRow.index()];
if (selectedData.id1 == 3) {
ds = new kendo.data.DataSource({
data: [
{ id2: 1, name2: "Person 1" },
{ id2: 2, name2: "Person 2" }
]
});
}
if (selectedData.id1 == 4) {
ds = new kendo.data.DataSource({
data: [
{ id2: 3, name2: "Person 3" },
{ id2: 4, name2: "Person 4" }
]
});
}
listbox.setDataSource(ds);
}
});

Related

How to override editing row and call custom edit in jsgrid

Tried this How to customize edit event in JsGrid as below. But doesnt seem to work
$("#jsgrd").jsGrid({
data: ds,
fields: [{
type: "control",
editItem: editrow(item)
}, ]
});
function editrow(item) {
var $row = this.rowByItem(item);
if ($row.length) {
console.log('$row: ' + JSON.stringify($row)); // I modify this
this._editRow($row);
}
}
The error I get now is "item" not defined.
What I m looking for is, when user clicks edit, I want to get the rowid stored in a hidden col and use it to fetch more data from server and populate outside jsgrid. And avoid changing the row to edit mode
You are not using the documented way. You should use editTemplate.
A simple working example is:
$(document).ready(function() {
$("#grid").jsGrid({
width: "100%",
editing: true,
autoload: true,
data: [ { id:1, name:"Tom"}, {id:2, name:"Dick"}],
fields: [
{ name: "id", type: "text", title: "Id"},
{ name: "name", type: "text", title: "Name",
editTemplate: function(item) {
return "<input type='checkbox'>" + item;
}},
{ type: "control"}
]
});
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid-theme.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.js"></script>
<div id="grid">
Test
</div>
For the purpose of illustration, I turn the edit of the name field from the standard text box into a check box.
You could use itemTemplate to get the required result.
itemTemplate is a function to create cell content. It should return markup as string, DomNode or jQueryElement. The function signature is function(value, item), where value is a value of column property of data item, and item is a row data item.
Inside of itemTemplate you can customise your dom element based on your requirement.
Run Demo
$("#jsGrid").jsGrid({
width: "100%",
height: "auto",
paging: false,
//for loadData method Need to set auto load true
autoload: true,
noDataContent: "Directory is empty",
controller: {
loadData: function(filter) {
var data = [{
id: 1,
nickname: "Test",
email: "t#gmail.com"
}, {
id: 2,
nickname: "Test 1",
email: "t1#gmail.com"
}, {
id: 3,
nickname: "Test 2",
email: "t2#gmail.com"
}, {
id: 4,
nickname: "Test 3",
email: "t3#gmail.com"
}];
return data;
}
},
fields: [{
name: "nickname",
type: "text",
width: 80,
title: "Name"
}, {
name: "email",
type: "text",
width: 100,
title: "Email Address",
readOnly: false
}, {
type: "control",
itemTemplate: function(value, item) {
var editDeleteBtn = $('<input class="jsgrid-button jsgrid-edit-button" type="button" title="Edit"><input class="jsgrid-button jsgrid-delete-button" type="button" title="Delete">')
.on('click', function (e) {
console.clear();
if (e.target.title == 'Edit') {
//Based on button click you can make your customization
console.log(item); //You can access all data based on item clicked
e.stopPropagation();
} else {
//Based on button click you can make your customization
console.log('Delete')
}
});
return editDeleteBtn; //
},
}]
});
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid-theme.min.css" />
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.js"></script>
<div id="jsGrid"></div>

KendoDropDownList - cascading data from one drop down to another

I am making a game, and have a specific requirement where players pick a playable character race, and then I want a second drop down list to show the list of available genders for that race. I thought this would be easy to do using the Cascade property of the kendo.ui.DropDownListOptions... like this.
var racesOptions = {
index: -1,
valuePrimitive: true,
dataTextField: "Name",
dataValueField: "Name",
dataSource: {
transport: {
read: {
dataType: 'json',
url: '/api/races/list',
type: 'GET'
}
}
}
};
var genderOptions = {
index: -1,
valuePrimitive: true,
cascadeFrom: 'race',
cascadeFromField: 'Genders'
};
The shape of data coming in from /api/races/list looks like this;
[{
"Name": "race1",
// ... other data ... //
"Genders": [ "Male", "Female", "Other" ]
}, {
"Name": "race2",
// ... other data ... //
"Genders" : ["Female"]
}, {
"Name": "race3",
// ... other data ... //
"Genders": ["Male"]
}]
I thought this was going to be a no-brainer. The second drop down cascades from the first; When the first has a value, I figured the second would get the CascadeFromFieldvalue. But that's not happening... In fact, the only way I've been able to accomplish this is with the following code in the #race widget's change event.
change: function (e) {
// the specific race entity selected
var entity = e.sender.dataItem().toJSON();
// set the selected race's genders
var genders = $('#genders').data('kendoDropDownList');
genders.destroy();
genders = $('#genders').kendoDropDownList({
index: -1,
valuePrimitive: true,
dataSource: {
data: entity.Genders
}
}).data('kendoDropDownList');
genders.select(-1);
genders.trigger('change');
}
That change event does work, but it's messy and kind of obtuse. Is there another way I can get the Cascading to work as I'm expecting?
The value for cascadeFromField: needs to point to the parent ID field. In your case the ID field in the Races datasource.
Here's a small example that should help.
<h4>Race:</h4>
<input id="race" />
<h4>Gender:</h4>
<input id="gender" />
<script>
$("#race").kendoDropDownList({
optionLabel: "Select race...",
dataTextField: "raceName",
dataValueField: "raceID",
dataSource: [
{ raceName: "Race1", raceID: 1 },
{ raceName: "Race2", raceID: 2 },
{ raceName: "Race3", raceID: 3 }
]
});
$("#gender").kendoDropDownList({
optionLabel: "Select gender...",
cascadeFrom: "race",
cascadeFromField: "raceID",
dataTextField: "genderName",
dataValueField: "genderID",
dataSource: [
{ genderName: "Male", genderID: 1, raceID: 1 },
{ genderName: "Female", genderID: 2, raceID: 1 },
{ genderName: "Other", genderID: 3, raceID: 1 },
{ genderName: "Female", genderID: 4, raceID: 2 },
{ genderName: "Male", genderID: 4, raceID: 3 }
]
});
</script>
You can check out this demo using the above code.

KendoUI: Get The ID on Button Click in PHP

i have used kendoui grid like;
<script>
$(function(){
$("#grid").kendoGrid({
dataSource:{
transport: {
read: "<?php echo base_url() ?>index.php/user_management/manage_users/list_view/"
},
schema:{
data: "data"
}
},
columns: [
{
field: "UserID",
hidden:true
},
{
field: "Username",
title:"Username"
},
{ field: "FirstName",
title:"First Name"
},
{field:"MiddleNames"},
{field:"LastName"},
{field:"City"},
{field:"Email"},
{field:"Actions"},
{command: { text: "View", click: showDetails }, title: " ", width: "140px"}
]
});
});
function showDetails(e) {
e.preventDefault();
//i want to get the id of the clicked row and pass that id to the next(redirected) page;
}
</script>
How do I get the current clicked row id i.e UserId column value and pass that id(redirect) to the next page?
From the event that you receive, you get the row that it belongs to:
var row = $(e.target).closest("tr");
And then you get the item using dataItem:
var item = $("#grid").data("kendoGrid").dataItem(row);
So it would be:
function showDetails(e) {
var row = $(e.target).closest("tr");
var item = $("#grid").data("kendoGrid").dataItem(row);
alert("UserId is:" + item.UserId);
}

KendoGrid doesn't work in kendoTabStrip

I'm using kendoTabStrip as is shown on KendoUI Page. In my case in each div I have rendered partial view. In a few of my partial views I have additionaly kendoGrid.
Problem
When I reload page in any tab and go to tab which contain kendoGrid then it do not work correctly. For example: I'm on tab#0 and go for tab#3 which contain kendoGrid with pagination, then pagination is not display. But when I reload it then pagination works fine.
What can I do to my Grids works inside TabStrip?
Any help would be appreciated.
UPDATE
My implementation of tabstrip
$("#tabStrip").kendoTabStrip({
animation: { open: { effects: false} },
select: function (e) {
document.location.hash = 'tab-' + $(e.item).index();
}
});
var tabStrip = $('#tabStrip').data('kendoTabStrip');
var tabId = 0;
var scheduledId = 0;
if (document.location.hash.match(/tab-/) == 'tab-') {
tabId = document.location.hash.substr(5);
}
if (document.location.hash.match(/scheduled-/) == 'scheduled-') {
tabId = 1;
scheduledId = document.location.hash.substr(11);
editSchedule('/admin/Course/Scheduled/' + scheduledId + '/Edit/' );
}
tabStrip.select(tabStrip.tabGroup.children('li').eq(tabId));
So I need it to make some rewrites from controller.
To fix this problem we must change :
$("#tabStrip").kendoTabStrip({
animation: { open: { effects: false} },
select: function (e) {
document.location.hash = 'tab-' + $(e.item).index();
}
});
for:
$("#tabStrip").kendoTabStrip({
animation: { open: { effects: false} },
select: function (e) {
document.location.hash = 'tab-' + $(e.item).index();
},
activate: function(e) {
$(e.contentElement).find('.k-state-active [data-role="grid"]').each(function() {
$(this).data("kendoGrid").refresh();
});
}
});
Event activate is 'Triggered just after a tab is being made visible, but before the end of the animation'. So we must refresh our grids then becouse js counts widths of hidden elements wrong.
I put together an example of Grids working inside of a TabStrip: http://jsfiddle.net/dpeaep/SJ85S/. Maybe, I am missing part of what you are asking in your question. If so, you can modify the jsfiddle to clarify what the problem is.
HTML
<div id="tabstrip">
<ul>
<li>Grid 1</li>
<li>Grid 2</li>
<li>Grid 3</li>
</ul>
<div><div id="grid1"></div></div>
<div><div id="grid2"></div></div>
<div><div id="grid3"></div></div>
</div>
Javascript
var tabstrip = $("#tabstrip").kendoTabStrip().data("kendoTabStrip");
tabstrip.select(0);
$("#grid1").kendoGrid({
columns: [
{ field: "FirstName", title: "First Name" },
{ field: "LastName", title: "Last Name" }
],
dataSource: {
data: [
{ FirstName: "Joe", LastName: "Smith" },
{ FirstName: "Jane", LastName: "Smith" }
]
}
});
$("#grid2").kendoGrid({
columns: [
{ field: "FirstName", title: "First Name" },
{ field: "LastName", title: "Last Name" }
],
dataSource: {
data: [
{ FirstName: "Betty", LastName: "Lakna" },
{ FirstName: "Fumitaka", LastName: "Yamamoto" },
{ FirstName: "Fred", LastName: "Stevenson" }
]
}
});
$("#grid3").kendoGrid({
columns: [
{ field: "Title", title: "Title" },
{ field: "Year", title: "Year" }
],
dataSource: {
data: [
{ Title: "Lost in Domtar", Year: "2012" },
{ Title: "Evergreen", Year: "2012" },
{ Title: "Fields of Yellow", Year: "2010" },
{ Title: "Where the Whistle Blows", Year: "2008" }
]
}
});

jqGrid and Google Chart API

Is it possible to add graphs using the Google Chart API or any other graph to one column of jqGrid? If it is possible, how? I need to filter each row of jqGrid and show a graph of that particular row in the last column of jqGrid.
You could use a custom formatter:
<script type="text/javascript">
$(function () {
$('#myGrid').jqGrid({
url: '#Url.Action("Data")',
datatype: 'json',
colNames: [ 'Foo', 'Bar', 'Chart' ],
colModel: [
{ name: 'foo', index: 'foo' },
{ name: 'bar', index: 'bar' },
{ name: 'chart', index: 'chart', formatter: chartFormatter },
]
});
});
function chartFormatter(el, cval, opts) {
return '<img src="' + el + '" alt="chart" title="" />';
}
</script>
<div style="height: 500px;">
<table id="myGrid"></table>
</div>
and your controller would return the corresponding Google Chart URLs:
public ActionResult Data()
{
return Json(new
{
rows = new[]
{
new { id = 1, cell = new[] { "foo 1", "bar 1", "https://chart.googleapis.com/chart?cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World" } },
new { id = 2, cell = new[] { "foo 2", "bar 2", "https://chart.googleapis.com/chart?cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World" } },
}
}, JsonRequestBehavior.AllowGet);
}
which gives:

Resources