kendo grid dynamic columns - javascript

I have a grid in kendo it is created dynamically, when creating generated once the titles of the columns well, but when I come back and recreational grid only puts me in the first column title
function GenerarTabla() {
var fieldsDinamicos;
var fieldDinamico;
myList = [];
fieldsdynamic = [];
$('#ColumnasaMostrar option').each(function () {
col = {};
col.text = $(this).attr("nombrecolumna");
col.operacion = $(this).val();
col.tipodato = $(this).attr("tipodato");
col.nombrefuncion = $(this).attr("nombrefuncion");
myList.push(col);
fieldsdynamic.push($(this).attr("nombrecolumna"));
});
var listaColumnas = fieldsdynamic.join(", ");
var datos;
url2 = urlServicio + '/DynamicService.svc/' + entidaddinamica + '?$select=' + listaColumnas;
//$.getJSON(url2, function (data) {
// datos = data;
//});
var model = {
fields: {
}
};
// model.fields["Id"] = { type: "number" };
var columnasDinamicas = [];
var columnasAgregadas = [];
var fieldsDinamicos = [];
$.each(myList, function (key, val) {
if (val.operacion != "undefined") {
columnasDinamicas.push({
field: val.text,
title: val.text,
footerTemplate: val.nombrefuncion + ": #: " + val.operacion + " #"
});
tipodato = consultarTipoDato(val.tipodato)
model.fields[val.text] = { type: tipodato };
columnasAgregadas.push({ field: val.text, aggregate: val.operacion });
} else {
columnasDinamicas.push({
field: val.text,
title: val.text
});
tipodato = consultarTipoDato(val.tipodato)
model.fields[val.text] = { type: tipodato };
}
})
$("#gridkendo").kendoGrid({
dataSource: {
type: "odata",
transport: {
read: {
url: url2,
dataType: "json"
}
},
schema: {
data: function (data) {
return data.value;
},
total: function (data) {
return data['odata.count'];
},
model: model
},
aggregate: columnasAgregadas,
pageSize: 10
//serverPaging: true,
//serverFiltering: true,
//serverSorting: true
},
height: 430,
filterable: false,
sortable: false,
pageable: true,
columns: columnasDinamicas
});
}
first created
second created

Related

Uncaught ReferenceError: function is not defined at HTMLButtonElement.onclick error on button inside datatable

