Metadata for uploaded documents

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

2 Likes

Is there a way to take the current name and attach the ID from the document to it? So the new name ist Test__10.pdf.
Here is my code.
Currently, the name is being changed via a workflow, but it would be nice if it could take place directly here.

fd.control(listOrLibrary).$on('filesUploaded',
    function(itemIds) {
        //get document library by Title
        
        var library = pnp.sp.web.lists.getByTitle(docLibraryTitle);
        
        //go through each uploaded Item Id and set field values
        library.getListItemEntityTypeFullName().then(function(entityTypeFullName){
            var newTitle= library.getListItemEntityTypeFullName();
            var batch = pnp.sp.web.createBatch();

            for(var i = 0; i < itemIds.length; i++){
                newTitle=  newTitle +'__'+library.items.getById(itemIds[i]);
                console.log(newTitle);
                //specify which fields to update and how
                library.items.getById(itemIds[i]).inBatch(batch).update({
                
                Name: newTitle, Data: fd.field('Attachments_x0020_document_x0020').value, Description0: fd.field('Description').value
                }, "*", entityTypeFullName);
                    
            }

            batch.execute().then(function(){
                fd.control(listOrLibrary).refresh();
            });
        });
});

Hello @Sternchen,

Please use this code to update file name:

var listOrLibrary = 'SPDataTable1';
//find the ID in the library settings page URL
var docLibraryId = 'e7503442-3db9-4f43-a10f-30637ca2083a';

fd.control(listOrLibrary).$on('filesUploaded',
    function(itemIds) {
        //get document library by ID
        var library = pnp.sp.web.lists.getById(docLibraryId);
        //go through each uploaded Item Id and set field values
        library.getListItemEntityTypeFullName().then(function(entityTypeFullName) {

            var batch = pnp.sp.web.createBatch();
            var currentName;
            var uri;


            for (var i = 0; i < itemIds.length; i++) {
                //specify which fields to update and how
                var itemId = itemIds[i];
                library.items.getById(itemId).select('FileRef', 'Id').get().then(function(item) {
                    return item

                }).then(function(item) {
                    uri = item.FileRef;
                    var fileID = item.Id;
                    filename = uri.substring(uri.lastIndexOf("/") + 1, uri.lastIndexOf(".")) + "_" + fileID;
                    var nbatch = pnp.sp.web.createBatch();
                    library.items.getById(fileID).inBatch(nbatch).update({
                        FileLeafRef: filename
                    }, "*", entityTypeFullName)
                    nbatch.execute().then(function() {
                        fd.control(listOrLibrary).refresh();
                    });
                });
            }
        });
    });

I tried your code and this happens:


I used the id from my url

image
What have I done wrong?

@Sternchen,

As I can tell there are more errors. Please share screenshot of all errors from the console.

Is this SharePoint 2019?

Yes, sorry it is sharepoint 2019.

@Sternchen,

Are the list for which the form is designed and the related document library on different sites?

If so, you should update the code:

var listOrLibrary = 'SPDataTable1';
//find the ID in the library settings page URL
var docLibraryId = '649776e6-7979-4bbd-82ec-109a2c05e23f';
//specify your site URL
let web = new Web('http://contoso.sharepoint.com/sites/Marketing')

fd.control(listOrLibrary).$on('filesUploaded',
    function(itemIds) {
        //get document library by ID
        var library = web.lists.getById(docLibraryId);
        //go through each uploaded Item Id and set field values
        library.getListItemEntityTypeFullName().then(function(entityTypeFullName) {

            var batch = web.createBatch();
            var currentName;
            var uri;


            for (var i = 0; i < itemIds.length; i++) {
                //specify which fields to update and how
                var itemId = itemIds[i];
                library.items.getById(itemId).select('FileRef', 'Id').get().then(function(item) {
                    return item

                }).then(function(item) {
                    uri = item.FileRef;
                    var fileID = item.Id;
                    filename = uri.substring(uri.lastIndexOf("/") + 1, uri.lastIndexOf(".")) + "_" + fileID;
                    var nbatch = web.createBatch();
                    library.items.getById(fileID).inBatch(nbatch).update({
                        FileLeafRef: filename
                    }, "*", entityTypeFullName)
                    nbatch.execute().then(function() {
                        fd.control(listOrLibrary).refresh();
                    });
                });
            }
        });
    });

No, they are on the same site.

@Sternchen,

What is the type of this portal? The URL is strange, it must be sites instead of groups.

Please try the code I've shared. Are you getting the same error?