So, I noticed my good buddy Christina Wheeler (@cwheeler76) wrote a little rant post on Twitter and Facebook today:
And I thought, here’s a great example where you could use jQuery and SharePoint in the wild. With jQuery you could easily hide the “Upload Multiple Files…” link… well.. I assumed you could.. I mean how hard could it be? Keep in mind that ANYTHING you see on the page that is not Flash, Silverlight, or an Active X control can be manipulated with jQuery. There’s probably a couple of other things that can’t be modified, but I don’t know what they are off the top of my head… generally, it can be manipulated.
Okay… let’s break this problem down into it’s pieces and tackle it. How do we hide the “Upload Multiple Files…” link for a specific document library? First of all let’s go to the upload page and take a look:
We can tell a couple of important things from this page.
- The page that needs to be modified is Upload.aspx (that creates some “opportunities”)
- There is a Query String Parameter that has our List GUID (that might come in handy)
Let’s also look at the page source to see what the DOM looks like. I viewed the DOM and searched for “Upload Multiple Files…” and found our link:
Creating our script
First thing we want to do is figure out how to delete the link. From looking at our DOM we see that the link has an id of “ctl00_PlaceHolderMain_ctl01_ctl05_UploadMultipleLink”. Hmmm… that’s actually not too messy of an ID. Could it be that it’s consistent? As far as I know it is consistent for SharePoint 2010. I’ve not looked at it in other versions, so I don’t know if it’s always going to be that ID. Regardless, that’s what we are using for this demo. We also know from the second blog post in this series how to get that element to manipulate it.
We also know from doing a quick search on Bing that we can hide an element using the “hide()” method. So, the script to hide the link is:
That’s pretty cool, but if we put that script on our page it would hide the link for EVERY document library, and we don’t want that. We just want our script to hide the link for one specific library. Hmmm.. so what do we do now? Well… luckily, if you remember, when we go to the Upload.aspx page there is a Query String parameter called “List” that contains the GUID for the document library. So, all we have to do is check the value of this parameter and compare it to the GUID for the list we want to hide.. and if they match, then we hide it! That sounds easy enough. So, doing a quick search with Bing I found a function that gets the Query String parameters for me (remember, you don’t have to write everything from scratch. Do a quick search to see if it’s been done before). When we add in other logic and create some easy to use functions our script looks like:
//function to get a Query String Parameter from the URL
//I did not write this code, I did a search on Bing for
//"Get Query String using jQuery" and copy and pasted it
name = name.replace(/[\/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.href);
if(results == null)
return decodeURIComponent(results.replace(/\+/g, " "));
//function that takes the GUID as a parameter.
function HideUploadLink(thisListGUID )
//Get the GUID from the "List" Query String Parameter
GUIDFromUrl = getParameterByName("List");
//if the GUID from the Query STring Parameter matches our
//particular Document Library's GUID, then hide the link
if (GUIDFromUrl == thisListGUID)
//hide the link
// the code that is executed after the page loads.
// this is where the action starts
//let's call the method that hides the link and pass
//in the GUID for our Document Library we want to hide
//the link on
There we go, our script is complete. Now we just need to save our script file to our document library and figure out how to add the script so it can be executed.
Adding our the script
So, now we just need to add our script and we should be good to go. We know from our previous blog posts how to add scripts to a page, but ummm… we don’t have the option to edit this page. What do we do? Unfortunately we are going to have to break one of our rules. Because we can’t edit the Upload.aspx page we need to place a reference to our script in the (da da dum) MasterPage… ugh.. I threw up in the back of my mouth just thinking about it, but that is the solution we are going to take here (I explain in more detail why later on). Just remember, you should always avoid adding scripts to your MasterPage…. and also remember there is an exception to every rule…
Go ahead and add the references to jQuery and our “HideUploadLink.js” file in your MasterPage right before the closing head tag </head>
Now as part of your MasterPage loading it will hide the “Upload Multiple Files…” link for a specific document library on the Upload.aspx page. Go ahead, give it a try… Not too hairy is it?
So, why use jQuery in this instance?
That’s a good question, and one you should always ask before using jQuery. As awesome as it is, it’s not the answer to every question nor is it the best answer many times. I know.. I know.. some of you are thinking that I drank the jQuery Kool-Aid and I think jQuery is the answer for EVERYTHING. Well it’s not… okay? In this instance though I think it may be the best choice and here’s why:
The page in question
So, you might be thinking “Why not just edit the page in something like SharePoint Designer and delete the link off the page or something? Well… even if that was an option I probably would not suggest it and in this instance it’s NOT an option. The page that has the ”Upload Multiple Files…” link is on the Upload.aspx page.. to be more specific it’s on the /_layouts/Upload.aspx">/_layouts/Upload.aspx">http://<site>/_layouts/Upload.aspx page. This is a page that resides on your file system in the _layouts directory. So, if you are using Hosted SharePoint 2010 or Office 365 you CAN’T modify this file at all (as far as I know). And even if you DO have access to the file system it’s generally bad practice to modify these files and you have no guarantee that some patch won’t overwrite your changes. So, editing the page itself is out of the question.
What other options do you have?
What would Eric Shupps do in this situation? That’s what I ask myself when I’m either writing code or at a bar and generally the answer is either “more code” or “more Corona”. Seriously though, what are the other options here? You have a page in your Layouts directory that you want to modify? I bet Eric would tilt his cowboy hat every so slightly and reach into his back pocket and pull out a custom HTTP handler. Wouldn’t that be slick? With a custom HTTP handler you could redirect the user to your own custom Upload page if they try to go to Upload.aspx. This opens up a world of possibilities for how to handle many situations. However, unless you happen to have a custom HTTP handler written already, it’s not a trivial task to implement one. Also, if you are using Hosted SharePoint 2010 or Office 365 I imagine you can’t deploy a custom HTTP handler as a sandbox solution (I’m sure someone will correct me if I’m wrong).
It is SharePoint version agnostic
The solution I’m proposing here will work on SharePoint 2007, 2010, Hosted SharePoint 2010, and Office 365… heck, I’m sure it would even work on SharePoint 2003 but does anyone really use that anymore?
Let’s face it. Time is important. Sometimes more important than money. When I saw Christina’s post I had no idea exactly how to do what she asked, I just knew it could be done. From the time I saw her post until the time I emailed her working code took less than half an hour, and I’m pretty sure that involved one bathroom break and a couple of other emails.
What I don’t like about this solution
So, even though this solution works well it’s not perfect. It has a couple of shortcomings that really make it less than ideal. The fact that the script is referenced in the MasterPage is not great because this means that the script gets executed on EVERY page, not just the upload.aspx page. That’s BAD mojo and makes me cringe to think about it. You could somewhat alleviate this problem by checking which page you are on before you execute the script and if it’s not Upload.aspx then don’t execute the rest of the script, but you have to execute script to check which page you are on. See why I don’t love this? Also, you actually “see” the “Upload Multiple Files…” link for a split second before the jQuery executes to hide the link. You do have other options here if you want to make the effort (I’m too lazy). You could do something like not hide the link, but instead make it pop up an alert that says “This document library does not allow multiple documents to be uploaded” or something like that. Then the user doesn’t see the link change, just the behavior when they click on it. Plus, if you make something idiot proof they will make a better idiot. You WILL get some user who calls complaining “There’s no link to upload multiple documents!!!” Ah users… if it wasn’t for users every deployment would be a success.
Anyway, there you have it. One of the many practical uses of jQuery. Have a better solution? There’s a comments section for a reason people!!
Previous Blogs in this series: