Wednesday, June 26, 2013

Yet Another SharePoint 2013 in Azure Post

Topics covered in this post:
  • 3 server Azure VM setup for SharePoint 2013
  • Shrinking Azure vhd blobs
  • Turning a DC into a server core install
I’ve long been thinking about provisioning a SharePoint 2013 dev farm in Windows Azure, and with the new MSDN pricing model this has become more attractive. You can now also do a VM shutdown instead of de-provisioning the full VM if you want to save some $$ by not running the VM 24/7.

In my case I have a Visual Studio Ultimate with MSDN subscription which gives me $150 free spending per month (http://www.windowsazure.com/en-us/offers/ms-azr-0049p), so we’ll see how that looks after a month’s use.

Thursday, June 20, 2013

Extending the existing search box in SharePoint 2013 with search as you type functionality

Back in February Murad Sæter blogged about using jQuery autocomplete to get real search results from SharePoint 2013 while you are entering the query.

image

Note   Executing live searches like this may cause load on your search server. You should monitor the load or restrict your queries if you see a load issue. You can also increase the delay time from the default 100ms to reduce the load.

imageInspired by this on a recent project I wanted to see if I could add this functionality to the existing search box on the search center.

The search box has three settings for search as you type suggestions. Suggestions based on what everyone searches which is recorded over time (or you can manually add suggestions), suggestions matching people names, and personal favorites – which are searches you perform often.

For my search scenario I was creating a page to find collaboration and project sites. Sort of a search based navigation to locate sites on the intranet. In my particular case I did not have any needs for person name results, and decided to re-use the person name container for real searches instead.

The effect is that while you are entering your query, real searches are executed against the Title field and limiting to sites only (contentclass:STS_Web).

The search suggestions functionality in SharePoint 2013 is provided by ajaxtoolkit.js. In order to extend the existing functionality  I had to override the _update function of the AjaxControlToolkit.AutoCompleteBehavior.prototype which is responsible for the search as you type functionality of the search box.

I also chose to use jQuery ajax and the search REST api in order to get my search results.

A simple way of adding the functionality is to drop a script editor web part on the page and simply paste in the code in this post. The code has some inline comments to describe what is going on.

image

<script type="text/javascript">
function Override() {
// Keep a copy of the original function
AjaxControlToolkit.AutoCompleteBehavior.prototype._update2 = AjaxControlToolkit.AutoCompleteBehavior.prototype._update;

// register the searchOnSuccess on the same prototype object in order for the update2 function to keep the
// context with all variables
AjaxControlToolkit.AutoCompleteBehavior.prototype.searchOnSuccess = function(data,prefixText,completionItems,cacheResults) {
var results = data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;

var names = [];
for (var i = 0; i < results.length; i++) {
var title = results[i].Cells.results[3].Value;
// Add highlighting of the search term
var idx = title.toLowerCase().indexOf(prefixText.toLowerCase());
if( idx >= 0) {
var hhtitle = title.substr(0,idx) + "" + title.substr(idx,prefixText.length) + "" + title.substr(idx+prefixText.length);
names.push(hhtitle);
} else {
names.push(title); // fallback if indexof fails
}
/* href = results[i].Cells.results[6].Value; */
}
// put our results in the people name container as we're not using it on our page
completionItems.set_peopleNames(names);
// call the original update function which renders out the results
this._update2(prefixText, completionItems, cacheResults);
};

// Register an overload update function which executes a real search
AjaxControlToolkit.AutoCompleteBehavior.prototype._update = function(prefixText, completionItems, cacheResults) {
var context = this;
$.ajax(
{
// Get top 5 results searching only on title field. Other paramaters can be added as well
// Query term is what the user has entered with a wildcard appended
url: _spPageContextInfo.webAbsoluteUrl + "/_api/search/query?rowlimit=5&querytext='title:\"" + prefixText + "*\"'",
method: "GET",
headers: {
"accept": "application/json;odata=verbose;charset=utf-8",
},
success: function(data){ context.searchOnSuccess(data,prefixText,completionItems,cacheResults);},
error: onError
}
);

function onError (err) {
alert(JSON.stringify(err));
}
}

}

// Replace url to your own jquery path
RegisterSod("jquery.min.js", "/_layouts/15/mAdcOW.SearchSuggestions/js/jquery-1.9.0.min.js");
LoadSodByKey("jquery.min.js", function () {
$(function () {
// Make sure ajaxtoolkit is loaded before registering the functions
ExecuteOrDelayUntilScriptLoaded(Override, 'ajaxtoolkit.js');
});
});
</script>

Tuesday, June 18, 2013

Highs, lows & random rants on SharePoint 2013

Here’s the presentation Harald Fianbakken and I gave at the Norwegian SharePoint Community meeting June 17th, 2013.

Basically a talk where we ranted on our experiences with 2013, highlighting the issues we ran into, and what we really love.

Here’s a small narrative per slide to give it all some more context.

Slide 6-8: The quality management system is an external system which stores it’s data as static HTML files. Along these files are corresponding image files when the artifact is a process diagram. The files are imported with a custom application which parses the <meta> tags of the HTML files, and stores the parsed data as publishing pages with custom columns to hold the metadata inside of SharePoint. The page library have several content types, and the right one is chosen on import depending on the parsed data. The images are stored in an image library.

The HTML files also contains image maps, which we parse and store the coordinates in order to re-create the navigation experience later inside of SharePoint.

Some of the metadata are stored as Managed Metadata, and a taxonomy is built upon import.

Slide 9: We auto-generate Content Types and lists based on reflection on annotated Poco’s. The poco’s are annotated using http://nuget.org/packages/Fianbakken.SharePointations/. Puzzlepart also has a framework which allows the use of Linq queries on the CT’s/Lists, instead of using CAML. Sort of like SP Metal, but you start with the poco, not the other way around.

Slide 11-13: The solution has a part which is an “Improvement Potential” log. When someone reports an improvement a workflow is started. We encountered multiple issues when developing this, mainly on the test server. The root cause was most of the time missing user profiles and missing e-mail addresses.

Slide 14: There is a bug in Workflows as of now which comes into play if you add custom task outcomes to the task form. Meaning, you want more than just Approve/Reject. If you add more, then the outcome is always “Approve”. You can however retrieve the real value in your workflow, and then act on it as a workaround. This took us one week to figure out (see the blogs referenced at the end slide for more info).

Slide 15: If you don’t click “Publish” before exporting a workflow you will get an error upon feature activation. Also, you have to retract/redploy your workflow if you re-export as the WSP’s get new id’s. This is an issue if you develop the workflow on one server and want to move it to another.

Slide 18-19: Excel rest is a good way to get graphs/named entities from within Excel files without having an Enterprise license.

Slide 20-21: See http://techmikael.blogspot.se/2013/04/how-to-enable-page-previews-in.html for more information.

Slide 23-24: By using the SP2013 social api, we can follow or bookmark publishing pages in SharePoint, allowing users to have favorites.

Slide 26-34: We use custom display templates, result sources, query rules and display blocks in order to create a sort of 360-view for processes. Searching for a process will show related improvements and related documents to a specific process.

The issues we encountered where related to pulling back managed properties for certain content types, and getting the display templates to trigger correctly. It’s all a bit buggy at the moment, but I’ve been told there are fixes coming in later CU’s.

What seems to work the best is to create managed properties on the SSA, stay away from the auto-generated ones, and have one result block per query rule, even though the rules are the same.

Slide 36-40: By using custom properties on terms, we created a configuration option for display forms. The taxonomy states which fields should be shown in our dynamic form based on values you choose, and which fields should show in new/edit mode. Basically we used the terms store as a way to configure an input form. The other choice would have been to create multiple forms to cover all scenarios. But the requirements kept changing, and this gave us flexibility and ease of configuration.

Slide 42-45: Be sure to keep people who know HTML and know SharePoint HTML at hand when implementing a custom design. It saves time!

Thursday, June 6, 2013

Add a “Clear Filters” link to your search page in SharePoint 2013

Using refiners or filters on a search page is an easy way to narrow down on the content you are looking for. If you need to start from scratch you can just click the search button again, but this may not be the best UI.

I’ve worked on many projects where they also want a “Clear filters” link.

As all calls on the 2013 search page is done using AJAX, the real query is added to the hash part of the url, the part coming after the # character. If you want to clear all filters and the search terms, then you can add what designers call a dummy link with a # to the page, and that will reset your query.

<a href=”#”>Clear filters</a>

A simple solution it so add a Content Editor Web Part above the refiner panel with the above markup.
image

Tuesday, June 4, 2013

Meticulous workaround for getting Cisco AnyConnect to work with Windows 8

At times I need to use Cisco AnyConnect VPN to get into remote systems, but unfortunately AnyConnect does not work very will with Windows 8. My first solution was to install Windows XP as a virtual machine to get a lightweight solution.

Windows XP with AnyConnect works just fine and I can browse from within my VM.

My next issue was that I wanted to use SharePoint Designer 2013. This cannot be installed on Windows XP. You need Windows 7 or newer. Bummer :(

Instead of installing a Win7 VM I went for this solution.

  1. VMWare machine running Windows XP with freeSSHd installed
  2. Connect to remote system from XP using AnyConnect
  3. On native client (Windows 8) use putty to ssh into the VM with a socks proxy on port 8080
  4. Configure IE to use 127.0.0.1:8080 as a socks proxy
  5. Use SharePoint designer in my native Windows 8 which will use IE proxy settings

Communication goes like this:

SharePoint Designer (native) –> ssh proxy to XP (native) –> Cisco Any Connect (in VM) –>Virtual network adapter back via host machine –> Remote system

Cumbersome but it works.. and maybe, just maybe AnyConnect will work perfect on Windows 8 one day.

Monday, June 3, 2013

Enabling PDF previews in your libraries

[Edit: I totally missed http://www.wictorwilen.se/sharepoint-2013-enabling-pdf-previews-in-document-libraries-with-office-web-apps-2013, so this post is almost a dupe - sorry about that]

You installed the March CU for Office Web Apps 2013 (WAC) which supports rendering PDF files, and followed Wictor Wilén’s post on how to enable PDF previews for your search results (and perhaps his post on installing the CU as well).

Then you read the comments and saw that others like yourself want to get these PDF previews for document libraries and not only on the search result page.
Want to know how? Read on!
Enabling PDF preview in a SharePoint Library

Sunday, June 2, 2013

How to: Change the default sort of a Search Result Web Part

When using the Content Search web part you can modify the query in the query builder. By default it lists recently changed items but often you want to change the query using advanced mode.

image

When clicking advanced mode, the default sorting is set to Rank, and you can click the sorting tab, choose LastModifiedTime in descending order, and you end up with the latest items with the filter you decide to add.

So far so good. Say you have either developed display templates for your search page, or want to do content by search in Office 365, and you want to use the Search Results web part instead which features more or less the same capabilities as the Content Search web part.

The procedure is almost similar. Drop a Content Search web part on the page and enter the query builder. In my case I want to limit the results based on one document library in particular and will use the query. I remove the {searchboxquery} token and enter:

(contentclass:STS_ListItem OR IsDocument:True) path:http://intranet.contoso.com/Documents

Further clicking “Test query” lists all results sorted by rank. I click the sorting tab, choose LastModifiedTime and the test results show as expected, sorted by the newest items on top.

image

Next I click ok, and save the web part settings, save the page, and…… the results are still sorted by rank!!

There is however a workaround. Instead of changing the sorting using the query builder, you have to change the UI sorting options for the web part.

When editing the web part, expand the Settings section. Check the “Show sort dropdown” option and replace the content with only one value, the one sorting my newest items on top. After you have modified the JSON value, click “Apply” to save the web part changes. Next uncheck the option again, and save the web part changes. The sorting now sticks, but you’re not showing the sort dropdown.

imageimage

Don’t know if this is a bug or by intention, but is sure bugged me for a couple of hours.