I've got a Kendo Grid and on its DataBound event, I want to add its data source to a Kendo MultiSelect. So, when the data from the grid is loaded, the below function is fired.
Here's what I have tried so far, without success, but from the code you can see what I intend:
function addToMultiSelect() {
var multiSelect = $("#multiSelect").data("kendoMultiSelect");
var grid = $("#grid").data("kendoGrid");
var places = grid.dataSource._data;
for (var i = 0; i < places.length; i++) {
var row = instPlaces[i];
var id = row.Id;
var mediumDescription = row.MediumDescription;
alert(id + " - " + mediumDescription);
multiSelect.dataSource.insert(i, { text: mediumDescription, value: id })
}
multiSelect.dataSource.read();
}
The alert properly shows the id and description of all the datagrid's items, so, I'm getting the data from the grid right.
I add them to the multiSelect's datasource, the last line is to refresh it and show the new data, but it doesn't. The multiSelect remains empty.
Try the following:
function addToMultiSelect() {
var multiSelect = $("#multiSelect").data("kendoMultiSelect");
var grid = $("#grid").data("kendoGrid");
var places = grid.dataSource.data();
// Read original data content
var multiData = multiSelect.dataSource.data();
for (var i = 0; i < places.length; i++) {
...
// insert new element into copy of multiselect data
multiData.push({ text: mediumDescription, value: id })
}
// Write back the modified data
multiSelect.dataSource.data(multiData);
}
See the following code example:
$(document).ready(function() {
function addToMultiSelect(e) {
var grid = this;
var data = this.dataSource.data();
var multiData = [];
for (var i = 0; i < data.length; i++) {
multiData.push({ text: data[i].ShipName, value: i });
}
multi.dataSource.data(multiData);
}
var multi = $("#multi").kendoMultiSelect({
dataSource: {
data: [
{ text: "ship 1", value: 1 },
{ text: "ship 2", value: 2 },
{ text: "ship 3", value: 3 },
{ text: "ship 4", value: 4 }
]
},
dataTextField: "text",
dataValueField: "value"
}).data("kendoMultiSelect");
$("#grid").kendoGrid({
dataSource: {
type: "odata",
transport: {
read: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
},
schema: {
model: {
fields: {
OrderID: { type: "number" },
Freight: { type: "number" },
ShipName: { type: "string" },
OrderDate: { type: "date" },
ShipCity: { type: "string" }
}
}
},
pageSize: 20,
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
dataBound: addToMultiSelect,
height: 550,
columns: [
"OrderID",
"Freight",
{
field: "OrderDate",
title: "Order Date",
format: "{0:MM/dd/yyyy}"
},
{
field: "ShipName",
title: "Ship Name"
},
{
field: "ShipCity",
title: "Ship City"
}
]
});
});
html { font-size: 12px; font-family: Arial, Helvetica, sans-serif; }
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1316/styles/kendo.common.min.css" />
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1316/styles/kendo.default.min.css" />
<script src="http://cdn.kendostatic.com/2014.3.1316/js/jquery.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.3.1316/js/kendo.all.min.js"></script>
Ship Names copied from Grid DataSource: <input id="multi"/>
Grid
<div id="grid"></div>
Related
I have defined my datatables editor as follows :
editor = new $.fn.dataTable.Editor({
ajax: "./DataServlet",
table: "#example",
legacyAjax: true,
idSrc: "rowID",
fields: [{
label: "Data Id",
name: "dataId",
type: "readonly"
},{
label: "Name",
name: "name",
type: "readonly"
},{
label: "Field L1",
name: "fieldL1",
type: "selectize",
options: getFieldL1()
},{
label: "Field L2",
name: "fieldL2",
type: "selectize",
options: getFieldL2()
},{
label: "Field L3",
name: "fieldL3",
type: "selectize",
options: getFieldL3()
},{
label: "User Name",
name: "userName",
type: "readonly"
}],
});
The fieldL3 value is dependent on fieldL2 which is dependent on fieldL1.
The dependency is as shown in the table below :
So, initially the fieldL1 dropdown values would be [A,B,C] and if value I select is 'A', then fieldL2 dropdown values should only be [Q,W,R] and if I select 'Q' for fieldL2, the fieldL3 dropdown should only have [T,U].
So, far I have tried the following :
$("#DTE_Field_fieldL1").on('change', function(data) {
let c1_value = data.currentTarget.value;
let c2_opts = $(".DTE_Field_Name_fieldL2 .selectize-dropdown-content")[0].children;
let valid_c2_opts = Object.keys(json[c1_value]);
for(let i = 0; i < c2_opts.length; i++) {
if(valid_c2_opts.includes(c2_opts[i].dataset.value))
{
c2_opts[i].className = "option";
}
else {
c2_opts[i].className = "option d-none";
}
}
editor.enable('fieldL2');
});
$("#DTE_Field_fieldL2").on('change', function(data) {
let c1_value = $("#DTE_Field_fieldL1")[0].value;
let c2_value = data.currentTarget.value;
let c3_opts = $(".DTE_Field_Name_fieldL3 .selectize-dropdown-content")[0].children;
let valid_c3_opts = Object.values(json[c1_value][c2_value]);
for(let i = 0; i < c3_opts.length; i++) {
if(valid_c3_opts.includes(c3_opts[i].dataset.value ))
{
c3_opts[i].className = "option";
}
else {
c3_opts[i].className = "option d-none";
}
}
editor.enable('fieldL3');
});
So, the json has the data separated in JSON format and I am trying to hide/show the values based on what is selected.
The issue I am facing with the above approach is whenever I try to change a value, the onChange function doesn't get called.
How do I achieve it in the datatables editor?
I want to use the ShieldUI library (grid component) in order to present tabular data to the user.
The issue with this library is that if I create a new item and right after I want to edit or delete it, the grid is unable to provide its id (as the database generates for me), although I return the id from backend after the INSERT query is executed. Here is what I tried:
<!-- HTML and JS part -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jQuery Shield UI Demos</title>
<link id="themecss" rel="stylesheet" type="text/css" href="//www.shieldui.com/shared/components/latest/css/light/all.min.css" />
<script type="text/javascript" src="//www.shieldui.com/shared/components/latest/js/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="//www.shieldui.com/shared/components/latest/js/shieldui-all.min.js"></script>
</head>
<body class="theme-light">
<div id="grid"></div>
<script type="text/javascript">
$(document).ready(function () {
$("#grid").shieldGrid({
dataSource: {
remote: {
read: "/products",
modify: {
create: {
url: "/products/productCreate",
type: "post",
data: function (edited) {
var date = edited[0].data.AddedOn ? edited[0].data.AddedOn.toJSON() : new Date().toJSON();
return {
Active: edited[0].data.Active,
AddedOn: date,
Category: edited[0].data.Category,
Name: edited[0].data.Name,
Price: edited[0].data.Price,
Id: edited[0].data.Id
};
}
},
update: {
url: "/products/productUpdate",
type: "post",
data: function (edited) {
var date = edited[0].data.AddedOn ? edited[0].data.AddedOn.toJSON() : new Date().toJSON();
return {
Active: edited[0].data.Active,
AddedOn: date,
Category: edited[0].data.Category,
Name: edited[0].data.Name,
Price: edited[0].data.Price,
Id: edited[0].data.Id
};
}
},
remove: {
url: "/products/productRemove",
type: "post",
data: function (removed) {
return { id: removed[0].data.Id };
}
}
}
},
schema: {
fields: {
Id: { path: "Id", type: Number },
Price: { path: "Price", type: Number },
Name: { path: "Name", type: String },
Category: { path: "Category", type: String },
AddedOn: { path: "AddedOn", type: Date },
Active: { path: "Active", type: Boolean }
}
}
},
rowHover: false,
columns: [
{ field: "Name", title: "Product Name", width: "300px" },
{ field: "Price", title: "Price", width: "100px" },
{ field: "Category", title: "Category", width: "200px" },
{ field: "AddedOn", title: "Added On", format: "{0:MM/dd/yyyy}" },
{ field: "Active", title: "Active" },
{
title: " ",
width: "100px",
buttons: [
{ cls: "deleteButton", commandName: "delete", caption: "<img src='/Content/img/grid/delete.png' /><span>Delete</span>" }
]
}
],
editing: {
enabled: true,
event: "click",
type: "cell",
confirmation: {
"delete": {
enabled: true,
template: function (item) {
return "Delete row with ID = " + item.Id
}
}
}
},
toolbar: [
{
buttons: [
{ commandName: "insert", caption: "Add Product" }
],
position: "top"
}
]
});
});
</script>
<style>
.deleteButton img
{
margin-right: 3px;
vertical-align: bottom;
}
</style>
</body>
</html>
Below is the ASP.MVC part:
[ActionName("productCreate")]
public Product PostProduct(Product item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
item.Id = Products.Max(i => i.Id) + 1;
Products.Add(item);
return item;
}
To make this work, I need to refresh the grid's content by performing a sort operation (the framework updates the grid before sorting) or worse, a page refresh.
So what is the issue with this approach? Am I missing something?
We need to modify the create object and use AJAX call in order to make this work.
So instead of:
create: {
url: "/products/productCreate",
type: "post",
data: function (edited) {
var date = edited[0].data.AddedOn ? edited[0].data.AddedOn.toJSON() : new Date().toJSON();
return {
Active: edited[0].data.Active,
AddedOn: date,
Category: edited[0].data.Category,
Name: edited[0].data.Name,
Price: edited[0].data.Price,
Id: edited[0].data.Id
};
}
}
You have to do:
create: function (items, success, error) {
var newItem = items[0];
$.ajax({
type: "POST",
url: "/products/productCreate",
dataType: "json",
data: newItem.data,
complete: function (xhr) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
// update the id of the newly-created item with the
// one returned from the server
newItem.data.Id = xhr.responseJSON.Id;
success();
return;
}
}
error(xhr);
}
});
}
I am using jsgrid with checkboxes for row selection such as below
$(function() {
$("#jsGrid").jsGrid({
...
headerTemplate: function() {
return $("<input>").attr("type", "checkbox").attr("id", "selectAllCheckbox");
},
itemTemplate : function(_, item) {
return $("<input>").attr("type", "checkbox").attr("class", "singleCheckbox")
.prop("checked", $.inArray(item, selectedItems) > -1)
.on("change", function () {
$(this).is(":checked") ? selectItem(item) : unselectItem(item);
});
},
}
fields :[{
{ name: "unique_id", type: "text", width: 100, visible:false },
{ name: "some_name", type: "text", width: 100},
...
]
});
$("#selectAllCheckbox").click(selectAllCheckBox);
});
The selectAllCheckBox function given below.
var selectAllCheckBox = function(item) {
selectedItems = [];
if(this.checked) { // check select status
$('.singleCheckbox').each(function() {
this.checked = true;
selectItem($(this).parent().next().text());//line 1
});
}else {
$('.singleCheckbox').each(function() {
this.checked = false;
unselectItem(item);
});
selectedItems = [];
}
}
I would like to collect all the selected unique_ids and process it on the server side. But, as unique_id is hidden, the code at line 1 always returns the values of some_name. How can I get the values of unique_id?
In jsGrid docs, I have not found any method regarding or getting hidden column but you can do like below manually implementation to get the selected record/id.
I have taken a custom selections config inside of jsGrid object as array to store the selected row into that.
*I am pushing full object of particular record in selections array inside of jsGrid.
DEMO
$("#jsGrid").jsGrid({
width: "100%",
paging: true,
selections: [],
data: [{
ClientId: 1,
Client: "Aaaa Joseph"
}, {
ClientId: 2,
Client: "Zzzz Brad"
}, {
ClientId: 3,
Client: "Mr Nice Guy"
}],
fields: [{
headerTemplate: function() {
var grid = this._grid;
return `<input class="all" type="checkbox" ${grid.selections.length==grid.data.length?'checked':''} />`;
},
itemTemplate: function(_, item) {
return `<input class="single" value=${item.ClientId} type="checkbox" _isall=${false} ${this._grid.selections.some(ClientId=>ClientId==item.ClientId)?'checked':''} />`
}
}, {
type: "text",
width: 80,
name: 'Client'
}]
});
$('#jsGrid input[type=checkbox]').on('change', function() {
var checkbox = $(this),
grid = checkbox.closest('#jsGrid').data().JSGrid;
if (checkbox.attr('class') == 'all') {
let checked = checkbox.is(":checked");
grid.selections = checked ? grid.data : [];
$.each($('#jsGrid input[class=single]'), (i, el) => $(el).prop('checked', checked))
} else {
if (checkbox.is(":checked")) {
grid.selections.push(grid.data.find(({
ClientId
}) => ClientId == checkbox.val()));
} else {
grid.selections = grid.selections.filter(({
ClientId
}) => ClientId != checkbox.val());
}
checkbox.closest('#jsGrid').find('input.all').prop('checked', grid.selections.length == grid.data.length);
}
});
$('button.getrecord').on('click', function() {
console.clear();
console.log($('#jsGrid').data().JSGrid.selections);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.css" />
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid-theme.min.css" />
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.js"></script>
<button class="getrecord">Get Selected record</button>
<div id="jsGrid"></div>
This is not answer.. i cant add the code in above comment, that has a related question. so adding it here.. what is wrong with this code. grid not loading. I am using adminLte plugin jsgrid in
https://adminlte.io/themes/v3/pages/tables/jsgrid.html
<script>
$("#jsGrid").jsGrid({
width: "100%",
paging: true,
selections: [],
controller: {
loadData: function() {
var d = $.Deferred();
$.ajax({
type: 'GET',
url: 'https://xkcd.com/info.0.json',
dataType: "json",
success: function (data) {
d.resolve(data);
},
error: function(e) {
alert("error: " + e.responseText);
}
});
console.log("here test");
return d.promise();
}
},
fields: [{
headerTemplate: function() {
var grid = this._grid;
return `<input class="all" type="checkbox" ${grid.selections.length==grid.loadData.length?'checked':''} />`;
},
itemTemplate: function(_, item) {
return `<input class="single" value=${item.num} type="checkbox" _isall=${false} ${this._grid.selections.some(num=>num==item.num)?'checked':''} />`
},
width: 10,
align: "center"
}, { name: "year", type: "textarea", title: "year", width: 50 },
{ name: "month", type: "number", title: "month", width: 50, align: "center" },
{ name: "day", type: "number", title: "day", width: 50 , align: "center"},
{ name: "title", type: "textarea", title: "title", width: 50 , align: "center"}]
});
$('#jsGrid input[type=checkbox]').on('change', function() {
var checkbox = $(this),
grid = checkbox.closest('#jsGrid').data().JSGrid;
if (checkbox.attr('class') == 'all') {
let checked = checkbox.is(":checked");
grid.selections = checked ? grid.data : [];
$.each($('#jsGrid input[class=single]'), (i, el) => $(el).prop('checked', checked))
} else {
if (checkbox.is(":checked")) {
grid.selections.push(grid.data.find(({
feed_id
}) => feed_id == checkbox.val()));
} else {
grid.selections = grid.selections.filter(({
feed_id
}) => feed_id != checkbox.val());
}
checkbox.closest('#jsGrid').find('input.all').prop('checked', grid.selections.length == grid.data.length);
}
});
$('button.getrecord').on('click', function() {
console.clear();
console.log($('#jsGrid').data().JSGrid.selections);
});
</script>
my issue is that I want to update existing store and show the changes on the grid.
What I'm doing to update is :
var record = store.getById(me.internalParameters.editInfo.id);
//console.log(me.InfoEditorPanel.hardwareIdField.value);
record.set('hardwareid', me.InfoEditorPanel.hardwareIdField.value);
record.set('location', me.InfoEditorPanel.locationField.value);
record.set('isActive', me.InfoEditorPanel.isActiveField.value);
record.commit();
store.load();
Here what I use to build the grid.
Utils.getPanelListGrid = function (parameters) {
if (parameters.initParameters == null)
parameters.initParameters = {};
var initParameters = parameters.initParameters;
initParameters.gridColumns = [
{ header: "ID", dataIndex: "id", flex: 1 },
{ header: "Hardware ID", dataIndex: "hardwareid", flex: 1 },
{ header: "Location", dataIndex: "location", flex: 1 },
{ header: "Active", dataIndex: "isActive", flex: 1 }
];
return new Backend.shared.MyDataGrid(parameters);
};
Ext.define(
"shared.MyDataGrid", {
extend: "Ext.grid.Panel",
xtype: "MyDataGrid",
title: "MyDataGrid - Hardcoded values",
initParameters: {
storeIdProperty: null,
},
initComponent: function () {
this.store = Ext.create('Ext.data.Store', {
storeId: 'myStore',
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items'
}
},
fields: ['id', 'hardwareid', 'location', 'isActive'],
data: {
'items': [{
'id': '123456',
'hardwareid': "HID-159",
'location': "Bedroom",
'isActive': "No"
}, {
'id': '789456',
'hardwareid': "HID-357",
'location': "Kitchen",
'isActive': "Yes"
}, {
'id': '147852',
'hardwareid': "HID-149",
'location': "Guest-room",
'isActive': "Yes"
}
]
}
});
this.columns = this.initParameters.gridColumns;
this.listeners = {
selectionchange: {
scope: this,
fn: function (selectionModel, selectedRecords, eventOptions) {
this.selectedIds = [];
this.selectedItems = [];
if (selectedRecords != null) {
for (var i = 0; i < selectedRecords.length; i++) {
var item = selectedRecords[i].data;
this.selectedIds.push(item[this.initParameters.storeIdProperty]);
this.selectedItems.push(item)
}
}
if (this.initParameters.selectionChangeCallback != null)
this.initParameters.selectionChangeCallback(this.selectedIds, this.selectedItems);
}
}
};
shared.MyDataGrid.superclass.initComponent.call(this);
},
getRecordCount: function () {
return this.getStore().getTotalCount();
},
getSelectedIds: function () {
return this.selectedIds;
},
getSelectedItems: function () {
return this.selectedItems;
}
});
Can anyone please explain what should I do exactly to make the grid show the updated row?
I suggest that use the following code in your 'selectionchange' event.
this.getStore().load({
params:{
'yourModelIdProperty':'selectedId'
}
});
It's call an store proxy. You should write a function for that proxy and load the updated data.
I have an ItemFileWriteStore on my page. When I click any row in my DataGrid I can get the id of that row, but then when I try to do fetchItemByIdentity using that id, it always returns null. Any idea why this could be?
I'm using Dojo 1.5.
function getRemoveFormatter(id) {
return '<img src="/images/icons/delete.png" />';
}
function deleteItem(id) {
console.log(id);
window.grid.store.fetchItemByIdentity({
identity: id,
onItem: function(item, request) { console.log(item); }
});
//window.grid.store.deleteItem(id);
}
dojo.ready(function() {
var store = new dojo.data.ItemFileWriteStore({data:{items:[]}});
window.grid = new dojox.grid.DataGrid({
store: store,
structure: [
{ name: "id", field: "id", width: "50px" },
{ name: "Stylist", field: "stylist", width: "100px" },
{ name: "Service", field: "service", width: "200px" },
{ name: "Length", field: "length", width: "50px" },
{ name: "Remove", field: "remove", width: "30px", formatter: getRemoveFormatter }
],
identifier: "id",
label: "id"});
dojo.byId("services_grid").appendChild(grid.domNode);
grid.startup();
observeAppointmentServiceAddClick(window.grid);
getAppointmentItems();
});
Try making a small change in the way you declare the store and the grid. The identifier and label properties belong in the data section of the store next to items.
var store = new dojo.data.ItemFileWriteStore({data:{
items:[],
identifier: "id",
label: "id"}});
window.grid = new dojox.grid.DataGrid({
store: store,
structure: [
{ name: "id", field: "id", width: "50px" },
{ name: "Stylist", field: "stylist", width: "100px" },
{ name: "Service", field: "service", width: "200px" },
{ name: "Length", field: "length", width: "50px" },
{ name: "Remove", field: "remove", width: "30px", formatter: getRemoveFormatter }
]});
Here is a simpler code and answer on jsfiddle.
http://jsfiddle.net/martlark/UkKXW/1/
<html>
<head><!--dojo stuff--></head>
<body>
<div id='store'></div>
<div id='log'></div>
</body>
</html>
dojo.require("dojo.data.ItemFileWriteStore");
var store = null;
function getItem(id) {
store.fetchItemByIdentity({
identity: id,
onItem: function (item, request) {
var v = store.getValue(item, 'value');
dojo.byId('log').innerHTML = 'getItem(' + id + ') =' + v;
}
});
}
dojo.ready(function () {
var items = [];
for (var p = 0; p < 5; p++) {
items.push({
id: p,
value: 'v ' + p
});
}
store = new dojo.data.ItemFileWriteStore({
data: {
identifier: 'id',
items: items
}
});
var gotList = function (items, request) {
var itemsList = "<ul>";
dojo.forEach(items, function (i) {
itemsList += '<li> id:' + p + ' = ' + store.getValue(i,
"value") + "</li>";
});
itemsList += '</ul>';
dojo.byId('store').innerHTML = itemsList;
}
var gotError = function (error, request) {
alert("The request to the store failed. " + error);
}
// Invoke the search
store.fetch({
onComplete: gotList,
onError: gotError
});
getItem('2');
});