0

My requirements are for user to complete a bootstrap form, attach files, and on submit, create new list item and upload the attachments.

CREATE NEW LIST ITEM

Below code works on adding a new list item:

function addNewItem() {
var newSubject = $("#subject").val();
var newBody = $("#body").val();

var siteUrl = '/sites/XXXX';
var clientContext = new SP.ClientContext(siteUrl);
var oList = clientContext.get_web().get_lists().getByTitle('FAQ2');

//Create new list item
var itemCreateInfo = new SP.ListItemCreationInformation();
var oListItem = oList.addItem(itemCreateInfo);
    oListItem.set_item('Title', newSubject);
    oListItem.set_item('Comments', newBody);
    oListItem.update();

clientContext.load(oListItem);
clientContext.executeQueryAsync(
    function() {
        window.location.replace('/sites/XXXX/Pages/FAQ2.aspx');
    },
);
}

ADDING ATTACHMENTS Source: how to attach file to list sharepoint 2013 via REST API

I inserted below lines above window.location.replace('/sites/XXXX/Pages/FAQ2.aspx');

itemId = oListItem.get_id();
uploadattachment(itemId);

And added below after addNewItem()

var getFileBuffer = function (file) {
    var deferred = $.Deferred();
    var reader = new FileReader();
    reader.onload = function (e) {
        deferred.resolve(e.target.result);
    }
    reader.onerror = function (e) {
        deferred.reject(e.target.error);
    }
    reader.readAsArrayBuffer(file);
    return deferred.promise();
};
function uploadattachment(itemId) {
    if ($("#getFile")[0].files.length > 0) {
        var count = $("#getFile")[0].files.length;
        for(var i=0; i<count; i++) {
            var file = $("#getFile")[0].files[i];
            alert(file.name);
            getFileBuffer(file).then(function (buffer) {
                $.ajax({
                    url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbytitle('FAQ2')/items(" + itemId + ")/AttachmentFiles/add(FileName='" + file.name + "')",
                    method: 'POST',
                    data: buffer,
                    processData: false,
                    headers: {
                        "Accept": "application/json; odata=verbose",
                        "content-type": "application/json; odata=verbose",
                        "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value
                    },
                    success: function () {

                    },
                    error: function (data) {

                    }
                });
            });
        }
    }
}

The above code only uploads 1 attachment. I can't figure how to get it to add subsequent attachments. When i run the alert(file.name); it loops through the files being uploaded but only 1 is attached.

0

You may check the below code for adding multiple attachments to a SharePoint list item :

