Friday, 20 December 2013

SharePoint 2013 - Displaying Multiple Rows of Links w/ Promoted Links Web Part

If you're like me and needed to have quite a few tiles in your Promoted Links Web Part, this should come in handy.

I've seen options to install custom solutions, and i've seen options to add a javascript file to the web part to force it to go to a new line.

Custom solutions?  meh.

Seperate 76kb javascript file?  meh.

Use what you've been given my friends; and make it simple for your siblings to see how it works.

It's not entirely a simple solution, but when completed I think it is the most elegant/clean solution.  Create two Promoted Links Web Parts underneath each other and use two separate Tile Views to display everything you need.  The only way I could find to create another Tile view was to use SharePoint Designer.

  • Navigate to list in SharePoint Designer 2013
  • Create new view
  • Copy CAML Query from original Tile View to new Tile view.  Copy This Bit (Make sure you keep the old view name, display name, url):
<XmlDefinition><View Name="{#######-####-####-###########}" Type="HTML" DisplayName="Tile2" Url="/Lists/Promoted Links/Tile2.aspx" Level="1" BaseViewID="1" ContentTypeID="0x" ><Query><OrderBy><FieldRef Name="TileOrder" Ascending="TRUE"/><FieldRef Name="Modified" Ascending="FALSE"/></OrderBy></Query><ViewFields><FieldRef Name="Title"/><FieldRef Name="BackgroundImageLocation"/><FieldRef Name="Description"/><FieldRef Name="LinkLocation"/><FieldRef Name="LaunchBehavior"/><FieldRef Name="BackgroundImageClusterX"/><FieldRef Name="BackgroundImageClusterY"/><FieldRef Name="Row_x0020__x0023_"/></ViewFields><RowLimit Paged="FALSE">6</RowLimit><JSLink>sp.ui.tileview.js</JSLink><XslLink Default="TRUE">main.xsl</XslLink><Toolbar Type="Standard"/></View></XmlDefinition>
  • Modify the CAML Query to select only certain tiles (i used the following, place directly after the opening <Query>):
<Where><Geq><FieldRef Name="TileOrder"/><Value Type="Integer">7</Value></Geq></Where>
  • Save
  • Use!

Wednesday, 11 December 2013

SharePoint 2013 - Hide Root Node Link in Global Navigation using CSS

The other solutions I've found regarding this involve javascript/jquery.  Was unable to find any CSS that resolves the issue nicely.

This seems to have resolved the issue for me so far without compromising any other areas of the site.  It hides the initial link and then goes back to displaying the rest of the navigation as per normal:

<style type="text/css">
.ms-core-listMenu-horizontalBox li.static > a{
display: none !important;
}
.ms-core-listMenu-horizontalBox li.static > ul a{
display: block !important;
}
</style>

Tuesday, 26 November 2013

SharePoint 2013 - Responsive SharePoint Design Issues with IE8 and @media tags

UPDATE:  After looking at this again, the answer is yes, I must have been doing something silly.  Guessing the page was not fully refreshing after checking in the Master Page with the changes or something like that, as I haven't changed anything to get it to work, just re-downloaded & re-added the respond.js files.

-----------------------------------------------------

I've been spending some time with the Responsive SharePoint solution I found on CodePlex here: https://responsivesharepoint.codeplex.com/

and have come across an issue that I am yet to resolve when using Internet Exploer 8 (IE8) to view the page.

Using: Bootstrap-3-server.master

Issue: When using IE8, the top navigation defaults to the mobile view even when full screen (wider than 768px). This is due (i think) to IE8 not reading the .navbar-toggle inside a @media tag, which when wider than 768px, is hidden via display:none. 


Normally, for a solution using bootstrap, to resolve issues with the @media css tag, they ask that you use respond.js which allows IE8 to use @media tags successfully.


I have saved the respond.js file locally on the server and referenced it within the bootstrap-3-master master page but the @media tags are still not being found by IE8.


Has anyone else had/solved this issue? Could it be something silly I'm doing wrong here?



Monday, 25 November 2013

InfoPath 2010 - How Do I Deploy InfoPath Forms & Updates to SharePoint

Deploying an InfoPath form

