Reloading datatable using ajax triggered by click

Reloading datatable using ajax triggered by click

jcarvalhojcarvalho Posts: 13Questions: 3Answers: 0

Hi! I have an error of "Invalid JSON response"
When I click in button to send an ajax request to the same method that I use to populate the datatable the first time
code for the button click

    $("#tblRecuperarEncomenda tbody").on('click','td button[class^="btnrecenc"]', function(){
        alert("click!");
        //var coiso = $(this).closest('tr').find('.escondido_artigos').val();
        var coiso = '[{"ref":"PRI4223","qtd":"2"},{"ref":"PRI4224","qtd":"0"},{"ref":"PRI4224","qtd":"1"}]';
        var coisas =JSON.parse(coiso);
        $.ajax({
            url: '<?php echo(base_url());?>clientes/getElementosFatura',
            type: 'POST',
            //dataType: 'json',
            data:  {coisas},
        })
        .done(function() {
            console.log("success");
        })
        .fail(function() {
            console.log("error");
        })
        .always(function() {
            $("#linhaFatura").DataTable().ajax.reload();
        });
        
    });

The console.log shows the values correctly
the datatable is done like this:

var table = $('#linhaFatura').DataTable({
            "ajax": {
                "url": "<?php echo(base_url());?>clientes/getElementosFatura",
                "type":"POST",
                "data":lista,
            },
            "processing": true,
            //"serverSide": true,
            "destroy":true,
           columns:
           [
                { data: "ref" },
                { data: "design" },
                //{ data: "qtd" },
                { data: "", render: function ( data, type, row, meta )
                    {
                        return "<input type='text' class='form-control txtQdtLinhaFatura' value='"+  row.qtd + "'>";
                    },                                
                },
                { data: "pvf" },
                { data: "iva" },
                { data: "pvf_total" },
                { data: "desconto" },
                { data: "PVF_Liq_Total" },
                { data: "", render: function ( data, type, row, meta )
                        {
                            return "<button class='btn btn-info btn-sm remove-linhafatura'><i class='fa fa-minus'></button>";
                        },
                        "bSortable": false
                },
            ],
            oLanguage: {
                sSearch: "Procurar:",
                oPaginate: {
                    sFirst:     "Primeiro",
                    sLast:      "Último",
                    sNext:      "Seguinte",
                    sPrevious:  "Anterior"
                },
                "sInfo": "A mostrar _START_ até _END_ registos de um total de _TOTAL_ registos",
                "sLengthMenu":     "Mostrar _MENU_ registos"
            },
            "iDisplayLength": 25,
            sPaginationType : "full_numbers",
        });    
        //obter os totais calculados no servidor
        table.on('xhr', function() {
          var totais_documento = table.ajax.json();
          atualizar_totais_documento(totais_documento);
        });
    });

The method is like

function getElementosFatura()
    {
        $linhas_de_encomenda = $this->input->post();
        //por causa do recupera encomenda
        if (array_key_exists('coisas', $linhas_de_encomenda ))
        {
            $linhas_de_encomenda = $linhas_de_encomenda['coisas'];
        }
        //verifica se existem artigos para fatura, se não existir devolve vazio para a datatable linhafatura
        if (count($linhas_de_encomenda) == 0 )
        {
            $linha_a_devolver=array();
            $data = array (
                'data'            =>  $linha_a_devolver,
                'total_pfv'       => null,
                'total_iva'       => null,
                'total_documento' => null,
            );
            echo(json_encode($data,JSON_UNESCAPED_UNICODE));
            exit;
        }       
        //obter as referencias de artigos
        $referencias ='';
        foreach ($linhas_de_encomenda as $key => $value)
        {
            $referencias .="'" . $value['ref'] ."',";
        }
        //remover a ultima virgula e adicionar parentesis
        $referencias = "(" . substr( $referencias, 0, -1 ) . ")";
        $artigos_com_preco = $this->st->getArtigosByRef( $referencias );
        //correr o ciclo para fazer o match de qtd e valores por linha
        foreach ($linhas_de_encomenda as $key => $value )
        {
            $linha_a_devolver[] = faz_match_ref_qtd($value['ref'], $value['qtd'],$artigos_com_preco); 
        }
        //calculos de totais
        $total_pvf = 0;
        $total_iva = 0;
        $total_documento = 0;
        foreach ($linha_a_devolver as $key => $value)
        {
            $total_pvf += $value['PVF_Liq_Total'];
            $total_iva += $value['PVF_Liq_Total'] * $value['iva']/100;
        }
        $total_documento = $total_iva + $total_pvf;
        //preparar a saida para a datatable #linhaFatura
        $data = array (
            'data'            => $linha_a_devolver,
            'total_pvf'       => round($total_pvf,2),
            'total_iva'       => round($total_iva,2),
            'total_documento' => round($total_documento,2),
        );

        echo(json_encode($data,JSON_UNESCAPED_UNICODE));
        //die();
        //devolver à view os elementos
        //$data = array( 'data' => $this->st->getArtigosAjax());
        //echo(json_encode($data,JSON_UNESCAPED_UNICODE));

        //print_r($data);
        
    }
}

