Using Datatables AltEditor requested unkown parameter - ajax

I'm having trouble with Datatable AltEditor when trying to update rows.
Btw, I'm using flask as back-end.
This is my setup:
First I'll show you what the datatable looks like
Html table:
<div id='contenidoBienvenida'>
<table class="dataTable table table-striped" id="example" style="width: 100%">
</table>
</div>
Flask Routes:
#app.route('/getProfesores') #This route sends the json data with all the teachers
def getProfesores():
if 'numEmpleado' in session:
try:
cur = mysql.connection.cursor()
cur.execute("SELECT * FROM usuarios")
r = [dict((cur.description[i][0], value) # IF NULO hacer algo
for i, value in enumerate(row)) for row in cur.fetchall()]
if (len(r) == 0):
return "No hay profesores"
return json.dumps({'data': r})
except Exception as e:
print(str(e))
return redirect(url_for('home'))
#This route receives the desired data to be edited, saves changes and returns new data as JSON
#app.route('/editar/profesor/', methods=['GET'])
def editarProfesor():
if 'numEmpleado' in session:
try:
numEmpleado = request.args.get('NumEmpleado')
nombre = request.args.get('nombre')
password = request.args.get('password')
correo = request.args.get('correo')
tipoCuenta = request.args.get('tipoCuenta')
perfilCompletado = request.args.get('perfilCompletado')
cur = mysql.connection.cursor()
query = "UPDATE usuarios SET NumEmpleado = %s, nombre = %s, password = %s, correo = %s, tipoCuenta = %s, perfilCompletado = %s WHERE NumEmpleado = %s"
cur.execute(query, (numEmpleado,nombre,password,correo,tipoCuenta,perfilCompletado,numEmpleado))
mysql.connection.commit() #Execute the update sql
cur.execute( #Now it grabs the edited row
"SELECT * FROM usuarios WHERE usuarios.NumEmpleado=%s" %
numEmpleado)
r = cur.fetchone()
cur.close()
return json.dumps({'data': r}) #sends the edited row as JSON -- SUCCESS
except Exception as e:
return redirect(url_for('home'))
profesoresDatatable.js:
$(document).ready(function() {
var columnDefs = [{
data: "NumEmpleado",
title: "Número Empleado",
},
{
data: "nombre",
title: "Nombre"
},
{
data: "password",
title: "Password"
},
{
data: "correo",
title: "Mail"
},
{
data: "tipoCuenta",
title: "Tipo Cuenta"
},
{
data: "perfilCompletado",
title: "¿perfilCompletado?"
}];
var myTable;
// local URLs are not allowed
var url_ws_mock_get = './getProfesores'; #Flask route which fill the datatable
var url_ws_mock_ok = './mock_svc_ok.json'; #not used
myTable = $('#example').DataTable({
"sPaginationType": "full_numbers",
destroy: true,
responsive: true,
ajax: {
url : url_ws_mock_get, #Flask route to obtain json data
// our data is an array of objects, in the root node instead of /data node, so we need 'dataSrc' parameter
dataSrc : 'data'
},
columns: columnDefs,
dom: 'Bfrtip', // Needs button container
select: 'single',
responsive: true,
altEditor: true, // Enable altEditor
buttons: [{
text: 'Agregar',
name: 'add' // do not change name
},
{
extend: 'selected', // Bind to Selected row
text: 'Editar',
name: 'edit' // do not change name
},
{
extend: 'selected', // Bind to Selected row
text: 'Borrar',
name: 'delete' // do not change name
},
{
text: 'Refrescar',
name: 'refresh' // do not change name
}],
onAddRow: function(datatable, rowdata, success, error) {
$.ajax({
// a tipycal url would be / with type='PUT'
url: url_ws_mock_ok,
type: 'GET',
data: rowdata,
success: success,
error: error
});
},
onDeleteRow: function(datatable, rowdata, success, error) {
$.ajax({
// a tipycal url would be /{id} with type='DELETE'
url: url_ws_mock_ok,
type: 'GET',
data: rowdata,
success: success,
error: error
});
},
onEditRow: function(datatable, rowdata, success, error) {
$.ajax({
// a tipycal url would be /{id} with type='POST'
url: './editar/profesor/', #flask route which save changes and returns edited row as JSON
type: 'GET',
data: rowdata,
success: success,
error: error
});
}
});
});
In the following example I will change the password for the user named Arturo Casanova, from '123' to 'password'
When I have finished editing and I click on save changes I get a warning about requested unknown parameters.
When I close the warning I get the success message
But the edited row is not inserted correctly
If I click on the Refrescar button(refresh button),it then will appear on the datatable correctly
This is the current JSON obtained by Flask Route'/getProfesores')
This is the JSON response after editing the row, the one that now should appear on the datatable
This are the scripts I'm using
<!--SCRIPTS-->
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script type="text/javascript"
src="https://cdn.datatables.net/v/bs4/jszip-2.5.0/dt-1.10.18/b-1.5.6/b-colvis-1.5.6/b-flash-1.5.6/b-html5-1.5.6/r-2.2.2/sl-1.3.0/datatables.min.js"></script>
<script src="{{url_for('static', filename='js/dataTables.altEditor.free.js')}}"></script>
<script src="{{url_for('static', filename='js/profesoresDatatable.js')}}"></script>