Once you have developed your InfoPath form, most likely you will need to deploy/publish it to SharePoint so that the information can be stored and reported on.  There are different methods for deployment, which are also dependent on whether you are publishing a fresh form, or updating an old form.

Two methods of Deploying/Publishing Forms

When it comes time to deploy your form to SharePoint, there are two different methods with reasons for and against why and when you would use each.  You can publish the form as a Form Library, or as a SharePoint Content Type.

Deployment Method 1:  As a Form Library
When you publish a form as a Form Library, it will create the library on the SharePoint Site of your choosing, and a copy of the form template can be found here:  http://rootsite/formlibrary/forms/template.xsn

Use this method when you only require one library for the forms and the forms do not get consumed by BizTalk for some other purpose.  The reason to go with this method is because it means a less complex setup of the forms on the SharePoint Site, and doesn’t require us to create a content type just for the form, which in turn keeps SharePoint's back end a bit cleaner.

Pros: Quick to setup.  Automatically creates library for you on the SharePoint Site

Cons:  Can’t re-use the template quickly.  GUID’s for all the template fields will not be the same across Libraries if you need to publish it to multiple locations.

Deployment Method 2: As a Content Type
When you publish a form as a Content Type on SharePoint, that Content Type is available across the entire Site Collection.  This is useful for when a form will be used by multiple departments that each require their own library to store the completed forms.  The difference with this is that the Template for the Content Type needs to be saved within a Document library, so you need to ensure all staff only have Read Only access to that library.

Pros: Form Template is saved as a Content Type to SharePoint, which means you can easily add the Content Type to any Document Library within a few clicks.  So if you need 3 libraries with the same content type for BizTalk it’s quicker to set up.  As it is published as a Content Type, the GUIDs for all the fields in the form will remain the same across libraries in SharePoint, which is a requirement for BizTalk.

Cons: Slower and more complicated to set up correctly.  Once you have published the content type, you still need to create the document library and add the Content type as a selectable option in the library.

Long Story Short:  
If you just need a single library to hold all the form information, just publish it as a Form Library.  If you require multiple libraries to hold the forms and their info, or if you are integrating the form data with other systems, publish it as a content type.

Publishing updates to existing InfoPath forms

If you’re doing it right, you should be saving all the versions of your InfoPath forms using TFS or similar, and deploying your updates to a test environment before pushing them out to your live environment.  With this method of test and publish, sometimes InfoPath can get a bit grumpy about re-using the same SharePoint GUID’s for the form when you re-publish it. 

For this reason, we need to double check that the GUID’s that are currently set against the fields in SharePoint, are the same as the GUID’s that are set against the fields within the form template before publishing.  And if they are not, then change the form template field GUID’s to match what is currently in SharePoint against those same fields.

How to do this:
  • Download a copy of the forms template from it’s current location in SharePoint (template.xsn location above if published as library, where you published the template if published as content type).
  • Open up the form in Design view and go to File > Publish > Export Source Files to a folder on your desktop
  • Do the same thing to your updated version of the InfoPath Form.
  • Open up the manifest.xsf file on both of your forms in Notepad or similar, and about a third of the way down you will find a section that will list all the columns that you have promoted as fields in SharePoint


  • Make sure that each of the ColumnId’s against each ColumnName are the same in both manifests, otherwise update the ColumnId’s in your updated form Manifest.
  • If you had to make changes, save and close the manifest file, then open up the manifest in Design Mode in InfoPath and Publish to SharePoint!


Thursday, 21 November 2013

SharePoint 2013 - Responsive Design

G'day,
       Just a quick note to say if you haven't heard of it already, then you should check out this solution on CodePlex that is absolutely awesome: http://responsivesharepoint.codeplex.com/

What it contains:
- Responsive resizeable Master Pages & Page Layouts for SharePoint 2013 that work with Twitter's Bootstrap CSS.
- Responsive resizeable Master Pages & Pages Layouts for SharePoint 2013 that work with Zurb's Foundation CSS.

I've tried both briefly but so far prefer the Bootstrap version for the font types and colours.  Although I most of us will be making modifications to suit the clients that we are working with, they are a great starting point to Responsive Design for SharePoint that have been designed very well.

