Kendo UI with Javascript Modular Pattern - javascript

I'm in the process of creating a big business application using kendo ui. Since application is big. we have started to follow modular patter in javascript code.
When using modular pattern wtih kendo ui. i'm getting some errors.
i have created hierarchy grid. Each grid code will be modular object. like below:
But i'm getting below error: (I have commented error lines like this //error. Please see below)
SCRIPT5007: Unable to get property 'find' of undefined or null reference.
Reason for error is "this" object is referred to window object. But it should refer kendo grid object.. how to resolve this
var Customer = (function ($,window) {
var gridCustomer = null;
var dataSource = null;
var createColumns = function () {
return [
{
field: "FirstName",
title: "First Name",
width: "110px"
},
{
field: "LastName",
title: "Last Name",
width: "110px"
},
{
field: "Country",
width: "110px"
},
{
field: "City",
width: "110px"
},
{
field: "Title"
}
]
};
var setDataSource = function () {
if (customerGridDataSource != undefined) {
return dataSource = new kendo.data.DataSource({
data: customerGridDataSource,
schema: {
data: function (response) {
return response;
},
total: function (response) {
return response.length;
},
model: {
id: "CustomerID",
fields: {
CustomerID: { editable: false, nullable: false, type: "int" },
FirstName: { editable: true, nullable: false, type: "string" },
LastName: { editable: true, nullable: true, type: "string" },
Country: { editable: true, nullable: true, type: "string" },
City: { editable: true, nullable: true, type: "string" },
Title: { editable: true, nullable: true, type: "string" }
}
}
},
pageSize: 5,
serverPaging: false,
serverSorting: false
});
}
else {
alert("Data Source undefined. Please Contact Administrator.")
}
};
var onDataBound = function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());//error
};
var init = function () {
gridCustomer = $("#gridCustomer").kendoGrid({
sortable: true,
filterable: true,
pageable: {
pageSize: 5,
pageSizes: true
},
columns: createColumns(),
dataSource: setDataSource(),
dataBound: onDataBound(),
detailInit: Order.Init()
});
};
return {
Init: function () {
init();
}
}
})(jQuery,window);
var Order = (function ($,window) {
var gridOrder = null;
var dataSource = null;
var createColumns = function () {
return [
{ field: "OrderID", width: "70px" },
{ field: "ShipCountry", title: "Ship Country", width: "110px" },
{ field: "ShipAddress", title: "Ship Address" },
{ field: "ShipName", title: "Ship Name", width: "200px" }
]
};
var setDataSource = function () {
if (customerGridDataSource != undefined) {
return dataSource = new kendo.data.DataSource({
data: customerGridDataSource,
schema: {
data: function (response) {
return response;
},
total: function (response) {
return response.length;
},
model: {
id: "CustomerID",
fields: {
OrderID: { editable: false, nullable: false, type: "int" },
ShipCountry: { editable: true, nullable: false, type: "string" },
ShipAddress: { editable: true, nullable: true, type: "string" },
ShipName: { editable: true, nullable: true, type: "string" }
}
}
},
pageSize: 5,
serverPaging: false,
serverSorting: false,
serverFiltering: false,
filter: { field: "CustomerID", operator: "eq", value: e.data.CustomerID }
});
}
else {
alert("Data Source undefined. Please Contact Administrator.")
}
};
var init = function (e) {
gridOrder = $("<div/>").appendTo(e.detailCell).kendoGrid({
scrollable: false,
sortable: true,
pageable: true,
columns: createColumns(),
dataSource: setDataSource()
});
};
return {
Init: function (e) {
init(e);
}
}
})(jQuery,window);
$(function () {
Customer.Init();
});

