Dynamic DataTable - Populate From a Fetch API

Dynamic DataTable - Populate From a Fetch API

zgoforthzgoforth Posts: 493Questions: 98Answers: 2

Hello,

So as you could probably see from my other post, I want to make a tabbed DataTable that will include 3 tables with separate data from the same SharePoint List.

These data I am pulling through have the IDs [Name.Title(Name is a metadata object),Weight, WeeklyWeight, Steps, WeeklySteps, ExerciseMinutes, WeeklyExerciseMin, StepPoints, and MinutePoints]. My plan is to have the first table show Name + Weekly Items(WeeklyWeight, WeeklySteps, WeeklyExerciseMin), the second table to show Name + Overall Items (Weight, Steps, Minutes), and lastly have the third table show Name + Points (StepPoints, MinutePoints).

For the third table I plan to separate into two collapsible rows, or use rowGroup to seperate the Points since contestants can only have one or the other points. They cannot earn both.

My only experience using DataTables, was populating (or drawing to) a single table from a simple AJAX call which I was able to do successfully. Now as for writing to three different ones I am unsure how to draw to all three of them simultaneously?

In my code to draw to the single datatable, I included the following in my onSuccess AJAX function:

if (data.d != null && data.d != undefined && data.d.results.length > 0) {
                        var table = $('#myTable').DataTable();
                        table.rows.add(data.d.results).draw();
                    }

Would something similar to this be used inside of my items.forEach arrow function within my loadData() function?

Here is my JS:

function loadData() {
console.clear();
let webUrl = _spPageContextInfo.webAbsoluteUrl;
var mili = new Request(webUrl + "/_api/lists/getbytitle('ContestInformation')/items?$select=Name/Id,Name/Title,Weight,WeeklyWeight,Steps,WeeklySteps,ExerciseMinutes,WeeklyExerciseMin,StepPoints,MinutePoints&$expand=Name"
    ,{
        method: 'GET',
        headers: new Headers({
            "Accept": "application/json; odata=verbose",
        })
    });
fetch(mili)
    .then((response) => response.json())
    .then((data) => {
        let items = data.d.results;
        items.forEach((item)=> {
            console.log(item.Name, item.Weight, item.WeeklyWeight, item.Steps, items.WeeklySteps, item.ExerciseMinutes, item.WeeklyExerciseMin, item.StepPoints, item.MinutePoints);
            console.log(item.Name.Title);
        });
    });
}

$(document).ready( function () {
        function filterGlobal () {
            $('#weeklytable').DataTable().search(
                $('#global_filter').val()
            ).draw();
            $('#overalltable').DataTable().search(
                $('#global_filter').val()
            ).draw();
            $('#pointstable').DataTable().search(
                $('#global_filter').val()
            ).draw();
        }
          
          var table = $('#weeklytable').DataTable({
                "ajax": "/ajax/objects.txt",
                "columns": [
                    { "data": "Name.Title" },
                    { "data": "WeeklyWeight" },
                    { "data": "WeeklySteps" },
                    { "data": "WeeklyExerciseMin" }
                ]
    }); 
          var table1 = $('#overalltable').DataTable({
                "ajax": "/ajax/objects.txt",
                "columns": [
                    { "data": "Name.Title" },
                    { "data": "Weight" },
                    { "data": "Steps" },
                    { "data": "ExerciseMinutes" }
                ]   
          });
          var table2 = $('#example2').DataTable({
                "ajax": "/ajax/objects.txt",
                "columns": [
                    { "data": "Name.Title" },
                    { "data": "StepPoints" },
                    { "data": "MinutePoints" }
                ]   
          });
        
          $('input.global_filter').on( 'keyup click', function () {
            filterGlobal();
          } );
        
         
        } );
        

Here is my HTML:

<!DOCTYPE html>
<html>

<head>
    <!-- Bootstrap -->
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">
    <!-- Datatables -->
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.13/css/dataTables.bootstrap.min.css">
    <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
    <script src="https://nightly.datatables.net/js/dataTables.bootstrap.js"></script>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta charset=utf-8 />
    <title>Move It & Lose It DataTable</title>
</head>