I am having some problems using datatables.net with requirejs and some buttons and data loaded through the ajax request from datatables.net (JSON). I have tried and tried but still no luck.
The problem I face is: Uncaught ReferenceError: editPermission is not defined at HTMLButtonElement.onclick (permissions.php:1)
Here is the full backend PHP function that is connecting to the DB:
public function getAllPermissions($request, $columns): array
{
$bindings = array();
try {
$sql = "SELECT p.id, p.name, p.description, p.category, NULL AS roles,
CASE WHEN
p.required = 0 THEN concat('<button id=\'editpermission_', p.id, '\' onclick=\'editPermission(',p.id,')\' class=\'btn btn-warning\'>Edit</button>')
ELSE null END
AS edit
FROM ".$this->tbl_permissions." p";
$stmt = $this->conn->prepare($sql);
$stmt->execute();
$data = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$return_data = array(
"data" => MiscFunctions::data_output($columns, $data)
);
return $return_data;
} catch (\PDOException $e) {
http_response_code(500);
$result = ["Error" => $e->getMessage()];
return $result;
}
}
Under here is the file that ajax asks for the data (permissions_getall.php):
<?php
try {
require '../../vendor/autoload.php';
session_start();
$request = new PHPLogin\CSRFHandler;
$auth = new PHPLogin\AuthorizationHandler;
$admin = new PHPLogin\AdminFunctions;
if ($request->valid_token() && ($auth->isSuperAdmin() || $auth->hasPermission('View Permissions'))) {
unset($_GET['csrf_token']);
$columns = array(
array( 'db' => 'id', 'dt' => 0 ),
array( 'db' => 'name', 'dt' => 1 ),
array( 'db' => 'description', 'dt' => 2 ),
array( 'db' => 'category', 'dt' => 3 ),
array( 'db' => 'roles', 'dt' => 4 ),
array( 'db' => 'edit', 'dt' => 5 )
);
$data = $admin->getAllPermissions($_GET, $columns);
echo json_encode($data);
} else {
http_response_code(401);
throw new Exception('Unauthorized');
}
} catch (Exception $e) {
error_log($e->getMessage());
echo json_encode($e->getMessage());
}
This is the JS file:
require(['jquery', 'multiselect', 'datatables', 'datatables.net', 'datatables.net-bs4', 'datatables.net-buttons', 'datatables.net-buttons-bs4', 'datatables.net-select-bs4', 'loadingoverlay'], function ($) {
console.log($);
//User Management scripts
/* HANDLES POPOVERS FOR USER INFO */
function userInfoPull(id, elem) {
$.ajax({
type: "POST",
url: "ajax/user_getinfo.php",
data: {"user_id": id, "csrf_token": $('meta[name="csrf_token"]').attr("value")},
async: false,
beforeSend: function () {
$.LoadingOverlay('show', {
image: '../login/images/Spin-0.8s-200px.svg',
imageAnimation: false,
imageColor: '#428bca',
fade: [200, 100]
});
},
complete: function () {
$.LoadingOverlay("hide");
},
success: function (user_info) {
user_info = JSON.parse(user_info);
var user_info_html = '';
for (var prop in user_info) {
if (user_info[prop] != '' && user_info[prop] != null) {
if (prop == 'UserImage') {
user_info_html += '<br><div class="img-thumbnail"><img src="' + user_info[prop] + '" height="240px"></div>';
} else {
user_info_html += '<div><b>' + prop.replace(/([A-Z])/g, ' $1') + ': </b>' + user_info[prop] + '</div>';
}
}
}
$(elem).attr('data-content', user_info_html).popover('show', {"html": true});
},
error: function (xhr, error, thrown) {
console.log(error);
}
});
};
$('body').on('mouseover', "a[id^='info_']", function () {
if ($(this).attr('data-content')) {
$(this).popover('show', {"html": true});
} else {
var id = this.id.split('_')[1];
userInfoPull(id, this);
}
});
$('body').on('mouseleave', "a[id^='info_']", function () {
$(this).popover('hide');
});
/****************************/
/* HANDLES MODAL FOR PERMISSION ROLES */
$('body').on('click', "button[id^='rolesbtn_']", function () {
var id = this.id.split('_')[1];
permissionRolesList(id);
});
function permissionRolesList(id) {
$.ajax({
type: "POST",
url: "ajax/permission_getroles.php",
data: {"permission_id": id, "csrf_token": $('meta[name="csrf_token"]').attr("value")},
beforeSend: function () {
$.LoadingOverlay('show', {
image: '../login/images/Spin-0.8s-200px.svg',
imageAnimation: false,
imageColor: '#428bca',
fade: [200, 100]
});
},
complete: function () {
$.LoadingOverlay("hide");
},
success: function (role_array) {
role_array = JSON.parse(role_array);
$('#permissionsButton').click();
$('#roles-selected').empty();
$('#roles-available').empty();
$('#permission_id').val(id);
$.each(role_array['permission_roles'], function (key, value) {
$('#roles-selected').append("<option value='" + value.id + "'>" + value.name + "</option>");
});
$.each(role_array['diff_roles'], function (key, value) {
$('#roles-available').append("<option value='" + value.id + "'>" + value.name + "</option>");
})
$("select[id^='roles-']").multiselect({
search: {
left: '<input type="text" name="q" class="form-control" placeholder="Search..." />',
right: '<input type="text" name="q" class="form-control" placeholder="Search..." />',
},
fireSearch: function (value) {
return value.length > 3;
}
});
},
error: function (xhr, error, thrown) {
console.log(error);
}
});
};
function editPermission(id) {
var id = id;
$.ajax({
type: "POST",
url: "ajax/permission_getdata.php",
data: {"permission_id": id, "csrf_token": $('meta[name="csrf_token"]').attr("value")},
beforeSend: function () {
$.LoadingOverlay('show', {
image: '../login/images/Spin-0.8s-200px.svg',
imageAnimation: false,
imageColor: '#428bca',
fade: [200, 100]
});
},
complete: function () {
$.LoadingOverlay("hide");
},
success: function (response) {
var respdata = JSON.parse(response);
$("#editPermissionForm").trigger("reset");
$("#edit_permission_id").val(respdata.id);
$("#edit_PermissionName").val(respdata.name);
$("#edit_PermissionDescription").val(respdata.description);
$("#edit_PermissionCategory").val(respdata.category);
$('#editPermission').modal('show');
},
error: function (xhr, error, thrown) {
console.log(error);
}
});
}
$('#saveRoles').click(function () {
var sendData = new FormData();
var formData = [];
var new_roles = [];
var id = $('#permission_id').val();
$('#roles-selected > option').each(function () {
new_roles.push($(this).val());
});
formJson = JSON.stringify(new_roles);
sendData.append('formData', formJson);
sendData.append('permissionId', id);
sendData.append('csrf_token', $('meta[name="csrf_token"]').attr("value"));
$.ajax({
type: "POST",
url: "ajax/permission_updateroles.php",
processData: false,
contentType: false,
data: sendData,
beforeSend: function () {
$.LoadingOverlay('show', {
image: '../login/images/Spin-0.8s-200px.svg',
imageAnimation: false,
imageColor: '#428bca',
fade: [200, 100]
});
},
complete: function () {
$.LoadingOverlay("hide");
},
success: function (response) {
response = JSON.parse(response);
permissionTable.ajax.reload();
$('#permissionsModal').modal('toggle');
},
error: function (xhr, error, thrown) {
console.log(error);
}
});
});
/****************************/
/* DATATABLE INITIALIZATION */
$(document).ready(function () {
permissionTable = $('#permissionList').DataTable({
dom: "<'row'<'col-sm-3'l><'col-sm-6 text-center'B><'col-sm-3'f>>" +
"<'row'<'col-sm-12'tr>>" +
"<'row'<'col-sm-5'i><'col-sm-7'p>>",
order: [[3, "asc"], [1, "asc"]],
columns: [
{
name: "id",
visible: true,
searchable: false,
sortable: false,
render: function (data, type, row) {
return "";
}
},
{
name: "name",
searchable: true
},
{
name: "description",
searchable: true
},
{
name: "category",
searchable: true
},
{
name: "assign roles",
width: "90px",
searchable: false,
render: function (data, type, row) {
return "<button id='rolesbtn_" + row[0] + "' class='btn btn-info'>Assign roles</button>"
}
},
{
name: "edit permission",
width: "40px",
searchable: false
}
],
columnDefs: [{
className: 'select-checkbox',
targets: 0
}],
paging: true,
ajax: {
url: "ajax/permissions_getall.php?csrf_token=" + $('meta[name="csrf_token"]').attr("value"),
error: function (xhr, error, thrown) {
alert(xhr.responseJSON.Error);
}
},
scrollY: "600px",
scrollCollapse: true,
lengthMenu: [[15, 30, -1], [15, 30, "All"]],
select: {
style: "multi",
selector: 'td:first-child'
},
buttons: [
{
extend: 'selectAll',
className: 'selectall',
action: function (e) {
e.preventDefault();
permissionTable.rows({page: 'current'}).select();
permissionTable.rows({search: 'removed'}).deselect();
}
},
"selectNone",
{
text: 'Add New Permission',
action: function (e, dt, node, config) {
$('#newPermission').modal('show');
},
className: "btn-success"
},
{
text: 'Delete Selected',
action: function (e, dt, node, config) {
var selected_array = dt.rows({selected: true}).data();
if (confirm("Are you sure you want to delete the selected permissions?")) {
for (var i = 0, len = selected_array.length; i < len; i++) {
deletePermission(selected_array[i][0], 'rolesbtn_' + selected_array[i][0]);
}
}
},
className: "btn-danger"
}
]
}).on("select", function () {
//console.log("selected");
});
});
/****************************/
function deletePermission(id, btn_id) {
var idJSON = "[" + JSON.stringify(id) + "]";
$.ajax({
type: "POST",
url: "ajax/permissions_delete.php",
data: {"ids": idJSON, "csrf_token": $('meta[name="csrf_token"]').attr("value")},
async: false,
success: function (resp) {
permissionTable.row($('#' + btn_id).parents('tr')).remove().draw();
},
error: function (err) {
console.log(err);
alert(err.responseText);
}
});
}
$("#newPermissionForm").submit(function (event) {
event.preventDefault();
var permissionName = $("#new_PermissionName").val();
var permissionDescription = $("#new_PermissionDescription").val();
var permissionCategory = $("#new_PermissionCategory").val();
$.ajax({
url: "ajax/permissions_add.php",
type: "POST",
data: {
"permissionName": permissionName,
"permissionDescription": permissionDescription,
"permissionCategory": permissionCategory,
"csrf_token": $('meta[name="csrf_token"]').attr("value")
},
beforeSend: function () {
$.LoadingOverlay('show', {
image: '../login/images/Spin-0.8s-200px.svg',
imageAnimation: false,
imageColor: '#428bca',
fade: [200, 100]
});
},
complete: function (resp) {
$.LoadingOverlay("hide");
},
success: function (response) {
permissionTable.ajax.reload();
$("#newPermission").modal('hide');
$("#newPermissionForm")[0].reset();
},
error: function (err) {
console.log(err);
}
});
});
$("#editPermissionForm").submit(function (event) {
event.preventDefault();
var permissionId = $("#edit_permission_id").val();
var permissionName = $("#edit_PermissionName").val();
var permissionDescription = $("#edit_PermissionDescription").val();
var permissionCategory = $("#edit_PermissionCategory").val();
$.ajax({
url: "ajax/permission_update.php",
type: "POST",
data: {
"permissionId": permissionId,
"permissionName": permissionName,
"permissionDescription": permissionDescription,
"permissionCategory": permissionCategory,
"csrf_token": $('meta[name="csrf_token"]').attr("value")
},
beforeSend: function () {
$.LoadingOverlay('show', {
image: '../login/images/Spin-0.8s-200px.svg',
imageAnimation: false,
imageColor: '#428bca',
fade: [200, 100]
});
},
complete: function (resp) {
$.LoadingOverlay("hide");
},
success: function (response) {
permissionTable.ajax.reload();
$("#editPermission").modal('hide');
$("#editPermissionForm")[0].reset();
},
error: function (err) {
console.log(err);
}
});
});
//Role assignment box button logic
(function () {
$('#btnRight').click(function (e) {
var selectedOpts = $('#roles-available option:selected');
if (selectedOpts.length == 0) {
alert("Nothing to move.");
e.preventDefault();
}
$('#roles-selected').append($(selectedOpts).clone());
$(selectedOpts).remove();
e.preventDefault();
});
$('#btnAllRight').click(function (e) {
var selectedOpts = $('#roles-available option');
if (selectedOpts.length == 0) {
alert("Nothing to move.");
e.preventDefault();
}
$('#roles-selected').append($(selectedOpts).clone());
$(selectedOpts).remove();
e.preventDefault();
});
$('#btnLeft').click(function (e) {
var selectedOpts = $('#roles-selected option:selected');
if (selectedOpts.length == 0) {
alert("Nothing to move.");
e.preventDefault();
}
$('#roles-available').append($(selectedOpts).clone());
$(selectedOpts).remove();
e.preventDefault();
});
$('#btnAllLeft').click(function (e) {
var selectedOpts = $('#roles-selected option');
if (selectedOpts.length == 0) {
alert("Nothing to move.");
e.preventDefault();
}
$('#roles-available').append($(selectedOpts).clone());
$(selectedOpts).remove();
e.preventDefault();
});
}(jQuery));
// Converts array to object
function toObject(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
rv[i] = arr[i];
return rv;
}
});
Here is a image of the page with the button that is causing problems circled:
Here is what I have tried so far:
Attempted to move the function editPermission around as well as placing it inside the $(document).ready
I have noticed that when I click it in Chrome it seems to open a new page where it executes the script. Sort of weird. Screenshot (Normal page file circled):
What things can I try to solve this?