If you don't have time to build your own solution from scratch, this is the perfect starting point to build on top of.  Congratulations and thank you to all who have worked on the project so far!

More to come...

Thursday, 24 October 2013

SharePoint 2010 - Items Added By Anonymous Users Cannot Start Workflows

On a public-facing website on SharePoint 2010, I was building a simple list to be used as the Contact Us form, so that when an item is added to the list, a workflow will run which sends an email to the owner of the website.

It all worked fine until I tested as an anonymous user that wasn't logged in.  I could create the item fine, but the workflow would not run.  The reason for this is, when an item is created by an anonymous user, the item does not set an author against itself (created by, modified by), which means the Workflow does not know what permissions it should use to run.

Turns out there's really only one way to get around this.  Open up your old mate Visual Studio and create an Event Receiver on the ItemAdded event.  What needs to happen is as soon as the item is added to the list, the event receiver will grab the item, and set the Author value to something generic (I used the System Account), then run the workflow.

(code in text at the bottom of this blog)


However, after deploying the solution to the site, I was still having issues with the Event Receiver & Workflow refusing to run and returning an error to the Event Viewer:

Error loading and running event receiver ExecuteWorkflow.EventReceiver1.EventReceiver1 in ExecuteWorkflow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0e007c3794fb9704. Additional information is below.
: <nativehr>0x80070005</nativehr><nativestack></nativestack>

After much hair pulling, I now realised I should have been face slapping myself, as the issue was happening because I had set Advanced Settings on the list so that users could only see and edit items that were created by themselves.  This was causing the event receiver to say 'hang on buddy, an item has been added, but I can't read it'.

Changed those settings back to being able to view and edit all items and the event receiver worked fine.

To get around the issues with Anonymous users being able to view all the data in the list, you have two options:
- Get the workflow to delete the item after it's details have been emailed.
- If you need to report on the list data (it needs to be kept), Get the workflow to copy the item to an identical list that Anonymous cannot access.

--------------------------------------------------
using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;

namespace SetAuthorForWorkflow.EventReceiver1
{
    
    /// <summary>
    /// List Item Events
    /// </summary>
    public class EventReceiver1 : SPItemEventReceiver
    {
       /// <summary>
       /// An item was added.       
       /// </summary>
       ///       
       public override void ItemAdded(SPItemEventProperties properties)
       {
           if (properties.ListTitle == "BookingList"  || properties.ListTitle == "ContactUsList")
           {
                Guid siteID, webID, listID;
                int itemID;
                listID = properties.ListId;
                itemID = properties.ListItem.ID;
                using (SPWeb web = properties.OpenWeb())
                {
                    siteID = web.Site.ID;
                    webID = web.ID;
                }
                //run this block as System Account
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite site = new SPSite(siteID))
                    {
                        using (SPWeb web = site.OpenWeb(webID))
                        {
                            web.AllowUnsafeUpdates = true;
                            SPListItem item = web.Lists[listID].GetItemById(itemID);
                            if (item != null)
                            {
                                //Impersonate the Author to be System Account
                                item["Author"] = web.AllUsers[@"SHAREPOINT\system"];
                                item.SystemUpdate();
                                //start the by add the item and workflow name
                                if (properties.ListTitle == "BookingList") { StartWorkflow(item, "EmailBooking"); }
                                else if (properties.ListTitle == "ContactUsList") { StartWorkflow(item, "ContactUs"); }
                            }
                            web.AllowUnsafeUpdates = false;
                        }
                    }
                });
           }
           else
           {
               return;
           }
       }

       private static void StartWorkflow(SPListItem listItem, string workflowName)
       {
           SPWorkflowAssociation wfAssoc = listItem.ParentList.WorkflowAssociations.GetAssociationByName(workflowName, System.Globalization.CultureInfo.CurrentCulture);
           listItem.Web.Site.WorkflowManager.StartWorkflow(listItem, wfAssoc, wfAssoc.AssociationData, true);
           listItem.Update();
       }
    }
}
------------------------------------------

Thursday, 3 October 2013

Programmers need to KISS

An old teacher once asked me why people think programming is so hard.  Being someone who enjoys it, I couldn't give him a good reason.  

