This post is about a feature that i was expecting some and was launch in @pnp/spfx-controls-react in version V2.1.0, that was the capability to use drag and drop of files in ListView and capture the file object to make the associated actions afterwards.
The following example explain how we can use the ListView Control to use drag and drop option and retrieve the file object from the new handler onDrop event and copy to a SharePoint Document Library.
The first thing that needs to be made is to configure the ListView properties in the control with the following:
- dragDropFiles as True, activates the drag and drop option.
- OnDrop handler, Method this._getDropFiles retrieves files from drop handler.
The handler OnDrop retrieves the files object that allow us to manage the content as we want.
This can be upload files to a libraries, validate what type of file, size of file, naming with capability or renaming, in the end multiple business requirements that can be stop or validated before file is included in the system.
When you test the control using "gulp serve" base in a existing Document Library you can see the normal list of documents as working in the older version.
To activate the drag and drop pick some files and drag to ListView area and upload information focus will appear, in this moment you can leave the files and the upload process can start.
After you drop the files in the List View area the handler drop sends objects to method _getDropFiles and uploads the files to a Document Library as explain the code below.
/**
* Method that retrieves files from drag and drop
* @param files
*/
private _getDropFiles = (files) =>{
let count=0;
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (file != undefined || file != null) {
let spOpts : ISPHttpClientOptions = {
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
},
body: file
};
var url = `${this.props.context.pageContext.web.absoluteUrl}/_api/Web/GetFolderByServerRelativeUrl('Shared%20Documents')/Files/Add(url='${file.name}', overwrite=true)`;
this.props.context.spHttpClient.post(url, SPHttpClient.configurations.v1, spOpts).then((response: SPHttpClientResponse) => {
console.log(`Status code: ${response.status}`);
console.log(`Status text: ${response.statusText}`);
response.json().then((responseJSON: JSON) => {
count++;
if(count=== (files.length) ) {
this.componentDidMount();
}
console.log(responseJSON);
});
});
}
}
}
The following method is a reuse function componentDidMount to make refresh of ListView to display the uploaded files that was managed in method below.
public componentDidMount() {
const restApi = `${this.props.context.pageContext.web.absoluteUrl}/_api/web/GetFolderByServerRelativeUrl('Shared%20Documents')/files?$expand=ListItemAllFields`;
this.props.context.spHttpClient.get(restApi, SPHttpClient.configurations.v1)
.then(resp => { return resp.json(); })
.then(items => {
this.setState({
items: items.value ? items.value : []
});
});
}
/**
* Method that retrieves files from drag and drop
* @param files
*/
private _getDropFiles = async (files) => {
for (var i = 0; i < files.length; i++) {
const fr = await sp.web.lists.getByTitle("Documents").rootFolder.files.configure({
headers: {
"content-length": `${files[i].length}`,
},
}).add(files[i].name, files[i]);
console.log(files[i].name);
}
}