First sorry for my bad english.
I am trying to create button in my datatable. The button for delete data in that row. Delete function works. The problem is after the delete, my Datatable did not refresh the content (Only when I refresh the page, the content refreshed).
I already try some suggestion in other's stackoverflow.
My datatble id = "data'
var data as global variable.
This is my JavaScript Code (inside document.ready) :
var temp = $('#data').DataTable
({
"columns":
[
null, null, null, null,
null, null, null,
{"width": "17%"}
]
});
table = JSON.parse('"' + temp + '"');
This is my code for button function
function delete(kode) {
var x = confirm("Do you want to delete this data?");
if (x == true)
{
jQuery.ajax({
type : "POST",
url : "***"
dataType : 'json',
success : function()
{
table.ajax.reload();
alert("delete success");
},
error : function()
{
table.ajax.reload();
alert("delete fail");
}
});
} }
Error in console :
Uncaught Type-error: Cannot read property 'ajax' of undefined
at Object.error (hotel:191)
at u (VM226 jquery.js:2)
at Object.fireWith [as rejectWith] (VM226 jquery.js:2)
at k (VM226 jquery.js:2)
at XMLHttpRequest. (VM226 jquery.js:2)
You need to write below in ajax success. It will retrieve or refresh all the data of it.
var $lmTable = $("#data").dataTable({bRetrieve: true});
$lmTable.fnDraw();
Related
I have a DataTable which is able to successfully fetches AJAX data once while initialising the table.Now I need to be able to "refetch" the AJAX data to update the DataTable, but without re-initialising the table.
After some research I found out I need to use the following line "as a function":
ajax.data( data, settings )
Explained here: http://datatables.net/reference/option/ajax.data
However. I cannot find how to use this "as a function". It has not one example on the page.
I tried it as follows.My original DataTable creation:
launch_datatable_ajax = function(){
get_ajax_data();
dyn_t = $('#dynamic_table').DataTable({
"ajax": {
"url":ajax_url,
"data":data,
"dataSrc":""
},
"columns": [
{ "data" : "ID" },
{ "data" : "post_title" },
{ "data" : "supplier_company" },
{ "data" : "img_src" },
{ "data" : "tags" },
{ "data" : "post_meta" },
],
});
}
Then I tried to reload the Data with new parameters. Here's where I'm stuck.
dyn_t.ajax.data(data,dyn_t.settings);
I think I'm correct for the parameters:
dyn_t.settings gives some info on: console.log(dyn_t.settings);
'data' gives my object (the get variables) on: console.log(data);
But console.log says:
Uncaught TypeError: dyn_t.ajax.data is not a function(…)
Reloading can be done with dyn_t.ajax.reload();.
However your requirement is to send updated URL parameters to the server also.
To do this, you need to use the function argument for ajax: http://datatables.net/reference/option/ajax#function
The function re-validates in every ajax.reload() call. This is why the new params will be sent. So assuming you have an HTML form with id my-form, try something like this:
ajax: function ( data, callback, settings ) {
$.ajax({
url: "ajax_url?" + $("my-form").serialize(),
data: { start: data.start, count: data.length }
});
},
The problem is very simple: i have to download a file when i submit a form, it's an ajax call when the form is submitted which lets me build a file with the data taken from the form, server side, and then send it as a link to an alert. The fact is that my boss want the file to be downloaded directly and not through a link in an alert. So i had to make sure that the file is available server side through tornado(web):
self.set_header('Content-Type', 'application/octet-stream')
self.set_header('Content-Disposition', 'attachment; filename=clients_counter.zip')
with open("static/clients_counter.zip", 'r') as f:
while True:
data = f.read()
if not data:
break
self.write(data)
self.finish()
The server side code seems to work fine, but the client side (extjs4.1) is really a nightmare. This is how my ajax call looks like now, and it doesn't work:
Ext.Ajax.request({
method : "GET",
url : 'http://whatever.com/count?client='+client+'&start='+start+'&end='+end,
timeout : 30000,
success :
function (response) {
//Ext.Msg.alert(response.responseText);
desktop.getWindow('count-win').doClose();
return response;
}//handler,
failure :
function(response) {
alert("Wrong request");
}});
After reading on various sources from Ext JS forum and here in stackoverflow, below is the approach I've chosen (using Ext JS version 4.2.1):
downloadFile: function(config){
config = config || {};
var url = config.url,
method = config.method || 'POST',// Either GET or POST. Default is POST.
params = config.params || {};
// Create form panel. It contains a basic form that we need for the file download.
var form = Ext.create('Ext.form.Panel', {
standardSubmit: true,
url: url,
method: method
});
// Call the submit to begin the file download.
form.submit({
target: '_blank', // Avoids leaving the page.
params: params
});
// Clean-up the form after 100 milliseconds.
// Once the submit is called, the browser does not care anymore with the form object.
Ext.defer(function(){
form.close();
}, 100);
}
I had a similar problem trying to download an Excel File in an Ajax call I solved it this way:
Make a standard sumbit instead of Ajax.
var form = Ext.create('Ext.form.Panel', { // this wolud be your form
standardSubmit: true, // this is the important part
url: '../ObtenerArchivoAdjuntoServlet'
});
form.submit({
params: {
nombreArchivo: nombreArchivo
}
});
After this you would be able return the desired file.
After extracting/reading many posts, I managed to get this simple method to work..
Ext.create('Ext.form.Panel', {
renderTo: Ext.getBody(),
standardSubmit: true,
url: 'URL'
}).submit({params: {'PARAM1': param1, 'PARAM2': param2}});
I think you can take a much easier solution. Forget about the ajax, and just get plain old js to open the file for you:
window.open('http://whatever.com/count?client='+client+'&start='+start+'&end='+end)
This will open a new tab and start the download from there.
The following code used to download the file using extjs 5 or 6. Add the following code to method and invoke this for button action. This downloads the file directly insteadof opening in new tab.
use an iframe like this:
/**
* prints the file
*/
printReport: function () {
var url = 'downloadURL';
Ext.Ajax.request({
url: url,
method: 'GET',
autoAbort: false,
success: function(result) {
if(result.status == 204) {
Ext.Msg.alert('Empty Report', 'There is no data');
} else if(result.status == 200) {
Ext.DomHelper.append(Ext.getBody(), {
tag: 'iframe',
frameBorder: 0,
width: 0,
height: 0,
css: 'display:none;visibility:hidden;height:0px;',
src: url
});
}
},
failure: function() {
//failure here will automatically
//log the user out as it should
}
});
}
Copied the answer from extjs forum
Option:2
If you want to open the file in new tab
/**
* open file in tab
*/
openReport: function () {
var url = 'downloadURL';
Ext.Ajax.request({
url: url,
method: 'GET',
autoAbort: false,
success: function(result) {
if(result.status == 204) {
Ext.Msg.alert('Empty Report', 'There is no data');
} else if(result.status == 200) {
var win = window.open('', '_blank');
win.location = url;
win.focus();
}
},
failure: function() {
//failure here will automatically
//log the user out as it should
}
});
}
You cannot use ajax to download file. I've implemented file downloading in extjs which is like ajax. see the blog ajaxlikefiledownload.
FileDownload.downloadFile = function(arguments) {
var url = arguments['url'];
var params = arguments['params'];
var successCallback = arguments['success'];
var failureCallback = arguments['failure'];
var body = Ext.getBody();
var frame = body.createChild({
tag:'iframe',
cls:'x-hidden',
id:'hiddenframe-frame',
name:'iframe'
});
var form = body.createChild({
tag:'form',
cls:'x-hidden',
id:'hiddenform-form',
action: url,
method: 'POST',
target:'iframe'
});
if (params) {
for (var paramName in params) {
form.createChild({
tag:'input',
cls:'x-hidden',
id:'hiddenform-'+paramName,
type: 'text',
text: params[paramName],
target:'iframe',
value: params[paramName],
name: paramName
});
}
}
form.dom.submit();
FileDownload.isFinished(successCallback,failureCallback);
};
FileDownload.isFinished = function(successCallback,failureCallback) {
//Check if file is started downloading
if (Ext.util.Cookies.get('fileDownload') && Ext.util.Cookies.get('fileDownload')=='true' ) {
//Remove cookie call success callback
Ext.util.Cookies.set('fileDownload', null, new Date("January 1, 1970"),application.contextPath+'/');
Ext.util.Cookies.clear('fileDownload',application.contextPath+'/');
successCallback();
return;
}
//Check for error / IF any error happens then frame will load with content
try {
if(Ext.getDom('hiddenframe-frame').contentDocument.body.innerHTML.length>0){
Ext.util.Cookies.set('fileDownload', null, new Date("January 1, 1970"),application.contextPath+'/');
Ext.util.Cookies.clear('fileDownload',application.contextPath+'/');
failureCallback();
//Cleanup
Ext.getDom('hiddenframe-frame').contentDocument.body.innerHTML = "";
return;
}
}
catch (e) {
console.log(e);
}
console.log('polling..');
// If we are here, it is not loaded. Set things up so we check the status again in 100 milliseconds
window.setTimeout('FileDownload.isFinished('+successCallback+','+failureCallback+')', 100);
};
Usage :
FileDownload.downloadFile({
url : url,
params : params,
success : function(){
//Success call back here
},
failure : function(){
//Failure callbak here
}
});
In the http response you need to add a cookie nammed fileDownload = true
I just had to ad to the success function of the ajax request:
window.open('urltothefile.ext')
I am looking to call an ajax function inside the Datatables mRender function that will use an id from the present ajax source to get data from a different ajax source.
To put this into perspective, I have:
A listing of requisitions from different clients in one Datatable.
In this listing I have a client id. I want to get the client Name to be shown on the table instead of the client Id. However the Client Name and other client details are in the clients table hence these details are not in the requisitions json data. But I have the Client Id.
How do I use this to get client name inside the mrender function? E.g
{"sTitle":"Client","mData":null,
"mRender":function(data){
//ajax function
}
},
Thank you in advance,
Regards.
I don't believe this is how you are supposed to deal with your data. However I also use an AJAX data source in my mRender function as stated below.
$(document).ready(function(e){
$('.products').dataTable({
"bProcessing": true,
"sAjaxSource": window.location.protocol + "//" + window.location.hostname + '/product/getAll',
"aoColumns": [
{ "sTitle": "Pid", "bVisible" : false},
{ "sTitle": "Pname" },
{ "sTitle": "Pprice" },
{ "sTitle": "Pgroups",
"mRender" : function( data, type, full ){
console.log( data, type, full );
console.log(category.getAll());
return 'test';
}
}
]
});
});
De category object is initialized in a selfinvoking function. I used this to prevent the function from loading the data remotely each time the function is called.
It looks like this:
(function(){
if(typeof category === 'undefined'){
category = {};
}
category.getAll = function(){
if(typeof category.all === 'undefined'){
$.ajax({
'type' : 'POST',
'async': false,
'url' : window.location.protocol + "//" + window.location.hostname + "/category/getAll",
'success' : function(data){
console.log(data);
category.all = data;
},
'error': function(a,b,c){
console.log("You shall not pass!",a,b,c);
alert('stop');
}
});
}
return category.all;
}
})();
I'm new in jqgrid.
I want to pass multi rows edited in jqgrid to pass MVC server controller.
controller expects json string type of data.
how my jsp pass all rows to controller?
jQuery("#save").click( function(){
alert("enter save fn");
var gridData=jQuery("#gridList").jqGrid('getGridParam','data');
jQuery.ajax({
url : '/uip/web/p2/saveEmployeeList.dev'
,type : 'POST'
,cache : false
,data : JSON.stringify(gridData)
,contentType : 'application/json; charset=utf-8'
,dataType : 'json'
})
});
I print out HttpServletRequest in controller. there is one row exist.
even little clue would be helpful.
If I understand you correctly you want to save all edited rows by one Ajax action instead of a Ajax request after any row is edited?
If so, this might be the solution. Instead of Ajax you use the 'clientArray' option in your configuration as your URL parameter. This causes jqGrid to save every edited row internally in JavaScript and post nothing to your server.
With a onclick on a save button you could do something as follows:
var changedRows = [];
//changedRows is a global array
if($('#save-rows').length) {
$('#save-rows').click(function() {
var postData = {}
$.each(changedRows, function(key) {
postData[key] = $('#paymentsgrid').jqGrid('getRowData', this);
});
$.post(baseUrl + '/controller/action', {
'data' : postData
}, function(response) {
$('<div></div>').html(response.content).dialog({
'title' : 'Message',
'modal' : true,
'width' : 800,
'height' : 400,
'buttons' : {
'OK' : function() {
$(this).dialog('close');
}
}
});
if(response.reload) {
$('#grid').trigger('reloadGrid');
}
}, 'json');
});
}
Also important is to specify a save event in your grid:
$('#paymentsgrid').jqGrid('saveRow', paymentController.lastsel, null, 'clientArray', null, function(rowId) {
changedRows.push(rowId);
});
You might should modify or optimize some things but in the basic, this should work or give you an idea how to accomplish what you want.
I have a GridPanel that is backed by a DataStore (ExtJS 4). OK, so when the user selects a row and clicks a delete button, I send a POST request to the server with the ID of the selected record, delete the record, and then on return, re-load the data store.
The record is deleted successfully, the server returns a status code of OK. But, if the user selects THE LAST ROW of the GridPanel, I get the following error:
Uncaught TypeError: Cannot read property 'id' of undefined
I have no other events on the Grid Panel or DataStore.
Here is my delete code:
function deleteTEDetailExceptions() {
try {
if(tedetailExceptionsEditorGrid.getSelectionModel().selected.length < 1) {
statusMessage("Please select an exception first", true);
return;
}
var record = tedetailExceptionsEditorGrid.getSelectionModel().selected.items[0];
currentTEDetailExceptionKey = record.data["tedetailExceptionKey"];
// send the delete request
Ext.Ajax.request({
url: '/timesheets/action.do',
method: 'POST',
params:{
tedetailExceptionKey : currentTEDetailExceptionKey,
type : "tedetailExceptions",
"delete" : "true"
},
success: function(response) {
if(response.statusText == "OK") {
tedetailExceptionsEditorGrid.getSelectionModel().clearSelections();
TEDetailExceptionsStore.remove(record);
// reload the store
Ext.Function.defer((function(){
TEDetailExceptionsStore.load({
params:{
timeEntryDetailKey : timeEntryDetailKey,
type : "tedetailExceptions"
}
});
}),250);
}
}
});
}
catch(e) {
console.log(e);
}
}
What am I doing wrong?
EDIT
I managed to solve the problem with the following code. It was pretty stupid of me to reload the data store when I didn't need to!!
function deleteTEDetailExceptions() {
try {
if(tedetailExceptionsEditorGrid.getSelectionModel().selected.length < 1) {
statusMessage("Please select an exception first", true);
return;
}
var record = tedetailExceptionsEditorGrid.getSelectionModel().selected.items[0];
tedetailExceptionsEditorGrid.getView().refresh();
currentTEDetailExceptionKey = record.data["tedetailExceptionKey"];
// send the delete request
Ext.Ajax.request({
url: '/timesheets/action.do',
method: 'POST',
params:{
tedetailExceptionKey : currentTEDetailExceptionKey,
type : "tedetailExceptions",
"delete" : "true"
},
success: function(response) {
if(response.statusText == "OK") {
TEDetailExceptionsStore.remove(record);
}
}
});
}
catch(e) {
// console.log(e);
}
}
I'm not sure why you're reloading the data after you've deleted a record. Are you using a paging toolbar as well?
ExtJs obviously thinks that there is a record in the last row and seeing as you're reloading all the data anyways have you tried calling TEDetailExceptionsStore.removeAll() before you reload the data store.
Another possibility might be to refresh the grid view after you remove the record from the store. You can do this with grid.getView().refresh() This might force ExtJS into recognizing that the last row does not contain a record