His reply was simple.  

Programming is not hard.  In fact, there are FOUR things you need to understand to be a programmer
  • Programs can run commands sequentially (1 line at a time)
  • They can loop through commands (repeat the same code multiple times)
  • They can handle conditional statements (If, Then, Else)
  • They can transfer control
And there are only TWO things that can go wrong
  • Syntax Error
  • Logical Error
So next time you get stuck on some mind-blowing complex piece of code, just remember... 

Keep It Simple Stupid.

Friday, 13 September 2013

SharePoint 2010 - Calendar with multiple resources and Double Booking prevention

So I know this is an OOTB feature, but I'd been looking for exactly this solution for (let's be honest) quite a while.

A SharePoint Calendar with which you can book items/resources like projectors, laptops, meeting rooms, etc.  A calendar that also checks whether that resource has already been booked on that specific date and time.

Anyway, There is an official Microsoft article at the bottom of this post, but because it took me so long to find, I'm duplicating it:

1.  Activate the 'Group Work Lists' Feature for the Site.
2.  Enable'Resource Reservation' in the Calendar List Settings > Title, Description and Navigation
3.  Ad resources to the 'Resource List' that would have been created when you enabled the Group Work Lists Feature
4.  Use Calendar
5. Profit





Official Article:
http://office.microsoft.com/en-au/sharepoint-server-help/enable-reservation-of-resources-in-a-calendar-HA101810595.aspx

Tuesday, 6 August 2013

SharePoint 2010 - Publishing Site 'Pages Library' no-no

Earlier today I wanted to modify the address of the 'Pages' library on a SharePoint 2010 site.  The reason behind this was to make the naming of the folders more user friendly for our developers who would be deploying reports there.

There wasn't a way to do it from the standard GUI, so I decided to modify it in SharePoint Designer (Hey, if SP Designer allows you to do it via GUI, it's safe right? ... right!?).

Bad move, as there's some behind the scenes magic that must be hard-coded to the Pages URL, which breaks the Navigation Settings page (this one: http://[sitecollection]/_layouts/AreaNavigationSettings.aspx).

'An Unknown Error has Occurred' - Great..

I'm sure there would be a way around it, but for the sake of saving a few hours of investigation, don't change the name of your Pages Library!

Ciao ciao!

Thursday, 11 July 2013

SharePoint 2010 - People Picker that is showing the wrong user profile information

Hi again,

introduction to this issue:  Someone has updated information on their MySite but their details have not propagated through to the People Picker, or any list that shows User Information in it.