Kendo ui provides a parameter called e for dataBound event. e.sender is the grid. So your code should seems to this:
var onDataBound = function (e) {
var grid = e.sender;
grid.expandRow(grid.tbody.find("tr.k-master-row").first());
};
As I mention in comments: It seems the problem is with the dataBound: onDataBound(), because you should set the function onDataBound to the dataBound event not the result of execution onDataBound().The e is undefined because kendo executing the onDataBound() when it wants to set the initial value of dataBound event, not the time the dataBound event has occurred. replace dataBound: onDataBound() with dataBound: onDataBound and try again:
var init = function () {
gridCustomer = $("#gridCustomer").kendoGrid({
sortable: true,
filterable: true,
pageable: {
pageSize: 5,
pageSizes: true
},
columns: createColumns(),
dataSource: setDataSource(),
dataBound: onDataBound, //Not immediately execution
detailInit: Order.Init //Not immediately execution
});
};

You have to remove the parentheses at the end of onDataBound when you add the handler to the grid's configuration object (same with Order.Init), otherwise you're immediately executing the function instead of when the event is triggered:
gridCustomer = $("#gridCustomer").kendoGrid({
sortable: true,
filterable: true,
pageable: {
pageSize: 5,
pageSizes: true
},
columns: createColumns(),
dataSource: setDataSource(),
dataBound: onDataBound,
detailInit: Order.Init
});

Related

Kendo ui grid Fiter mode:row

