jquery – AJAX POST Request to SharePoint List from HTML Form


I have been working on a project for quite some time now.

Functionality:

  • Read in SharePoint list items from 8 different subsites with a GET request.
  • Populate those items in an orderly(grouped) fashion in a DataTable on a single landing page.
  • DataTable has collapsible/expandable rows grouped by program, followed by deliverable.
  • Dropdown menu with buttons to print/excel/PDF/Update the table.
  • (I figured using an HTML form to send the data back to the corresponding SharePoint list would be easier to update the DataTable rather than writing it to the DataTable then have it send back to the SharePoint List)

Issue:

  • When I fill in the HTML Form, and click submit, the console throws this error:
{
    "readyState": 4,
    "responseText": "{"error":{"code":"-1, Microsoft.SharePoint.Client.InvalidClientQueryException","message":{"lang":"en-US","value":"The parameter __metadata does not exist in method GetByTitle."}}}",
    "responseJSON": {
        "error": {
            "code": "-1, Microsoft.SharePoint.Client.InvalidClientQueryException",
            "message": {
                "lang": "en-US",
                "value": "The parameter __metadata does not exist in method GetByTitle."
            }
        }
    },
    "status": 400,
    "statusText": "error"
}
  • This isn’t the only error that I have gotten, sometimes if this one disappears it will throw a status 403 error aswell

I have watched countless YouTube video tutorials showing the process of how to fix the error/properly perform a CRUD Operation, scanned through a ton of stack overflow posts aswell as sharepoint.stackexchange and MSDN and I have had 0 luck fixing the error. I have kind of been stuck.

Here is my code (actual SharePoint baseurl has been changed):

