Category Archives: Document library

SPJS Upload for SharePoint: Custom upload page for uploading documents to various document libraries in a site collection

Change log
August 04, 2016
New version that supports opening the EditForm after upload. This can be controlled with a variable:

// Go to EditForm after upload
var showEditFormAfterUpload = true;

Set to false to skip this feature.This new feature requires a few extra fields added to the list with the upload destination – and you must update your function call with these new fields.

If you are crating the <option> manually you must add a few extra attributes – see description in the code where you specify the <option> tags.

I got a request from Gilbert Okello regarding a custom upload solution for submitting documents to various document libraries in a site collection. This solution uses the “CopyIntoItems” method to let the user select a document from the local computer and upload it to a document library / folder within the site collection.
IMG

I must start off emphasizing that this solution requires Internet Explorer 10 or another modern browser to work. There is NO WAY you can make it work in any Internet Explorer version below 10. I have tested it in SP 2010 and SP 2013, but I guess it should work in SP 2007 as well.

The code provided at the bottom of this article builds the upload control by reading a set of predefined upload locations from a custom list. This is the code that builds the dropdown select containing the predefined options:

$(document).ready(function(){
	spjs.upload.getUploadDestinations({
		"listName":"UploadDestination",
 		"listBaseUrl":"",
 		"friendlyNameField":"Title",
 		"relPathField":"RelPath",
 		"baseUrlField":"BaseUrl",
 		"guidField":"DocLibraryGUID",
 		"editFormRelUrlField":"EditFormRelUrl",
 		"orderByField":"Title"
	});
});

listName: The GUID or the display name of the list where the upload destinations are stored.
listBaseUrl: The base URL of the list. If it is in the root site, use “”. If it is in a subsite, use “/MySubsite” or “/Sites/MySubsite” depending on your setup. The list name should NOT be included in this variable.
friendlyNameField: The FieldInternalName of the field that holds the friendly name of the destination.
relPathField: The FieldInternalName of the field that holds the relative URL to the library or folder to upload the files.
BaseUrl: Holds the base URL of the SITE where the document library is located. For example “/Sites/Site1/YourSiteName”
DocLibraryGUID: The GUID of the document library you are uploading into. View source and search for “ctx.listName” to find it.
EditFormRelUrl: The relative URL to the EditForm of your library. For example “/Sites/Site1/YourSiteName/Shared documents/Forms/EditForm.aspx”.
orderByField: The FieldInternalName of the field to sort by.

How to set up this list

Create a custom list with one additional single line of text field “RelPath”. Enter the friendly name in the Title field, and the relative path to the library or folder in the field “RelPath”.
IMG
In addition to the above fields you must add the following if you like to use the new “Go to EditForm after upload” feature.
BaseUrl: Single line of text.
DocLibraryGUID: Single line of text.
EditFormRelUrl: Single line of text.

Using this list is optional. If you like, you can enter the destination directly in the code in the <select> control with id “fileUploadTo”. If you prefer to use the manual approach, ensure you comment out the function call to “getUploadDestinations” in the code example.

The script file “spjs-utility.js” is only used for the function “getUploadDestinations” an you can remove it if you enter the destinations manually.

The code

Get the file “spjs-utility.js” from here. You will also need jQuery. Put this code in a HTML Form Web part where you want the upload control to appear – change the path to the scripts in the top of the code to match you locale files:

<!-- 
/* SPJS Upload for SharePoint
 * ---------------------------------------------
 * Created by Alexander Bautz
 * alexander.bautz@gmail.com
 * https://spjsblog.com
 * Copyright (c) 2013-2016 Alexander Bautz (Licensed under the MIT X11 License)
 * ---------------------------------------------
 * Include reference to:
 * jquery - http://jquery.com
 * spjs-utility.js - http://spjsfiles.com
 * ---------------------------------------------
*/
 -->
 
<script type="text/javascript" src="/SPJS/DFFS/plugins/jquery.js"></script>
<script type="text/javascript" src="/SPJS/DFFS/plugins/spjs-utility.js"></script>
<script type="text/javascript">
/*
 Pull the upload destinations from this list
 If you prefer, you can add the destinations manuelly in the <select> with id "fileUploadTo".
 In that case, comment out this function call

 Ensure the list you pull the upload destination from has all the fields specified in this article: http://wp.me/p3eibN-1nr
*/
$(document).ready(function(){
 spjs.upload.getUploadDestinations({
 "listName":"UploadDestination",
 "listBaseUrl":"",
 "friendlyNameField":"Title",
 "relPathField":"RelPath",
 "baseUrlField":"BaseUrl",
 "guidField":"DocLibraryGUID",
 "editFormRelUrlField":"EditFormRelUrl",
 "orderByField":"Title"
 });
});

