kendoAutoComplete shows [object object] when clicked on template or item - kendo-ui

This code return the result below in snaps.
How to populate text field with FirstName and LastName when click on template instead of [object object] ?
function forAutoComplete(FieldName){
var autoCompleteUsers = $("#employees").kendoAutoComplete({
minLength: 1,
dataTextField: FieldName,
template: '<div style="border-bottom: 1px solid DARKGRAY; padding:10px 0; clear:both;">' +
'<img style="float:left; margin-right:20px;" width=\"127\" height=\"127\" src=\"<?php echo base_url() ?>/user_uploads/employee_images/${data.Photo}\" alt=\"${data.Photo}\"/>'+
'<div style="display: inline-block;"><p>${ data.FileNo}</p>' +
'<h3>${ data.FirstName } ${ data.LastName }</h3></div>'+
'<div style="clear: both; "></div></div>',
dataSource: {
serverFiltering: true,
transport: {
read: {
type: "GET",
dataType: "json",
contentType:'application/json; charset=utf-8',
url: "<?php echo base_url() ?>index.php/hr_management/manage_hr/search_employee/",
data: function (arg){
return {FieldName : autoCompleteUsers.data("kendoAutoComplete").value()};
}
}
}
},
height: 300,
change: onChangeAutoComplete
});
}

The problem is likely to be related with the value that you set for dataTextField.
Doing some-sort-of-reverse-engineering, I guess that the JSON data that you return is something like:
[
{data: { FileNo: "0001", FirstName: "OnaBai", LastName: "it's me", Photo: "https://si0.twimg.com/profile_images/2648375258/7f7e451f0de1eb467fe35f4f481d7bf7_bigger.jpeg" } },
{data: { FileNo: "0002", FirstName: "Burke", LastName: "Holland", Photo: "https://si0.twimg.com/profile_images/3342899483/51e933d69222ce8ad8cd14e655116959.jpeg" } },
{data: { FileNo: "0003", FirstName: "Todd", LastName: "Anglin", Photo: "https://si0.twimg.com/profile_images/1478082886/todd-anglin-close-up_illustrated.png" } }
]
If so, you should be defining it as data.FirstName.
If you are defining it as:
[
{ FileNo: "0001", FirstName: "OnaBai", LastName: "it's me", Photo: "https://si0.twimg.com/profile_images/2648375258/7f7e451f0de1eb467fe35f4f481d7bf7_bigger.jpeg" },
{ FileNo: "0002", FirstName: "Burke", LastName: "Holland", Photo: "https://si0.twimg.com/profile_images/3342899483/51e933d69222ce8ad8cd14e655116959.jpeg" },
{ FileNo: "0003", FirstName: "Todd", LastName: "Anglin", Photo: "https://si0.twimg.com/profile_images/1478082886/todd-anglin-close-up_illustrated.png" }
]
Then it should be just FirstName.
Example of the first approach in here while second in here
If you define dataTextField: "data", and use the first approach for your JSON then you get the [object Object]. See it here

Related

jsGrid calling Controller .Net Core - Cells not loading data

