0

Searching for how to use javascript or jquery to add an attachment to a list item? Been having a hard time with this. Any good tutorials or articles?

1

Definitely doable. You need to use a FileReader to create a buffer of your file, and if you get your list item (also via REST) that you want to add the attachment to, it has a property that has the correct URL to post to that is specific to that particular list item.

Disclaimer: the following code was originally written using ES6 fat arrow function syntax with actual Promises, and used axios.js to make the AJAX calls. I very quickly re-wrote it to use ES5 syntax and jQuery. It is completely untested as it is here, and I might have made a mistake somewhere when rewriting, so it might not actually work, but at least you will get the idea of the general steps:

function getFileBuffer (file) {
    var dfd = new $.Deferred();
    var reader = new FileReader();
    reader.onload = function (e) {
        dfd.resolve(e.target.result);
    };
    reader.onerror = function (e) {
        dfd.reject(e.target.error);
    };
    reader.readAsArrayBuffer(file);
    return dfd;
};

function uploadAttachment (file, spListItem) {

    // in this example i'm passing in the SP List Item that you want to upload the attachment to.
    // you need the list item because the URL to use to upload attachments is in a property
    // on the list item.  conceivably you could wite your code to retreive the item by ID or
    // something right here instead of passing it in.
    //
    // in any case, you need the item because:

    var attachmentBaseUrl = spListItem.AttachmentFiles.__deferred.uri;

    // you have to encode any single quotes in the file name
    // because it will mess with the uri of the REST request
    var fileName = file.name;
    var encodedFileName = encodeURIComponent(fileName).replace(/'/g, '%27%27');

    getFileBuffer(file).then(function (buffer) {
        var restUri = attachmentBaseUrl + "/add(FileName='" + encodedFileName + "')";
        $.ajax({
            url: restUri,
            method: 'POST',
            data: buffer,
            processData: false,
            headers: {
                accept: 'application/json;odata=verbose',
                'X-RequestDigest': document.getElementById('__REQUESTDIGEST').value
            }
        }).then(function (result) {

            // do something with the result?

        }).catch(function (err) {
            console.log('file upload error:', err);
        });
    }).catch(function (err) {
        console.log('file reader error:', err);
    });
};
0

The following code example for your reference. Add the code into a script editor web part in page.

<script src="https://code.jquery.com/jquery-1.12.4.min.js" type="text/javascript"></script>
<script>
function AddAttachments(){
    var listName=$("#listname").val();
    var itemId=$("#itemId").val();
    if(listName!=""&&itemId!=""){
        var fileInput = $('#uploadFile');
        var fileName = fileInput[0].files[0].name;
        var reader = new FileReader();
        reader.onload = function (e) {
            var fileData = e.target.result;
            var res11 = $.ajax({                             
                url: _spPageContextInfo.webAbsoluteUrl+"/_api/web/lists/getbytitle('"+listName+"')/items("+itemId+")/AttachmentFiles/ add(FileName='" + fileName + "')",                                       
                method: "POST",
                binaryStringRequestBody: true,
                data: fileData,
                processData: false,
                headers: {
                    "ACCEPT": "application/json;odata=verbose",                                                                                                                                   
                    "X-RequestDigest": $("#__REQUESTDIGEST").val(),
                    "content-length": fileData.byteLength
                },                                                                                                                            
                success: function (data) {                                            
                    alert("Success.");
                },
                error: function (data) {
                    alert("Error occured." + data.responseText);
                }
            });
        };
        reader.readAsArrayBuffer(fileInput[0].files[0]);  
    }else{
        alert("The listname and itemId can not be empty.");
    }

}
</script>
<div>
    <p>ListName:<input id="listname" type="textbox"/>&nbsp; ItemId:<input id="itemId" type="textbox"/></p>
    <p><input id="uploadFile" type="file"><input type="button" onclick="AddAttachments()" value="Add Attachments"></input></p>
</div>

enter image description here

  • It seems awfully restrictive to hard code the list name and the item ID. You would have to go in and edit the code if you wanted to upload an attachment somewhere else, or for a different list item. – Dylan Cristy Apr 11 at 18:52
  • I modify the code in reply above, you can check it. – LZ_MSFT Apr 12 at 1:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.