Got it working
I changed the line 285 of dataTables.altEditor.free.js
that._editRowCallback(data,b,c,d,e); changed to that._editRowCallback(rowDataArray,b,c,d,e);
Complete section:
that.onEditRow(that,
rowDataArray,
function(data,b,c,d,e){ that._editRowCallback(rowDataArray,b,c,d,e); },
function(data){ that._errorCallback(data);
});
And now it doesn't show warnings and it refreshes as it should do

I know this was posted a while ago but I'll repsond as I had exactly the same problem, and also because I got in touch with the developers of the altEditor who responded below with a comment about the proposed fix.
The reason that the fix works is that it uses the JSON that the browser sent to the server, and it's valid JSON.
Without the proposed fix the editor uses the JSON returned by your server and I think you will find that this is where the problem is. As long as your server returns valid JSON with a key/value pair for each column in your table, it will work.
As an example, here's my table:
In the function called by onEditRow I create a string containing keys and values and then encode it to JSON and return it:
$row = '{"client_number": "1", "name": "Mark", "phone": "89797979", "link": "http://someserver.com"}';
echo json_encode($row);
With that code when I click the edit button on any row it will display the record from the table. When I click to close the edit dialog the row in the table will change to show that $row I returned. If you try that it should be enough to demonstrate that with valid JSON containing a value for each column, the editor works.
When I look in the browser to see what it received from the call to the server, it shows this:
And finally, here's the table after closing the edit dialog box. It shows that record I returned:
Obviously your server function will need to deal with the actual record clicked on and generate $row from that.

I know this is a bit old, but Mark's answer seems to be the correct one per the documentation on github.
AJAX Setup
The datatable accepts the following callback functions as arguments:
onAddRow(alteditor, rowdata, success, error)
onEditRow(alteditor, rowdata, success, error, originalrowdata)
onDeleteRow(alteditor, rowdata, success, error)
In the most common case, these function should call $.ajax as expected
by the webservice. The two functions success and error should be
passed as arguments to $.ajax.
Within the procedures onAddRow, onEditRow, onDeleteRow, you can access
datatable object using alteditor.s.dt.
Webservice must return the modified row in JSON format, because the
success() function expects this. Otherwise you have to write your own
success() callback (e.g. refreshing the whole table).
There needs to be a matching JSON response with the modified data to update the record natively

Related

Redraw datatables with search

I am using DataTables. I have added the below code when the page is loading and the table getting all data as expected.
var table = $('#expensesTable').DataTable({
responsive: true,
searchDelay: 500,
processing: true,
serverSide: true,
ajax: {
url: '/books/daybooks/datatable',
type: 'POST',
},
columns: [
{data: 'expense_id'},
{data: 'expense_date'},
{data: 'expense_description'},
{data: 'expense_amount'},
{data: 'vendor_name'},
],
});
Now, I have added a date range picker where it will search data in the server and response will be given back to query via Ajax.
$('#datepicker').on('apply.daterangepicker', function(ev, picker) {
var start = picker.startDate.format('YYYY-MM-DD');
var end = picker.endDate.format('YYYY-MM-DD');
jQuery.ajax({
type: "POST",
url: '/books/daybooks/datatable',
data: {start : start, end : end},
success: function(data)
{
console.log(data);
} // Success End
}); //AJAX End
});
Now i am getting all expected filter data as success, but now I need to redraw the table with newly got data after the filter of Ajax call.
if i use $('#expensesTable').DataTable().draw(); then it will do draw without filter,
So i can draw table with filter data?
Thanks in advance.
Instead of introducing a new ajax call (the jQuery ajax), you can re-use your existing DataTables ajax call when submitting your date range filter data.
To do this, you need to take the following steps:
(1) Update your DataTables ajax option:
ajax: {
url: '/books/daybooks/datatable',
type: 'POST',
data: function () {
return { "start": start, "end" end };
}
},
This data function allows you to dynamically assign values to your request. They will be added as standard URL-encoded form data, in the usual way for POST requests.
See here for more information. There are several different ways to use ajax.data. For example, if you were using serverSide processing (which you are not) then the above approach would not work correctly.
(2) To re-use your DataTables ajax call, you can use this:
table.ajax.reload();
See here for more information.
This replaces your jQuery ajax call:
var start;
var end;
$('#datepicker').on('apply.daterangepicker', function(ev, picker) {
start = picker.startDate.format('YYYY-MM-DD');
end = picker.endDate.format('YYYY-MM-DD');
table.ajax.reload();
});
When the table first loads (not using reload()), the filter values will be null.