Why:  This is due to the User Information List, which is used to supply User Information to all the SharePoint functions that use it.  The User Information List only seems to get updated when a user is first introduced to a Site Collection.  Not even a full Profile Sync will fix it. (You can find the User Information List here: http://[rootsite]/_layouts/people.aspx?MembershipGroupId=0).  This issue has been documented before and done very nicely on Gary's blog here: http://blog.falchionconsulting.com/index.php/2011/12/updating-sharepoint-2010-user-information/

The difference is between Gary's blog post and mine, is that his shows how to get a script to iterate through every Web Application and update specific fields.  Where as I will be showing how to look for a specific field & update it manually.

HOW TO FIX USING POWERSHELL

First get the User ID of the person who is having the issue:

$user = Get-SPUser -Identity 'domain\username' -Web http://sharepointserver
$user.id

Then you need to navigate to the Users details in the User Information List using their user ID you just found.  This code will list all the fields for that user appearing in the User Information List

$web = Get-SPWeb http://SharePointServer
$list = $web.Lists["User Information List"]
$item = $list.GetItemById($user.id)
$list.fields | % {Write-Host "$($_.InternalName) = $($item[$_.InternalName])"}

Now you should have found the field causing the issue, so you can update it like this:

$item["FieldName"] = "  "
$item.SystemUpdate()

Done!  Because this is a manual way of searching for the right fields to update, you will need to do this for every Web Application.

Tuesday, 9 July 2013

Making a jQuery banner from scratch

Woah, hang on a minute...  You mean you want me to build my own jQuery solution from scratch!?  Why would I do that when there are so many pre-packaged jQuery solutions out there?

Good question, if you are only making something very simple, maybe you'd like to optimise the amount of code the browser has to execute, and the pre-packaged solution may have many more features than you need...  Ok, I'll admit that's a bit far fetched for me to use as my own excuse.  I had some spare time, and wanted to see how easy it was.

The answer, as always, is it depends.

I was migrating a website from the early 2000's to a SharePoint site and I just wanted to replace a simple flash banner that faded in/out images & animated text.  Great little project I thought.

Here's how:
First I made a simple HTML page with a div for every image and sentence I wanted to fade in and out.  and an id against every div, so that I could reference them in the jQuery.

<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js" />
</head>
<body>
<div id="background">
<div id="sydney"><div id="busy">Busy Joint</div></div>
<div id="melbourne"><div id="cold">Cold Joint</div></div>
<div id="brisbane"><div id="small">Small Joint</div></div>
<div id="perth"><div id="exxy">Exxy Joint</div></div>
</div>
</body>

I used CSS to hide all div's by default using 'display: none'.  and of course, used CSS to set all the other look/feel goodies.

Now to start Querying the J (jQuerying... ahem.):

A few pointers.

  • All jQuery needs to be inside <script> tags
  • Anything inside the Document Ready Function will run when the page loads
  • If you wish to cycle your animation indefinitely, my favourite way is to put the animation inside it's own function, which calls itself on the last line of the function.
  • Whenever you want to do something to an item, you call it like this: $("#[css id]").[dosomething]()   So the jQuery Syntax is: $(selector).action() 

Here's the beginning of my jQuery, fading in my 'sydney' and 'busy' divs, then animating the 'busy' words and then fading them out again:

<script>    
$(document).ready(function(){  
  
    $("#sydney").fadeIn("slow");    
    $("#busy").fadeIn("slow");        
    $("#busy").animate({left:"150px"}, 700, function(){     
        $("#sydney").fadeOut("slow");    
        $("#busy").fadeOut("slow");  
    });

});
</script>

Notice on the animate step, I've called a function which runs the FadeOut steps.  This is because although jQuery runs step by step, it doesn't wait until one step is finished to run the next step unless you tell it to.  So what I'm saying here is, don't fade the suckers out until the animation has completed.

So I wanted to make the banner do this four times with different DIV's.  All you need to do is rinse and repeat really!  Yes I probably could have optimised the code even further, but this is a simplistic version in order to teach a beginner how it works:

<script>
$(document).ready(function(){


startAnimation();

function startAnimation(){    
    $("#sydney").fadeIn("slow");    
    $("#busy").fadeIn("slow");        
    $("#busy").animate({left:"150px"}, 700, function(){     
    $("#sydney").fadeOut("slow");    
    $("#busy").fadeOut("slow");  

    $("#melbourne").delay(1000).fadeIn("slow");    
    $("#cold").delay(1000).fadeIn("slow");        
    $("#cold").animate({right:"150px"}, 700, function(){     
    $("#melbourne").fadeOut("slow");    
    $("#cold").fadeOut("slow");  

    $("#brisbane").delay(1000).fadeIn("slow");    
    $("#small").delay(1000).fadeIn("slow");        
    $("#small").animate({left:"150px"}, 700, function(){     
    $("#brisbane").fadeOut("slow");    
    $("#small").fadeOut("slow");  

    $("#perth").delay(1000).fadeIn("slow");    
    $("#exxy").delay(1000).fadeIn("slow");        
    $("#exxy").animate({right:"150px"}, 700, function(){     
    $("#perth").fadeOut("slow");    
    $("#exxy").delay(1000).fadeOut("slow",startAnimation);  
    });
   });
 });
});
}
});
</script>

I added a little bit extra there..
  • Used the Delay Action to make the steps wait 1 second.
  • Inserted a function to run all the animations, so that I could get the function to call itself and run forever.
  • The animate settings is telling the CSS to move the div right and left.
Hopefully that's not too much info.  Comment if you have any questions.

Monday, 1 July 2013

Entertainment book - Melbourne CBD - 2012-2013

Go to 2 expensive restaurants that do 2-for-1 and you've already made back the money you paid for the book.

Oh wow, now you have 700 other tickets of varied usefulness that can save you cash.

I personally prefer just to use all the restaurant ones as they give you the most value for money and force me to go to new restaurants!

Friday, 28 June 2013

SharePoint 2010 - Copy documents across libraries while keeping Versioning

I've recently been looking into a good Document Management solution using OOTB SharePoint 2010 functionality.  I'll explain my solution that should cover ISO in another post, but here I'd like to explain another issue I had with moving files from one Document Library to another while keeping all the version history.

The only way I've found to keep all the version history is to make both libraries identical, then to open both libraries with File Explorer & move the files to the second Library.  Alternatively, you can use the 'Manage Content & Structure' area to move them as well.

If you are like me, you have some trust issues with Microsoft at times, and don't want to risk moving the files and all their information if it doesn't work!

So here's the easiest (oh god) way I found to do it safely.
  • Export (Backup) a copy of the Document Library containing all the data you wish to transfer:
Export-SPWeb -Identity "http://[servername]/[site]/" -Path "\\[servername]\Backup\[FileName].cmp" -ItemUrl "[DocLibrary Address]/" -includeversions All -IncludeUserSecurity -verbose

I'm using -includeversions all to keep every version of every document in the library.  and i'm using -IncludeUserSecurity to preserve the user detail like created by, modified by, etc..

  • Restore a copy of the Document Library to a temporary site (Create the site first, I've had troubles with the moving unless both sites are directly beneath the root site.  So if you can, don't build the temp site beneath the site you will be copying to):
Import-SPWeb -Identity "http://[servername]/temp" -Path "\\[servername]\Backup\[FileName].cmp" -IncludeUserSecurity -force

  • Open up both libraries via File Explorer (Temp Library and Library where you wish to move the docs to), Drag & Drop all files (Move!).  
  • Check to ensure success

Like I said, easiest way to move files with their version history in the safest manner without risking losing data from your live source.

You are welcome.

Thursday, 18 April 2013

SharePoint 2010 - When [Today] just isn't your day

Sometimes your SharePoint environment doesn't want to play ball with OOTB features, so if you like me have once had an issue with the [Today] option not working on list filters, here is the slower but successful way of getting it to work:

Create the view using CAML Query in SharePoint Designer 2010.

The CAML equivalent of [Today] is:
<Value Type="DateTime"><Today/></Value>

Or if you want to be a few days ahead or behind today

<Value Type="DateTime"><Today OffsetDays="-31"/></Value>

Cheers,
The Baretta

SharePoint 2010 - List View Threshold


Any well utilised SharePoint farm will hit this limit at one point or another, the annoying but not hard to resolve LIST VIEW THRESHOLD ISSUE!!!!!!


If you're on the ball, you'll know to cater for this when first creating a list you know is going to be quite popular with the lads.  This involves creating indexed columns, and creating views that filter on the indexed columns.

But woe to those who wait for the dreadful message to appear, and also to those who prepared for it, but it is still occurring anyway.   WHHHHHHYYYYYYYYYYYYYYYYYYY!!!!!!!!!!!!....

STOP!  CAML TIME!

Well it's because when you modify a view using the SharePoint GUI, and you filter on a indexed column and maybe a few others, SharePoint turns your filters & options into a CAML query, and if that query contained a few different column filters, SharePoint occasionally doesn't render the CAML query in a manner that ensures you are always querying less than the List View Threshold!

OH NOES!

Oh yes.  If this happens, it means that you will have to manually create the CAML query on the page using SharePoint Designer.  Just make sure that the FIRST column you filter on is an indexed column that will bring back less items than the List View Threshold limit.

Never had to write CAML?  well there's plenty of info on Google for CAML queries, so I won't explain it here.  but I will supply an example below for interests sake.  Any questions let me know :)