Using jsGrid / .net core 2.2 / MVC I'm successfully returning data in my ajax call and logging to the console, but I can't figure out why the fields aren't populated?
My View
<div id="jsGrid"></div>
#section scripts {
<script>
$(function () {
$("#jsGrid").jsGrid({
height: "50%",
width: "100%",
filtering: true,
inserting: true,
editing: true,
sorting: true,
paging: true,
autoload: true,
pageSize: 10,
pageButtonCount: 5,
//deleteConfirm: "Do you really want to delete client?",
controller: {
loadData: function () {
var d = $.Deferred();
$.ajax({
type: 'GET',
url: "/operator/GridJson",
dataType: "json",
success: function (data) {
d.resolve(data);
console.log('success ', data);
},
error: function (e) {
alert("error: " + e.responseText);
}
});
return d.promise();
}
},
fields: [
{ name: "OperatorId", type: "number", width: 50 },
{ name: "FirstName", type: "text", width: 150 },
{ name: "LastName", type: "text", width: 150 },
{ name: "LicenseNumber", type: "number", width: 50, filtering: false },
{ name: "RFIDNumber", type: "number", width: 50, filtering: false },
{ name: "DateCreated", type: "date", width: 50, filtering: false },
{ name: "LastUpdated", type: "date", width: 50, filtering: false },
{ name: "CompanyId", type: "number", width: 50 }
// { type: "control" }
]
});
console.log("test");
});
</script>
}
My Controller Method
[HttpGet]
public string GridJson()
{
List<OperatorDetail> operators = service.GetOperators();
string json = JsonConvert.SerializeObject(operators);
return json;
}
The Console log
(5) [{…}, {…}, {…}, {…}, {…}]
0: {OperatorId: 1, FirstName: "driver1", LastName: "driver1", LicenseNumber: 12345, RFIDNumber: 12345, …}
1: {OperatorId: 2, FirstName: "driver2", LastName: "driver2", LicenseNumber: 23456, RFIDNumber: 23456, …}
2: {OperatorId: 3, FirstName: "driver3", LastName: "driver3", LicenseNumber: 34567, RFIDNumber: 34567, …}
3: {OperatorId: 4, FirstName: "driver4", LastName: "driver4", LicenseNumber: 45678, RFIDNumber: 45678, …}
4: {OperatorId: 5, FirstName: "driver5", LastName: "driver5", LicenseNumber: 56789, RFIDNumber: 56789, …}
length: 5
__proto__: Array(0)
The reason is your loadData() async function returns before you get a response.
To fix that, change your loadData function to return a promise.
loadData: function(filter){
return $.ajax({
type:"GET",
url: "/operator/GridJson",
data:filter,
dataType:"JSON",
});
}
[Edit]
Actually, if you inspect the source with the F12 developer tool, you will find the fields rendered already. It turns out we also need change the height: "100%" as it will make those fields invisible.
Here's a complete list of a working sample:
$("#jsGrid").jsGrid({
width: "100%",
height: "100%",
height: "400px",
inserting: true,
editing: true,
sorting: true,
paging: true,
autoload: true,
pageSize: 10,
pageButtonCount: 5,
//deleteConfirm: "Do you really want to delete client?",
controller: {
loadData: function(filter){
return $.ajax({
type:"GET",
url: "/book/index",
data:filter,
dataType:"JSON",
});
}
},
fields: [
{ name: "OperatorId", type: "number", width: 50 },
{ name: "FirstName", type: "text", width: 150 },
{ name: "LastName", type: "text", width: 150 },
{ name: "LicenseNumber", type: "number", width: 50, filtering: false },
{ name: "RFIDNumber", type: "number", width: 50, filtering: false },
{ name: "DateCreated", type: "date", width: 50, filtering: false },
{ name: "LastUpdated", type: "date", width: 50, filtering: false },
{ name: "CompanyId", type: "number", width: 50 }
// { type: "control" }
]
});
A demo:
I recently had the same issue recently and took me a while to find someone else to point it out to me, too. itminus has a good portion of the solution, but since you have Paging enabled, you need to return your data in a specific JSON object.
{
data: [{your list here}],
itemsCount: {int}
}
It's barely in the documentation, as it's inline and not very obvious. (Bolding mine.)
loadData is a function returning an array of data or jQuery promise that will be resolved with an array of data (when pageLoading is true instead of object the structure { data: [items], itemsCount: [total items count] } should be returned). Accepts filter parameter including current filter options and paging parameters when
http://js-grid.com/docs/#controller

loadData just won't work