function loadData() { //Initializing the AJAX Request function to load in the external list data from different subsites
        //create an array of urls to run through the ajax request instead of having to do multiple AJAX Requests
        var urls = ("https://baseurl.sharepoint.com/sites/Projects/USMC/AMMO/_api/web/lists/getbytitle('AMMO Deliverables')/items?$select=Program,Deliverable,To,Date,Approved,Notes",
            "https://baseurl.sharepoint.com/sites/Projects/USMC/DARQ/_api/web/lists/getbytitle('Dar-Q Deliverables')/items?$select=Program,Deliverable,To,Date,Approved,Notes",
            "https://baseurl.sharepoint.com/sites/Projects/USMC/WTBn/_api/web/lists/getbytitle('WTBn Deliverables')/items?$select=Program,To,Date,Approved,Notes,Deliverable",
            "https://baseurl.sharepoint.com/sites/Projects/Army/ODMulti/_api/web/lists/getbytitle('ODMultiDeliverables')/items?$select=Program,To,Date,Approved,Notes,Deliverable",
            "https://baseurl.sharepoint.com/sites/Projects/Army/OE/_api/web/lists/getbytitle('OEDeliverables')/items?$select=Program,To,Date,Approved,Notes,Deliverable",
            "https://baseurl.sharepoint.com/sites/Projects/Army/Doctrine/_api/web/lists/getbytitle('DocDeliverables')/items?$select=Program,To,Date,Approved,Notes,Deliverable",
            "https://baseurl.sharepoint.com/sites/Projects/Army/AHR/_api/web/lists/getbytitle('AHRDeliverables')/items?$select=Program,To,Date,Approved,Notes,Deliverable",
            "https://baseurl.sharepoint.com/sites/Projects/Army/SRC/_api/web/lists/getbytitle('SRCDeliverables')/items?$select=Program,To,Date,Approved,Notes,Deliverable"
        );
    
        for (i = 0; i < urls.length; i++) { //for loop to run through the AJAX until all URLs have been reached
            $.ajax({
                url: urls(i),
                method: "GET",
                headers: {
                    "Accept": "application/json; odata=verbose"
                },
                success: function(data) { // success function which will then execute "GETTING" the data to post it to a object array (data.value)
                    console.log(data);
                    if (data.d != null && data.d != undefined && data.d.results.length > 0) {
                        var table = $('#myTable').DataTable();
                        table.rows.add(data.d.results).draw();
                    }
                }
            });
        }
    }
    
    $(document).ready(function() {
        var collapsedGroups = {};
        var top = '';
        var parent = '';
    
        var table = $('#myTable').DataTable({
        "pageLength" : 50,
            "columns": ({
                    "data": "Program",
                    visible: false
                },
                {
                    "data": "Deliverable",
                    visible: false
                },
                {
                    "data": "To"
                },
                {
                    "data": "Date"
                },
                {
                    "data": "Approved"
                },
                {
                    "data": "Notes"
                }
            ),
    
            dom: "<'row'<'col-sm-12 col-md-10'f><'col-sm-12 col-md-2'B>>" +
                "<'row'<'col-sm-12'tr>>" +
                "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",
            buttons: ({
                extend: 'collection',
                className: "btn-dark",
                text: 'Export/Update Table',
                buttons: ({
                        extend: "excel",
                        className: "btn-dark"
                    },
                    {
                        extend: "pdf",
                        className: "btn-dark"
                    },
                    {
                        extend: "print",
                        className: "btn-dark"
                    },
                    {
                        text: 'Update Table',
                        action: function (e, dt, node, config){
                        $('#myModal').modal('show');
            }
        },
                ),
            }),
            order: (
                (0, 'asc'),
                (1, 'asc')
            ),
            rowGroup: {
                dataSrc: (
                    'Program',
                    'Deliverable'
                ),
                startRender: function(rows, group, level) {
                    var all;
                    if (level === 0) {
                        top = group;
                        all = group;
                    } else if (level === 1) {
                        parent = top + group;
                        all = parent;
                        // if parent collapsed, nothing to do
                        if (!collapsedGroups(top)) {
                            return;
                        }
                    } else {
                        // if parent collapsed, nothing to do
                        if (!collapsedGroups(parent)) {
                            return;
                        }
                        all = top + parent + group;
                    }
    
                    var collapsed = !collapsedGroups(all);
                    console.log('collapsed:', collapsed);
    
                    rows.nodes().each(function(r) {
                        r.style.display = collapsed ? 'none' : '';
                    });
                    //Add category name to the <tr>.
                    return $('<tr/>')
                        .append('<td colspan="8">' + group + ' (' + rows.count() + ')</td>')
                        .attr('data-name', all)
                        .toggleClass('collapsed', collapsed);
    
    
                }
    
            }
        });
    
        loadData();
    
        $('#myTable tbody').on('click', 'tr.dtrg-start', function() {
            var name = $(this).data('name');
            collapsedGroups(name) = !collapsedGroups(name);
            table.draw(false);
        });
    
        $("#btn").click(function(e) {
            PostItem();
        });
    });
    
        function PostItem() {
            return getFormDigest("https://baseurl.sharepoint.com/sites/Projects/USMC/AMMO").then(function(digestData) {
                console.log(digestData.d.GetContextWebInformation.FormDigestValue);
                $.ajax({
                    async: true, // Async by default is set to “true” load the script asynchronously  
                    // URL to post data into sharepoint list  or your own url
                    url: "https://baseurl.sharepoint.com/sites/Projects/USMC/AMMO/_api/web/lists/getbytitle('AMMO Deliverables')",
                    method: "POST", //Specifies the operation to create the list item  
                    data: JSON.stringify({  
                        '__metadata': {  
                            'type': getItemTypeForListName("AMMO Deliverables") // it defines the ListEnitityTypeName  
                        }, 
                        Program: $("#dProgram").val(),
                        Deliverable: $("#dDeliverable").val(),
                        To: $("#dTo").val(),
                        Date: $("#dDate").val(),
                        Approved: $("#dApproved").val(),
                        Notes: $("#dNotes").val()
                    }),
                    headers: {
                        "content-type": "application/json;odata=verbose", //It defines the content type as JSON
                        "X-RequestDigest": digestData.d.GetContextWebInformation.FormDigestValue,
                        "Accept": "application/json;odata=verbose",
                        "If-Match": "*"
                    },
                    success: function(data) {
                        alert('Success'); // Used sweet alert for success message
                    },
                    error: function(error) {
                        alert(JSON.stringify(error));
                        console.log(JSON.stringify(error));
    
                    }
    
                });
            })
        }
            function getItemTypeForListName(listName) {
                var itemType = "SP.Data." + listName.charAt(0).toUpperCase() + listName.slice(1) + "ListName";
                var encItemType = itemType.replace(/s/g,'_x0020_');
                return(encItemType);
    }       
        function getFormDigest(baseurl) {
    
            return $.ajax({
    
                url: "https://baseurl.sharepoint.com/sites/Projects/USMC/AMMO/_api/contextInfo",
    
                method: 'POST',
    
                headers: {
                    'Accept': 'application/json; odata=verbose'
                }
    
            });
            }   