I recall that the method GetElementosFatura is 100% working when I first draw the datatable with ajax, just gives error invalid JSON on update with new data.
What am I doing wrong? Sorry my english, it is not my native language
Many thanks!

Answers

  • colincolin Posts: 15,237Questions: 1Answers: 2,599

    We're happy to take a look, but as per the forum rules, please link to a test case - a test case that replicates the issue will ensure you'll get a quick and accurate response. Information on how to create a test case (if you aren't able to link to the page you are working on) is available here.

    Cheers,

    Colin

  • jcarvalhojcarvalho Posts: 13Questions: 3Answers: 0
    edited June 2020

    Hi Colin, I can't do a test case, this part of the code is a small drop in the whole project(SQL Server, MySql, codeigniter,bootstrap) .
    I have validated the json output with the tools suggested by datatables.net json lint and the other. Both validated the output json. I have also uncommented //dataType: 'json', in the ajax call but same problem, it says invalid json.
    What I do when I first call the datatable is to pass an javascript object array with the keys ref that is the product ID and qtd that is the quantity. For testing I used that array for the click button update datatable to emulate what data should be sent to the ajax call method that is the same used to first build the datatable
    Many thanks!

  • colincolin Posts: 15,237Questions: 1Answers: 2,599

    OK, please could you post the ajax that is being returned? Ideally, can you link to your page too?

    Colin

  • jcarvalhojcarvalho Posts: 13Questions: 3Answers: 0

    Hi Colin, many thanks for your kindness.
    Here it goes
    payload from FF
    {"data":[{"ref":"PRI4223","design":"Anilha PROTOTYPE AL Pratos Pedaleiro 12x8x1 (4pcs)","qtd":"2","pvf":"2.65","iva":"23.00","pvf_total":5.3,"desconto":".00","PVF_Liq_Total":5.3},{"ref":"PRI4224","design":"Aro PROTOTYPE MTB 26 - 28F","qtd":"1","pvf":"55.64","iva":"23.00","pvf_total":55.64,"desconto":".00","PVF_Liq_Total":55.64}]}

    JSON separator thing in Firefox
    XHRPOSThttp://local.ncpicking.pt/clientes/getElementosFatura
    [HTTP/1.1 200 OK 306ms]

    data    [ {…}, {…} ]
    0   Object { ref: "PRI4223", design: "Anilha PROTOTYPE AL Pratos Pedaleiro 12x8x1 (4pcs)", qtd: "2", … }
    ref "PRI4223"
    design  "Anilha PROTOTYPE AL Pratos Pedaleiro 12x8x1 (4pcs)"
    qtd "2"
    pvf "2.65"
    iva "23.00"
    pvf_total   5.3
    desconto    ".00"
    PVF_Liq_Total   5.3
    1   Object { ref: "PRI4224", design: "Aro PROTOTYPE MTB 26 - 28F", qtd: "1", … }
    ref "PRI4224"
    design  "Aro PROTOTYPE MTB 26 - 28F"
    qtd "1"
    pvf "55.64"
    iva "23.00"
    pvf_total   55.64
    desconto    ".00"
    PVF_Liq_Total   55.64
    

    I have tried without "data" when doing php json_encode

  • colincolin Posts: 15,237Questions: 1Answers: 2,599

    Thanks for the JSON - everything looks as expected, so we'll need to see this. Are you able to link to your site so we can look, please?

    Colin

  • jcarvalhojcarvalho Posts: 13Questions: 3Answers: 0

    Hi Colin, sorry for the delay. I am working on it. This project is hosted in my laptop

  • kthorngrenkthorngren Posts: 21,172Questions: 26Answers: 4,923

    The button click event handler does this ajax request:

        $.ajax({
            url: '<?php echo(base_url());?>clientes/getElementosFatura',
            type: 'POST',
            //dataType: 'json',
            data:  {coisas},
        })
    

    Which you don't seem to do anything with. In the same handler you have:

        .always(function() {
            $("#linhaFatura").DataTable().ajax.reload();
        });
    

    Which uses this ajax request:

                "ajax": {
                    "url": "<?php echo(base_url());?>clientes/getElementosFatura",
                    "type":"POST",
                    "data":lista,
                },
    

    They look similar. Is there a difference between the two?

    payload from FF
    {"data":[{"ref":"PRI4223","design":"Anilha PROTOTYPE AL Pratos Pedaleiro 12x8x1 (4pcs)","qtd":"2","pvf":"2.65","iva":"23.00","pvf_total":5.3,"desconto":".00","PVF_Liq_Total":5.3},{"ref":"PRI4224","design":"Aro PROTOTYPE MTB 26 - 28F","qtd":"1","pvf":"55.64","iva":"23.00","pvf_total":55.64,"desconto":".00","PVF_Liq_Total":55.64}]}

    Is this when clicking the button? Is it for the first ajax request using data: {coisas} or the second using "data":lista from Datatables?

    Kevin

  • jcarvalhojcarvalho Posts: 13Questions: 3Answers: 0

    Hi Colin! the payload from FF is the result when I click in the button. I send an javascript array to the ajax call, I named it "coisas" that means things in english.
    so on button click I use $.ajax({
    url: '<?php echo(base_url());?>clientes/getElementosFatura',
    type: 'POST',
    //dataType: 'json',
    data: {coisas},
    })

    To try to reload the existing datatable that are lines on an invoice that was saved previously by the salesman.

    When I use
    "ajax": {
    "url": "<?php echo(base_url());?>clientes/getElementosFatura",
    "type":"POST",
    "data":lista,
    }, is when the salesman is building an invoice with the costumer, he selects the articles, the items goes to array lista when a modal is closed and the datatable is correctly populated.

    The button that triggers the **coisas ** array is when the salesman wants to retrieve a saved list of articles so he can add more, both calls the method getElementosFatura (get Invoice item elements translated to english)
    from the controller clientes (clients translated to english)
    What I do is to save in Mysql table an array of itens and want to retrieve then to populate the datatable. What I store in database is this text [{"ref":"PRI4223","qtd":"2"},{"ref":"PRI4224","qtd":"0"},{"ref":"PRI4224","qtd":"1"}], then I convert to JSON var coisas =JSON.parse(coiso); And send to controller clientes/getElementosFatura.

  • kthorngrenkthorngren Posts: 21,172Questions: 26Answers: 4,923
    edited June 2020

    the payload from FF is the result when I click in the button.

    So thats not the Ajax response for $("#linhaFatura").DataTable().ajax.reload(); since that executes after. What is the JSON response for the $("#linhaFatura").DataTable().ajax.reload(); request?

    Kevin

  • jcarvalhojcarvalho Posts: 13Questions: 3Answers: 0

    Hi Kevin, when you click the button the response is {"data":[{"ref":"PRI4223","design":"Anilha PROTOTYPE AL Pratos Pedaleiro 12x8x1 (4pcs)","qtd":"2","pvf":"2.65","iva":"23.00","pvf_total":5.3,"desconto":".00","PVF_Liq_Total":5.3},{"ref":"PRI4224","design":"Aro PROTOTYPE MTB 26 - 28F","qtd":"1","pvf":"55.64","iva":"23.00","pvf_total":55.64,"desconto":".00","PVF_Liq_Total":55.64}]}
    Because it is just a matter of retrieving some stored items and quantities. The datatable is working only when I add "fresh" items that I am going to choose from a list. I use another datatable only to list articles prices and articles ID's, when the seller finish the selection I grab all the itens and send to clientes/getElementosFatura. That generates JSON and populate the datatable.

    When I have stored some itens I want to retrieve those by clicking in the button I grab those itens call clientes/getElementosFatura and got {"data":[{"ref":"PRI4223","design":"Anilha PROTOTYPE AL Pratos Pedaleiro 12x8x1 (4pcs)","qtd":"2","pvf":"2.65","iva":"23.00","pvf_total":5.3,"desconto":".00","PVF_Liq_Total":5.3},{"ref":"PRI4224","design":"Aro PROTOTYPE MTB 26 - 28F","qtd":"1","pvf":"55.64","iva":"23.00","pvf_total":55.64,"desconto":".00","PVF_Liq_Total":55.64}]}. I use those for testing and I have the invalid JSON error.
    I have tried $("#linhaFatura").DataTable().clear().destroy() before
    $("#linhaFatura").DataTable().ajax.reload();

  • kthorngrenkthorngren Posts: 21,172Questions: 26Answers: 4,923
    edited June 2020

    Sounds like we are at a point of needing to see the problem. Please post a link to your page or a test case.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    The other thing you can try is to collect Debugger for the developers after clicking the button.

    Kevin

  • jcarvalhojcarvalho Posts: 13Questions: 3Answers: 0

    Hi Colin, many thanks for your kindness.
    Here it goes
    payload from FF
    {"data":[{"ref":"PRI4223","design":"Anilha PROTOTYPE AL Pratos Pedaleiro 12x8x1 (4pcs)","qtd":"2","pvf":"2.65","iva":"23.00","pvf_total":5.3,"desconto":".00","PVF_Liq_Total":5.3},{"ref":"PRI4224","design":"Aro PROTOTYPE MTB 26 - 28F","qtd":"1","pvf":"55.64","iva":"23.00","pvf_total":55.64,"desconto":".00","PVF_Liq_Total":55.64}]}

    JSON separator thing in Firefox
    XHRPOSThttp://local.ncpicking.pt/clientes/getElementosFatura
    [HTTP/1.1 200 OK 306ms]

    data    [ {…}, {…} ]
    0   Object { ref: "PRI4223", design: "Anilha PROTOTYPE AL Pratos Pedaleiro 12x8x1 (4pcs)", qtd: "2", … }
    ref "PRI4223"
    design  "Anilha PROTOTYPE AL Pratos Pedaleiro 12x8x1 (4pcs)"
    qtd "2"
    pvf "2.65"
    iva "23.00"
    pvf_total   5.3
    desconto    ".00"
    PVF_Liq_Total   5.3
    1   Object { ref: "PRI4224", design: "Aro PROTOTYPE MTB 26 - 28F", qtd: "1", … }
    ref "PRI4224"
    design  "Aro PROTOTYPE MTB 26 - 28F"
    qtd "1"
    pvf "55.64"
    iva "23.00"
    pvf_total   55.64
    desconto    ".00"
    PVF_Liq_Total   55.64
    

    I have tried without "data" when doing php json_encode

  • jcarvalhojcarvalho Posts: 13Questions: 3Answers: 0

    Hi guys! I managed to put the site online
    http://novoscanais.ddns.net/tester/

    please login with rsismeiro and password ric++

    To simulate the error please:
    1- click in "Encomendas" on the left pannel
    2- then click "Nova Encomenda"
    3) Click in "Recuperar Encomenda"
    4) In the modal click "Recuperar"

    If you want to see the datatable working please click in "Artigo Representado" choose quantity and click in the + sign "the buttons have the disabled class" but for testing it will work

  • kthorngrenkthorngren Posts: 21,172Questions: 26Answers: 4,923

    What happens if you change your event handler to this:

    $("#tblRecuperarEncomenda tbody").on('click','td button[class^="btnrecenc"]', function(){
        alert("click!");
    
            $("#linhaFatura").DataTable().ajax.reload();
      
         
    });
    

    What is the JSON response after clicking the button?

    Kevin

  • jcarvalhojcarvalho Posts: 13Questions: 3Answers: 0

    Hi guys! I managed to put the site online
    http://novoscanais.ddns.net/tester/

    please login with rsismeiro and password ric++

    To simulate the error please:
    1- click in "Encomendas" on the left pannel
    2- then click "Nova Encomenda"
    3) Click in "Recuperar Encomenda"
    4) In the modal click "Recuperar"

    If you want to see the datatable working please click in "Artigo Representado" choose quantity and click in the + sign "the buttons have the disabled class" but for testing it will work

  • jcarvalhojcarvalho Posts: 13Questions: 3Answers: 0

    Hi kthorngren, same thing, invalid Json error

  • kthorngrenkthorngren Posts: 21,172Questions: 26Answers: 4,923
    edited June 2020

    Using the browser's debugger I found the following. when opening the modal you are initializing this Datatable:

        $('#modalClienteExistente').on('shown.bs.modal', function ()
        {    
            var table = $('#dtClientesExistentes').DataTable({
                "ajax": "http://novoscanais.ddns.net/tester/clientes/getClientesAjax",
                "processing": true,
                //"serverSide": true,
                "destroy":true,
    

    This is the request URL:
    Request URL: http://novoscanais.ddns.net/tester/clientes/recuperarEncomenda

    With this response:

    {"data":{"tabela":"teste","data":"2020-06-12"}}
    

    This happens when clicking the Recuperar button:

    First this ajax request is sent:

            $.ajax({
                url: 'http://novoscanais.ddns.net/tester/clientes/getElementosFatura',
                type: 'POST',
                dataType: 'JSON',
                data:  {coisas},
            })
    

    This is the request URL:
    Request URL: http://novoscanais.ddns.net/tester/clientes/getElementosFatura

    This is the JSON response:

    {"data":[{"ref":"PRI4223","design":"Anilha PROTOTYPE AL Pratos Pedaleiro 12x8x1 (4pcs)","qtd":"2","pvf":"2.65","iva":"23.00","pvf_total":5.3,"desconto":".00","PVF_Liq_Total":5.3},{"ref":"PRI4224","design":"Aro PROTOTYPE MTB 26 - 28F","qtd":"1","pvf":"55.64","iva":"23.00","pvf_total":55.64,"desconto":".00","PVF_Liq_Total":55.64}]}
    

    However this is not the response that is causing the Datatables "Invalid JSON Response" error.

    The next thing that happens is this:

                myTable.clear().draw();
                
                myTable.ajax.reload();
    

    This ajax.reload() is using the URL from the dtClientesExistentes Datatable, which is:
    Request URL: http://novoscanais.ddns.net/tester/clientes/novaEncomenda?_=1592005190451

    The response is the web page:

    <!DOCTYPE HTML>
    <html>
        <head>
        <title>NCIndustry</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="keywords" content="" />
        <link href="http://novoscanais.ddns.net/tester/css/bootstrap.css" rel='stylesheet' type='text/css' />
    ....
    

    This is the response that I've been trying to get you to show. The difference is the ?_=1592005190451 added to the URL. This is a mechanism to prevent caching. Take a look at the first response from jLinux in this thread for a good response and a way to eliminate it if needed. I suspect your server is not setup for this and is having an error and simply returning the page. So you can try the cache: true option or debug and fix the issue with your server.

    Kevin

  • jcarvalhojcarvalho Posts: 13Questions: 3Answers: 0

    Hi Kevin!
    What a mess :blush: I tried right now the cache:true in the ajax request with no luck :(

  • kthorngrenkthorngren Posts: 21,172Questions: 26Answers: 4,923

    Did you try cache:true with this Datatable?

        var table = $('#dtClientesExistentes').DataTable({
            "ajax": "http://novoscanais.ddns.net/tester/clientes/getClientesAjax",
            "processing": true,
            //"serverSide": true,
            "destroy":true,
    

    If it doesn't work then you will need to debug your server code to fix the problem.

    Kevin

This discussion has been closed.