Child row its not working

Child row its not working

FrederikLarrualdeFrederikLarrualde Posts: 2Questions: 1Answers: 0

I am using the Django framework. I'm trying to insert a dynamic row, in theory the code is fine. But when I click to "open the row". Like it runs twice, it opens and closes it. See the problem? If any data is missing, do not hesitate to ask me, thank you.

This is the js:

$('#tabla_granjas tbody').on('click', 'td.details-control',
                function () {
                    var tr = $(this).closest('tr');
                    var row = table.row(tr);
                    var idgd = $(this).attr("idgd");
                    var idrn = $(this).attr("idrn");
                    var idgl = $(this).attr("idgl");
                    var coor = $(this).attr("coor");
                    console.log(row)
                    if (row.child.isShown()) {                        
                        // This row is already open - close it
                        row.child.hide();
                        tr.removeClass('shown');
                        console.log("cerrar")
                    } else {
                        // Open this row
                        row.child(format(idgd, idrn, idgl)).show();
                        tr.addClass('shown');
                        console.log("abrir")
                    }
                });
function format(idgd, idrn, idgl) {
                    if (idgd != "x" && idgl != "x") {
                        return `<div class="btn-group">                                        
                                    <button class="btn btn-secondary" onclick="abrir_modal_detalle(${idgd})">Detalle</button>  
                                    <a class="btn btn-secondary" href="${idgl}">Galpones</a>                                      
                                    <a id="botonNuevoRelevamiento" href="${idrn}" type="button" class="btn btn-secondary"> Relevamiento</a>
                                    <button class="btn btn-secondary">Geolocalizacion</button>
                                </div>`;
                    } else {
                        return `<div class="btn-group">                              
                                    <button class="btn btn-secondary" data-toggle="modal" data-target="#myModal">Detalle</button>  
                                    <button class="btn btn-secondary" data-toggle="modal" data-target="#myModal" href="">Galpones</button>                                      
                                    <a id="botonNuevoRelevamiento" href="${idrn}" type="button" class="btn btn-secondary"> Relevamiento</a>
                                    <button class="btn btn-secondary">Geolocalizacion</button>
                                </div>`;
                    }
                }

And this is the table:

<div class="table-responsive hero-callout">
                <table class="table table-hover table-striped table-sm display" id="tabla_granjas">
                    <thead class="thead-dark">
                        <tr>
                            <th></th>
                            <th scope="col">C</th>
                            <th scope="col">Nombre</th>
                            <th scope="col">Avícola</th>
                            <th scope="col">Localidad</th>
                            <th scope="col">Distancia</th>
                            <th scope="col">Superficie</th>
                            <th scope="col">Capacidad</th>
                            <!-- <th scope="col">Acciones</th> -->
                        </tr>
                    </thead>
                    <tbody>
                        {% for granja in granjas %}
                        <tr>
                            {% if granja.ultimoRelevamiento %}
                            <td class="details-control" idgl="{% url 'granjas:lista_galpones_granja' granja.id %}"
                                idgd="'{% url 'granjas:granja_detalle' granja.id %}'"
                                idrn="{% url 'granjas:granja_relev' granja.ultimoRelevamiento.id %}?relev=True"
                                coor="{{granja.coordenadas}}"></td>
                            <td>{{ granja.calificacion }}</td>
                            {% else %}
                            <td class="details-control" idgl="x" idgd="x"
                                idrn="{% url 'granjas:granja_relev' granja.id %}?relev=False"
                                coor="{{granja.coordenadas}}"></td>
                            <td>RP</td>
                            {% endif %}
                            <td>{{ granja.nombre }}</td>
                            <td>{{ granja.avicola }}</td>
                            <td>{{ granja.localidad }}</td>
                            {% if granja.distancia %}
                            <td class="text-right">{{ granja.distancia }}</td>
                            {%else%}
                            <td class="text-right">RP</td>
                            {%endif%}
                            {% if granja.ultimoRelevamiento and granja.sumSuperficieGalpones and granja.sumCapacidadGalpones  %}
                            <td class="text-right">{{ granja.sumSuperficieGalpones|floatformat }} m<sup>2</sup></td>
                            <td class="text-right">{{ granja.sumCapacidadGalpones|floatformat|intcomma }}</td>
                            <!-- <td>
                                <div class="btn-group">
                                    <button
                                        onclick="abrir_modal_detalle('{% url 'granjas:granja_detalle' granja.id %}')"
                                        class="btn btn-secondary">Detalle</button>
                                    <a id="botonNuevoRelevamiento" value="nuevoReRelev" type="button"
                                        class="btn btn-primary"
                                        href="{% url 'granjas:granja_relev' granja.ultimoRelevamiento.id %}?relev=True">
                                        Relevamiento</a>
                                </div>
                            </td> -->
                            {% else %}
                            <td class="text-right">RP</td>
                            <td class="text-right">RP</td>
                            <!-- <td>
                                <div class="btn-group">
                                    <button type="button" class="btn btn-secondary" data-toggle="modal"
                                        data-target="#myModal">Detalle</button>

                                    <a id="botonNuevoRelevamiento" type="button" value="nuevoRelev"
                                        class="btn btn-primary"
                                        href="{% url 'granjas:granja_relev' granja.id %}?relev=False">
                                        Relevamiento</a>
                                </div>
                            </td> -->
                            {% endif %}
                        </tr>
                        {% endfor %}
                    </tbody>
                    <tfoot>
                        <tr>
                            <th></th>
                            <th colspan="5" data-toggle="popover" data-placement="bottom"
                                data-content="Los totales 
                            son respecto a los valores de la tabla, para que sea ulti, utilize correctamente el filtro">
                                Total: Capacidad/Superficie</th>
                            <th class="text-right"> m<sup>2</sup></th>
                            <th class="text-right"></th>
                        </tr>
                    </tfoot>
                </table>