Below is my complete code. There are no errors and Directory is empty is shown.
<script>
$(document).ready(function() {
$("#table").jsGrid({
width: "100%",
height: "auto",
paging: false,
autoload: false,
noDataContent: "Directory is empty",
controller: {
loadData: function(filter) {
var data = {
data: [{
nickname: "test",
email: "t#gmail.com"
}]
};
console.log(data);
return data;
}
},
fields: [{
name: "nickname",
type: "text",
width: 80,
title: "Name"
}, {
name: "email",
type: "text",
width: 100,
title: "Email Address",
readOnly: false
}]
});
});
</script>
The console output is as below. Is there anything incorrect about the formatting?
Is there a way to enable more diagnostics, like printing out what data it is actually receiving so as to allow troubleshooting?
You need to set autoload:true
autoload (default false)
A boolean value specifying whether controller.loadData will be called when grid is rendered.
And also you need to return data.data inside of loadData() mehtod because you have array inside of data.
CODE SNIPPET
controller: {
loadData: function(filter) {
var data = {
data: [{
nickname: "test",
email: "t#gmail.com"
}]
};
return data.data; //As per your data array is like this console.log(data.data) so you need to send like this data.data
}
},
DEMO
$(document).ready(function() {
$("#table").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) {
alert('Table load data method fire because we have set config autoload:true')
var data = {
data: [{
nickname: "test",
email: "t#gmail.com"
}]
};
return data.data;//As per your data array is like this console.log(data.data) so you need to send like this data.data
}
},
fields: [{
name: "nickname",
type: "text",
width: 80,
title: "Name"
}, {
name: "email",
type: "text",
width: 100,
title: "Email Address",
readOnly: false
}]
});
$("#table1").jsGrid({
width: "100%",
height: "auto",
paging: false,
//for loadData method will not work with auto load false
autoload: false,
noDataContent: "Directory is empty",
controller: {
loadData: function(filter) {
alert('Table 1 load data method not fire')
return []
}
},
fields: [{
name: "nickname",
type: "text",
width: 80,
title: "Name"
}, {
name: "email",
type: "text",
width: 100,
title: "Email Address",
readOnly: false
}]
});
});
<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="table"></div>
<br>
<br>
<br>
<div id="table1"></div>

free jqGrid with Caption and without column headers

I want to display the caption, but not the column headers. When the grid is first displayed only the caption should be visible. When the grid is expanded, the column headers are visible. Please see jsFiddle
var $grid = $("#grid");
$grid.closest("div.ui-jqgrid-view")
.children("div.ui-jqgrid-hdiv")
.hide();
Here you go with a solution https://jsfiddle.net/7v70640y/5/
$("#grid").jqGrid({
colModel: [
{ name: "firstName" },
{ name: "lastName" }
],
caption: "The caption",
hiddengrid: true,
data: [
{ id: 10, firstName: "Angela", lastName: "Merkel" },
{ id: 20, firstName: "Vladimir", lastName: "Putin" },
{ id: 30, firstName: "David", lastName: "Cameron" },
{ id: 40, firstName: "Barack", lastName: "Obama" },
{ id: 50, firstName: "François", lastName: "Hollande" }
]
});
$('div[role="columnheader"]').parent().hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.14.1/css/ui.jqgrid.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.14.1/jquery.jqgrid.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/themes/redmond/jquery-ui.min.css" rel="stylesheet"/>
<table id="grid"></table>
Just hide the div & it's parent div which has role as columnheader
$('div[role="columnheader"]').parent().hide();
Update with multiple jqGrid
Here you go with a solution https://jsfiddle.net/7v70640y/6/
$("#grid1").jqGrid({
colModel: [
{ name: "firstName" },
{ name: "lastName" }
],
caption: "The caption",
hiddengrid: true,
data: [
{ id: 10, firstName: "Angela", lastName: "Merkel" },
{ id: 20, firstName: "Vladimir", lastName: "Putin" },
{ id: 30, firstName: "David", lastName: "Cameron" },
{ id: 40, firstName: "Barack", lastName: "Obama" },
{ id: 50, firstName: "François", lastName: "Hollande" }
]
});
$("#grid2").jqGrid({
colModel: [
{ name: "firstName" },
{ name: "lastName" }
],
caption: "The caption",
hiddengrid: true,
data: [
{ id: 10, firstName: "Angela", lastName: "Merkel" },
{ id: 20, firstName: "Vladimir", lastName: "Putin" },
{ id: 30, firstName: "David", lastName: "Cameron" },
{ id: 40, firstName: "Barack", lastName: "Obama" },
{ id: 50, firstName: "François", lastName: "Hollande" }
]
});
$('#gview_grid1').find('div[role="columnheader"]').parent().hide();
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/themes/redmond/jquery-ui.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.14.1/css/ui.jqgrid.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.14.1/jquery.jqgrid.min.js"></script>
<table id="grid1"></table>
<br/><br/>
<table id="grid2"></table>
Hope this will help you.