EXAMPLE CAML:

<Query>
<Where>
<And>
<Eq>
<FieldRef Name="Status"/>
<Value Type="Text">Open</Value>
</Eq>
<Or>
<Eq>
<FieldRef Name="AssignedTo"/>
<Value Type="User">Simon Blob</Value>
</Eq>
<Or>
<Eq>
<FieldRef Name="AssignedTo"/>
<Value Type="User">Roger Reporter</Value>
</Eq>
<Or>
<Eq>
<FieldRef Name="AssignedTo"/>
<Value Type="User">Moses Roses</Value>
</Eq>
<Eq>
<FieldRef Name="AssignedTo"/>
<Value Type="User">Daniel Dogood</Value>
</Eq>
</Or>
</Or>
</Or>
</And>
</Where>
</Query>
END OF EXAMPLE CAML.

SharePoint 2010 - CSS & JS Across Multiple Web Applications

An issue I came across the other day involved creating a web application with the look & feel as another web application on the SharePoint 2010 Farm.

I decided to link all the CSS from the second Web Application to the first Web Application, which works fine for the majority of functions (background, colours, images, page width, etc).

Here's what was failing for me, and the only workaround was to make a copy of the CSS on both Web Applications:

  • Certain JQuery & Javascript files failed to render
  • Custom Markup Styles in the Ribbon failed to appear