I'm using filter column mode:row in my grid. For my numeric column the menu is showned as below
What i need is a filter in this column as the filter that is used in menu mode
Here is a part of my code
schema: {
data: "results",
total: "total",
model: {
id: "accountingTransactionKey",
fields: {
accountingTransactionKey: { editable: false, nullable: false },
date: { editable: false, nullable: false },
organization: { editable: false, nullable: false },
accountDebit: { editable: false, nullable: true },
costArticleUsed: { editable: false, nullable: true },
accountCredit: { editable: false, nullable: true },
isIntraGroupPartnerOrganization: { editable: false, nullable: true, type: "number" },
currency: { editable: false, nullable: true },
sum: { editable: false, nullable: true, type: "number"},...
...{
field: "sum",
title: "Сумма",
width: "150px",
//format: "{0:n2}",
locked: true,
filterable:
{
multi: true,
cell:
{
operator: "eq",
suggestionOperator: "eq",
showOperators: true
}
},
template: function (dataItem) { return numberWithSpaces(dataItem.sum.toFixed(2)) },
footerTemplate: "<b>" +"#: numberWithSpaces(sum.toFixed(2)) #"+"</b>"
},
There is a soltion for my request?
Thank you
I have tried the following script and it gives me a range filter by using the property extra.
<script>
$(document).ready(function() {
var griddata = createRandomData(50);
$("#grid").kendoGrid({
dataSource: {
data: griddata,
schema: {
model: {
fields: {
City: { type: "string" },
Title: { type: "string" },
BirthDate: { type: "date" },
Age: { type: "number" }
}
}
},
pageSize: 15
},
height: 550,
scrollable: true,
filterable: {
extra: false,
operators: {
string: {
startswith: "Starts with",
eq: "Is equal to",
neq: "Is not equal to"
}
}
},
pageable: true,
columns: [
{
title: "Name",
width: 160,
filterable: false,
template: "#=FirstName# #=LastName#"
},
{
field: "City",
width: 130,
filterable: false,
},
{
field: "Title",
filterable: false,
},
{
field: "BirthDate",
title: "Birth Date",
format: "{0:MM/dd/yyyy HH:mm tt}",
filterable: false,
},
{
field: "Age",
width: 100,
filterable:
{
extra: true
}
}
]
});
});
</script>
If you want to create a customized range filter.
columns: [
{
field: "Age",
filterable: {
cell: { template: betweenAgeFilter }
}
}
]
function betweenAgeFilter(args) {
var filterCell = args.element.parents(".k-filtercell");
filterCell.empty();
filterCell.html('<span style="justify-content:center;"> <span>From:</span><input id="startAge"/><span>To:</span><input id="endAge"/></span>');
$("#startAge").kendoNumericTextBox({
change: function (e) {
var startAge = e.sender.value();
var endAge = $("#endAge").data("kendoNumericTextBox").value();
var dataSource = $("#grid").data("kendoGrid").dataSource;
if (startAge & endAge) {
var filter = { logic: "and", filters: [] };
filter.filters.push({ field: "Age", operator: "gte", value: startAge });
filter.filters.push({ field: "Age", operator: "lte", value: endAge });
dataSource.filter(filter);
}
}
});
$("#endAge").kendoNumericTextBox({
change: function (e) {
var startAge = $("#startAge").data("kendoNumericTextBox").value();
var endAge = e.sender.value();
var dataSource = $("#grid").data("kendoGrid").dataSource;
if (startAge & endAge) {
var filter = { logic: "and", filters: [] };
filter.filters.push({ field: "Age", operator: "gte", value: startAge });
filter.filters.push({ field: "Age", operator: "lte", value: endAge });
dataSource.filter(filter);
}
}
});
}

Uncaught TypeError: e(...).parents(...).andSelf on Kendo UI Grid

I'm having problem with using Kendo UI Grid whenever I click on add new button it always produce this script error.
This is the code that I'm using:
dataSource = new kendo.data.DataSource({
batch: true,
pageSize: 20,
transport: {
read: {
url: 'SaladEntry/GetSupport2/',
dataType: "json"
},
destroy: {
url: 'SaladEntry/DeleteSupportKendo2/',
type: "POST",
contentType: 'application/json'
},
create: {
url: 'SaladEntry/SaveSupportKendo2/',
type: "POST",
contentType: 'application/json',
complete: function (e) {
SupportGrid();
}
},
update: {
url: 'SaladEntry/EditSupportKendo2/',
type: "POST",
contentType: 'application/json',
complete: function (e) {
SupportGrid();
}
},
parameterMap: function (options, operation) {
if (operation == "read") {
return saladparamObj;
}
else {
options.models[0].CountryNo = $('#Country_No').val();
var SaladParamSerialized = JSON.stringify(options.models);
return SaladParamSerialized;
}
}
},
schema: {
model: {
id: "PK",
fields: {
CountryNo: { editable: true, nullable: true },
EffectiveDate: { type: "date" },
stringEffectiveDate: { type: "string" },
ScaleMin: { validation: { required: true } },
ScaleMax: { validation: { required: true } },
Currency: { type: "string" }
}
}
},
sort: {
field: "stringEffectiveDate",
dir: "desc",
compare: function (a, b, dir) {
return kendo.parseDate(a.EffectiveDate) - kendo.parseDate(b.EffectiveDate);
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
height: 300,
toolbar: ["create"],
columns: [
{
field: "stringEffectiveDate", title: "Date",
template: "#= kendo.toString(kendo.parseDate(EffectiveDate, 'yyyy-MM-dd'), 'yyyy-MM-dd') #", width: "100px",
sortable: {
allowUnsort: false,
compare: function (a, b, dir) {
return kendo.parseDate(a.EffectiveDate) - kendo.parseDate(b.EffectiveDate);
}
}
},
{ field: "EffectiveDate", title: "Effective Date", template: "#= kendo.toString(kendo.parseDate(EffectiveDate, 'yyyy-MM-dd'), 'yyyy-MM-dd') #", width: "100px" },
{ field: "ScaleMin", title: "BG1 Min", width: "100px" },
{ field: "ScaleMax", title: "BG7 Max", width: "100px" },
{ field: "Currency", title: "Currency", width: "100px" },
{ command: ["edit", "destroy"], title: "Commands", width: "160px" }
],
height: 300,
scrollable: true,
sortable: true,
filterable: true,
pageable: true,
resizable: true,
selectable: true,
editable: "popup",
cancel: function (e) {
nEdit();
},
edit: function(e) {
e.container.find(".k-edit-label:first").hide();
e.container.find(".k-edit-field:first").hide();
if (!e.model.isNew()) {
var dt = e.container.find("input[name=EffectiveDate]").data("kendoDatePicker");
dt.enable(false);
}
}
}).css("background-color", "#C7D6A7");
No popup modal shown when I click on Add or Edit button. Below is the screenshot of my view.
.andSelf was removed in jQuery 3.0. You are referencing 3.1.1. You'll have to downgrade jQuery or find an update for Kendo.

How to get selected row and its dataItem in the KendoUI?

this is my Kendo Grid
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "/Actionables/GetAccessibleTemplateForAssets/",
data: { assetID: '#Model.AssetID', types: '#Model.TypeName' },
dataType:"Json",
type: "GET"
},
},
schema: {
model: {
id: "ID",
fields: {
ID: { type: "int" },
Name: { type: "string" },
Description: { type: "string" },
Types: { type: "string" },
EntryGroupID: {type:"int"}
}
}
},
pageSize: 3,
});
$("#grid").kendoGrid({
dataSource: dataSource,
dataBound: onDataBound,
autoSync: true,
serverPaging: true,
serverSorting: true,
serverFiltering: true,
height: 250,
sortable: true,
filterable: {
mode: "row"
},
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
columns:
[{
field: "Types",
width: 100,
title: "Type",
template: "<image src='/Content/Images/Pins/#:data.Types#.png'/>",
filterable: false
},{
field: "Name",
width: 150,
title: "Name",
filterable: {
cell: {
operator: "contains"
}
}
}, {
field: "Description",
width: 150,
title: "Description",
filterable: {
cell: {
operator: "contains"
}
}
},{
command: [
{ name: "remove", text: " ", click: removeTab, iconClass: "fa fa-trash" },
{ name:"view", text: " ", click: addTab , iconClass: "fa fa-plus-circle"}],
title: "Action",
width: 100,
}],
editable: {
mode:"popup"
},
}).data("kendoGrid");
wnd = $("#details").kendoWindow({
title: "View Tab",
modal: true,
visible: false,
resizable: false,
width: 300
}).data("kendoWindow");
detailsTemplate = kendo.template($("#ViewDetails").html());
this will get called when user clicked '+' sign in command column. it opens a popup window.
function addTab(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
wnd.content(detailsTemplate(dataItem));
wnd.center().open();
}
the popup window contains two button, on that button click event OpenRecentlyClosed() function will get called.
<script type="text/x-kendo-template" id="ViewDetails">
<div id="details-container">
<button id="oldEntryGroup" class="k-button" onclick="OpenRecentlyClosed()">Open recently closed</button>
<br /><br />
<button id="NewEntryGroup" class="k-button">Open new</button>
</div>
the below function I'm trying to access dataItem of clicked/selected row. please help. thank you in advance
function OpenRecentlyClosed() {
//trying to access dataItem here.. please help
//var grid = $("#grid").data("kendoGrid");
//var dataItem = grid.dataItem(grid.select());
$.ajax({
cache: false,
type: "GET",
url: "some url",
data: {x: dataItem.ID},// need to pass value of dataItem.ID
success: function () {
//my code
}
});
}
Event to capture row click and get data from that row:
$(document).on("click", "#grid tbody tr", function (e) {
var element = e.target || e.srcElement;
var data = $("#grid").data("kendoGrid").dataItem($(element).closest("tr"));
});
I think you need to keep a reference to the selected dataItem in your javacript function addTab.
function addTab(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
wnd.selectedDataItem = dataItem;
wnd.content(detailsTemplate(dataItem));
wnd.center().open();
}
Then in OpenRecentlyClosed you could access the dataItem.
function OpenRecentlyClosed() {
var dataItem = wnd.selectedDataItem;
$.ajax({
cache: false,
type: "GET",
url: "some url",
data: {x: dataItem.ID},// need to pass value of dataItem.ID
success: function () {
//my code
}
});
}
Please try with the below code snippet.
function OpenRecentlyClosed() {
var grid = $("#grid").data("kendoGrid");
var selectedRows = grid.select();
selectedRows.each(function(index, row) {
var selectedItem = grid.dataItem(row);
alert(selectedItem.ID);
});
...
...
}
Let me know if any concern.
Note: grid.dataItem(row) will just get what's in the row. If you have a database and really want the dataItem and maybe some items in another dataset that are in some relationship with your item, you can do e.g. an AjaxCall.

Kendo grid expand row not working correctly

I have a Kendo grid which is populated from a SQL database. The kendo expand works fine and returns a different kendo grid in the expand when the program first starts but if I do a new search and return different results the expand row does not work.
My code for the expand ->
function detailInitd(e) {
TextvalueFile = "manno test";
$.ajax({
type: "post",
data: JSON.stringify({
search_string: TextvalueFile,
}),
url: "/Search.aspx/File_Search",
dataType: "json",
contentType: 'application/json',
success: function (object) {
response(object);
},
complete: function (object) {
},
error: function (object) {
}
});
function response(object) {
var grid = this;
$("<div/>").appendTo(e.detailCell).kendoGrid({
dataSource: {
data: object.d,
schema: {
model: {
path: { type: "string" },
st_size: { type: "number" },
},
},
pageSize: 20,
},
reorderable: true,
resizable: true,
navigatable: true,
selectable: "multiple",
scrollable: true,
sortable: true,
filterable: true,
columnMenu: true,
pageable: {
input: true,
numeric: true
},
columns: [
{ field: "path", title: "Path", width: 200 },
{ field: "st_size", title: "Size", width: 60 },
{ field: "st_blks", title: "BLKS", width: 60 },
{ field: "st_acctime", title: "acc Time", width: 70 },
{ field: "st_modtime", title: "mod Time", width: 75 },
]
});
}
};
My code for the original kendo grid ->
function DisplaySearch() {
}
textS.value = value;
valsearch = textS;
$.ajax({
type: "post",
data: JSON.stringify({
search_string: valsearch,
}),
url: "/Search.aspx/display_search",
dataType: "json",
contentType: 'application/json',
success: function (object) {
response(object);
},
complete: function (object) {
},
error: function (object) {
}
});
function response(object) {
$("#searchGrid").kendoGrid({
theme:"Default",
dataSource: {
data: object.d,
schema: {
model: {
archive_header_key: { type: "number" },
group_Name: { type: "string" },
Server: { type: "string" },
archive: { type: "string" },
display_name: { type: "string" },
file_written: { type: "number" },
session_ID: { type: "string" },
create_browse: {type:"number"},
},
},
pageSize: 20,
},
detailInit: detailInit,
dataBound: function () {
this.expandRow(this.tbody.find("tr"));
},
reorderable: true,
navigatable: true,
selectable: "single",
scrollable: true,
sortable: true,
filterable: false,
columnMenu: true,
reordable: true,
resizable: true,
pageable: {
input: true,
numeric: true,
},
columns: [
{ field: "archive_header_key", title: "Key", width: 50 },
{ field: "Server", title: "Server", width: 75 },
{ field: "group_Name", title: "Group", width: 75 },
{ field: "archive", title: "Archive", width: 50 },
{ field: "display_name", title: "Display name", width: 300 },
{ field: "file_written", title: "Files", width: 50 },
{ field: "session_ID", title: "Session", width: 200 },
{field: "create_browse", title:"Browse", Width: 50},
],
change: function(){
var grid = this;
grid.select().each(function(){
var dataItem = grid.dataItem($(this));
testdata = dataItem.archive_header_key;
grid.expandRow(grid.element.closest("tr"));
})
},
dataBound: function () {
this.expandRow();
},
});
}
Any help would be appreciated.
There is some sample code to check if a kendoGrid is already initialized:
https://www.telerik.com/forums/grid-creation-best-practices
It works for me and fixed the expandRow issue.
function searchButtonClick() {
var gridElement = $("#grid"),
grid = gridElement.data("kendoGrid");
if (!grid) {
gridElement.kendoGrid({
...
});
} else {
grid.dataSource.read();
}
}
I think this is duplicated instances. When you are searching, and call your response() you instanciate always an kendoGrid probably, you have to do something like:
Declare an variable out of response() like:
var $searchGrid = null;
And change your response() :
function response(object) {
if($searchGrid){
$searchGrid .destroy();
$("#searchGrid").empty();
$("#searchGrid").remove();
}
$("#searchGrid").kendoGrid({
theme:"Default",
dataSource: {
data: object.d,
schema: {
model: {
archive_header_key: { type: "number" },
group_Name: { type: "string" },
Server: { type: "string" },
archive: { type: "string" },
display_name: { type: "string" },
file_written: { type: "number" },
session_ID: { type: "string" },
create_browse: {type:"number"},
},
},
pageSize: 20,
},
detailInit: detailInit,
dataBound: function () {
this.expandRow(this.tbody.find("tr"));
},
reorderable: true,
navigatable: true,
selectable: "single",
scrollable: true,
sortable: true,
filterable: false,
columnMenu: true,
reordable: true,
resizable: true,
pageable: {
input: true,
numeric: true,
},
columns: [
{ field: "archive_header_key", title: "Key", width: 50 },
{ field: "Server", title: "Server", width: 75 },
{ field: "group_Name", title: "Group", width: 75 },
{ field: "archive", title: "Archive", width: 50 },
{ field: "display_name", title: "Display name", width: 300 },
{ field: "file_written", title: "Files", width: 50 },
{ field: "session_ID", title: "Session", width: 200 },
{field: "create_browse", title:"Browse", Width: 50},
],
change: function(){
var grid = this;
grid.select().each(function(){
var dataItem = grid.dataItem($(this));
testdata = dataItem.archive_header_key;
grid.expandRow(grid.element.closest("tr"));
})
},
dataBound: function () {
this.expandRow();
},
}).data("kendoGrid");;
}
Hope this help

How to use date type field in kendo ui Javascript in MVC

I am create one sample application and use kendo-ui inline editing grid.
Problem is: not come date field value in action controller.
View page Code is:
<script type="text/javascript">
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: {
type: "json",
transport: {
read: {
url: "#Html.Raw(Url.Action("CriticalDateList", "Home"))",
type: "POST",
dataType: "json"
},
create: {
url: "#Html.Raw(Url.Action("InsertCriticalDate", "Home"))",
type: 'POST',
dataType: "json"
},
},
change: function (e) {
if (e.action == "itemchange") {
e.items[0].dirtyFields = e.items[0].dirtyFields || {};
e.items[0].dirtyFields[e.field] = true;
}
},
batch: true,
schema: {
data: "Data",
total: "Total",
errors: "Errors",
model: {
id:"Id",
fields: {
Id: { editable: false},
Date: { editable: true, type: "date" },
}
}
},
error: function (e) {
//display_kendoui_grid_error(e);
this.cancelChanges();
},
pageSize:5,
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
pageable: true,
height: 500,
toolbar: ["create"],
columns: [
{field: "Date", title: "Date", format: "{0:dd-MMM-yyyy hh:mm:ss tt}", parseFormats: ["yyyy-MM-dd'T'HH:mm:ss.zz"], width: "130px"},
{ command: ["edit", "destroy"], title: "Action", width: "250px" }],
editable: "inline"
});
Action Code is:
public ActionResult InsertCriticalDate(CriticalDateModels model)
{
return null;
}
output is.
And in my action i am getting different date.

Categories