Tuesday, 6 November 2012

Disable the standard SharePoint mobile view

The standard SharePoint mobile view is kinda useless for internet facing sites, as it requires the user is authorized.

SharePoint detects the user agent of the browser and displays the mobile view in case of a mobile browser.
To disable this, you have two options:

  • Disable it in the web.config file
  • Disable it in the compat.browser file in the App_Browsers directory

I chose to disable it manually in the web.config (quick and dirty).
To do so add the following markup to the configuration/system.web node:


    <browserCaps>
      <result type="System.Web.Mobile.MobileCapabilities, System.Web.Mobile, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
      <filter>isMobileDevice=false</filter>
    </browserCaps>


See How to disable mobile view in SharePoint 2010 for a more thorough explination of the matter.

Friday, 13 July 2012

Emphasize site features/site collection features links with help from a custom action

I have been working with SharePoint for almost 2 years now, and still I have trouble finding the links to site features/site collection featues on the site settings page.

I have just come up with a solution to my frustration: Make javascript that emphasizes the links, and deploy it with a CustomAction. :D

Where's Waldo/the feature activation links


In my case I have made it as a custom action for portability reasons.

The structure of my project is as follows:


  • I have a site collection feature that activates the customaction.
  • Two modules - one with the custom action itself (names CustomAction), and one with the javascript files I'm using (named Assets). The latter modules is used to get the javascript files deployed to a library in SharePoint because you can't deploy physical files to the layouts folder with a sandboxed solution.

The custom action Elements.xml:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction Id="EC2D0A294F4C44868FF1E7DB7EA650E0"
              ScriptSrc="~SiteCollection/SiteAssets/Assets/jquery-1.7.2.min.js"
              Location="ScriptLink"
              Sequence="100">
  </CustomAction>
  <CustomAction Id="D2A0E5E1080D4C7ABA51361E574434DE"
               ScriptSrc="~SiteCollection/SiteAssets/Assets/myscript.js"
               Location="ScriptLink"
               Sequence="150">
  </CustomAction>
</Elements>



myscript.js:

function emphasize(elm) {
 
    var style = elm.attr('style');
    style += '; font-weight: bold;';
    elm.attr('style', style);  
}

$(document).ready(function () {
    var elm = $('a[href="/_layouts/ManageFeatures.aspx"]');
    emphasize(elm);
    elm = $('a[href="/_layouts/ManageFeatures.aspx?Scope=Site"]');
    emphasize(elm);

});



The custom action activates the two scripts when SharePoint loads. The sequece number defines in which order they are loaded. In my case I use jquery, so it is important, that the jQuery library is loaded before my script, that uses the library.

In my script I'm selecting the links to the feature activation page. For each of the I'm just adding a style that makes the link text bold - here you can get creative a do what ever. E.g. add a icon in front of the link, move the link to the top of its section or whatever. :)


Wednesday, 9 May 2012

SPQuery on a User field

Filtering on a user field in a SPQuery can be a bit tricky.

The following query would look at the displayname in the userfield on the list (not very practical):


<Where>
  <Eq><FieldRef Name="UserId" /><Value Type="User" >contoso\sp</Value></Eq>
</Where>


The userfield is actually a string like this "42#;contoso\sp"
You would then believe, that it was easy to filter on the loginname. However... If the displayname of the user is set, the string value og the userfield would then be "42;#Sune Popp".
The consistent thing is the user id. This id is unique within the site collection.

So... A better way (imho) is to query on the user lookup id. Your caml should then look like this:


<Where>
  <Eq><FieldRef Name="UserId" LookupId="TRUE"/><Value Type="User" >42</Value></Eq>
</Where>


Hint! As the user id is only unique within the site collection, you should use EnsureUser on the loginname, if your solution is spread across more site collections.

Monday, 7 May 2012

Enable publishing on a team site

You can make your SharePoint teamsite a publishing site like this.

Active the two features:

On site collection level activate first:
Sharepoint Server Publishing Infrastructure




On site (web) level active:
Sharepoint Publishing


Cannot complete this action. Please try again

I got the error: "Cannot complete this action. Please try again. <nativehr>0x80004005</nativehr><nativestack></nativestack>"
The error itself doesn't say much about where its was thrown, but with some debugging I localized to be centered around an SPQuery on a list in SharePoint.

I checked everything, datatypes, permissions on the list and so forth.

However it turned out to be because I had nested three <Eq></Eq> statements in one <And></And> statement. It turns out that the <And></And> statement can only have to nested elements.
So if you like in my case has to filter on more than two parameters on the list build your caml something like this:


<Where>
  <And>
    <And>
      <Eq><FieldRef Name="UserId" LookupId="TRUE"/><Value Type="User" >{0}</Value></Eq>
      <Eq><FieldRef Name="SiteId" /><Value Type="Text">{1}</Value></Eq>
    </And>
    <Eq><FieldRef Name=\"TSPRelation\" /><Value Type=\"Text\">{2}</Value></Eq>
  </And>
</Where>