<body>
    <div class="container">
        <input type="text" class="global_filter" id="global_filter">
        <div class="clearfix"></div>
        <ul class="nav nav-tabs">
            <li class="active"> <a href="#1" data-toggle="tab">Weekly Measures</a>
            </li>
            <li><a href="#2" data-toggle="tab">Overall Measures</a>
            </li>
            <li><a href="#3" data-toggle="tab">Points</a>
            </li>
        </ul>
        <div class="tab-content ">
            <div class="tab-pane active" id="1">
                <table id="weeklytable" class="table table-striped table-hover table-bordered" width="100%">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Weekly Weight &Delta;</th>
                            <th>Weekly Steps</th>
                            <th>Weekly Exercise Minutes</th>
                        </tr>
                    </thead>
                    <tfoot>
                        <tr>
                            <th>Name</th>
                            <th>Weekly Weight &Delta;</th>
                            <th>Weekly Steps</th>
                            <th>Weekly Exercise Minutes</th>
                        </tr>
                    </tfoot>
                </table>
            </div>
            <div class="tab-pane" id="2">
                <table id="overalltable" class="table table-striped table-hover table-bordered" width="100%">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Overall Weight &Delta;</th>
                            <th>Overall Steps</th>
                            <th>Overall Exercise Minutes</th>
                        </tr>
                    </thead>
                    <tfoot>
                        <tr>
                            <th>Name</th>
                            <th>Overall Weight &Delta;</th>
                            <th>Overall Steps</th>
                            <th>Overall Exercise Minutes</th>
                        </tr>
                    </tfoot>
                </table>
            </div>
            <div class="tab-pane" id="3">
                <table id="pointstable" class="table table-striped table-hover table-bordered" width="100%">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Step Points</th>
                            <th>Minutes Points</th>
                        </tr>
                    </thead>
                    <tfoot>
                        <tr>
                            <th>Name</th>
                            <th>Step Points</th>
                            <th>Minute Points</th>
                        </tr>
                    </tfoot>
                </table>
            </div>
        </div>
    </div>
    </div>
