ajaxflaskdatatablejquery-datatables-editor

Using Datatables AltEditor requested unkown parameter


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

Datatables example

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'

enter image description here

When I have finished editing and I click on save changes I get a warning about requested unknown parameters.

enter image description here

When I close the warning I get the success message

enter image description here

But the edited row is not inserted correctly

enter image description here

If I click on the Refrescar button(refresh button),it then will appear on the datatable correctly

enter image description here

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>

Solution

  • 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:

    Example 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:

    Browser Network Tab

    And finally, here's the table after closing the edit dialog box. It shows that record I returned:

    enter image description here

    Obviously your server function will need to deal with the actual record clicked on and generate $row from that.