How to specify results source name for search query using SharePoint 2013 JavaScript Client Object Model

For using SharePoint 2013 search CSOM/JSOM there are already existing posts that explain how to perform search, gor example this or this

Today, however, I needed to set Results Source for my search query. You can do it using keywordQuery.set_sourceId(guid), but this requires GUID … and who likes dealing with GUIDs. Especially if you move configurations between environments.

I was able to peek into how Search Query Results webpart works, and it actually uses source name, this way making it possible to export/import webpart configuration.

As it turned out it was setting two query properties: SourceName and SourceLevel.

  • SourceName is obviously your source display name.
  • SourceLevel indicates the level at which given source was defined, with possible values:
    • SPWeb - sources defined locally for current web
    • SPSiteSubscription - sources defined for sote subscription (for SharePoint online this is the level where all your custom results sources are defined in tenant administration)
    • Ssa - search service application (for SharePoint Online all global predefined sources)

So for example to query “My Custom Source” defined in SharePoint Online admin center (tenancy) I could use the following code:

var clientContext = new SP.ClientContext.get_current();
var keywordQuery = new Microsoft.SharePoint.Client.Search.Query.KeywordQuery(clientContext);
keywordQuery.set_queryText("*");

// set Source Name
keywordQuery.get_properties().set_item('SourceName', 'Test Global');
// set Source Level
keywordQuery.get_properties().set_item('SourceLevel', 'SPSiteSubscription');

var searchExecutor = new Microsoft.SharePoint.Client.Search.Query.SearchExecutor(clientContext);
var searchResults = searchExecutor.executeQuery(keywordQuery);

clientContext.executeQueryAsync(function onSuccess() {
	// process searchResults
	// e.g. iterate through searchResults.get_value().ResultTables[0].ResultRows
}, function onFailure(args) {
	// process failure
});

And you need to reference sp.search.js. How you do that will depend on whether you are inside app, regular web or app web. For the master page on regular web just add script reference:

<script type="text/javascript" src="/_layouts/15/sp.search.js"></script>
Posted in SharePoint 2013, Sharepoint | Leave a comment

How to get termStore by name using SharePoint 2013 JSOM

All the examples of retrieving Terms Store and getting all terms using JavaScript object model were using GUIDs. Well, we know that GUIDs work only for specific environment, and not for moving stuff around.

You will need to include sp.js and SP.Taxonomy.js. The way you do it will differ based on whether you are running inside SharePoint web (example) or inside app (check Taxonomy Menu in  Office App Samples).

So once you are at the point when JS libraries are loaded, what do you need:

var termSetName = "Your term set name";
var locale = 1033; // your locale. Here is English

var clientContext  = SP.ClientContext.get_current();
var taxonomySession = SP.Taxonomy.TaxonomySession.getTaxonomySession(clientContext);
var termStore = taxonomySession.getDefaultSiteCollectionTermStore();
var termSets = termStore.getTermSetsByName(termSetName, locale);
var termSet = termSets.getByName(termSetName);
var terms = termSet.getAllTerms();

clientContext.load(taxonomySession);
clientContext.load(termStore);
clientContext.load(termSet);
clientContext.load(terms);

clientContext.executeQueryAsync(function onSuccess() {
    var enumerator = terms.getEnumerator();

    while (enumerator.moveNext()) {
        var spTerm = enumerator.get_current();
        var name = spTerm.get_name();
        var id = spTerm.get_id();
        // ... etc, do your logic for terms
    }
}, function onFailure(args) {
    alert('Error: '+args.get_message());
});
Posted in SharePoint 2013, Sharepoint | Leave a comment

How to get original Request URL in SharePoint

If you need to get current request URL in ordinary web application, you usually do

string requestURL = Request.Url.AbsoluteUri;

But as SharePoint does it’s own URL rewrites, if you would try that for example for the page

http://yourdomain/sites/yoursite/_layouts/YourPage.aspx

It would return

http://yourdomain/_layouts/YourPage.aspx

The solution is to use special property on SPUtility class – SPUtility.OriginalServerRelativeRequestUrl

This property returns the original URL before it was rewritten, which is useful if you need to get the subweb from which an application page was loaded.

As this URL is server-relative, to get full url, you can use:

SPUtility.GetFullUrl(SPContext.Current.Site, SPUtility.OriginalServerRelativeRequestUrl);

This can be useful if you need to redirect for example to the same URL with some additional parameters.

Posted in Uncategorized | Leave a comment

Sharepoint 2007 – Quirks mode box model for all browsers with box-sizing

Sometimes you still have to develop for Sharepoint 2007. And, you know, there is no DOCTYPE declaration in standart master pages. Which means, pages are rendered in quirks mode in IE. Which means, magins and padding are counted inside of the element, not outside, as in all other browsers.

Which means, if you have to develop something cross-browser, you add some nested div-s and, for example, just set margins on inner. It works, but it is not pretty and not convenient.

The proper solution from HTML/CSS standpoint – add your own master page, set DOCTYPE there and be happy. Not always possible.
So, there is no way to toggle IE in standarts mode without DOCTYPE. But, maybe, there is something that allows to toggle other browsers into “quirks” mode?
And, actually, there is CSS3 property, which does exactly that: box-sizing.

box-sizing: border-box” sets element’s box model to the model, used in quirks mode = margin, border and padding are counted inside of the element. Some explanations and general of the property is available on css-tricks.

Browser support for box-sizing:

  • Mozilla Firefox: 1+
  • Google Chrome: 0.2+
  • Safari: 3+
  • Opera: 7+
  • Internet Explorer: 8+

As you see, it is quite good in all browsers except IE. But we have quirks mode in IE here, so we do not actually need this property.

