amal50 amal50 - 2 months ago 34
Ajax Question

Get data in child row based on id on parent row, using two ajax calls in datatable - jQuery

I have a datatable that use two Ajax Calls to load data in it. I was following demo here JSFiddle
I'm trying to get from the first Ajax call all data about replies, and load them in the parent row.
then I'm trying to get from the second Ajax call all attachments related to the reply, by reply id, so I want to get in each parent row (reply id, and other data related to the reply), and I want to get in the child row all attachments related to this particular (reply id) , [for now I'm using fileName for loading the attachments]




so the table will load all replies, and when the user click on the first "td" to open the child row, the user must see only attachments that are related to this reply, and when the user open another child row , will see different attachment, which are related only to the reply that he clicked on its "td"




my problem is with the child row, it doesn't load anything, and when I put fixed id in the ajax call, it load same files in all child rows, but I don't want that, I want each child row to load only related attachments (attachments by reply id)

I spent 5 days trying , but I couldn't solve it, and also I didn't find any similar problem in the net that can help.
is it possible to achieve what I want using datatable?

here is my HTML code

<table id="replyTable" class="display table-bordered nowrap" cellspacing="0" width="100%">
<thead>
<tr>
<th>Attachments</th>
<th>Reply ID</th>
<th>Ticket ID</th>
<th>Message</th>
<th>Transaction Status</th>
<th>Created Date</th>
</tr>
</thead>
<tbody></tbody>
</table>


here is my JS code

<script>
$(document).ready(function () {

var TicketID = $("#txtTicketID").val();
var table = $('#replyTable').DataTable({
ajax: {
type: "GET",
url: "/api/TicketsReplies/GetTicketsRepliesByTicketID/" + TicketID,
dataSrc: "",
datatype: 'json',
cache: false,
},
columns: [
{
className: "details-control",
orderable: false,
defaultContent: ""

},
{
className: "replyIdClass",
data: "id",

},
{ data: "ticketsId" },
{ data: "message" },
{ data: "transactionStatus.nameEnglish" },
{ data: "createdDate" }
],
"order": [[1, 'asc']]

});

// Add event listener for opening and closing details
$('#replyTable').on('click', 'td.details-control', function () {

var tr = $(this).closest('tr');
var row = $('#replyTable').DataTable().row(tr);

if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
} else {
// Open this row
format(row.child);
tr.addClass('shown');
}
});

function format(callback) {
var IdValue = $('#replyTable').find('.replyIdClass').text();
$('.replyIdClass').each(function (i) {

var repId = $(this).text();

$.ajax({
url: '/api/TicketAttachmentApi/GetRepliesAttachments/' + repId,
dataType: "json",
complete: function (response) {
var data = JSON.parse(response.responseText);
console.log(data);
var tbody = '';

$.each(data, function (i, d) {
tbody += '<tr><td>' + d.fileName + '</td><td>' + d.id + '</td></tr>';
});
console.log('<table>' + tbody + '</table>');
callback($('<table>' + tbody + '</table>')).show();
},
error: function () {
$('#output').html('Bummer: there was an error!');
}
});
});
}

});

</script>

Answer

Finally after 4 days trying, I could solve the problem, after better understanding how the datatable and child row work, so I would like to put my solution here, so maybe I can benefit others who have same problem. well the problem here is using foreach in format function to get the replies ids, it is wrong, I must pass the reply id from the child row where I clicked the cell, to the format function and retrieve only the attachment where the reply id = the reply id in the cell where I clicked

here is my solution, it is working perfectly. This is the HTML

<input type="hidden" value='@ViewContext.RouteData.Values["id"]' id="txtTicketID" />

<table id="replyTable" class="display table-bordered table-hover" cellspacing="0" width="100%">
        <thead>
            <tr>
                <th>Attachments</th>
                <th>Reply ID</th>
                <th>Message</th>
                <th>Transaction Status</th>
                <th>Created Date</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>

here is the Ajax and jQuery code

<script>
    $(document).ready(function () {

        var TicketID = $("#txtTicketID").val();
        // Get Replies From API by TicketID
        var table = $('#replyTable').DataTable({
            ajax: {
                type: "GET",
                url: "/api/TicketsReplies/GetTicketsRepliesByTicketID/" + TicketID,
                dataSrc: "",
                datatype: 'json',
                cache: false,
            },
            columns: [
                {
                    className: "details-control",
                    orderable: false,
                    defaultContent: ""
                },
                {
                    className: "replyIdClass",
                    data: "id",
                },
                {
                    data: "message",

                },
                { data: "transactionStatus.nameEnglish" },
                { data: "createdDate" }
            ],
            "order": [[1, 'asc']]

        });

        // Add event listener for opening and closing details
        $('#replyTable').on('click', 'td.details-control', function () {

            var id = $(this).closest("tr").find('.replyIdClass').text();
            var tr = $(this).closest('tr');
            var row = $('#replyTable').DataTable().row(tr);

            if (row.child.isShown()) {
                // This row is already open - close it
                row.child.hide();
                tr.removeClass('shown');
            } else {
                // Open this row
                format(row.child, id); // here pass the reply id to function format
                tr.addClass('shown');
            }
        });

        function format(callback, vRid) {

            var TicketID = $("#txtTicketID").val();

            var repId = $(this).text();
            $.ajax({
                type: "GET",
                url: "/api/TicketAttachmentApi/GetRepliesAttachments/" + vRid,
                dataType: "json",
                cache: false,
                complete: function (response) {
                    var data = JSON.parse(response.responseText);
                    console.log(data);
                    var tbody = "";

                    $.each(data, function (i, d) {
                        tbody += "<tr><td><a href='/Attachments/Tickets/" + TicketID + "/Replies/"
                          + vRid + "/" + d.fileName + "' target='_blank'>" + d.fileName + "</a></td></tr>";
                    });
                    console.log("<table>" + tbody + "</table>");
                    callback($("<table>" + tbody + "</table>")).show();
                },
                error: function () {
                    $('#output').html('Bummer: there was an error!');
                }
            });
        } //-- end format (callback)

    });

</script>