Conditional formatting of KO grid cells

I'm using kogrid to display data as shown below:
My knockout vm makes an ajax call to an MVC controller to retrieve a DTO shaped as follows:
I would like to colour in RED the cell background that have values that failed validation. For example, the 1st element of the data array contains a "CostCentreIsValid" member with a value of "False", so I would like the "Cost Centre (Dim1)" column of the 1st row to be RED. For the same array element, the "AccountIsValid" member contains the value "True", so I would like the "GL Account (Account)" cell of the first row to be GREEN.
Knockout view model:
"use strict";
function ViewModel(interchangeId) {
var edited = function (interchangeId, accountIsValid, costCentreIsValid, supplierIsValid, supplierNo, invoiceNo, costCentre, glAccount, amount, invoiceDesc, originalRec) {
var self = this;
// Properties
self.interchangeId = interchangeId;
self.supplierNo = ko.observable(supplierNo);
self.invoiceNo = ko.observable(invoiceNo);
self.costCentre = ko.observable(costCentre);
self.glAccount = ko.observable(glAccount);
self.amount = ko.observable(amount);
self.invoiceDesc = ko.observable(invoiceDesc);
self.originalRec = originalRec;
}
var editBatchVm = function () {
var self = this;
var $loadingIndicator = $('#loading-indicator');
// Properties
self.recs = ko.observableArray([]);
self.selected = ko.observableArray();
var textEditTemplate = '<div><input type=\"text\" data-bind=\"visible: $parent.selected(), value: $parent.entity[$data.field]" /><span data-bind=\"visible: !$parent.selected(), text: $parent.entity[$data.field]\"></span></div>';
self.columnDefs = [
{ width: 100, field: 'supplierNo', displayName: 'Supplier No', cellTemplate: textEditTemplate },
{ width: 150, field: 'invoiceNo', displayName: 'Invoice No' },
{ width: 150, field: 'costCentre', displayName: 'Cost Centre (Dim1)', cellTemplate: textEditTemplate },
{ width: 200, field: 'glAccount', displayName: 'GL Account (Account)', cellTemplate: textEditTemplate },
{ width: 100, field: 'amount', displayName: 'Amount' },
{ width: 300, field: 'invoiceDesc', displayName: 'Invoice Description' },
];
self.filterOptions = {
filterText: ko.observable(""),
useExternalFilter: false
};
self.pagingOptions = {
currentPage: ko.observable(1),
pageSizes: ko.observableArray([10, 20, 50]),
pageSize: ko.observable(10),
totalServerItems: ko.observable(0)
};
self.sortInfo = ko.observable({ column: { 'field': 'TimeReceived' }, direction: 'desc' });
self.gridOptions = {
data: self.recs,
columnDefs: self.columnDefs,
autogenerateColumns: false,
showGroupPanel: true,
showFilter: true,
filterOptions: self.filterOptions,
enablePaging: true,
pagingOptions: self.pagingOptions,
sortInfo: self.sortInfo,
rowHeight: 35,
selectWithCheckboxOnly: true,
selectedItems: self.selected,
canSelectRows: true,
displaySelectionCheckbox: true,
};
self.batchId = ko.observable();
// Methods
self.get = function () {
$loadingIndicator.show();
$.ajax({
url: BASE_URL + 'EditBatch/GetRecords',
type: 'get',
data: {
'interchangeId': interchangeId
},
contentType: 'application/json; charset=utf-8',
success: function (data) {
var recsArray = [];
$.each(data, function (key, value) {
recsArray.push(
new edited(
interchangeId,
value.AccountIsValid,
value.CostCentreIsValid,
value.SupplierIsValid,
value.Transaction.Voucher[0].Transaction[0].ApArInfo.ApArNo,
value.Transaction.Voucher[0].Transaction[0].ApArInfo.InvoiceNo,
value.Transaction.Voucher[0].Transaction[0].GLAnalysis.Dim1,
value.Transaction.Voucher[0].Transaction[0].GLAnalysis.Account,
value.Transaction.Voucher[0].Transaction[0].Amounts.Amount,
value.Transaction.Voucher[0].Transaction[0].Description,
value.Transaction
)
);
});
self.recs(recsArray);
//batch level info
self.pagingOptions.totalServerItems(data.length);
self.batchId(data[0].BatchId);
}
});
$loadingIndicator.hide();
};
self.resubmit = function () {
var data = { Recs: ko.toJS(this.recs) };
$.ajax({
type: "POST",
url: BASE_URL + 'EditBatch/Resubmit',
data: ko.toJSON(data),
contentType: 'application/json',
async: true,
success: function (data) {
window.location = BASE_URL + 'APInvoicesSummary/Index';
},
error: function (data) {
toastrs(false);
}
});
}
// Subscriptions
self.pagingOptions.pageSize.subscribe(function (data) {
self.pagingOptions.currentPage(1);
self.get();
});
self.pagingOptions.currentPage.subscribe(function (data) {
self.get();
});
self.sortInfo.subscribe(function (data) {
self.pagingOptions.currentPage(1);
self.get();
});
//self.gridOptions.selectedItems.subscribe(function (data) {
// if (data.length > 0) {
// self.date(data[0].date);
// self.voucherNo(data[0].voucherNo);
// self.description(data[0].description);
// self.amount(data[0].amount);
// }
//});
}
/////////////////////////////////////////////////////////////////
// Let's kick it all off
var vm = new editBatchVm();
ko.applyBindings(vm, $("#KoSection")[0]);
vm.get();
};
Has anyone come across examples of how to do this please?
You can bind the style:
<li data-bind="style: { color: !AccountIsValid() ? 'red' }">
Or bind the css:
<li data-bind="css: { failed--account: !AccountIsValid() }">
And then in your stylesheet:
failed--account {
color: red;
}
NOTES
I suposed your data is in a model and AccountIsValid is an observable, if is binded but not observable just remove the parenthesis color: !AccountIsValid.
If your data is not binded you can access it via data[0].AccountIsValid... But I would recommend to bind it.
Here's how I fixed it:
In the site.css
.failed-validation { color: red; }
.passed-validation { color: green; }
and in the knockout js:
var supplierEditTemplate =
`<div><input type=\"text\" data-bind=\"visible: $parent.selected(), value:
$parent.entity[$data.field]" />
<span data-bind=\"visible: !$parent.selected(), text: $parent.entity[$data.field],
css: $parent.entity.supplierIsValid() === 'True' ? \'passed-validation\' : \'failed-validation\'">
</span>
</div>`;
self.columnDefs = [
{ width: 100, field: 'supplierNo', displayName: 'Supplier No', cellTemplate: supplierEditTemplate }];

