I’ve been developing some apps using AngularJS and REST.
Doing some Googleing I noticed that most developers use jQuery Ajax to make REST requests, however if you do that, you will miss out on some awesome AngularJS features.
First of all, you should check out this post on how to refresh the form digest value. You need the digest value to do CRUD operations or SharePoint will deny your requests.
Let’s create a SharePoint list with some custom fields. Note that the field internal names will be different from the display names, just to make the development easier.
When working with SharePoint 2013/online, REST, CRUD and SPA you will need the Form Digest token. This a unique key based on user and and site and it’s only valid for a limited time.
Wictor Wilén wrote a very good post about it here
We have an App that is not using a master-page which means that the Form Digest value won’t update nor exist as a hidden input element. This means that we can not retrieve it using $(‘#__REQUESTDIGEST’).val(). Also, I have not been able to update the Digest value using UpdateFormDigest(relativeUrl,interval) from init.js.
Now, let’s build a service in AngularJS that will handle the Form Digest value for us and automatically update it with the same refresh rate as it would in the master-page. If you check the js-variable _spFormDigestRefreshInterval on a page based on a master-page, you will find the value 1440000 (ms), which means that the Form Digest key will update every 24 minutes.
When adding properties to the Advanced search web part you are bound to know exactly which metadata is included and how it’s spelled. This could be frustrating.
For some reason MS has decided not to help us spell like every other search component would do nowadays.
Consider you have 3 different metadata tags which is all choice or lookup fields. Now, you might want to autocomplete those fields in the Advanced search property restrictions to make sure that the spelling is correct or just to show the users which choices they have.
I implemented this with jQuery-UI which has jQuery-autocomplete included. I also decided to do all the gets by using the SharePoint client OM.
I will not tell you how to define your metadata properties in the search service or how to make them appear in the Advanced search webpart, you can google that
If you have a metadata-oriented structure in you document libraries, you might want to use unique permissions for each document.
This is NOT a good choice if you use folders. It will create a huge permissions matrix.
I have implemented this at my customer and I haven’t noticed any noticeable performance issues.
Let’s say you create a choice field called “Security class” with 4 choices, “Base, low, medium, high” and you want this to control the permissions for the current document.
- Base – Base permission, keep inheritance, every one can contribute. <– Default value for the field.
- Low – Everyone can read, members can contribute, owners and created by has full control.
- Medium – Members can read, no contributors, owners and created by has full control.
- High – No readers, no contributors, Owners and created by has full control.
So basically, in your editform.aspx you have a drop-down with these 4 options.
First, create a class that will handle the permissions.
My colleague has created our intranet in SharePoint online. Using standard features in SharePoint we wanted to have a Wall feature (like Facebook) where users could post what ever they wanted.
We decided to use the SiteFeed WebPart. This is a WebPart which is unique for every site, using SharePoint list called “MicroFeed” to provide data. This is the same way as the Microblog is used on MySite.
The SiteFeed WebPart looks quite good and it provides all the functionality we wanted for a Wall feature, such as comments, likes, tagging people and other social stuff.
The SiteFeed Title “Neewsfeed” can’t be changed. This is NOT the title of the standard WebPart control, this is a built in title in SiteFeed WebPart. This title is not hard-coded, but it’s located in a predefined resource, profilebrowserscriptres.resx, which requires hive-access to change. See this blog-post for more information about the resx. Bare in mind that changing the resource will change the SiteFeed Title everywhere.
The WebPart has Chrome Type none by default, which means that the standard WebPart Title won’t be displayed.
I encountered this problem in a WSS 3.0 environment. Hopefully this can help newer versions of SharePoint as well.
My customer has a old WSS 3.0 environment with a huge site collection. It’s a root-site with 200 sub sites with sub sites. This is a free for all SharePoint with no boundaries. Which makes the maintenance a pain in the ass.
Someone (with to high permissions) renamed the built in field “Title” to “DayReportDate” on the root-site and published it over all sites changing all content types that inherit from Object.. which is well, all. And users on sub sites discovered this pretty quickly and changed their child content types title field back to “Title”. This caused a huge problem since when trying to rename the root-site title field back to “Title”, SharePoint would say “The column name that you entered is already in use or reserved.” even if it’s just reserved on one of the sub sites.
Everyone panicked because their title field was changed to “DayReportDate” and more than 200 sites where affected by this mistake. Having this problem for 6 months they decided that someone with SharePoint experience should take a look at the problem so the case landed on my desk. Yippie!
A problem for me was that I had no server access, so I could not create a console application (or likewise) using the SharePoint server API to correct it. And since it was WSS 3.0 there would be no PowerShell either. So I simply had to fix it on the client side.
I found two solutions.
Links are meant to be broken, at least if you move files or change file names of documents in SharePoint.
I had a customer that required links not to be broken when file name was changed or a document was moved. They also wanted to be able to create links to a specific version, current version and latest major version. The idea was by using the document context menu, users would have the option to create these URL’s.
I wrote a post about creating URL handler for document URLs, this time we will focus on how we can reuse that URL handler to create dynamic and static URLs to documents and document-versions directly from the GUI.
Microsoft has implemented a great way to reach documents by the document id, but it seems that they didn’t fully implement it’s potential into SharePoint. Therefor I would like to show you how we implemented a useful way to reach document versions by using the document id.
This implementation requires the document id feature in SharePoint 2010 enabled. It can be found under Site Collection Features.
Creating the context menu feature
Adding a new option to the context menu is quite easy, it’s all XML. Just add a new Module to your project, I called mine CustomContextMenuActions. Then, by editing the Elements.xml, add a new CustomAction like this. By using the query-string IsDlg=1 we tell SharePoint to remove stuff from the master-page that isn’t relevant to the dialog.
Description="Create a dynamic or static document url"
It would create an action like this.
I wrote a post about adding the built in document id to the document file name. Now I will show you another way to use the built in document id when referring to the documents.
Lets say we are in a big project with several baselines . And every baseline requires it’s own version of a document, but the same document. It could be that new requirements have been added along the way or maybe the architecture has changed from one to another. This might cause the document name to change for some reason and that will break the link from a previous baseline.
What if you had a link that:
- Will never break as long as the document or version is not deleted.
- Can point to the current version.
- Can point to a specific version.
- Can point to the latest major version.
Lets say that link would look something like this
Latest version -> Dynamic
Specific version -> Static, kind of
Latest major version -> Dynamic
Microsoft has provided some great functions from the Office API that we can use when we search for the document via the document id.
Creating the application page – URL handler
First of we need to create an application page that can handle the query-strings from the URL. This can be done quite easy, just map the SharePoint layouts folder to you project (I also added a new folder called customapplicationpages) and add an Application Page. In our case I added a page called getdocbyid.aspx. We don’t have to create any markup for this application page, just code behind. So basically, what we need to do is capture the id and the version and find the right document and redirect to the URL. This is how I implemented it, note that the current version of a document is not a part of the document version history.
Office has a lot of nice features connected to SharePoint, one of them should be a way to insert the version history into your document. Unfortunately there’s no such thing. Maybe because MS wants you use SharePoint when you check the version history. But documents can be taken offline, moved, mailed or whatever and the person reading the document doesn’t necessary have access to SharePoint but still wants to know the story behind the document.
There is no fancy way to do this, not without an Office-Addin and nobody wants that, considering development hours and distribution to clients.
I had to figure out a way to get the document-version-history from SharePoint 2010 into MS Word using SharePoint/Office functionality. This is nothing standard and from what I have found, there is no easy way to do this.
What if I could use a Quick Part to show this? And since fields from SharePoint can be shown as Quick Parts in MS Word, this might be an easy way to do it!?
First I created a hidden field with PowerShell, a Note field with unlimited length and added it to the Content Types used by the documents. You can of course create a feature, console application or likewise to do this.
Do not use $field.Hidden = $true, this will cause the field to NOT appear as a Quick Part.
$web = Get-SPWeb http://server/site
$fieldName = $web.Fields.Add("VersionHistory", [Microsoft.SharePoint.SPFieldType]::Note, $false)
$field = $web.Fields[$fieldName];
$field.UnlimitedLengthInDocumentLibrary = $true;
$field.ShowInDisplayForm = $false;
$field.ShowInEditForm = $false;
$field.ShowInNewForm = $false;
$field.ShowInVersionHistory = $false;
$ct = $web.ContentTypes[%TheContentType%];
$linkField = new-object Microsoft.SharePoint.SPFieldLink $field
When this is done, you will have a field that will not be shown in SharePoint forms, but it will appear as a Quick Part in MS Word.
I discovered that this has been done many times after we did it. Anyway, I will share my experience.
Back in 2010 I was involved in a project which consisted of creating a strict SharePoint site with meta-data oriented document storage. No folders what so ever, except for 10 document libraries. This idea wasn’t that hard to implement considering how easy it is to create static metadata in SharePoint and adding it to Content Types. How ever, if you want to put all documents in the same container, you will have to use unique file-names, otherwise files with same names will overwrite each other with new versions.
Now, how do you create a unique file name that i based on the file name which the user has entered? Well, you can always just add a custom ID or the list-item-ID in the end of the file name or you can use folders like normal people and pray that no one uploads a document with identical name.
In this case we had already decided to use SharePoint 2010’s built-in feature for generating Document-ID. By using this we will also be able to use some other features that is connected to the Document-ID, like search and the ability to create dynamic URLs (which i will get back to).
One of the requirements was that the user should never have to see their document in SharePoint without the unique ID in the file name.