</body>
</html>

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 20,270Questions: 26Answers: 4,765

    Yes, use rows.add() for each Datatable. You can simply use orws.add( data.d.results ).draw(); for each table. Each table will have all the data in the Datatables data cache but will only show the columns you specify. Or you can loop through the data and just add the properties you want for each table.

    Kevin

  • zgoforthzgoforth Posts: 493Questions: 98Answers: 2

    @kthorngren I understand that, but I am confused on how to actually draw them. Would I include in the function above my JS and HTML something like this?

    fetch(mili)
            .then((response) => response.json())
            .then((data) => {
                let items = data.d.results;
                items.forEach((item)=> {
                    if (data.d != null && data.d != undefined && data.d.results.length > 0) {
                        var table= $('#weeklytable').DataTable();
                        var table1=$('#overalltable').DataTable();
                        var table2=$('#pointstable').DataTable();
                        table.rows.add(data.d.results).draw();
                    }
                    console.log(item.Name, item.Weight, item.WeeklyWeight, item.Steps, items.WeeklySteps, item.ExerciseMinutes, item.WeeklyExerciseMin, item.StepPoints, item.MinutePoints);
                    console.log(item.Name.Title);
                });
            });
    
  • kthorngrenkthorngren Posts: 20,270Questions: 26Answers: 4,765

    Have you tried it? What happens?

    You will need to use rows.add() for each Datatalbe, like this:

    table.rows.add(data.d.results).draw();
    table1.rows.add(data.d.results).draw();
    table2.rows.add(data.d.results).draw();
    

    Kevin

  • kthorngrenkthorngren Posts: 20,270Questions: 26Answers: 4,765

    You don't need the forEach loop if you use table.rows.add(data.d.results).draw(); as Datatables will process all the rows in the data. You can remove lines 4 and 5 and 14.

    Kevin

  • zgoforthzgoforth Posts: 493Questions: 98Answers: 2
    fetch(mili)
        .then((response) => response.json())
        .then((data) => {
            if (data.d != null && data.d != undefined && data.d.results.length > 0) {
                var table = $('#weeklytable').DataTable();
                var table1 = $('#overalltable').DataTable();
                var table2 = $('#pointstable').DataTable();
                table.rows.add(data.d.results).draw();
                            table1.rows.add(data.d.results).draw();
                          table2.rows.add(data.d.results).draw();
            }
            console.log(item.Name, item.Weight, item.WeeklyWeight, item.Steps, items.WeeklySteps, item.ExerciseMinutes, item.WeeklyExerciseMin, item.StepPoints, item.MinutePoints);
            console.log(item.Name.Title);
        });
    

    So if I read your response correct, this is what it should look like. I am implementing now and will let you know the outcome

  • zgoforthzgoforth Posts: 493Questions: 98Answers: 2

    Here is the error I am getting:

    jquery.min.js:2 Uncaught TypeError: $(...).DataTable is not a function
        at HTMLDocument.<anonymous> (DataTable.aspx?PageView=Shared&InitialTabId=Ribbon.WebPartPage&VisibilityContext=WSSWebPartPage:684)
        at e (jquery.min.js:2)
        at t (jquery.min.js:2)
    

    As you can see in my script below, I have linked the jQuery library
    Here is my full script:

    <!DOCTYPE html>
    <html>
    
    <head>
        <!-- Bootstrap -->
        <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">
        <!-- Datatables -->
        <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.13/css/dataTables.bootstrap.min.css">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
        <script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
        <script src="https://nightly.datatables.net/js/dataTables.bootstrap.js"></script>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta charset=utf-8 />
        <title>Move It & Lose It DataTable</title>
        <style>
            body {
        font: 90%/1.45em "Helvetica Neue", HelveticaNeue, Verdana, Arial, Helvetica, sans-serif;
        margin: 0;
        padding: 0;
        color: #333;
        background-color: #fff;
    }
      
        </style>
    </head>
    
    <body>
        <div class="container">
            <input type="text" class="global_filter" id="global_filter">
            <div class="clearfix"></div>
            <ul class="nav nav-tabs">
                <li class="active"> <a href="#1" data-toggle="tab">Weekly Measures</a>
                </li>
                <li><a href="#2" data-toggle="tab">Overall Measures</a>
                </li>
                <li><a href="#3" data-toggle="tab">Points</a>
                </li>
            </ul>
            <div class="tab-content ">
                <div class="tab-pane active" id="1">
                    <table id="weeklytable" class="table table-striped table-hover table-bordered" width="100%">
                        <thead>
                            <tr>
                                <th>Name</th>
                                <th>Weekly Weight &Delta;</th>
                                <th>Weekly Steps</th>
                                <th>Weekly Exercise Minutes</th>
                            </tr>
                        </thead>
                        <tfoot>
                            <tr>
                                <th>Name</th>
                                <th>Weekly Weight &Delta;</th>
                                <th>Weekly Steps</th>
                                <th>Weekly Exercise Minutes</th>
                            </tr>
                        </tfoot>
                    </table>
                </div>
                <div class="tab-pane" id="2">
                    <table id="overalltable" class="table table-striped table-hover table-bordered" width="100%">
                        <thead>
                            <tr>
                                <th>Name</th>
                                <th>Overall Weight &Delta;</th>
                                <th>Overall Steps</th>
                                <th>Overall Exercise Minutes</th>
                            </tr>
                        </thead>
                        <tfoot>
                            <tr>
                                <th>Name</th>
                                <th>Overall Weight &Delta;</th>
                                <th>Overall Steps</th>
                                <th>Overall Exercise Minutes</th>
                            </tr>
                        </tfoot>
                    </table>
                </div>
                <div class="tab-pane" id="3">
                    <table id="pointstable" class="table table-striped table-hover table-bordered" width="100%">
                        <thead>
                            <tr>
                                <th>Name</th>
                                <th>Step Points</th>
                                <th>Minutes Points</th>
                            </tr>
                        </thead>
                        <tfoot>
                            <tr>
                                <th>Name</th>
                                <th>Step Points</th>
                                <th>Minute Points</th>
                            </tr>
                        </tfoot>
                    </table>
                </div>
            </div>
        </div>
        </div>
    </body>
    <script>
        function loadData() {
    console.clear();
    let webUrl = _spPageContextInfo.webAbsoluteUrl;
    var mili = new Request(webUrl + "/_api/lists/getbytitle('ContestInformation')/items?$select=Name/Id,Name/Title,Weight,WeeklyWeight,Steps,WeeklySteps,ExerciseMinutes,WeeklyExerciseMin,StepPoints,MinutePoints&$expand=Name"
        ,{
            method: 'GET',
            headers: new Headers({
                "Accept": "application/json; odata=verbose",
            })
        });
        fetch(mili)
        .then((response) => response.json())
        .then((data) => {
            if (data.d != null && data.d != undefined && data.d.results.length > 0) {
                var table = $('#weeklytable').DataTable();
                var table1 = $('#overalltable').DataTable();
                var table2 = $('#pointstable').DataTable();
                table.rows.add(data.d.results).draw();
                            table1.rows.add(data.d.results).draw();
                          table2.rows.add(data.d.results).draw();
            }
            console.log(item.Name, item.Weight, item.WeeklyWeight, item.Steps, items.WeeklySteps, item.ExerciseMinutes, item.WeeklyExerciseMin, item.StepPoints, item.MinutePoints);
            console.log(item.Name.Title);
        });
    }
    
    $(document).ready( function () {
            function filterGlobal () {
                $('#weeklytable').DataTable().search(
                    $('#global_filter').val()
                ).draw();
                $('#overalltable').DataTable().search(
                    $('#global_filter').val()
                ).draw();
                $('#pointstable').DataTable().search(
                    $('#global_filter').val()
                ).draw();
            }
              
              var table = $('#weeklytable').DataTable({
                    "ajax": "/ajax/objects.txt",
                    "columns": [
                        { "data": "Name.Title" },
                        { "data": "WeeklyWeight" },
                        { "data": "WeeklySteps" },
                        { "data": "WeeklyExerciseMin" }
                    ]
        }); 
              var table1 = $('#overalltable').DataTable({
                    "ajax": "/ajax/objects.txt",
                    "columns": [
                        { "data": "Name.Title" },
                        { "data": "Weight" },
                        { "data": "Steps" },
                        { "data": "ExerciseMinutes" }
                    ]   
              });
              var table2 = $('#pointstable').DataTable({
                    "ajax": "/ajax/objects.txt",
                    "columns": [
                        { "data": "Name.Title" },
                        { "data": "StepPoints" },
                        { "data": "MinutePoints" }
                    ]   
              });
            
              $('input.global_filter').on( 'keyup click', function () {
                filterGlobal();
              } );
            
             
            } );
    </script>
    </html>
    
  • zgoforthzgoforth Posts: 493Questions: 98Answers: 2

    Then when I try to load into live web server through VSC,

    DataTables warning: table id=weeklytable - Ajax error. For more information about this error, please see http://datatables.net/tn/7
    

    I get this for every table id

  • zgoforthzgoforth Posts: 493Questions: 98Answers: 2

    It is because of

    "ajax": "/ajax/objects.txt",
    

    under each var table = $

    I am unsure what to replace that with as I have not used ajax/am not using ajax but instead a fetch.

    I removed those leaving this:

    var table = $('#weeklytable').DataTable({
                    "columns": [
                        { "data": "Name.Title" },
                        { "data": "WeeklyWeight" },
                        { "data": "WeeklySteps" },
                        { "data": "WeeklyExerciseMin" }
                    ]
        }); 
    

    and so on. But now, I am still getting the error:

    jquery.min.js:2 Uncaught TypeError: $(...).DataTable is not a function
        at HTMLDocument.<anonymous> (DataTable.aspx?PageView=Shared&InitialTabId=Ribbon.WebPartPage&VisibilityContext=WSSWebPartPage:684)
        at e (jquery.min.js:2)
        at t (jquery.min.js:2)
    
  • kthorngrenkthorngren Posts: 20,270Questions: 26Answers: 4,765
    edited March 2021 Answer ✓

    I copied your code into this test case:
    http://live.datatables.net/telehezu/1/edit

    I changed the url to use /ajax/objects.txt and the columns.data to match the data structure. Added a call to loadData() and the code works.

    $(...).DataTable is not a function

    Hard to day what the problem is. Take a look at the line the error is on and see what the selector ($(...)) is and make sure it exists. Can you update the test case to show the problem? Or provide a link to your page?

    Kevin

  • zgoforthzgoforth Posts: 493Questions: 98Answers: 2

    It worked perfectly, I forgot to call loadData() thats why thank you much sir

This discussion has been closed.