Kendo UI grid comboBox undefined on focus out?

I have working on Keno UI grid and I have added a comboBox as a column in the grid which also supports autocomplete feature. Apparently, comboBox is working fine but when I type half of world and focus out of the comboBox cell then it shows undefined. I have tried to handle it on combobox change event, but it is still showing undefined value? Below is my code for combobox and grid.
function productDropDownEditor(container, options) {
$('<input id="ProductDropDown" style="width:250px;" data-bind="value:' + options.field + '"/>')
.appendTo(container).kendoComboBox({
dataSource: dataSource,
autoBind: false,
dataTextField: 'ProductName',
dataValueField: 'ProductID',
filter: "contains",
suggest: true,
index: 3,
change: function (e) {
debugger;
var cmb = this;
// selectedIndex of -1 indicates custom value
if (cmb.selectedIndex < 0) {
cmb.value(0); // or set to the first item in combobox
}
},
close: function (e) {
debugger;
var cmb = this;
}
});
And here is following code for kendo grid.
$(function () {
$("#grid").kendoGrid({
columns: [
{
field: "Products", width: "250px",
editor: productDropDownEditor,
title: "Product",
template: "#=Products.ProductName#",
attributes: {
"class": "select2_single"
}
},
{ field: "PurchasePrice", width: "150px" },
{ field: "PurchaseQuantity", width: "150px" },
{ field: "SaleRate", title: "Sale Rate", width: "150px" },
{ field: "Amount", title: "Amount", width: "150px" },
{ command: "destroy", title: "Delete", width: "110px" },
],
editable: true, // enable editing
pageable: true,
navigatable: true,
sortable: true,
editable: "incell",
toolbar: ["create"], // specify toolbar commands
edit: function (e) {
//debugger;
//// var parentItem = parentGrid.dataSource.get(e.model.PurchaseID);
////e.model.set("ShipCountry", parentItem.Country);
//if (e.model.isNew()) {
// // set the value of the model property like this
// e.model.set("PropertyName", Value);
// // for setting all fields, you can loop on
// // the grid columns names and set the field
//}
},
//editable: "inline",
dataSource: {
serverPaging: true,
requestStart: function () {
kendo.ui.progress($("#loading"), true);
},
requestEnd: function () {
kendo.ui.progress($("#loading"), false);
},
serverFiltering: true,
serverSorting: true,
batch: true,
pageSize: 3,
schema: {
data: "data",
total: "Total",
model: { // define the model of the data source. Required for validation and property types.
id: "Id",
fields: {
PurchaseID: { editable: false, nullable: true },
PurchasePrice: { nullable: true },
PurchaseQuantity: { validation: { required: true, min: 1 } },
SaleRate: { validation: { required: true, min: 1 } },
Amount: { type: "number", editable: false },
Products: {
nullable: false,
validation: { required: true},
defaultValue: {ProductID:1, ProductName:"Googo" },
//from: "Products.ProductName",
parse: function (data) {
debugger;
if (data == null) {
data = { ProductID: 1};
}
return data;
},
type: "object"
}
}
}
},
batch: true, // enable batch editing - changes will be saved when the user clicks the "Save changes" button
change: function (e) {
debugger;
if (e.action === "itemchange" && e.field !== "Amount") {
var model = e.items[0],
type = model.Type,
currentValue = model.PurchasePrice * model.PurchaseQuantity;//formulas[type](model);
if (currentValue !== model.Amount) {
model.Amount = currentValue;
$("#grid").find("tr[data-uid='" + model.uid + "'] td:eq(4)").text(currentValue);
}
//if (e.field == "Products") {
// $("#grid").find("tr[data-uid='" + model.uid + "'] td:eq(0)").text(model.Products);
//}
}
},
transport: {
read: {
url: "#Url.Action("Read", "Purchase")", //specify the URL which should return the records. This is the Read method of the HomeController.
contentType: "application/json",
type: "POST", //use HTTP POST request as by default GET is not allowed by ASP.NET MVC
},
parameterMap: function (data, operation) {
debugger;
if (operation != "read") {
// post the products so the ASP.NET DefaultModelBinder will understand them:
// data.models[0].ProductID = data.models[0].Product.ProductID;
var result = {};
// data.models[0].ProductID = $("#ProductDropDown").val();
for (var i = 0; i < data.models.length; i++) {
var purchase = data.models[i];
for (var member in purchase) {
result["purchaseDetail[" + i + "]." + member] = purchase[member];
}
}
return result;
} else {
var purchaseID = $("#hdnPurchaseId").val();
//output = '{ purchaseID: ' + purchaseID + '}';
data.purchaseID = purchaseID; // Got value from MVC view model.
return JSON.stringify(data)
}
}
}
},
}).data("kendoGrid");

Why Kendo TreeList DataSourceTransport with custom read method written in Typescript does go wild?

I'm working with Angular 1.4.9 with Typescript and I would like to display a treelist where data coming from server called by Restangular. So that, I have custom transport method in Kendo DataSource as you can see below.
Unfortunately, I'm not vell experienced in Typescript yet.
The issue:
When the page is loaded then Kendo TreeList fires the readRepository method to get data from the server, when data, or partial data - I mean a row -, is loaded then it fires many calls to the server, for me it seem when it gets a line of data it uses it and call the server again unnecessarily. I don't understand why.
Please find the relevant code attached!
What I did so far:
I created the same controller written in javascript and it is working like a charm
I have tried to change how the DataSourceTransport.read invokes the this.readRepository according to this answer, but the result is the same.
ShowTestSuitTreeController written in Typescript:
module sayusiando.gonogo.web.spa.mainpage.showtestsuittree.controllers {
import IGeneralTestSuitTestCaseContract = sayusiando.gonogo.web.spa.common.contracts.IGeneralTestSuitTestCaseContract;
import DataSourceTransport = kendo.data.DataSourceTransport;
import DataSourceSchema = kendo.data.DataSourceSchema;
import DataSourceSchemaModelFields = kendo.data.DataSourceSchemaModelFields;
import TestManagementService = sayusiando.gonogo.web.spa.service.ITestManagementService;
"use strict";
export interface IShowTestSuitTreeController {
activate: () => void;
}
class ShowTestSuitTreeController implements IShowTestSuitTreeController {
//#region Variables
testSuiteTree = [];
testSuiteTreeKendoTreeListOptions: kendo.ui.TreeListOptions = {};
//#endregion
//#region Inject and ctor
static $inject: string[] = ['testManagementService'];
constructor(
private testManagementService: gonogo.web.spa.service.ITestManagementService
) {
this.activate();
}
//#endregion
activate(): void {
var dataSourceTransport = <DataSourceTransport>{
//read: this.readRepository.bind(this)
read: (e) => this.readRepository(e)
};
var schema: DataSourceSchema = <DataSourceSchema>{
model: {
id: "id",
parentId: "parentId",
fields: <DataSourceSchemaModelFields>{
id: { type: "number", editable: false, nullable: true },
name: { type: "string", editable: false, nullable: true }
}
}
};
var dataSource = new kendo.data.TreeListDataSource({
transport: dataSourceTransport,
schema: schema,
batch: true
});
var idColumn: kendo.ui.TreeListColumn = <kendo.ui.TreeListColumn>{
field: "id",
width: "100px"
};
var nameColumn: kendo.ui.TreeListColumn = <kendo.ui.TreeListColumn>{
field: "name",
width: "400px"
};
this.testSuiteTreeKendoTreeListOptions.dataSource = dataSource;
this.testSuiteTreeKendoTreeListOptions.sortable = false;
this.testSuiteTreeKendoTreeListOptions.editable = false;
this.testSuiteTreeKendoTreeListOptions.columns = [
idColumn,
nameColumn
];
}
readRepository(e): any {
this.testManagementService.getTestSuitTree().then((result: Array<IGeneralTestSuitTestCaseContract>): void => {
e.success(result);
}, (reason: any): void => {
e.error(reason);
});
console.log('e', e);
return e;
}
}
angular
.module("goNoGo")
.controller("showTestSuitTreeController", ShowTestSuitTreeController);
}
The generated javascript:
var sayusiando;
(function (sayusiando) {
var gonogo;
(function (gonogo) {
var web;
(function (web) {
var spa;
(function (spa) {
var mainpage;
(function (mainpage) {
var showtestsuittree;
(function (showtestsuittree) {
var controllers;
(function (controllers) {
"use strict";
var ShowTestSuitTreeController = (function () {
function ShowTestSuitTreeController(testManagementService) {
this.testManagementService = testManagementService;
//#region Variables
this.testSuiteTree = [];
this.testSuiteTreeKendoTreeListOptions = {};
this.activate();
}
//#endregion
ShowTestSuitTreeController.prototype.activate = function () {
var _this = this;
var dataSourceTransport = {
//read: this.readRepository.bind(this)
read: function (e) { return _this.readRepository(e); }
};
var schema = {
model: {
id: "id",
parentId: "parentId",
fields: {
id: { type: "number", editable: false, nullable: true },
name: { type: "string", editable: false, nullable: true }
}
}
};
var dataSource = new kendo.data.TreeListDataSource({
transport: dataSourceTransport,
schema: schema,
batch: true
});
var idColumn = {
field: "id",
width: "100px"
};
var nameColumn = {
field: "name",
width: "400px"
};
this.testSuiteTreeKendoTreeListOptions.dataSource = dataSource;
this.testSuiteTreeKendoTreeListOptions.sortable = false;
this.testSuiteTreeKendoTreeListOptions.editable = false;
this.testSuiteTreeKendoTreeListOptions.columns = [
idColumn,
nameColumn
];
};
ShowTestSuitTreeController.prototype.readRepository = function (e) {
this.testManagementService.getTestSuitTree().then(function (result) {
e.success(result);
}, function (reason) {
e.error(reason);
});
console.log('e', e);
return e;
};
//#endregion
//#region Inject and ctor
ShowTestSuitTreeController.$inject = ['testManagementService'];
return ShowTestSuitTreeController;
}());
angular
.module("goNoGo")
.controller("showTestSuitTreeController", ShowTestSuitTreeController);
})(controllers = showtestsuittree.controllers || (showtestsuittree.controllers = {}));
})(showtestsuittree = mainpage.showtestsuittree || (mainpage.showtestsuittree = {}));
})(mainpage = spa.mainpage || (spa.mainpage = {}));
})(spa = web.spa || (web.spa = {}));
})(web = gonogo.web || (gonogo.web = {}));
})(gonogo = sayusiando.gonogo || (sayusiando.gonogo = {}));
})(sayusiando || (sayusiando = {}));
//# sourceMappingURL=showTestSuitTreeController.js.map
The javscript controller which works fine:
(function () {
'use strict';
angular
.module('goNoGo')
.controller('showTestSuitTreeController2', showTestSuitTreeController2);
showTestSuitTreeController2.$inject = ['testManagementService'];
function showTestSuitTreeController2(testManagementService) {
/* jshint validthis:true */
var vm = this;
activate();
function activate() {
vm.testSuiteTreeKendoTreeListOptions = {
dataSource: {
transport: {
read: getTestSuiteTree
},
schema: {
model: {
id: "id",
parentId: "parentId",
fields: {
Id: { type: "number", editable: false, nullable: false },
ParentId: { type: "number", editable: false, nullable: false },
Name: { type: "string", editable: false, nullable: false }
}
}
}
},
sortable: false,
editable: false,
columns: [
{ field: "id", width: "30px" },
{ field: "name", width: "300px" }
]
};
}
function getTestSuiteTree(e) {
testManagementService.getTestSuitTree().then(function (result) {
e.success(result.plain());
}, function (error) {
e.error(error);
});
console.log('e', e);
return e;
}
}
})();
The solution is that the plain() method of the result must be called. The result is provided by Restangular.

How to Populate Highchart using Json Object

I am trying to populate highchart from server side using json object.frankly speaking I have average knowledge of jquery and highchart. I am newbie in json, jquery and highchart.
I am able to receive the json object from server side but facing issue while populating highchart.
can any body help me with this.
my json object receive from server look like this
[Object { year=2001, populations=10000}, Object { year=2002, populations=20000}, Object { year=2003, populations=30000}, Object { year=2004, populations=40000}, Object { year=2005, populations=50000}, Object { year=2006, populations=60000}, Object { year=2007, populations=70000}]
my script to populate the highchart is
$(document).ready(function () {
$.ajax({
type: "GET",
url: 'dispatcherServlet/reportController/getreport',
dataType: "json",
contentType: "application/json",
crossDomain: true,
success: function (data) {
console.log(data);
var name = Array();
var value = Array();
var dataArrayFinal = Array();
for (i = 0; i < data.length; i++) {
name[i] = data[i].year;
value[i] = data[i].populations;
}
for (var j = 0; j < name.length; j++) {
var temp = new Array(name[j], value[j]);
dataArrayFinal[j] = temp;
}
// draw chart
$('#container').highcharts({
chart: {
type: "column"
},
title: {
text: "City Population"
},
xAxis: {
allowDecimals: false,
title: {
text: "Year"
}
},
yAxis: {
title: {
text: "Population",
data: value[i].year
}
},
series: [{
data: dataArrayFinal
}]
});
}
});
});
When I am simply passing my data receive from server to highchart series. I am getting balnk highchart.
The second script look like this
$(document).ready(function () {
$.ajax({
type: "GET",
url: '/dispatcherServlet/reportController/getreport',
dataType: "json",
contentType: "application/json",
crossDomain: true,
success: function (data) {
console.log(data);
for (var i = 0; i < data.length; i++) {
// alert(data[i].year);
// alert(data[i].populations);
// draw chart
$('#container').highcharts({
chart: {
type: "column"
},
title: {
text: "City Population"
},
xAxis: {
allowDecimals: false,
title: {
text: "Year"
}
},
yAxis: {
title: {
text: "Population",
}
},
series: [{
data: data
}]
});
}
}
});
});
Finally it worked
$(document).ready(function () {
$.ajax({
type: "GET",
url: '/dispatcherServlet/reportController/getreport',
dataType: "json",
contentType: "application/json",
crossDomain: true,
success: function (data) {
console.log(data);
// Populate series
var processed_json = new Array();
for (i = 0; i < data.length; i++) {
processed_json.push([data[i].year, parseInt(data[i].populations)]);
}
// draw chart
$('#container').highcharts({
chart: {
type: "column"
},
title: {
text: "City Population"
},
xAxis: {
allowDecimals: false,
title: {
text: "Year"
}
},
yAxis: {
title: {
text: "Population"
}
},
series: [{
data: processed_json
}]
});
}
});
});
[ { "year":2001, "populations":10000},
{ "year":2002,"populations":20000},
{ "year":2003, "populations":30000},
{ "year":2004, "populations":40000},
{ "year":2005, "populations":50000},
{ "year":2006, "populations":60000},
{ "year":2007, "populations":70000}
]
var title = prompt("Please enter Title of your Chart: ", "");
// var chart = $('#container').highcharts();
var x=new Array();
//var product = prompt("Please enter Column Name: ", "");
var stock = prompt("Please enter Y Axis Name: ", "");
//var name = prompt("Please enter Series Name: ", "");
$(function () {
var text="Stock Level";
var y=new Array();
var attr="";
var processed_json = new Array();
$.getJSON('data2.json', function(data) { //Getting data from JSON file
//var keys=new Array();
var obj=JSON.stringify(data[1]);
//alert(obj);
attr=JSON.stringify(obj.substring(2,obj.indexOf(":")-1))
//alert(JSON.stringify(obj.substring(2,obj.indexOf(":")-1)));
var attr1=attr.substring(1,attr.length-1);
//alert(attr1);
//alert(attr1);
$.each(data, function(key, value)
{
// var yName="Stock";
//var product="ProductId";
var idd=value[attr1];
//Getting Values of 1st Attribute that has to be represented along X-axis
x.push(idd);
//Getting Values of 2nd attribute that has to be represented along Y-axis
y.push(value.populations);
//$("ul").append("<li>"+value.ProductId+" "+value.Stocklevel+"<li>")
});
// draw chart
$('#container').highcharts({
chart: {
type: "column"
},
title: {
text: title
},
xAxis: {
categories: x, //Populating X-axis
type: 'category',
allowDecimals: false,
title: {
text: ""
}
},
yAxis: {
title: {
text: stock
}
},
series: [
{
name: name ,
data:y //Populating Y-axis
}
]
});
});
});

Categories

Resources