Wednesday, August 24, 2011

What the hack?!? Not OOTB, but OTS

Adding metadata to uploaded documents automaticly, based on the context from where the Upload action was started.


From a dashboard (webpart page with related lists and library combined) I want to be able to start an upload action to add project documents to the library and want metadata (like project number, document type) added automaticly afterwards.
Well this is certainly not OOTB SharePoint. Normally you would set default values to columns before the upload, or use the Edit in Datasheet view to copy and paste properties to the documents after the upload.

We are going to combine several Off-The-Shelf scripts to get to the solution.
  1. TextToHTML-script from PathToSharePoint to render HTML-code from a calculated column so I can show an icon as upload "button" in the list view with a hyperlink that will call a javascript function with project data as variables.
  2. “sessvars.js” from Thomas Frank, also frequently used by Alexander from SharePoint JavaScripts, that let you use JavaScript session variables without using cookies. In this way I am able to store the context before the upload, and use it afterwards.
  3. SPServices, a jQuery Library for SharePoint Web Services, to use the function $().SPServices.SPUpdateMultipleListItems to update the document properties after the upload.
Download the scripts and add them to a Javascripts library in the site collection.


So I have a list for my projects and I will add a calculated column with HTML-code:
="<a href='javascript:upload(&#39;"&Projectnumber&"&#39;,&#39;Reports&#39;);'><img src='/_layouts/images/upload.gif' border='0' alt='Reports'></a>"

Then add a CEWP at the bottom of the dashboard page and paste the following script in the Source editor:

<script src="/Javascripts/sessvars.js" type="text/javascript"></script>
<script type="text/javascript">
sessvars.$.clearMem();
function upload(projectNumber,docType){
  sessvars.projectNumber = projectNumber;
  sessvars.docType = docType;
  sessvars.userId = _spUserId;
  var targetUrl = "/_layouts/Upload.aspx?List=%7BE69813A0%2D6E90%2D4D26%2D852A%2DBE0952C165CB%7D&RootFolder=%2FDocuments&Source=http%3A%2F%2Fwww%2Esharepointserver%2Eeu%2FPages%2FJavascript%2Easpx&MultipleUpload=1";
  window.location.href = targetUrl;
}
</script>

<script type="text/javascript">
/*
Text to HTML Lite - version 2.1.1
Questions and comments: Christophe@PathToSharePoint.com
*/
function TextToHTML(NodeSet, HTMLregexp) {
var CellContent = "";
var i=0;
while (i < NodeSet.length){
try {
CellContent = NodeSet[i].innerText || NodeSet[i].textContent;
if (HTMLregexp.test(CellContent)) {NodeSet[i].innerHTML = CellContent;}
} 
catch(err){}
i=i+1;
}
}
// Calendar views
var regexpA = new RegExp("\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*");
TextToHTML(document.getElementsByTagName("a"),regexpA);
// List views
var regexpTD = new RegExp("^\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*$");
TextToHTML(document.getElementsByTagName("TD"),regexpTD);
</script>

The list view will show an upload button thanks to the TextToHTML script.
The javascript function will add the project number, document type and current user to the session variables, followed by a redirect to the standard upload page. You should replace the targetUrl with your own (click Upload Multiple Documents in the target library and copy the url). The source parameter refers to another page with javascript: /Pages/Javascript.aspx


Next step is to create this web part page, add a CEWP and paste the following script in the Source editor:

<script src="/Javascripts/sessvars.js" type="text/javascript"></script>
<script src="/Javascripts/jquery-1.6.2.min.js" type="text/javascript"></script>
<script src="/Javascripts/jquery.SPServices-0.6.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
var projectNumber = sessvars.projectNumber;
var docType = sessvars.docType;
var userId = sessvars.userId;
if((projectNumber!=undefined)&&(docType!=undefined)&&(userId!=undefined)){
  $().SPServices.SPUpdateMultipleListItems({ 
    listName: "Documents",
    CAMLRowLimit: 0,
    CAMLQuery: "<Query><Where><And><Eq><Fieldref Name='Author' LookupId='TRUE'/><Value Type='Integer'>" + userId + "</Value></Eq><IsNull><Fieldref Name='Projectnumber'/></IsNull></And></Where></Query>",
    valuepairs: [["Projectnumber", projectNumber], ["Documenttype", docType]]
  });
  sessvars.$.clearMem();
  window.location.href = "/Pages/Projects.aspx";
}
</script>

The session variables are read out and the values are used to update the documents that are selected by the CAML query: Created By the current user and no project number.
Finally the memory of the session variables is cleared and there's a redirect back to the dashboard page that will show the update document properties.


No comments:

Post a Comment