#myform {
                margin:0 auto;
                width:250px;
                padding:14px;
                align: center;
            }

            label {
                width: 10em;
                float: left;
                margin-right: 0.5em;
                display: block;
                vertical-align: middle;
            }
            .submit {
                float:right;
            }
            h1{
            text-align: center;
            }
            
            fieldset {
                background:#EBF4FB none repeat scroll 0 0;
                border:2px solid #B7DDF2;
                width: 450px;
            }

            legend {
                color: #fff;
                background: #80D3E2;
                border: 1px solid #781351;
                padding: 2px 6px;
                text-align: center;
            }
            .elements {
                padding:10px;
            }
            p {
                border-bottom:1px solid #B7DDF2;
                color:#666666;
                font-size:12px;
                margin-bottom:20px;
                padding-bottom:10px;
            }
            span {
                color:#666666;
                font-size:12px;
                margin-bottom:1px;
                
            }
            .btn{
            padding: 4px 12px;
            margin-bottom: 0;
            font-size: 14px;
            line-height: 20px;
            color: #333333;
            text-align: center;
            text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
            vertical-align: middle;
            cursor: pointer;
            background-color: #f5f5f5;
            border: 1px solid #B7DDF2;
            
            }

            .btn:hover{
            color: #333333;
            background-color: #e6e6e6;
            }

            div.container {
                min-width: 980px;
                margin: 0 auto;
            }
            .header {
            padding: 10px;
            text-align: center;
            }
            body {
                font: 90%/1.45em "Helvetica Neue", HelveticaNeue, Verdana, Arial, Helvetica, sans-serif;
                margin: 0;
                padding: 0;
                color: #333;
                background-color: #fff;
            }
            div.dt-button-collection {
                position: static;
            }#myform {
                margin:0 auto;
                width:250px;
                padding:14px;
                align: center;
            }

            label {
                width: 10em;
                float: left;
                margin-right: 0.5em;
                display: block;
                vertical-align: middle;
            }
            .submit {
                float:right;
            }
            h1{
            text-align: center;
            }
            
            fieldset {
                background:#EBF4FB none repeat scroll 0 0;
                border:2px solid #B7DDF2;
                width: 450px;
            }

            legend {
                color: #fff;
                background: #80D3E2;
                border: 1px solid #781351;
                padding: 2px 6px;
                text-align: center;
            }
            .elements {
                padding:10px;
            }
            p {
                border-bottom:1px solid #B7DDF2;
                color:#666666;
                font-size:12px;
                margin-bottom:20px;
                padding-bottom:10px;
            }
            span {
                color:#666666;
                font-size:12px;
                margin-bottom:1px;
                
            }
            .btn{
            padding: 4px 12px;
            margin-bottom: 0;
            font-size: 14px;
            line-height: 20px;
            color: #333333;
            text-align: center;
            text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
            vertical-align: middle;
            cursor: pointer;
            background-color: #f5f5f5;
            border: 1px solid #B7DDF2;
            
            }

            .btn:hover{
            color: #333333;
            background-color: #e6e6e6;
            }

            div.container {
                min-width: 980px;
                margin: 0 auto;
            }
            .header {
            padding: 10px;
            text-align: center;
            }
            body {
                font: 90%/1.45em "Helvetica Neue", HelveticaNeue, Verdana, Arial, Helvetica, sans-serif;
                margin: 0;
                padding: 0;
                color: #333;
                background-color: #fff;
            }
            div.dt-button-collection {
                position: static;
            }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel ="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.css"/>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://momentjs.com/downloads/moment.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.flash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.html5.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.print.min.js"></script>
