How do I use a v-for loop to populate data when using an API call with server side pagination

How do I use a v-for loop to populate data when using an API call with server side pagination

barrierreefbarrierreef Posts: 7Questions: 2Answers: 0
edited August 2023 in Free community support

I am trying to use a v-for loop to populate the table body. I need to do this because I need to render a font-awesome icon with a change event for each row. Here is how I currently am trying to create the template for the table:

 <DataTable :options="gridOptions" ref="settingsTable" id="AccountingSettingsTable" class="table table-striped table-bordered">
                        <tbody>
                            <tr v-for="data in gridData" :key="data.fund">
                                <td>{{data.fund}}</td>
                                <td>{{data.fundNumber}}</td>
                                <td>{{data.status}}</td>
                                <td>
                                <font-awesome-icon :icon="['fas', 'ellipsis-vertical']" @click="displayPopup('#mergeAccountPopup')"">
                                    </font-awesome-icon>
                                </td>
                            </tr>
                        </tbody>
                    </DataTable>

Here are my table options (this is what gridOptions is equal to):

const columns = [

        {
            "data": "fund",
            "title": "Fund",
            "responsivePriority": 0
        },
        {
            "data": "fundName",
            "title": "Fund Name",
            "responsivePriority": 1
        },
        {
            "data": "status",
            "title": "Status",
            "responsivePriority": 2
        },
        {
            "data": "",
            "title": "Merge",
            "responsivePriority": 3,
            "width": "10%",
            "orderable": false,
            "sortable": false,
        }];

const datatableSettings = {
        /*pageLength: pageLengthAsNumber,*/
        lengthMenu: [[5, 10, 25, -1], [5, 10, 25, "All"]],
        processing: true,
        serverSide: true,
        scrollCollapse: true,
        responsive: true,
        deferRender: false,
        infoCallback(settings: any, start: any, end: any, max: any, total: any) {
            setTimeout(() => { /*Layout.Loader.hideBusy()*/ }, 300);
            if (total === 0) {
                return "";
            }

            return `Showing ${start} to ${end} of ${total} fund(s)`;
        },
        language: {
            "emptyTable": `There are no funds.`,
            "lengthMenu": "Show _MENU_ funds"
        },
        ajax: (data: any, callback: any, settings: any) => {
            data.glmajorid = webId;
            $.ajax({
                url: `/Accounts/GetAccountsForTable`,
                data: data,
                type: "Get",
                success: (json) => {
                    console.log(json);
                    settings._iDisplayStart = json.startIndex;
                    callback(json);
                    //Layout.Loader.hideBusy();
                },
                error: (error) => { console.log(error) }
            });
        },
        columns: columns,
        order: [[1, "asc"]],
        searching: false, //Turns the search feature on and off
        retrieve: true,
        paging: true,
        fnDrawCallback: () => {
            //Popup.setupPopups();
        },
        dom: ([
            "<'row'<'col-12 JS-dataTable-inputAppend'l>>" +
            "<'row'<'col-12'tr>>" +
            "<'row'<'col-12 col-sm-5'i><'col-12 col-sm-7'p>>"
        ]).join("\n"),
        drawCallback: function () {
            //QTip.applyDataTableQtips("#JS-glMajorsTable");
        }
    };

I am unsure how to go about getting access the data received from the backend and being able to iterate through it using the v-for loop.

Replies

  • kthorngrenkthorngren Posts: 20,790Questions: 26Answers: 4,859

    If you are using ajax, regardless of the serverSide setting, to fetch the table data the tbody will be overwritten. Instead use columns.render to display the font-awesome icon. See this example.

    Use delegated events like this example for the event handler.

    Kevin

  • allanallan Posts: 62,469Questions: 1Answers: 10,258 Site admin

    Just to add to Kevin's excellent answer - v-for will not work with DataTables, since you would end up having both Vue and DataTables trying to control the DOM for the table.

    You need to use a renderer to create the Font Awesome HTML for the moment. At some point I'll add the ability for the renderer to use Vue components, but I'm not yet sure when!

    Allan

  • barrierreefbarrierreef Posts: 7Questions: 2Answers: 0

    Thank you both for your help. However, I am running into an issue with trying to add the font awesome icon using the columns.render. I am trying to follow this example for how I render my icon: https://datatables.net/extensions/buttons/examples/styling/icons.html

    However, using the 'i' element doesn't work. I have to use the 'svg' element to get it to display. Here is the column object I am referring too:

    {
                "data": "",
                /*"defaultContent": '<i class="fa-solid fa-ellipsis-vertical"></i>',*/
                "render": function (data: any, type: any, row: any, meta: any) { // This works
                    return '<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 128 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M64 360a56 56 0 1 0 0 112 56 56 0 1 0 0-112zm0-160a56 56 0 1 0 0 112 56 56 0 1 0 0-112zM120 96A56 56 0 1 0 8 96a56 56 0 1 0 112 0z"/></svg>'
                },
                /*"render": function (data: any, type: any, row: any, meta: any) { This doesn't work
                    return '<i class="fa-solid fa-ellipsis-vertical"></i>' 
                },*/
                "title": "Merge",
                "width": "10%",
                "orderable": false,
                "sortable": false,
            }
    

    Is there some reason why doing it the second way causes it to not work? I would much rather use just the i element instead of the full svg element.

  • kthorngrenkthorngren Posts: 20,790Questions: 26Answers: 4,859

    Using the latest font-awesome CDN your code works here:
    https://live.datatables.net/cuvapepu/1/edit

    Kevin

  • barrierreefbarrierreef Posts: 7Questions: 2Answers: 0

    Thank you, I went down a rabbit hole and realized that I never added the CDN to the index.html file.

    Once this was added, I was able to use just the 'i' tag and everything worked as expected.

  • allanallan Posts: 62,469Questions: 1Answers: 10,258 Site admin

    Good to hear. Thanks for the update :)

    Allan

Sign In or Register to comment.