Apr 20

Add a content editor web part to the document library page. On the content editor web part, add the following javascript. Be sure to modify the value for strAction to what you need. In this case, it is set to redirect to SomePage.aspx with the ListID and ItemID Parameters.

<script type="text/javascript">
function Custom_AddDocLibMenuItems(m, ctx) {
 var strDisplayText = "Edit Item Metadata";
 var strAction = "window.location.href='../../Pages/SomePage.aspx?ListID=" + ctx.listName.substr(1, 36) + "&ItemID=" + currentItemID + "';";
 var strImagePath = "/_layouts/images/edititem.gif";
 CAMOpt(m, strDisplayText, strAction, strImagePath);
 CAMSep(m);
 return false;
}</script>

Apr 12

I've always wondered why SP 2010 document libraries has an Add Document but not a New Document link on their document libraries. Probably because they don't expect users to click on New Document very often and only expect users to Add Documents (upload documents from their PC to the document library).

Anyway, the client has these custom word templates and they require users to use these word templates when creating new documents. This means their process requires users to click on New Document everytime they want to place something in the document library. So to make things easier for them, I have added a Content Editor web part and added code to it that would allow users to click the link to create the document based off the template.

<IMG alt="" src="/_layouts/images/rect.gif">&nbsp;<a href="#" onclick="createNewDocumentWithProgID('http:\u002f\u002fintranet\u002fDocument Library\u002fForms\u002fDocument Template.dotx', 'http:\u002f\u002fintranet\u002fDocument Library', 'SharePoint.OpenDocuments', false)">New Document</a>

&nbsp;&nbsp;&nbsp;

<span style="height:10px;width:10px;position:relative;display:inline-block;overflow:hidden;"><img src="/_layouts/images/fgimg.png" alt="" style="left:-0px !important;top:-128px !important;position:absolute;" /></span>&nbsp;<a id="idHomePageNewDocument" href="http://intranet/_layouts/Upload.aspx?List={DocLibGUID}&amp;RootFolder=" onclick="javascript:NewItem2(event, &quot;http://intranet/_layouts/Upload.aspx?List={DocLibGUID}&amp;RootFolder=&quot;);javascript:return false;" target="_self">Add document</a>

Don't forget to edit the DocLibGUID with the GUID to the document library in order for the Add document link to work. Remember to also check the path to the document libraries and templates.

Using the same method, we can replicate everything in the ribbon on the site itself. This way, the client has an option to hide the ribbon and have more control over what options are available to different groups of users.

Apr 12
More notes on 404 error page for .exe files
Posted by Wei in C# on 04 12th, 2011| | No Comments »

It has been brought to my attention that my previous post to modify IIS to enable users to click on .exe files and download them is flawed as it will disable quite a bit of other functionality in SharePoint. One big one is the inability to use SharePoint designer to navigate to subsites. Big problem there if you have SPD workflows or custom page layouts etc on those subsites.

So in the end, I had to undo the solution as discussed and create a custom web part to add to the document library in question that would modify the div (using Javascript) with the same Javascript link that is used to download the file.

It's not the neatest piece of code since the client needed it in a hurry so I didn't really think about the best way to do things. I just made it work.

The code will prompt you to download anything in the document library. So if the document is a .html file or a .aspx file, it won't open it, it will instead prompt you to download it. You can modify the code to distinguish between files that should be opened vs files that should be downloaded though with a simple if statement.

In addition, the code works for items that have been grouped. If the document library is not grouped, then the code can be simplified. However, the way it is now will work whether the document library is grouped or not.

Here's the javascript part of things:

<script language='javascript'>
function changeDownloadLink(id,NewHtml) {
    // check that the element exists
    if (document.getElementById(id)) {
        // check that the element does not yet contain the string stsnavigate
        // if it doesn't then replace the html
        if (document.getElementById(id).innerHTML.indexOf(""STSNavigate"") == -1) document.getElementById(id).innerHTML=NewHtml;
    }
}

items = new Array();

function saveArray(item) {
    items[items.length]=item;
}

function resetLinks() {
    // loop through the items array
    for (var i=0;i<items.length;i++) {
        if (i%2!=0) {
            changeDownloadLink(items[(i-1)],items[i]
);
            //if (i==1) alert(items[(i-1)] + ' - ' + items[i]
);
        }
    }
}

window.setInterval(function()
{  
   resetLinks();
}, 1000);

</script>

And here is the C# Render method (DocLibName) is the name of the document library that contains all the files that should be downloaded.

           try
            {
                SPWeb mySite = SPContext.Current.Web;
                SPList oList = mySite.Lists[DocLibName];

                SPListItemCollection listItems = oList.Items;

                if (listItems.Count > 0)
                {
                    for (int i = 0; i < listItems.Count; i++)
                    {
                        SPListItem item = listItems[i];

                        writer.Write("<script>changeDownloadLink('" + item["ID"].ToString() + "','<a href=\"#\" onclick=\"STSNavigate(\\'" + mySite.Url + "/_layouts/download.aspx?SourceUrl=" + HttpUtility.UrlEncode(item.File.ServerRelativeUrl) + "\\')\">" + item.DisplayName + "</a>')</script>");

                        string url = "<a href=\"#\" onclick=\"STSNavigate(\\'" + mySite.Url + "/_layouts/download.aspx?SourceUrl=" + HttpUtility.UrlEncode(item.File.ServerRelativeUrl) + "\\')\">" + item.DisplayName + "</a>";
                        writer.Write("<script>saveArray('" + item["ID"].ToString() + "');</script>");
                        writer.Write("<script>saveArray('" + url + "');</script>");
                    }
                }
                //writer.Write("All Done");
            }
            catch (Exception ex)
            {
                writer.Write(ex.ToString());
            }

It's not the prettiest code, but it works and the clients are happy.