Metadata for uploaded documents

Good Morning,

is there a way of adding additional Metadata to documents uploaded through a List or Library Control something along the lines of the updateDroppedDocuments function that existed within Forms Designer?

Thanks

Dear Tony,

Please consider “filesUploaded” event of the List/Library control: https://plumsail.com/docs/forms-sp/javascript/controls.html

Knowing the IDs of uploaded files, it’s possible to update their metadata with the help of Pnp JS: https://github.com/pnp/pnpjs/blob/dev/packages/sp/docs/items.md

Hi Alex,

I have eventually got around to implementing this functionality and it is working well, the one thing I would like to do is rename the uploaded document, I can’t see any documentation anywhere on how to do this…
Could you help on this if possible, how would I add this to the code below?

// Function to update MetaData on Upload Documents
function updateMetadata(uploadedItemId) {
	var companyId = fd.field('Company_x0020_Name').value.LookupId;
	var addressId = fd.field('Address_x0020_Name').value.LookupId;
	var contactId = null;
	var contact = fd.field('Contact_x0020_Name').value;
	if (contact != null && contact != '') {
		contactId = fd.field('Contact_x0020_Name').value.LookupId;
	}
	var typeOfActivity = fd.field('Type_x0020_of_x0020_Activity').value;
	var activityReference = fd.field('Title').value;		
	var list = pnp.sp.web.lists.getByTitle("Work%20Item%20Repository");
	list.items.getById(uploadedItemId).update({
		Company_x0020_NameId: companyId,
		Address_x0020_NameId: addressId,
		Contact_x0020_NameId: contactId,
		Type_x0020_of_x0020_Activity: typeOfActivity,
		Title: activityReference
	}).then(function(){
	    console.log("Updated!");
		fd.control('SPDataTable1').refresh();
	})		
}

Thanks

Dear @Tony_Duke,
You just need to change FileLeafRef property, for example, like this:

...
var newName = "HelloWorld";    
var list = pnp.sp.web.lists.getByTitle("Documents2");
list.items.getById(uploadedItemId).update({
    ...
    FileLeafRef: newName
}).then(function(){
    console.log("Updated!");
    fd.control('SPDataTable1').refresh();
})

P.S. Be careful with folders, as it also contains path to file.

Hi Guys,

So I am now looking at implementing this with a little more functionality, nothing too complicated but I can't work it out. As above I need to rename the document, but I actually need to use the current file name in the new name i.e. current name = 1234.pdf - new name = company - site - 1234.pdf. Should be fairly easy but I can't seem to retrieve the current name of the file prior to the rename: -

var list = pnp.sp.web.lists.getByTitle("Site%20Documents");
	var currentName = '';
	list.items.getById(uploadedItemId).get().then(function (item) {
		console.log(item);
		currentName = item.FileLeafRef;
	});
	var newName = contractReference + ' - ' + siteCompanyName + ' - ' + siteAddressName + ' - PO - ' + currentName;
	console.log(newName);

I simply get nothing returned from the code and no errors or anything in the console.

Thanks

Dear @Tony_Duke,
Unfortunately, it seems impossible to retrieve FileLeafRef when getting item by Id, you can use the following trick instead:

list.items.select("FileLeafRef", "FileRef").filter("Id eq " + uploadedItemId).get().then(function(items) {
    var currentName = items[0].FileLeafRef;
    var newName = contractReference + ' - ' + siteCompanyName + ' - ' + siteAddressName + ' - PO - ' + currentName;
    console.log(newName);
});

Keep in mind that this is an async function, so everything that you want to be a result (like newName value) must be either placed inside or called from inside. Otherwise newName will simply be assigned before the information is retrieved.

On file upload is the script below. Our intention is to rename the files on upload of course. This time, the new filename must contain the uploaded filename. We used the original script to rename a file but added this part to retrieve the original filename.

library.items.select("FileLeafRef", "FileRef").filter("Id eq " + itemIds[i]).get().then(function(items) {
  currentName = items[0].FileLeafRef;
  var extension = currentName.substring(currentName.lastIndexOf(".")+1);
  var fname = currentName.substring(0, currentName.lastIndexOf('.'));
  finalName = newfilename + ' ' + fname + ' ' + newDate + '.' + extension;
  alert(currentName);                        
})

We get the uploaded file name and pull it apart as needed. Then we expect to move on to the actual renaming but we never get any of the global var's set in the above script for this section.

library.items.getById(itemIds[i]).inBatch(batch).update({
  Title: currentName
}, "*", entityTypeFullName);
  }
batch.execute().then(function(){
   fd.control('Documents').refresh();
  alert('Refreash Complete');

Full upload script in the

fd.spRendered(function() {

fd.control('Documents').$on('filesUploaded',
        function(itemIds) {
            var library = pnp.sp.web.lists.getByTitle('Project Documents');
            library.getListItemEntityTypeFullName().then(function(entityTypeFullName){
                var batch = pnp.sp.web.createBatch();
                statusdate = fd.field('Status_x0020_Date').value;
                var newDate = convertDate(statusdate);
                for(var i = 0; i < itemIds.length; i++){
                    alert('Count = ' + i);
                    library.items.select("FileLeafRef", "FileRef").filter("Id eq " + itemIds[i]).get().then(function(items) {
                        currentName = items[0].FileLeafRef;
                        var extension = currentName.substring(currentName.lastIndexOf(".")+1);
                        var fname = currentName.substring(0, currentName.lastIndexOf('.'));
                        finalName = newfilename + ' ' + fname + ' ' + newDate + '.' + extension;
                        alert(currentName);                        
                    })
                    library.items.getById(itemIds[i]).inBatch(batch).update({
                        Title: currentName
                    }, "*", entityTypeFullName);
                }
                batch.execute().then(function(){
                    fd.control('Documents').refresh();
                    alert('Refreash Complete');
                
            });
        });
    });

I'm sure it's simple, just need a push?

Hello @Office365guy,

I'm sorry for the delayed reply.

library.items.select("FileLeafRef", "FileRef").filter("Id eq " + itemIds[i]).get().then(function(items) {
This is an asynchronous function and it can't be used with inBatch.

You can either update each uploaded file separately or create the array of new names and then get a new name under batch request.

I am having trouble updating the Metadata on uploaded documents. Here is my code. I have been over it multiple times and cannot figure out what I have done wrong. Any help is appreciated!

fd.spRendered(function(ctx) {
$('.hideMe').hide();
fd.field('Project_x0020_Manager').disabled=true;
fd.field('Title').disabled=true;
fd.field('Project_x0020_Description').disabled=true;
var docdt = fd.control('Documents');
var docLibraryTitle = 'Project Documents';
var combo = fd.field('Project_x0020_Description').value;
//var whereUpload = String(docLibraryTitle + '/' + combo + '/05 Purchasing');
//alert(whereUpload);

docdt.$on('ready', function() {
    docdt.baseRootFolder = String(combo + '/05 Purchasing');
});

function uploadReady() {
    var addDoc = fd.field('AddDocument').value;
    if (addDoc == '-') {
        fd.control('Documents').readonly = true;
    } else {
        fd.control('Documents').readonly = false;
    }
};

uploadReady();

fd.field('AddDocument').value = '-';
fd.field('AddDocument').$on('change', uploadReady);

docdt.$on('filesUploaded', function(itemsIds) {
        var newTitle = fd.field('AddDocument').value;
        var library = pnp.sp.web.lists.getByTitle(docLibraryTitle);
        //go through each uploaded Item Id and set field values
        library.getListItemEntityTypeFullName().then(function(entityTypeFullName){
            var batch = pnp.sp.web.createBatch();
            for(var i = 0; i < itemIds.length; i++){
                //specify which fields to update and how
                library.items.getById(itemIds[i]).inBatch(batch).update({
                    Title: newTitle
                }, "*", entityTypeFullName);
            }
            batch.execute().then(function(){
                doctdt.refresh();
            });
        });
        fd.field('AddDocument').value = '-';
    });

function setStatus () {
    fd.field('Received_x0020_Status').value = fd.field('Received').value;
};

setStatus();
fd.field('Received').$on('change', setStatus);
});

Hello @cwalter2,

You have typos in your code, precisely the name of docdt variable and itemIds. I've updated this part of the code, see below:

docdt.$on('filesUploaded', function(itemIds) {
        var newTitle = 'new name';
        var library = pnp.sp.web.lists.getByTitle(docLibraryTitle);
        //go through each uploaded Item Id and set field values
        library.getListItemEntityTypeFullName().then(function(entityTypeFullName){
            var batch = pnp.sp.web.createBatch();
            for(var i = 0; i < itemIds.length; i++){
                //specify which fields to update and how
                library.items.getById(itemIds[i]).inBatch(batch).update({
                    Title: newTitle
                }, "*", entityTypeFullName);
            }
            batch.execute().then(function(){
                docdt.refresh();
            });
        });
        fd.field('AddDocument').value = '-';
    });

Thank you! It took me a minute even looking at your code to figure out where it was.

1 Like

How can I update 2 fields in this code?

docdt.$on('filesUploaded', function(itemIds) {
var newTitle = 'new name';
var library = pnp.sp.web.lists.getByTitle(docLibraryTitle);
//go through each uploaded Item Id and set field values
library.getListItemEntityTypeFullName().then(function(entityTypeFullName){
var batch = pnp.sp.web.createBatch();
for(var i = 0; i < itemIds.length; i++){
//specify which fields to update and how
library.items.getById(itemIds[i]).inBatch(batch).update({
Title: newTitle
}, "*", entityTypeFullName);
}
batch.execute().then(function(){
docdt.refresh();
});
});
fd.field('AddDocument').value = '-';
});

Hello @danlim26,

You can list all fields that you want to update under the update method like this:

docdt.$on('filesUploaded', function(itemIds) {
        var newTitle = 'new name';
        var library = pnp.sp.web.lists.getByTitle(docLibraryTitle);
        //go through each uploaded Item Id and set field values
        library.getListItemEntityTypeFullName().then(function(entityTypeFullName){
            var batch = pnp.sp.web.createBatch();
            for(var i = 0; i < itemIds.length; i++){
                //specify which fields to update and how
                library.items.getById(itemIds[i]).inBatch(batch).update({
                    Title: newTitle,
                    Description: 'New text'
                }, "*", entityTypeFullName);
            }
            batch.execute().then(function(){
                docdt.refresh();
            });
        });
        fd.field('AddDocument').value = '-';
    });

Please find more information in PnPjs library documentation here:
https://pnp.github.io/pnpjs/sp/items/#update

1 Like