how do i always show kendo grid default data row at the end of data source angularjs

how do i always show a default data entering row at the end of data source in kendo grid ??
i want to have a kendo grid with input row at the grid bottom at all times. when i enter data and press 'enter' key, the data should be inserted in the grid from top to bottom but the default data entry row should stay at grid bottom.
Below is the grid initialization. i have used angularjs / javascript with kendo grid.
//-> Grid Sample data for demo purposes
var s1 = [];
//##########################
//-> Grid Start
var configAddPaymentsEnter = {};
configAddPaymentsEnter.resizable = true
configAddPaymentsEnter.sortable = true;
configAddPaymentsEnter.pageable = false;
//{
// input: true,
// numeric: false
// };
configAddPaymentsEnter.editable =
{
createAt: 'bottom'
};
configAddPaymentsEnter.columns = [
{
field: "ConnectionReference",
attributes: {
"navi-text": ""
},
headerTemplate: 'Connection Reference',
template: '<input ng-keydown="AA(this,$event)" type ="text" ng-model="dataItem.ConnectionReference" class="k-fill text-right aa" format-number ng-pattern="/^[0-9]+(\.[0-9]{2})?$/" />',
width: "130px"
// ,aggregates: ["count"], footerTemplate: "Total Count: #=count#"
},
{
field: "ContractNumber",
attributes: {
"navi-text": ""
},
headerTemplate: 'Contract Number',
template: '<input ng-keydown="AA(this,$event)" type ="text" class="k-fill text-right aa" ng-model="dataItem.ContractNumber" format-number ng-pattern="/^[0-9]+(\.[0-9]{2})?$/" />',
width: "130px"
},
{
field: "Amount",
attributes: {
"navi-text": ""
},
headerTemplate: 'Amount',
template: '<input ng-keydown="AA(this,$event)" kendo-numeric-text-box type ="text" class="k-fill text-right aa" ng-model="dataItem.Amount" format-number ng-pattern="/^[0-9]+(\.[0-9]{2})?$/" />',
width: "130px"
// ,aggregates: ["sum"], footerTemplate: "Total Amount: #=sum#"
},
{
field: "ReferenceNumber",
attributes: {
"navi-text": ""
},
headerTemplate: 'Reference Number',
template: '<input ng-keydown="AA(this,$event)" type ="text" class="k-fill text-right aa" ng-model="dataItem.ReferenceNumber" format-number ng-pattern="/^[0-9]+(\.[0-9]{2})?$/" />',
width: "130px"
}
//,
//{
// field: "RowIndex",
// attributes: {
// "navi-text": ""
// },
// headerTemplate: 'RowIndex',
// template: '<input ng-keydown="AA(this,$event)" type ="text" class="k-fill text-right aa" ng-model="dataItem.RowIndex" format-number ng-pattern="/^[0-9]+(\.[0-9]{2})?$/" />',
// width: "130px"
//}
];
configAddPaymentsEnter.scrollable = true;
configAddPaymentsEnter.dataSource = new kendo.data.DataSource({
data: [s1],
//group: {
// field: "ConnectionReference", aggregates: [
// { field: "ConnectionReference", aggregate: "count" },
// { field: "Amount", aggregate: "sum" }
// ]
//},
//aggregate: [{ field: "ConnectionReference", aggregate: "count" },
// { field: "Amount", aggregate: "sum" }],
schema: {
model: {
id: "ID",
fields: {
'ConnectionReference': { editable: true, type: "number" },
'ContractNumber': { editable: true, type: "number" },
'Amount': { editable: true, type: "number" },
'ReferenceNumber': { editable: true, type: "number" }
//,
// 'RowIndex': { editable: false, type: "number" }
}
}
},
pageSize: 5000,
});
$scope.dgGridAddPaymentsEnter = new DataGrid();
$scope.dgGridAddPaymentsEnter.options(configAddPaymentsEnter);
$scope.Init = function (arg) {
$scope.dgGridAddPaymentsEnter.Init(arg);
};
$scope.Init = function (arg) {
$scope.dgGridAddPaymentsEnter.Init(arg);
};
This 'how to' example would be helpful:
http://docs.telerik.com/kendo-ui/controls/data-management/grid/how-to/Editing/add-row-when-tabbed-out-of-last-row
You can try using the Locking option of Kendo Grid UI.
http://docs.telerik.com/kendo-ui/controls/data-management/grid/appearance#locking
But, unfortunately frozen rows are not supported at the moment as far as i know. The best technique would be to include the frozen data in the Grid's footer, and take care of manually syncing any changes (edits) to the data values