<script src="https://cdn.datatables.net/rowgroup/1.1.2/js/dataTables.rowGroup.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.3/js/buttons.bootstrap4.min.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/dataTables.bootstrap4.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
<link rel ="stylesheet" href="https://cdn.datatables.net/rowgroup/1.1.2/css/rowGroup.bootstrap4.min.css"/>
<link rel ="stylsheet" href="https://cdn.datatables.net/1.10.21/css/dataTables.bootstrap4.min.css"/>
<link rel ="stylesheet" href="https://cdn.datatables.net/buttons/1.6.3/css/buttons.bootstrap4.min.css"/>
<h1><strong>G3G Deliverables</strong></h1>
        <div class ="container">
            <table id="myTable" class="table table-bordered" cellspacing="0" width="100%">
                <thead class="thead-dark">
                    <tr>
                    <th>Program</th>
                    <th>Deliverable</th>
                    <th>To</th>
                    <th>Date</th>
                    <th>Approved</th>
                    <th>Notes</th>
                    </tr>
                </thead>
            </table>
            </div>
             <meta name="_csrf" content="${_csrf.token}"/>
        <meta name="_csrf_header" content="${_csrf.headerName}"/>
        <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title" id="myModalLabel">Update DataTable</h4>
      </div>
      <div class="modal-body">
            <form id="myform" type="post" runat="server">
                <SharePoint:FormDigest ID="myForm" runat="server">
                <fieldset>
                    <legend align="center">Update Datatable</legend>
                    <p>Please fill out the shown fields to add data to the DataTable</p>
                    <div class="elements">
                    <label for="program">Program :</label>
                    <select name = "program" id="dProgram">
                            <option value = "AHR">AHR</option>
                            <option value = "AMMO">AMMO</option>
                            <option value = "DAR-Q">DAR-Q</option>
                            <option value = "Doctrine Development">Doctrine Development</option>
                            <option value = "Operational Energy">Operational Energy</option>
                            <option value = "Ordnance Multimedia">Ordnance Multimedia</option>
                            <option value = "SRC Handbook">SRC Handbook</option>
                            <option value = "WTBn">WTBn</option>
                        </select>
                    </div>
                    <div class="elements">
                    <label for="Deliverable">Deliverable :</label>
                    <select name="Deliverable" id="dDeliverable">
                            <option value = "Meeting Minutes">Meeting Minutes</option>
                            <option value = "Monthly Status Report (MSR)">Monthly Status Report (MSR)</option>
                            </select>
                    </div>  
                    <div class="elements">
                    <label for="To"> To:</label>
                    <input type="text" align= "center" id="dTo" name="To" placeholder="example@example.com">
                    </div>      
                    <div class="elements">
                    <label for="Date">Date: </label>
                    <input type="date" align= "center" id="dDate" name="Date" placeholder="MM/DD/YYYY"> 
                    </div>  
                    <div class="elements">
                    <label for="Approved">Approved :</label>
                    <select name="Approved" id="dApproved">
                            <option value = "True">Yes</option>
                        <option value = "False">No</option></select>
                    </div>  
                    <div class="elements">
                    <label for="Notes"> Notes :</label>
                    <input type="text" align= "left" id="dNotes" name="Notes" placeholder="Please provide notes">
                </div>
                <div class="submit">
                    <input type="submit" id="btn" name="btn" class="btn" value="Submit" />
                    </div>
                </fieldset>
                </SharePoint:FormDigest>
            </form>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
      </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->