Moral of the story, Don't point Master pages to another Web Applications CSS & JS files.  Make a copy of them on each Web App

SharePoint 2010 - SQL Server 2012 Reporting Services Integration Steps (Multiple Server Farm)

Most SharePoint customers suffer no issues when integrating SQL Server Reporting Services 2012 (SSRS 2012) with SharePoint 2010 (SP 2010), I however, had quite a bit of trouble.  So for those at home who may also be having some trouble, I thought I'd prescibe you some troubleshooting medicine along with a few spoonfuls of errors.

The official steps you may have read about:
- Install SQL Server with Reporting Services Add-in for SharePoint
- Install SharePoint on the Reporting Services Server and connect that server up to the farm (using Configuration Wizard)
- Install the rsSharePoint.msi file provided by Microsoft on all your front-end servers running SharePoint.
- Run these two commands on all front-end servers running sharepoint

  • Install-SPRSService
  • Install-SPRSServiceProxy
- Navigate to Central Administration > System Settings > Manage services on server.  Start the SQL Server Reporting Services Service
- Navigate to Central Administration > Application Management > Manage Service Applications.  Create a new SQL Server Reporting Services Service Application

----------------------------------------------------------------------------------------

Here's the issues you may come across and the solutions I found to the issues:

Issue 1:
"Install-SPRSService : The term 'Install-SPRSService' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again"

Solution:
You need to install the Reporting Services SharePoint Add-In (Found on your SQL Server 2012 installation media) on every server running SharePoint.  Please don't use the rsSharePoint.msi provided on Microsoft's website, here's why....

----------------------------------------------------------------------------------------

Issue 2:
"When I try to create a SQL Server Reporting Services Service Application under 'Manage Service Applications', I receive an error relating to permissions to a registry key"

Solution:
There's nothing wrong with your registry except that SharePoint is looking for files that don't exist.  This is because you most likely installed the Reporting Services SharePoint Add-In with the rsSharePoint.msi file that Microsoft provides on their website.  That file is a cut-down version of what gets installed when you install the Add-In from the SQL Server 2012 installation media.  Uninstall it from Control Panel, and re-install it with the SQL Server 2012 installation media.  

Things to note:  
  • Your Windows servers running SharePoint will need to be updated to SP1 if WS2008R2, or SP2 if WS2008
  • Trying to create the Service Application may have created the databases on your SQL Server but not deleted them.  You will have to remove them manually (at your own risk!).
----------------------------------------------------------------------------------------

Issue 3:
"I've created my SQL Server Reporting Services Service Application, but when I try to access any of the links inside it (system settings for instance), I'm receiving a 503 unauthorised error message"

Solution:
This may vary from case to case, but for me it was because I ran these commands on every front end server:
  • Install-SPRSService
  • Install-SPRSServiceProxy
When in actual fact, depending on your scenario (SharePoint Standard Licensing I think is the cause), you should only run these scripts on the server that you wish to be running the Server Service.  You will need to uninstall them by using the following scripts (remember to delete the application and stop the service  in Central Admin first)
  • Install-SPRSServiceProxy -uninstall
  • Install-SPRSService -uninstall
----------------------------------------------------------------------------------------

That's it!  You should now be winning at SharePoint life.  I did spend quite a bit of time on this, so if anyone has any questions, please feel free to comment.