How to send data to the controller from the Kendo UI TreeView

I have two TreeViews, one has a list of countries, and the other is empty, now I want drag and drop selected countries into the second tree-view. I don't know how to send data to the controller from the TreeView and there is also some text field on the page in a form. So, how can I send both the form data and the TreeView's data to the controller.
Here is the code for the second tree-view which is empty and I want to add the selected nodes to:
#(Html.Kendo().TreeView()
.Name("treeview-right")
.DragAndDrop(true)
.Events(events => events
.Drag("onDrag")
.Drop("onDrop")
)
)
Please try with the below code snippet.
HTML/VIEW
<div style="border: 1px solid green;">
<div id="treeview-left"></div>
</div>
<div style="border: 1px solid red;">
<div id="treeview-right"></div>
</div>
<div id="mydiv" onclick="SaveData()">Click me to save data</div>
<script>
$("#treeview-left").kendoTreeView({
dragAndDrop: true,
dataSource: [
{
id: 11, text: "Furniture", expanded: true, items: [
{ id: 12, text: "Tables & Chairs" },
{ id: 13, text: "Sofas" },
{ id: 14, text: "Occasional Furniture" }
]
},
{
id: 15, text: "Decor", items: [
{ id: 16, text: "Bed Linen" },
{ id: 17, text: "Curtains & Blinds" },
{ id: 18, text: "Carpets" }
]
}
]
});
$("#treeview-right").kendoTreeView({
dragAndDrop: true,
dataSource: [
{
id: 1, text: "Storage", expanded: true, items: [
{ id: 2, text: "Wall Shelving" },
{ id: 3, text: "Floor Shelving" },
{ id: 4, text: "Kids Storage" }
]
},
{
id: 5, text: "Lights", items: [
{ id: 6, text: "Ceiling" },
{ id: 7, text: "Table" },
{ id: 8, text: "Floor" }
]
}
]
});
var selectedID;
function SaveData() {
selectedID = '';
var tv = $("#treeview-right").data("kendoTreeView");
selectedID = getRecursiveNodeText(tv.dataSource.view());
alert(selectedID);
var data = {};
data.str = selectedID;
$.ajax({
url: 'Home/SaveData',
type: 'POST',
data: data,
dataType: 'json',
success: function (result) {
alert("Success");
},
error: function (result) {
alert("Error");
},
});
}
function getRecursiveNodeText(nodeview) {
for (var i = 0; i < nodeview.length; i++) {
selectedID += nodeview[i].id + ",";
//nodeview[i].text; You can also access text here
if (nodeview[i].hasChildren) {
getRecursiveNodeText(nodeview[i].children.view());
}
}
return selectedID;
}
</script>
CONTROLLER
namespace MvcApplication2.Controllers
{
public class HomeController : Controller
{
[HttpPost]
public JsonResult SaveData(string str)
{
foreach (string s in str.Split(','))
{
if (!string.IsNullOrEmpty(s))
{
//Perform your opeartion here
}
}
return Json("");
}
}
}
jsfiddle Demo

Resources