Perhaps the table seems difficult to understand, but the data is also dynamically inserted with Django, in the example they use it with an Ajax. And the data that I use in the "format" function I send as attributes of the tag. Before I had all that js, inside the drawCallback of the table, and it seemed to work, but it gave some conflicts with the modal html that I insert with the format function. If you see, there are two console.logs, one is close and the other is open, the console shows open close when I click on the td.details-control. I cannot identify the problem.

Example: https://datatables.net/examples/api/row_details.html

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 21,342Questions: 26Answers: 4,954
    Answer ✓

    Sounds like you are creating your event handler more than once:

    $('#tabla_granjas tbody').on('click', 'td.details-control',

    Do you have this or call this multiple times?

    In order to help we will need to see your page or a running test case showing the issue.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • FrederikLarrualdeFrederikLarrualde Posts: 2Questions: 1Answers: 0

    Hi Kevin, With the test case that you recommended me to run, you can find the error. The truth is that if I had put the complete code you probably would have seen it. The problem is that I invoke the event outside of where I define the table. I show the code with the error. Inside the new row, I have a button to a modal that gives an error when I want to open it (Uncaught TypeError: $ (...). Modal is not a function). But that's something else, the biggest problem was solved, thank you.

    $(document).ready(function () {
                    if ($.fn.dataTable.isDataTable('#tabla_granjas')) {
                        table = $('#tabla_granjas').DataTable();
                    } else {
                        table = $('#tabla_granjas').DataTable({
                            "language": {
                                "lengthMenu": "Mostrando _MENU_ relevamientos por pagina",
                                "zeroRecords": "No se econtro niguna coincidencia",
                                "info": "Mostrando _PAGE_ de _PAGES_",
                                "infoEmpty": "No hay registros diponibles",
                                "infoFiltered": "(filtered from _MAX_ total records)",
                                "paginate": {
                                    "previous": "Anterior",
                                    "next": "Siguente",
                                },
                            },
                            "oLanguage": {
                                "sSearch": "Buscar"
                            },
                            "order": [
                                [1, 'asc']
                            ],
                            "columnDefs": [{
                                "orderable": false,
                                "targets": 0,
                            }],
                            drawCallback: () => {
                                const table = $('#tabla_granjas').DataTable();
                                const tableData = table.rows({
                                    search: 'applied'
                                }).data().toArray();
                                const totals = tableData.reduce((total, rowData) => {
                                    if (rowData.length == 8) {
                                        if (rowData[7] != "RP" && rowData[7] != "RG" &&
                                            rowData[
                                                7] != "None") {
                                            var valorCap = rowData[7].replace(".", "");
                                            total[1] += parseInt(valorCap);
                                        }
                                        if (rowData[6] != "RP" && rowData[6] !=
                                            "m<sup>2</sup>") {
                                            var valorSup = rowData[6].replace(
                                                " m<sup>2</sup>",
                                                "");
                                            total[0] += parseInt(valorSup);
                                        }
                                    }
                                    return total;
                                }, [0, 0]);
                                $(table.column(6).footer()).html(totals[0] + " m<sup>2</sup>");
                                $(table.column(7).footer()).text(totals[1]);
                            }
                        });
                    }
                    $('#tabla_granjas tbody').on('click', 'td.details-control',
                    function () {
                        var tr = $(this).closest('tr');
                        var row = table.row(tr);
                        var idgd = $(this).attr("idgd");
                        var idrn = $(this).attr("idrn");
                        var idgl = $(this).attr("idgl");
                        var coor = $(this).attr("coor");
                        console.log(row)
                        if (row.child.isShown()) {                        
                            // This row is already open - close it
                            row.child.hide();
                            tr.removeClass('shown');
                            console.log("close")
                        } else {
                            // Open this row
                            row.child(format(idgd, idrn, idgl)).show();
                            tr.addClass('shown');
                            console.log("open")
                        }
                    });                
                });
    
This discussion has been closed.