Datatables Ajax call not displaying data

I'm using the datatables library to display some data and would like to update this every 30 seconds with data fetched form a URL. I've followed the api documentation and have implemented the code below to do this:
$( document ).ready(function() {
var table = $('#performance_summary').DataTable( {
ajax: 'https://myjasonurl.com'
} );
setInterval( function () {
table.ajax.reload();
}, 30000 );
});
When the page loads I can see that the correct URL is called to retrieve data, and data is returned in the correct format to display properly in the table (I've checked this works by loading this into the table directly). Unfortunately the resulting datatable when using the ajax call states that it is "loading" but never loads/shows the data, does anyone have any idea of how I fix this?
Try the DataTable().ajax.url function,
Following code works fine for me:
$(document).ready(function() {
var table = $('#performance_summary').DataTable({
paging: false,
searching: false,
ajax: "https://api.myjson.com/bins/897v1",
columns: [{
"title":"Test",
"data": "test"
}]
});
setInterval( function () {
$('#performance_summary').DataTable().ajax.url(
"https://api.myjson.com/bins/897v1"
).load();
}, 3000 );
});
here's the fiddle: https://jsfiddle.net/ju2bmtm7/84/

Extjs- Paging Toolbar Next Page and Previous Page Disable

I have three parameters startdate, enddate and name which I have to send to the server to get back Json response. I am displaying the response in a GridPanel.
My Ajax Request looks like this:
FilterOperSet: function(button){
var win = button.up('window');
var form = win.down('form');
var start = form.getForm().findField('startDate').getSubmitValue();
var end = form.getForm().findField('endDate').getSubmitValue();
var act = form.getForm().findField('actor').getSubmitValue();
Ext.Ajax.request({
url: 'ListData',
params: { type: 'recordedRequest', startDate: start,
endDate: end, actor: act, start:0,limit:10 },
success: function(response) {
var json = Ext.decode(response.responseText);
var mystore = Ext.data.StoreManager.lookup('RecordedRequestStore');
mystore.loadData(json.recordedRequests);
},
scope: this});
}
I have a button, when user enters values for startdate, enddate and name and clicks on the button the above listener sends them as parameters along with start and limit for paging and response is captured and stored in gridpanel.
My issue with paging toolbar is: I could see the following as response
recordedRequests
// has some meta data here
success
true
total
1339
But my paging tool bar show only one page and at bottom says 0 of 0 and to the right nothing to display. Infact it should say 1 of 14 and should allow me to go through next pages.
2) Also when I click on refresh button it calls my store and calls server, but i want to make a ajax request with startdate, enddate and name as parameters(which would be exactly what my button above listerner does)
My Store looks like this:
autoLoad: false,
remoteFilter: true,
buffered: false,
pageSize: 10,
//leadingBufferZone: 1000,
fields:['start', 'end', 'actor','serviceOp'],
proxy: {
type: 'ajax',
url: 'ListData',
store: 'RecordedRequestStore',
startParam:'start',
limitParam:'limit',
pageParam:'page',
reader: {
type: 'json',
root: 'recordedRequests',
successProperty: 'success',
totalProperty: 'total'
},
extraParams: {
'type': 'recordedRequest',
},
//sends single sort as multi parameter
simpleSortMode: true,
// Parameter name to send filtering information in
filterParam: 'query',
// The PHP script just use query=<whatever>
encodeFilters: function(filters) {
return filters[0].value;
}
},
listeners: {
filterchange: function(store, filters, options){
console.log( filters )
},
totalcountchange: function() {
console.log('update count: ')
//this.down('#status').update({count: store.getTotalCount()});
}
}
Any sort of help will of great value for me. Thanks in Advance.
Instead of Ajax Request. I should use
store.load(params{your params})
For nextpage and previouspage I used beforeload listener for custom parameters.

