After following the solution in a previous post, I have found that the jqGrid refresh after add/edit with the inlineNav using the successfunc does not work if extraparams is present.
Here's my code:
var editOptions = {
keys: true,
successfunc: function () {
alert('success');
var $self = $(this);
setTimeout(function () {
alert('refreshing');
$self.setGridParam({ datatype: 'json' });
$self.trigger("reloadGrid");
}, 500);
}
.jqGrid('inlineNav', {
addParams: {
useDefValues: true,
addRowParams:
{
editOptions,
extraparam: {
userId: function () {
return currentUserId;
},
companyId: function () {
return currentCompanyId;
}
}
}
},
editParams: {
editOptions
}
I have tried different combinations of where the editOptions is placed, but no luck.
You placed extraparam in the wrong place. It should be the property of editOptions.
UPDATED:
var reloadGridFunc = function () {
alert('success');
var $self = $(this);
setTimeout(function () {
alert('refreshing');
$self.setGridParam({ datatype: 'json' });
$self.trigger("reloadGrid");
}, 500);
};
.jqGrid('inlineNav', {
addParams: {
useDefValues: true,
addRowParams: {
// here are editOption used for Add
keys: true,
successfunc: reloadGridFunc,
extraparam: {
userId: function () {
return currentUserId;
},
companyId: function () {
return currentCompanyId;
}
}
}
},
editParams: {
// here are editOption used for Edit
keys: true,
successfunc: reloadGridFunc
}
});
Ok - I found what I was doing wrong. It was actually in both parts of my code above. First, I changed:
function successFunc() {
var $self = $(this);
setTimeout(function () {
$self.setGridParam({ datatype: 'json' });
$self.trigger("reloadGrid");
}, 500);}
I got rid of the var editOptions, which included the keys and successfunc parameters inside it. This apparently was conflicting with the successfunc call in the addParams part of the inlineNav method. So here's what the parameters section looks like now:
.jqGrid('inlineNav', {
addParams: {
addRowParams:
{
keys: true,
extraparam:
{ userId: currentUserId,
companyId: currentCompanyId
},
successfunc: successFunc
}
},
editParams: {
successfunc: successFunc
}
});
So now when I either add or edit an inline record, the refresh happens when the successfunc is called. Hope this helps someone else in the future. Thanks #Oleg for the initial help with this.
Related
for my kendo treeview, i set load on demand to true but it is not hitting the server to load childs, because the 'children' property is set for the datasource model, even its empty.
homogeneous = new kendo.data.HierarchicalDataSource({
transport: {
read: {
type: 'POST',
contentType: "application/json; charset=utf-8",
url: obj.DataSourcesURL,
dataType: "json"
},
parameterMap: function (options) {
if (!options.Id) {
options.Id = null;
}
if (options.filter) {
options.Search = options.filter.filters[0].name;
}
else {
options.Search = '';
}
return JSON.stringify(options);
}
},
schema: {
data: "d",
errors: function (response) {
console.log(response);
console.log("errors");
},
model: {
hasChildren: "hasChild",
children:'items',
id: "Id"
}
}
});
And treeView code is
$treeView.kendoTreeView({
dataTextField: 'Description',
checkboxes: {
checkChildren: true
},
dataSource: homogeneous,
loadOnDemand: loadOnDemand,
check: function () {
var checkedNodes = [];
var treeView = $treeView.data("kendoTreeView");
getCheckedNodes(treeView.dataSource.view(), checkedNodes);
setMessage(checkedNodes.length);
},
dataBound: function (e) {
if (e !== undefined)
resetCheckedNodes(e.sender.dataItems());
},
messages: {
loading: "Laden..."
},
expand: function (e) {
var dataItem = this.dataItem(e.node);
}
});
Try to set hasChildren like this in your schema:
schema: {
data: "d",
errors: function (response) {
console.log(response);
console.log("errors");
},
model: {
hasChildren: function(e) {
return e.items && e.items.length;
},
children:'items',
id: "Id"
}
}
And also from your question I am not sure do you even get any data or it is only Children data that is not returned. Maybe you could also show how your data structure look like.
I need to setup my datasource to use localForage to manage my offline data storage.
The problem I'm having is that localForage is asynchronous by nature, only allowing us to use a callback or a promise to retrieve data.
This is how my code is set-up:
(function () {
'use strict';
var serviceId = 'employeeDataSource';
angular.module('app').factory(serviceId, function () {
var crudServiceBaseUrl = 'Data/Employees';
var dataSource = new kendo.data.DataSource({
type: "odata",
offlineStorage: {
getItem: function () {
localforage.getItem('employees-key').then(function (value) {
console.log(value);
return JSON.parse(value);
});
},
setItem: function (item) {
if (item.length > 0) {
localforage.setItem("employees-key", JSON.stringify(item));
}
}
},
transport: {
read: {
url: crudServiceBaseUrl + "/",
dataType: "json"
},
update: {
url: function (data) {
return crudServiceBaseUrl + "(guid'" + data.EmployeeId + "')";
}
},
create: {
url: crudServiceBaseUrl
},
destroy: {
url: function (data) {
return crudServiceBaseUrl + "(guid'" + data.EmployeeId + "')";
}
}
},
batch: false,
pageSize: 5,
serverPaging: true,
schema: {
data: function (data) {
return data.value;
},
total: function (data) {
return data['odata.count'];
},
model: {
id: "EmployeeId",
fields: {
EmployeeId: { editable: false, nullable: true },
Name: { validation: { required: true } },
Email: { validation: { required: true } },
IsManager: { type: "boolean" },
MaxHolidaysPerYear: { editable: false, type: "number", validation: { min: 0, required: true } },
HolidaysLeftThisYear: { type: "number", validation: { min: 0, required: true } }
}
}
},
error: function (e) {
if (e.xhr.responseText !== undefined) {
console.log(e.xhr.responseText);
}
}
});
dataSource.online(navigator.onLine);
$(window).on("offline", function () {
dataSource.online(false);
});
$(window).on("online", function () {
dataSource.online(true);
});
return dataSource;
});
})();
When off-line, the getItem gets called, then the setItem gets call as well with an empty array, hence the:
if (item.length > 0) {
localforage.setItem("employees-key", JSON.stringify(item));
}
When the promise finally returns the off-line data (with the correct values I expected), the Grid displays no results.
This behaviour is presumably because of the promise ?
I tried the same thing with sessionStorage and its worked perfectly... i.e.:
getItem: function () {
return JSON.parse(sessionStorage.getItem("employees-key"));
},
setItem: function (item) {
sessionStorage.setItem("employees-key", JSON.stringify(item));
}
What can I do to get around this?
Just got a heads-up from Telerik
There is an issue logged in their GitHub repo about the same problem.
You can keep track on the progress here:
https://github.com/telerik/kendo-ui-core/issues/326
I load a complex treeview with kendo ui via ajax because I need to load the tree with one request (works fine):
$(document).ready(function() {
buildTree();
});
function buildTree(){
$.getJSON("admin_get_treedata.php", function (data) {
$("#treeview").kendoTreeView({
select: function(item) { editTreeElement(item,'tree'); },
dataSource: data
});
})
}
If I try to reload the complete tree after changing some data via ajax the new build tree does not work correct and does not update the text.
$.ajax({
type: 'POST',
url: 'ajax/ajax_update_layer.php',
data: {
layerid:id,
...
},
success: function(data){
buildTree();
}
});
What can Ido?
Thanks
Sven
try this on ajax success callback
var data = $("#treeView").data('kendoTreeView');
data.dataSource.read();
I got mine to work.
This is what I did:
Function that creates the tree view:
function CreateNotificationTree(userId)
{
var data = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: "../api/notifications/byuserid/" + userId,
contentType: "application/json"
}
},
schema: {
model: {
children: "notifications"
}
}
});
$("#treeview").kendoTreeView({
dataSource: data,
loadOnDemand: true,
dataUrlField: "LinksTo",
checkboxes: {
checkChildren: true
},
dataTextField: ["notificationType", "NotificationDesc"],
select: treeviewSelect
});
function treeviewSelect(e)
{
var $item = this.dataItem(e.node);
window.open($item.NotificationLink, "_self");
}
}
Modification & data source refresh:
$('#btnDelete').on('click', function()
{
var treeView = $("#treeview").data("kendoTreeView");
var userId = $('#user_id').val();
$('#treeview').find('input:checkbox:checked').each(function()
{
var li = $(this).closest(".k-item")[0];
var notificationId = treeView.dataSource.getByUid(li.getAttribute('data-uid')).ID;
if (notificationId == "undefined")
{
alert('No ID was found for one or more notifications selected. These notifications will not be deleted. Please contact IT about this issue.');
}
else
{
$.ajax(
{
url: '../api/notifications/deleteNotification?userId=' + userId + '¬ificationId=' + notificationId,
type: 'DELETE',
success: function()
{
CreateNotificationTree(userId);
alert('Delete successful.');
},
failure: function()
{
alert('Delete failed.');
}
});
treeView.remove($(this).closest('.k-item'));
}
});
});
Hope that helps.
I have built a jquery dialog to show a partial view for entering data.
I have built the action link:
#Html.ActionLink("Add New Service Provider", "PartialNewCust", "Customer", null, new { #class = "addServiceProviderLink" })
I have the controller action:
public ActionResult PartialNewCust()
{
return PartialView();
}
And the div / jQuery code:
<div id="AddServiceProvDialog" title="Add Service Provider"></div>
<script type="text/javascript">
var linkObj;
$(function () {
$(".addServiceProviderLink").button();
$('#AddServiceProvDialog').dialog(
{
autoOpen: false,
width: 400,
resizable: false,
modal: true,
buttons:
{
"Add": function () {
$("#addProviderForm").submit();
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
$(".addServiceProviderLink").click(function () {
linkObj = $(this);
var dialogDiv = $('#AddServiceProvDialog');
var viewUrl = linkObj.attr('href');
$.get(viewUrl, function (data) {
dialogDiv.html(data);
//validation
var $form = $("#addProviderForm");
// Unbind existing validation
$form.unbind();
$form.data("validator", null);
// Check document for changes
$.validator.unobtrusive.parse(document);
// Re add validation with changes
$form.validate($form.data("unobtrusiveValidation").options);
//open dialog
dialogDiv.dialog('open');
return false;
});
});
});
The partial view renders fine but opens a new page and does not come up as a modal dialog.
What am I doing wrong.
On a side note: my autocomplete code is also not working by my jQuery datetime picker is...
$(document).ready(function()
{
$(".date").datepicker();
}
);
$(document).ready(function () {
$("#CustByName").autocomplete(
{
source: function (request, response) {
$.ajax(
{
url: "/Cases/FindByName", type: "GET", dataType: "json",
data: { searchText: request.term, maxResults: 10 },
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data, function (item) {
return {
label: item.CustomerName,
value: item.CustomerName,
id: item.CustomerID
}
})
);
}
});
},
minLength: 3
});
});
My guess is that you misplaced the return false statement in the button's click handler, thus the default behavior is not prevented as you expect, and the link is simply followed:
$(".addServiceProviderLink").click(function () {
...
$.get(viewUrl, function (data) {
dialogDiv.html(data);
...
dialogDiv.dialog('open');
// this return statement should be in the "click" handler,
// not in success callback of the .get() method !
return false;
});
});
Your code should then be:
$(".addServiceProviderLink").click(function () {
...
$.get(viewUrl, function (data) {
...
});
// return here to prevent default click behavior
return false;
});
I'm not able to see any parameters value passing to server in firebug. Here is the code.
//BuyBackGridInit() start
function BuyBackGridInit(tabID){
$('table[id$="'+tabID+'_BuyBackGrid"]').jqGrid({
url :'/Controls/Advertiser/BuyBackControlNew.ascx.ashx?action=getBuyBackData',
datatype: 'json',
mtype: 'POST',
height:'100%',
width:'100%',
colNames: result.colNamesData,
colModel: result.colModelData,
postData: {
advertiserID: function() { return $('#advertiser_id').text(); },
CampaignsDdlSelectedValue: function() { return $('select[id$="CampaignDdl"] option:selected').val(); },
startDate: function() { return $('input[id$="'+tabID+'_FromCalBuyBack_CalendarTbx"] ').val(); },
endDate: function() { return $('input[id$="'+tabID+'_ToCalBuyBack_CalendarTbx"] ').val(); }
},
rowNum : 100,
shrinkToFit :false,
altRows: true,
altclass:'altRow',
autowidth: true,
multiselect: true,
gridComplete:function (){
var recs = parseInt( $('table[id$="'+tabID+'_BuyBackGrid"]').getGridParam("records"),10);
if (recs == 0){
$('div[id$="'+tabID+'_NoDataFoundBuyBackdiv"]').show();
$('input[id$="AddToCartBtn"]').hide();
$('input[id$="BuyBackDownloadBtn"]').hide();
}
else {
$('div[id$="'+tabID+'_NoDataFoundBuyBackdiv"]').hide();
$('input[id$="AddToCartBtn"]').show();
$('input[id$="BuyBackDownloadBtn"]').show();
}
},
serializeGridData: function (data){
return $.toJSON(data);
}
});//end of jQuery("#BuyBackGrid").jqGrid()
}//BuyBackGridInit() End
Thanks,
A
You current implementation of serializeGridData just remove all functions parameters from the postData. So you should either extend data parameter inside of serializeGridData instead of the usage of postData. Another way is to modify serializeGridData to the following:
serializeGridData: function (data){
var propertyName, propertyValue, dataToSend = {};
for (propertyName in data) {
if (data.hasOwnProperty(propertyName)) {
propertyValue = data[propertyName];
if ($.isFunction(propertyValue)) {
dataToSend[propertyName] = propertyValue();
} else {
dataToSend[propertyName] = propertyValue
}
}
}
return JSON.stringify(dataToSend);
}
In the code above we enumerate all properties and call all functions explicitly. Moreover I prefer to use JSON.stringify function from json2.js. The function will be native implemented in many web browsers.
See the demo here.