// Go to EditForm after upload
var showEditFormAfterUpload = true;

</script>
<style type="text/css">
td.spjs_fileUploadLabel{
 width:150px;
 height:25px;
 font-size:16px !important;
 font-weight:bold;
 font-family:Calibri;
 color:#ffffff;
 vertical-align:middle;
 background-color:#5B9BD5;
 border:1px #41719C solid; 
 padding:3px 3px 3px 6px;
 cursor:default;
}
td.spjs_fileUploadBody{ 
 width:350px;
 font-size:16px !important;
 border:1px #41719C solid; 
 padding:3px;
 cursor:default;
}
input.spjs_fileUploadBtn{
 width:100%;
 height:33px; 
 font-size:16px !important;
 font-weight:bold;
 font-family:Calibri;
 color:#ffffff;
 border:1px #41719C solid;
 background-color:#5B9BD5; 
 cursor:pointer;
 margin:0px;
 padding:0px;
 display:none;
}
input.spjs_fileUploadBtn:hover{
 color:#5B9BD5;
 background-color:#ffffff;
}
.spjs_fileUploadSelect{
 width:100%;
 height:25px;
 background-color:#ffffff !important;
 border:none; 
 font-size:14px;
}
.spjs_empty{
 border:1px #FF0000 dashed !important;
}
</style>
<table cellpadding="0" cellspacing="5" style="border-collapse:separate;">
 <tr>
 <td class="spjs_fileUploadLabel">File</td>
 <td class="spjs_fileUploadBody">
 <input type="file" id="filePicker" style="width:100%;padding:0px;">
 <span style="display:none;color:red;font-size:12px;">Your browser is not supported!<br>Use Internet Explorer 10 or another modern browser.</span>
 </td>
 </tr>
 <tr>
 <td class="spjs_fileUploadLabel">Upload To</td>
 <td class="spjs_fileUploadBody"> 
 <select id="fileUploadTo" class="spjs_fileUploadSelect">
 <!--
 // guid attribute must be guid of destination document library
 // baseurl attribute must be baseURL of site wher the document library is located
 // editformurl attribute must be relative url to the EditForm of this library
 <option value="">Select destination</option>
 <option guid='' baseurl='/Upload' editformurl='/Upload/Forms/EditForm.aspx' value="/Upload/Folder1">Folder 1</option>
 <option guid='' baseurl='/Upload' editformurl='/Upload/Forms/EditForm.aspx' value="/Upload/Folder2">Folder 2</option>
 --> 
 </select>
 </td>
 </tr>
 <tr>
 <td></td>
 <td class="spjs_fileUploadBtn">
 <input id="uploadFileBtn" type="button" class="spjs_fileUploadBtn" onclick="spjs.upload.submitFile();" value="Submit" />
 <span id="uploadError" style="display:none;color:red;"></span>
 </td>
 </tr>
</table>
<script type="text/javascript">

/******************************************************
 Do not change anything below this line
*******************************************************/
var spjs = spjs || {};