<script type="text/javascript">
var oLoader;
var attcount = 0;
var arraycount = 0;
$(document).ready(function ($) {
$(‘#file_input’).multifile();//For facilitate multi file upload
$("#NewSaveItem").click(function () { formSave() });
});
function formSave() {
oLoader = SP.UI.ModalDialog.showWaitScreenWithNoClose("Working on it", "Creating New Bank Account…");
for (i = 0; i < count; i++) {
var data = [];
var fileArray = [];
$("#attachFilesHolder input:file").each(function () {
if ($(this)[0].files[0]) {
fileArray.push({ "Attachment": $(this)[0].files[0] });
}
});
data.push({
"Name": $("input[title=’Name’]").val(),
" Address ": $("input[title=’Address’]").val(),
"City": $("input[title= City]").val(),
"ContactNumber": $("input[title=’ContactNumber’]").val(),
"Files": fileArray
});
createNewItemWithAttachments("BankDetails", data).then(
function () {
if (oLoader.close) setTimeout(function () { oLoader.close(); window.location.replace(_spPageContextInfo.siteAbsoluteUrl + "/Lists/BankDetails/AllItems.aspx"); }, 3000);
},
function (sender, args) {
console.log(‘Error occured’ + args.get_message());
}
)
}
}
var createNewItemWithAttachments = function (listName, listValues) {
var fileCountCheck = 0;
var fileNames;
var context = new SP.ClientContext.get_current();
var dfd = $.Deferred();
var targetList = context.get_web().get_lists().getByTitle(listName);
context.load(targetList);
var itemCreateInfo = new SP.ListItemCreationInformation();
var listItem = targetList.addItem(itemCreateInfo);
listItem.set_item("Name", listValues[0].Name);
listItem.set_item("Address", listValues[0].Address);
listItem.set_item("City", listValues[0].City);
listItem.set_item("ContactNumber", listValues[0].ContactNumber);
listItem.update();
context.executeQueryAsync(
function () {
var id = listItem.get_id();
if (listValues[0].Files.length != 0) {
if (fileCountCheck <= listValues[0].Files.length – 1) {
loopFileUpload(listName, id, listValues, fileCountCheck).then(
function () {
},
function (sender, args) {
console.log("Error uploading");
dfd.reject(sender, args);
}
);
}
}
else {
dfd.resolve(fileCountCheck);
}
},
function (sender, args) {
console.log(‘Error occured’ + args.get_message());
}
);
return dfd.promise();
}
function loopFileUpload(listName, id, listValues, fileCountCheck) {
var dfd = $.Deferred();
uploadFileHolder(listName, id, listValues[0].Files[fileCountCheck].Attachment).then(
function (data) {
var objcontext = new SP.ClientContext();
var targetList = objcontext.get_web().get_lists().getByTitle(listName);
var listItem = targetList.getItemById(id);
objcontext.load(listItem);
objcontext.executeQueryAsync(function () {
console.log("Reload List Item- Success");
fileCountCheck++;
if (fileCountCheck <= listValues[0].Files.length – 1) {
loopFileUpload(listName, id, listValues, fileCountCheck);
} else {
console.log(fileCountCheck + ": Files uploaded");
attcount += fileCountCheck;
if (arraycount == attcount) {
if (oLoader.close) setTimeout(function () { oLoader.close(); window.location.replace(_spPageContextInfo.siteAbsoluteUrl + "/Lists/BankDetails/AllItems.aspx"); }, 3000);
}
}
},
function (sender, args) {
console.log("Reload List Item- Fail" + args.get_message());
});
},
function (sender, args) {
console.log("Not uploaded");
dfd.reject(sender, args);
}
);
return dfd.promise();
}

function uploadFileHolder(listName, id, file) {
var deferred = $.Deferred();
var fileName = file.name;
getFileBuffer(file).then(
function (buffer) {
var bytes = new Uint8Array(buffer);
var binary = ";
for (var b = 0; b < bytes.length; b++) {
binary += String.fromCharCode(bytes[b]);
}
var scriptbase = _spPageContextInfo.webServerRelativeUrl + "/_layouts/15/";
console.log(‘ File size:’ + bytes.length);
$.getScript(scriptbase + "SP.RequestExecutor.js", function () {
var createitem = new SP.RequestExecutor(_spPageContextInfo.webServerRelativeUrl);
createitem.executeAsync({
url: _spPageContextInfo.webServerRelativeUrl + "/_api/web/lists/GetByTitle(‘" + listName + "‘)/items(" + id + ")/AttachmentFiles/add(FileName=’" + file.name + "‘)",
method: "POST",
binaryStringRequestBody: true,
body: binary,
success: fsucc,
error: ferr,
state: "Update"
});

function fsucc(data) {
console.log(data + ‘ uploaded successfully’);
deferred.resolve(data);
}

function ferr(data) {
console.log(fileName + "not uploaded error");
deferred.reject(data);
}
});
},
function (err) {
deferred.reject(err);
}
);
return deferred.promise();
}

function getFileBuffer(file) {
var deferred = $.Deferred();
var reader = new FileReader();
reader.onload = function (e) {
deferred.resolve(e.target.result);
}
reader.onerror = function (e) {
deferred.reject(e.target.error);
}
reader.readAsArrayBuffer(file);
return deferred.promise();
}
</script>

Reference URL :

Upload multiple attachments to list items using JSOM and REST API in SharePoint Online/2013/2016

  • i'm getting Cannot read property '0' of undefined in loopFileUpload – Tamras Merin Mar 25 at 17:01
0

I had a similar problem and you need to make sure that the first file is uploaded successfully before trying to upload the next file. Note that I used 3 file input, accepting a single file for each control.

function uploadAttachments(ID, listName, fileControl) {

    var fileDeffered = $.Deferred();

    var fileInput = $("#" + fileControl);

    if(fileInput.get(0).files.length !== 0) {

        var file = fileInput.get(0).files[0];

        var getFileBuffer = function(file) {    
            var deferred = $.Deferred();
            var reader = new FileReader();

                reader.onload = function(e) {
                    deferred.resolve(e.target.result);
                }
                reader.onerror = function(e) {
                    deferred.reject(e.target.error);
                }
                reader.readAsArrayBuffer(file);
            return deferred.promise();
        };

        getFileBuffer(file).then(function(buffer) {
            $.ajax({
                url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbytitle('" + listName + "')/items(" + ID + ")/AttachmentFiles/add(FileName='" + file.name + "')",
                method: 'POST',
                data: buffer,
                processData: false,
                headers: {
                    "Accept": "application/json; odata=verbose",
                    "content-type": "application/json; odata=verbose",
                    "X-RequestDigest": $("#__REQUESTDIGEST").val()
                },
                success: function (data) {
                    fileDeffered.resolve();
                },
                error: function (data) {
                    fileDeffered.reject();
                    errorMsg(data);
                }
            });
        });
    }
    return fileDeffered.promise();
};

Called the above function when the actual list item were successfully created.

success: function (data) {

    var newItemID = data.d.ID;

    if($("input:file").get(0).files.length !== 0) {

        $.when(
            uploadAttachments(newItemID, listName, 'file1').then(function() {
                uploadAttachments(newItemID, listName, 'file2').then(function() {
                    uploadAttachments(newItemID, listName, 'file3').then(function() {
                    })
                })
            })
        ).done(function() {
            successMsg();
        });
    }
    else {
        successMsg();
    }
};

I'm sure there's better ways to solve this but this is how I did it.

  • Thanks but I rather have only 1 input control that accepts multiple files but this is worth looking into if I can't figure out the former – Tamras Merin Mar 25 at 17:55
  • Ah, some slight modifications should be enough, went with multiple options as my users needed to select files from different folders. :) – Christoffer Mar 25 at 18:02

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.