So, for example, we have our container on the page, #my_container, and we want it, and everything inside of it to have the same (border-box, quirks in IE) box model in all browsers. How do we accomplish it? Well, it is true, that all browsers support the property, mozilla and webkit do that with vendor prefix (-moz-box-sizing and -webkit-box-sizing). So, the actual declaration will be:

#my_container, #my_container * {
  -webkit-box-sizing: border-box; /* WebKit = Safari, Chrome */
  -moz-box-sizing: border-box; /* Mozilla Firefox */
  box-sizing: border-box; /* Other = Opera, etc. */
}

So, what can we do now with all that?
Well, we can set margins and paddings and don’t think about breaking everything in IE (or otherwise)
And it works in IE6+ and all other modern browsers.
And we can do nice things like specifying width: 50% and padding for the elements at the same time.

So, here are two test pages: without box-sizing: border-box and with box-sizing: border-box.

Posted in CSS, Sharepoint | Tagged , | Leave a comment

Sandboxed WebPart on .aspx page using replaceable parameters in Sharepoint 2010

Although it is not possible to create real (in _layouts folder) application pages in sanboxed solutions, there is a way to create site pages with codebehind – basically just .aspx page that renders webpart. Page is deployed as a part of a module, and all the logic is located in the wepart.

There are some examples how to accomplish that.
One thing – there is no simple .aspx page template in VS 2010, that can be deployed in module. I am using CKS: Development Tools Edition. It adds site page template and some more, which is nice.

Another thing – to render WebPart, you have to specify AssemblyFullName, SolutionId and TypeFullName. Finding these values every time is somewhat annoying.

Here come Visual Studio Replaceable parameters. See the whole list.

For our webpart we need AssemblyFullNameand SolutionId. And we get them:

    <WebPartPages:SPUserCodeWebPart ID="MyAppWebPart"
      runat="server"
      AssemblyFullName="$SharePoint.Project.AssemblyFullName$"
      SolutionId="$SharePoint.Package.Id$"
      TypeFullName="AppPagesTest.AppPagesWebPart.AppPagesWebPart">
    </WebPartPages:SPUserCodeWebPart>

We can also use replaceable parameter for TypeFullName. For that we need to add Guid parameter to the WebPart class:

using System.Runtime.InteropServices;

Parameter is located in System.Runtime.InteropServices namespace, so we add it.

    [Guid("72e3609b-0350-4821-839a-02658b5fc008")]
    public class AppPagesWebPart : WebPart
    {
        ...
    }

And the definition becomes

    <WebPartPages:SPUserCodeWebPart ID="MyAppWebPart"
      runat="server"
      AssemblyFullName="$SharePoint.Project.AssemblyFullName$"
      SolutionId="$SharePoint.Package.Id$"
      TypeFullName="$SharePoint.Type.72e3609b-0350-4821-839a-02658b5fc008.FullName$">
    </WebPartPages:SPUserCodeWebPart>

Replacement of the Type token is useful if it is possible that the namespace or WepPart class name will change.

Posted in Sharepoint | Tagged , , | Leave a comment

Referencing javascript files using CustomAction in Sharepoint 2010 Sandboxed Solutions

When you are creating farm solution, it is easy to include javascript file into all site pages using CustomAction.
The main idea is that you add javascript file to _layouts folder and use

  <CustomAction
      Location="ScriptLink"
      ScriptSrc="/_layouts/.../your_javascript_file.js" Sequence="100">

Problem is, in sandboxed solutions you are not allowed to put files into _layouts, and it is not possible to reference Assets files using ScriptSrc.

What else is available to us? Actually, there is one thing – you can use ScriptBlock attribute to add custom javascript.

  <CustomAction
      Location="ScriptLink"
      ScriptBlock="alert('hello');"
      Sequence="100">

What it means – it means that you can do anything you usually do with javascript. And you can create <script src="..." tags using javascript itself.

Simple example.

  1. Create new Sharepoint 2010 solution.
  2. Add a module (Add -> New Item -> Module), for example JavascriptReferenceTestAssets

  3. Add a javascript file to it (Test.js).

  4. To keep things simple, put there
    alert("Test file loaded!");
    
  5. Now it is time to add CustomAction element. Add new Empty element to project (Add -> New Item -> Empty Element). Name it, for example, JavascriptReferenceAction:

  6. Open Elements.xml inside added element (JavascriptReferenceAction). Put there
    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
      <CustomAction
        Location="ScriptLink"
        ScriptBlock="
          document.write('&lt;script type=&quot;text/javascript&quot; src=&quot;~site/JavascriptReferenceTestAssets/Test.js&quot;&gt;&lt;/' + 'script&gt;');"
        Sequence="100" />
    </Elements>
    

Update: You can actually use ScriptLink="~Site/JavascriptReferenceTestAssets/Test.js" instead of ScriptBlock and it will work like in _layouts.

Notice ~site token inside ScriptBlock. It will be replaced with the server relative url of the current site (SPWeb). Another available token is ~sitecollection, which gives server relative url of current site collection (SPSite). It is useful, if you are deploying your feature to site scope.

Now deploy your solution, and while loading the page the alert should appear.

If you view source code of the page, you should find a bit of javascipt similar to this. The only difference may be the path to the javascript file depending on the site path you deployed your feature to.

document.write('<script type="text/javascript" src="/JavascriptReferenceTestAssets/Test.js"></' + 'script>');

This way you can include arbitrary javascript libraries like jQuery or your custom code.

Posted in Sharepoint | Tagged , , | Leave a comment

Ready to start!

Blog is set up and I am ready to begin writing. Let’s see what will come out.
What I am struggling with these days mostly is Sharepoint, Sharepoint Sandboxed solutions, Web Development in general and the thing that I am migrating from Ruby/Rails to .NET/C#.

Posted in Uncategorized | Leave a comment