Multiple Ajax PUTs in Laravel 4 Giving Errors

I am updating my Model through a resource controller via jQuery Ajax Put. No problems at all the first time. This works fine:
$(".addNest").click(function() {
var nid = msg; //once the LI is added, we grab the return value which is the nest ID
var name = $('.nestIn').val();
if(name == '') {
$("textarea").css("border", "1px solid red");
}else {
$.ajax({
type: 'PUT', // we update the default value
url: 'nests/' + nid,
data: {
'name': name
},
success: function(msg) {
alert(msg)
window.location.replace('nests/' + nid ); //redirect to the show view
}
});
}
});
Later in a separate code block, I try to call the PUT again like this:
$(".nestEdit").click(function() {
$(".nestEdit").hide();
var name = $('.nestName').data("name");
var nid = $('.nestName').data("id");
$(".nestName").html("<textarea class='updateNest'>"+ name +"</textarea> <span><a href='#' class='btn btn-mini nestUpdate'><i class='icon-plus'></i> Update</a></span>");
$(".nestUpdate").click(function() {
var updatedName = $('.updateNest').val();
$.ajax({
type: 'PUT', // we update the default value
url: 'nests/' + nid,
data: {
'name': updatedName
},
success: function(msg) {
alert(msg) // showing the error here
location.reload( ); //refresh the show view
}
});
});
The 'updatedName' values and the 'nid' values are passing fine when I 'alert' them. When I view the return for the first PUT it comes back fine. However, when I view the return for the second PUT I get this:
{"error":{"type":"Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException","message":"","file":"\/Applications\/MAMP\/htdocs\/n4\/bootstrap\/compiled.php","line":8643}}
Anyone have some insights here? As you can tell, I am trying to do an inline edit. I have tried to wrap everything into a function but still not helping...
Laravel does not use PUT and DELETE natively since it is not supported in all browsers, you need to send a POST request with '_method' set to either put or delete.
$.ajax({
type: 'POST',
url: 'nests/' + nid,
data: {
'name': updatedName,
'_method': update
},
success: function(msg) {
alert(msg) // showing the error here
location.reload( ); //refresh the show view
}
EDIT: Ajax request do support PUT AND DELETE.
In your JavaScript code, for the inline editing, you are not making proper use of $.
If you click on .nestEdit, it's inner function should not be calling it by name, provided you have multiple objects of the same class on that page. This is why you get the error. Instead of sending the nest ID, it's sending an array object, which your Laravel Router will not pick up, because it is more than likely not defined.
Simply put, you should not be doing this:
$(".nestEdit").click(function() {
$(".nestEdit").hide();
...
You should be making a call to this:
$(".nestEdit").click(function() {
$(this).hide();
...
So, for every .nestEdit within the inner function, you need to call for this instead.

datatables fnRowCallback: binding click to an event handler

Using datatables and fnRowCallback.
I am trying to bind click to each row on the 2nd column.
The table is returning the correct anchor in the 2nd column with the correct variables, but when I click on the link, ajax is sending each one as the same userid.
I think i need to use .each().click but every thing I try doesn't work.
Anybody know what im doing wrong.....
"fnRowCallback": function( nRow, aData, iDisplayIndex ) {
$('td:eq(1)', nRow).html(''+ aData[3] +'').click(function() {
var url = $('.view_log').attr("id");
var timestamp = (new Date()).getTime();
$("#table_container").hide();
$(".themenu").hide();
$("#log").show();
$.ajax({
type: "GET",
url: ''+url+'&x='+timestamp,
dataType: "html",
success: function(data) {
$("#log").html(data);
}
});
});
}
$('.view_log').attr("id"); will get only the first occurrence.
In this SO page try this in the console:
$('.post-tag') //returns all the tags element
$('.post-tag').attr('href') //returns only the href value of the first occurrance
In the handler, specify the event parameter and then use $(e.target) instead.
So $(e.target).attr('id') should do the job.
... .click(function(e){
var url = $(e.target).attr('id');
});
Demo

Resources