spjs.upload = {
 "version":"1.1",
 "versionDate":"August 04, 2016",
 "data":{"fileDataStr":""},
 "handleFileSelect":function(evt){
 // Modified from http://jsfiddle.net/eliseosoto/JHQnk/
 var files = evt.target.files, file = files[0], reader;
 if(files && file){
 reader = new FileReader();
 reader.onload = function(readerEvt) {
 var binaryString = readerEvt.target.result;
 spjs.upload.data.fileDataStr = binaryString.substring(binaryString.indexOf(",")+1);
 $("#uploadFileBtn").show();
 };
 reader.readAsDataURL(file);
 }
 },
 "submitFile":function() {
 if($("#fileUploadTo").val() === ""){
 $("#fileUploadTo").addClass("spjs_empty");
 return;
 }else{
 $("#fileUploadTo").removeClass("spjs_empty");
 }
 var filePath, fileName, destination, b;
 filePath = $("#filePicker").val();
 fileName = filePath.substring(filePath.lastIndexOf("\\")+1);
 destination = location.protocol+"//"+location.host+$("#fileUploadTo").val()+"/"+fileName;
 b = [];
 b.push("<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>");
 b.push("<soap:Body>");
 b.push("<CopyIntoItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'>");
 b.push("<SourceUrl>" + fileName + "</SourceUrl>");
 b.push("<DestinationUrls>");
 b.push("<string>"+destination+"</string>");
 b.push("</DestinationUrls>");
 b.push("<Fields>");
 b.push("<FieldInformation Type='Text' DisplayName='Title' InternalName='Title' Value='"+fileName+"' />");
 b.push("</Fields>");
 b.push("<Stream>"+spjs.upload.data.fileDataStr+"</Stream>");
 b.push("</CopyIntoItems>");
 b.push("</soap:Body>");
 b.push("</soap:Envelope>");
 $.ajax({
 url: "/_vti_bin/copy.asmx",
 beforeSend: function (xhr) { xhr.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/sharepoint/soap/CopyIntoItems"); },
 type: "POST",
 dataType: "xml",
 data: b.join(""),
 complete: spjs.upload.processResult,
 contentType: "text/xml; charset=\"utf-8\""
 });
 },
 "processResult":function(data, status) {
 var errorCode, errorMessage;
 errorCode = $(data.responseText).find("CopyResult").attr("ErrorCode");
 errorMessage = $(data.responseText).find("CopyResult").attr("ErrorMessage");
 if(errorCode !== "Success"){
 $("#uploadFileBtn").fadeOut(400,function(){
 $("#uploadError").html("Ensure the selected destination exists!<br><br>Error message: "+errorMessage).show();
 setTimeout(function(){
 $("#uploadError").fadeOut();
 $("#fileUploadTo").val("");
 $("#uploadFileBtn").fadeIn();
 },10000);
 }); 
 }else{
 $("#uploadFileBtn").attr("disabled","disabled").val("File successfully uploaded");
 if(typeof showEditFormAfterUpload !== "undefined" && showEditFormAfterUpload){
 var fileDir = $(data.responseText).find("CopyResult").attr("DestinationUrl");
 var docLibBaseUrl = $("#fileUploadTo option:selected").attr('baseurl');
 var docLibGuid = $("#fileUploadTo option:selected").attr('guid');
 var docLibEditFormUrl = $("#fileUploadTo option:selected").attr('editformurl')
 var fileMetadata = spjs.utility.queryItems({"listName":docLibGuid,"listBaseUrl":docLibBaseUrl,"query":"<Where><Eq><FieldRef Name='EncodedAbsUrl' /><Value Type='Text'>"+fileDir+"</Value></Eq></Where>","scope":"RecursiveAll","viewFields":["FileLeafRef","FileDirRef"]})
 if(fileMetadata.count > 0){
 var id = fileMetadata.items[0].ID;
 SP.UI.ModalDialog.showModalDialog({"url":makeAbsUrl(docLibEditFormUrl+"?ID="+id+"&Mode=Upload")});
 }
 }
 setTimeout(function(){
 $("#uploadFileBtn").fadeOut(400,function(){
 $(this).removeAttr("disabled").val("Submit");
 $("#fileUploadTo").val("");
 })
 },3000);
 $("#filePicker").val("");
 }
 },
 "getUploadDestinations":function(args){
 var res, q, b;
 b = ["<option value=''>Select destination</option>"];
 q = "<Where><IsNotNull><FieldRef Name='ID' /></IsNotNull></Where><OrderBy><FieldRef Name='"+args.orderByField+"' /></OrderBy>";
 res = spjs_QueryItems({"listName":args.listName,"listBaseUrl":args.listBaseUrl,"query":q,"viewFields":[args.friendlyNameField,args.relPathField,args.baseUrlField,args.guidField,args.editFormRelUrlField]});
 $.each(res.items,function(i,item){
 b.push("<option editformurl='"+item.EditFormRelUrl+"' baseurl='"+item.BaseUrl+"' guid='"+item.DocLibraryGUID+"' value='"+item[args.relPathField]+"'>"+item[args.friendlyNameField]+"</option>")
 });
 $("#fileUploadTo").html(b.join(""));
 }
};

if(window.File && window.FileReader && window.FileList && window.Blob){
 document.getElementById('filePicker').addEventListener('change', spjs.upload.handleFileSelect, false);
}else{
 $("#filePicker").hide().next().show();
 $("#fileUploadTo").hide(); 
}
</script>

Post questions and feedback in the comments section below, and if you use this solution, please consider sending me a few beers by clicking the “beer button” in the top right corner of this page.

Enjoy,
Alexander

Document library: script to update Title from Filename

I got a request for a script that updates the Title field to be the same as the Name field in a document library. This to be able to use a lookup column to pick relevant documents from another list or library.

This code will insert a button that lets you search for all documents that do not already have a Title set, and update it to be the same as the file name.

Add this code to a list view in the library you want to update:

<input type="button" onclick="updateTitleFromName()" value="Update Title from Name" />

<script type="text/javascript" src="/Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="/Scripts/spjs-utility/spjs-utility.js"></script>
<script type="text/javascript">

function updateTitleFromName(){
	var q, res, uRes, count;
	count = 0;
	q = "<Where><IsNull><FieldRef Name='Title' /></IsNull></Where>";
	res = spjs_QueryItems({"listName":_spPageContextInfo.pageListId,"query":q,"viewFields":["ID","FileLeafRef"]});
	if(res.count === 0){
		alert("No files without title found.");
		return;
	}
	if(!confirm("There are "+res.count+" files to update. The page will appear as frozen while the script is working.\n\nContinue?")){
		return;
	}
	$.each(res.items,function(i,item){
		uRes = spjs_updateItem({"listName":_spPageContextInfo.pageListId,"id":item.ID,"data":{"Title":item.FileLeafRef.split(";#")[1]}});
		if(!uRes.success){
			alert("Could not update the file: "+item.FileLeafRef+" due to the follwing error:\n\n"+uRes.errorText);
		}else{
			count += 1;
		}
	});
	alert("Updated "+count+" files.");
	location.href = location.href;
}
</script>

If you want to add this code directly to the page, use a HTML form web part to hold the code. You can also use a CEWP to link to the code from another location (like a document library).

You find jQuery here
And you find spjs-utility.js here

Let me know if you have any questions.

Alexander

Edit document metadata without creating a new version or triggering workflows

Have you noticed that when uploading a new documents in a document library, the connected workflows do not trigger?

This behavior can be used to “sneak” in changes in a documents metadate without triggering new versions or connected workflows.

The trick is simply to load the page with the parameter “&Mode=Upload” in the URL:
[your root address]/test/English/DocumentLibrary/Forms/EditForm.aspx?ID=1&Mode=Upload

Make the changes and click “OK”. The changes are merged into the current version and no workflows are triggered!

Note: “Modified” and “Modified By” is updated.

Alexander

Manipulate upload link in document library

I got this request from JGilmore:

Anyone know how to change the URL of the ‘Upload’ button as well as the links under its dropdown? I would like to have the user directed to a custom upload page with ‘Overwrite existing files’ unchecked by default.

Thanks in advance.


Here is one possible approach

Add this code in a CEWP below the list view to override the default links:

&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;

// Manipulate direct click on upload button
$(&quot;*[id$='_UploadMenu']&quot;).parents('td:first').removeAttr('onclick').click(function(){
	redirectUpload(false);
});

// Manipulate &quot;Upload Document&quot;
$(&quot;*[id$='_Upload']&quot;).attr('onMenuClick','redirectUpload(false)');
		
// Manipulate &quot;Upload Multiple Documents&quot;
$(&quot;*[id$='_MultipleUpload']&quot;).attr('onMenuClick','redirectUpload(true)');		
		
function redirectUpload(multi){
	// Set your new upload destination (custom upload page)
	// ctx.listName is provided by SharePoint
	if(multi){
		window.location='/test/English/MyCustomUploadPage.aspx?List='+ctx.listName+&quot;&amp;MultipleUpload=1&quot;;
	}else{
		window.location='/test/English/MyCustomUploadPage.aspx?List='+ctx.listName;
	}
}
&lt;/script&gt;

Change the new upload location in the function “redirectUpload”. Also edit the source of the jQuery script if you prefer to use a local copy.

Ask if anything is unclear.

Alexander

Manipulating the Custom Send To Destination in document library with javascript

You all know that you can send a copy of a document from one document library to another by using the dropdown on the “Name” column and selecting “Send to > Other location”.

Some of you also know that you can add a predefined “send to location” under Document library settings > Advanced settings.

The irritating fact is that you can only add one custom location here.


Here is a method for setting this custom send to location by javascript – and being able to manipulate it for each view – or by a dropdown select.

To set the location for a view – put this code in a CEWP below the list view:

<script type="text/javascript" src="../../Javascript/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
// Name displayed on the link
ctx.SendToLocationName = "My custom send to location";
// The full url to the document library to send to - i used ctx.HttpRoot as it reflects the current root
ctx.SendToLocationUrl = ctx.HttpRoot + "/TestLibrary";
</script>

IMG

To have a dropdown select, use this code:

<script type="text/javascript" src="../../Javascript/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
// Define array of locations
var mySendToArr = ['<select location>|',
		 'Archive|http://www.mysendtolocation.com/Archive',
		 'Publish|http://www.mysendtolocation.com/Publish',
		 'AnotherPlace|http://www.mysendtolocation.com/AnotherPlace'];
			  	   
// Build the dropdown			  	   
var mySelect = $("<select id='myCustomSendToSelector'></select>");
$.each(mySendToArr,function(idx,item){
	var split = item.split('|');
	var opt = $("<option></option>");	
	opt.text(split[0]);
	opt.val(split[1]);
	mySelect.append(opt);
});

// Place the dropdown
$("#onetidPageTitle").append("<div style='font-size:10px;float:right;margin-top:-15px' id='insertMySendToSelectHere'>Send to location: </div>");
$("#insertMySendToSelectHere").append(mySelect);

// Add onchange
$("#myCustomSendToSelector").change(function(){
	var SendToLocationName = $(this).find('option:selected').text();
	var SendToLocationUrl = $(this).find('option:selected').val();
	if(SendToLocationUrl!=''){
		ctx.SendToLocationName = SendToLocationName;
		ctx.SendToLocationUrl = SendToLocationUrl;
	}else{
		ctx.SendToLocationName = "";
		ctx.SendToLocationUrl = "";
	}
});
</script>

This script adds a dropdown above the view selector like this:
IMG

Ask if anything is unclear!

Regards
Alexander

Master document template library

Have you ever wanted to:

  • have multiple document templates in i one document library
    – without having to use content types?
  • use the same template in multiple document library’s?
  • have different document templates available in each view?
  • have easy access to editing the templates?

I will provide a javascript solution that uses a standard document library as a master template placeholder. This library can have an unlimited number of templates and each template can be used in multiple document libraries. On each template you can specify which document library to use it in, and whether to use the template in all views, or to specify which views to use it in.

Then, in the document library where you want to use these templates, just drop a CEWP with some script references and like magic – your templates appear. No need to hand code each menu item – they are pulled straight from your master template library based on your metadata on each template.

As always we start like this:
Create a document library to hold your scripts (or a folder on the root created in SharePoint Designer). In this example i have made a document library with a relative URL of “/test/English/Javascript” (a sub site named “test” with a sub site named “English” with a document library named “Javascript”):
IMG

The jQuery-library is found here. The pictures and the sourcecode refers to jquery-1.3.2.min. If you download another version, be sure to update the script reference in the sourcecode.

The scripts “interaction.js” and “stringBuffer.js” is created by Erucy and published on CodePlex.

The sourcecode for “MasterDocumentTemplates.js” is provided below.

Create your master template placeholder library like this:

Create a standard document library and add two columns:
UsedIn of type “Multiple lines of text”

Here the document library’s where the template will be accessible is specified like this:
– DisplayNameOfYourLibrary|viewNameFromURL;
– You can add multiple libraries and multiple views for each library – separated by “|” for each view, and “;” for each library.

MouseOver of type “Single line of text”.

Here the description (in “bigIcon-mode”) or MouseOver (in “smallIcon-mode”) on the template in the dropdown is set.

The columns in the template library looks like this:
IMG

And the template library look like this with a few templates added:
IMG

As you see from the screenshot – all templates is used in the document library named “MyDocumentLibrary”. The file “PowerPoint template” is visible only in the view “PowerPoint” in “MyDocumentLibrary”. The rest of the templates is visible in all views.

Here is the code for the file “MasterDocumentTemplates.js”:

/* Add dropdown menu in document library - pulls templates from master template library and points &quot;save&quot; to the current library
 * Requires a &quot;Templates&quot; document library with the following fields (FieldInternalName):
 * &quot;UsedIn&quot;
 * - Multiple line of plain text. Here the document library's where the template will be accessible is specified like this:
 *   DisplayNameOfYourLibrary|viewNameFromURL;
 *   You can add multiple libraries and multiple views for each library - separated by &quot;|&quot; for each view, and &quot;;&quot; for each library. 
 *   If you do not specify view - the template is accessible to all views that have this script referred.
 * &quot;MouseOver&quot;
 * - Description (in &quot;bigIcon-mode&quot;) or MouseOver (in &quot;smallIcon-mode&quot;) on the template in the dropdown
 *
 * -----------------------------
 * Author: Alexander Bautz
 * Version: 1.2
 * LastMod: 18.10.2009
 * -----------------------------
 * Must include reference to jQuery and to the folloving scripts (http://spjslib.codeplex.com):
 * ----------------------------------------------------
 * interaction.js
 * stringBuffer.js
 * ----------------------------------------------------
Ex:
getTemplatesForThisLibrary('DocumentTemplates','/test/English','',true,true,'Upload document','Select template from list');

Parameters explained:
* templatesListName:
  Document library DisplayName of your master template library
* templatesListbaseUrl:
  The baseUrl of the site the library resides in (not the URL to the Document library it selves)
* targetListUrlDir:
 The actual URL path to the save location - to save in &quot;current&quot; library - where the menu is - use ''
* bigIcon:
 true for large icon and description (from field &quot;MouseOver&quot;) below the template name
 false for small icon mode with the value from the field &quot;MouseOver&quot; as tooltip and only the template name visible
* uploadOption:
 true add option for upload
 false hides option for upload
* uploadButtonTitle:
 if uploadOption set to true - the text displayed on the upload &quot;option&quot;&lt;/li&gt;
* menuTitle:
 The text on the dropdown-menu
*/

function getTemplatesForThisLibrary(templatesListName,templatesListbaseUrl,targetListUrlDir,bigIcon,uploadOption,uploadButtonTitle,menuTitle){
var bgColor = $('.ms-quicklaunchheader').css('background-color');
var btnBgColor = $('.ms-viewselector').css('background-color');
var thisViewNameRaw = $(&quot;#aspnetForm&quot;).attr('action');
var thisViewName = thisViewNameRaw.substring(0,thisViewNameRaw.indexOf('.aspx'));

wsBaseUrl = templatesListbaseUrl + '/_vti_bin/'; 
var q = &quot;&lt;Where&gt;&lt;Contains&gt;&lt;FieldRef Name='UsedIn'/&gt;&lt;Value Type='Text'&gt;&quot; + ctx.ListTitle + &quot;&lt;/Value&gt;&lt;/Contains&gt;&lt;/Where&gt;&quot; +
		&quot;&lt;OrderBy&gt;&lt;FieldRef Name='FileLeafRef' Ascending='True'/&gt;&lt;/OrderBy&gt;&quot;;
var links = '';
if(bigIcon){
	var iconPrefix = 'lg_';
	var menuClass = 'ms-MenuUILarge';
	var uploadIMG = 'menuuploaddocument.gif';
}else{
	var iconPrefix = '';
	var menuClass = 'ms-MenuUI';
	var uploadIMG = 'doclink.gif';
}

var res = queryItems(templatesListName,q,['UsedIn','FileLeafRef','MouseOver','DocIcon'],25);
	if(res.count&gt;0){
		if(targetListUrlDir==''){
			var listURLRaw = ctx.listUrlDir;
			var listUrl = listURLRaw.substring(listURLRaw.lastIndexOf('/'));
		}else{
			listUrl = &quot;/&quot; + targetListUrlDir;
		}
	    $.each(res.items, function(idx, item){ 
	    var showInView = false;
	    // Split the UsedIn value to separate the document library names
	    var useInSplit = item['UsedIn'].split(';');
	        for(i=0;i&lt;useInSplit.length;i++){ 
	        	// Split the value to find the view's in which to show the template
	       		var usedInSplitAgain = useInSplit[i].split('|');	       		
	       		if(usedInSplitAgain.length&gt;1){ // If length &gt; 1 there is specified one or more views
		       		if(usedInSplitAgain[0]==ctx.ListTitle){
				        for(j=1;j&lt;usedInSplitAgain.length;j++){
			        		if(usedInSplitAgain[j].toLowerCase()==thisViewName.toLowerCase()){
				        		// Show in this view
				        		showInView = true;
				        	}
				        }
					}				
				}else{ // View not specified - show in all views
					if(usedInSplitAgain[0]==ctx.ListTitle){
						showInView = true;
					}
				}
	        }
	        
			if(showInView){
		        var DocIcon = item['DocIcon'];
		        var docName = item['FileLeafRef'].substring(item['FileLeafRef'].indexOf(';#')+2);
		        var docDescription = '';
		        var mouseOver = '';		        
		        if(item['MouseOver']!=null){
		        	var docDescription = &quot;&lt;font color='#696969'&gt;&quot; + item['MouseOver'] + &quot;&lt;/font&gt;&quot;;
			        	if(!bigIcon){
			        		var mouseOver = item['MouseOver'];
			        	}
		        }	        
		        var link = &quot;createNewDocumentWithProgID('&quot; + ctx.HttpRoot + &quot;/&quot; + templatesListName + &quot;/&quot; + docName + &quot;','&quot; + ctx.HttpRoot + listUrl + &quot;','SharePoint.OpenDocuments', false)&quot;;
				if(bigIcon){
					 links += &quot;&lt;table style='border:1px white' width='100%' cellpadding='2' cellspacing='0' &quot; +
					 &quot;class='templateMenuHover &quot; + menuClass + &quot;' &quot; +
	        		 &quot;title='&quot; + mouseOver + &quot;' onclick=&quot;javascript:hideMenu($(this));&quot; + link + &quot;&quot;&gt;&quot; +
	        		 &quot;&lt;tr&gt;&lt;td style='vertical-align:middle'&gt;&lt;img style='text-align:center;vertical-align:middle' src='/_layouts/images/&quot; + iconPrefix + &quot;ic&quot; + DocIcon + &quot;.gif' /&gt;&lt;/td&gt;&quot; +
	        		 &quot;&lt;td width='100%' style='padding:0 15 0 10'&gt;&lt;b&gt;&quot; + docName + &quot;&lt;/b&gt;&lt;br&gt;&quot; + docDescription + &quot;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&quot;;	        		 
				}else{
					 links += &quot;&lt;table style='border:1px white' width='100%' cellpadding='2' cellspacing='0' &quot; +
					 &quot;class='templateMenuHover &quot; + menuClass + &quot;' &quot; +
	        		 &quot;title='&quot; + mouseOver + &quot;' onclick=&quot;javascript:hideMenu($(this));&quot; + link + &quot;&quot;&gt;&quot; + 
	        		 &quot;&lt;tr&gt;&lt;td style='vertical-align:middle;padding-left:2px'&gt;&lt;img src='/_layouts/images/&quot; + iconPrefix + &quot;ic&quot; + DocIcon + &quot;.gif' /&gt;&lt;/td&gt;&quot; + 
	        		 &quot;&lt;td width='100%' style='padding:0 15 0 10;white-space:nowrap'&gt;&quot; + docName + &quot;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&quot;;
				}
	    	}
	    }); 
    }else{ 
    	// No templates available for this view
		 links += &quot;&lt;table style='border:1px white' width='100%' cellpadding='2' cellspacing='0' &quot; +
		 &quot;class='templateMenuHover &quot; + menuClass + &quot;' &quot; + &quot;title=''&gt;&quot; + 
		 &quot;&lt;tr&gt;&lt;td style='vertical-align:middle;padding-left:2px'&gt;&lt;img src='/_layouts/images/&quot; + iconPrefix + &quot;ichlp.gif' /&gt;&lt;/td&gt;&quot; + 
		 &quot;&lt;td width='100%' style='white-space:nowrap;padding:0 10 0 10'&gt;No templates available&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&quot;;
   	
    }
    // Show upload option
    if(uploadOption){
		 links += &quot;&lt;table style='border:1px white' width='100%' cellpadding='2' cellspacing='0' &quot; +
		 &quot;class='templateMenuHover &quot; + menuClass + &quot;' &quot; + &quot;title='' onclick='location.href=&quot;&quot; + ctx.HttpRoot + &quot;/_layouts/Upload.aspx?List=&quot; + ctx.listName + &quot;&quot;'&gt;&quot; + 
		 &quot;&lt;tr&gt;&lt;td style='vertical-align:middle;padding-left:2px'&gt;&lt;img src='/_layouts/images/&quot; + uploadIMG +&quot;' /&gt;&lt;/td&gt;&quot; + 
		 &quot;&lt;td width='100%' style='white-space:nowrap;padding:0 10 0 10'&gt;&quot; + uploadButtonTitle + &quot;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&quot;;    			 
    }
    // Build the menu
  	links = &quot;&lt;div style='border-top:thin groove white;border-bottom:thin groove white;border-left:thin groove white;background-color:&quot; + bgColor + &quot;;height:25' &gt;&quot; +
  			&quot;&lt;div style='cursor:pointer;float:left;border:thin groove silver;padding:2;background-color:&quot; + btnBgColor + &quot;' class='templateMenuFirst'&gt;&quot; +
  			&quot;&lt;div title='Open Menu'&gt;&quot; + menuTitle + &quot;&lt;img alt='' src='/_layouts/images/menudark.gif'/&gt;&lt;/div&gt;&quot; +
  			&quot;&lt;div class='templateMenu ms-MenuUIPopupBody' style='display:none'&gt;&quot; + links + &quot;&lt;/div&gt;&quot; +
  			&quot;&lt;/div&gt;&quot; +
  			&quot;&lt;/div&gt;&quot;;
    
    // Insert the menu
	$(&quot;.ms-bodyareaframe&quot;).prepend(links);
	// Add show-hide functionality to the menu
	addShowHideToCustomMenu();
}

function addShowHideToCustomMenu(){ 
	// Add onclick and mouseleave to show and hide the menu
	$('.templateMenuFirst').click(function(){
		$('.templateMenu').slideDown(250)
		.css('position','absolute')
		.css('zIndex','1000')
	})
	.mouseleave(function(){
		$('.templateMenu').fadeOut(350);
	});
	
	// Add hover effect to highlight the element hovered with the mouse
	$(&quot;.templateMenuHover&quot;).hover(
	function () {
		$(this).addClass('ms-MenuUIItemTableHover');
	}, 
	function () {
		$(this).removeClass('ms-MenuUIItemTableHover');
	});
}

function hideMenu(obj){
	// Remove rather than hide to prevent flicker
	$('.templateMenu').remove();
	// Reload page - needed for Firefox
	history.go(0);
}

// Overcome the zIndex glitch in IE7 - http://www.vancelucas.com
$(function() { 
	var zIndexNumber = 1000;
	$('div.templateMenu').each(function() {
		$(this).css('zIndex', zIndexNumber);
		zIndexNumber -= 10;
	});
});

Save this as a file named “MasterDocumentTemplates.js” – be sure to use the right file extension, and upload to the javascript library as shown above.

Then add a CEWP below the list view in the document library where you want the menu to appear.
IMG

And add this code to it:

&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jquery-1.3.2.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/interaction.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/stringBuffer.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/MasterDocumentTemplates.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
// bigIcon mode true
getTemplatesForThisLibrary('DocumentTemplates','/test/English','',true,true,'Upload document','Select template from list');
&lt;/script&gt;

Parameters explained:

  • templatesListName
    Document library DisplayName of your master template library
  • templatesListbaseUrl
    The baseUrl of the site the library resides in (not the URL to the Document library it selves)
  • targetListUrlDir
    The actual URL path to the save location – to save in “current” library – where the menu is – use ”
  • bigIcon
    true for large icon and description (from field “MouseOver”) below the template name
    false for small icon mode with the value from the field “MouseOver” as tooltip and only the template name visible
  • uploadOption
    true add option for upload
    false hides option for upload
  • uploadButtonTitle
    if uploadOption set to true – the text displayed on the upload “option”
  • menuTitle
    The text on the dropdown-menu

The menu will appear like this:
IMG
You can edit the color of the “button” and its background “banner” in line 44-45 in the script.

The menu should look like this in the “Default view” (note that the PowerPoint template is not displayed:
IMG

And like this in the view “PowerPoint”:
IMG

If you select “bigIcon=false” the menu looks like this:
IMG

I hope someone finds this “feature” handy!
Ask if something is unclear.

Regards
Alexander