Tag Archives: SharePoint 2013

Birthdays and Anniversaries

After much procrastinating and work, I finally revisited the Birthdays widget I introduced in JavaScript Templating with SharePoint 2013 (Part 3) about a year ago. The template was well received and liked by many. My initial post was prototype code with a handful of bugs. I’ve since worked fixed those bugs and converted the template to a web part. A web part? Yes..a web part. I know…I know. I should have used a SharePoint hosted app but a web part was too easy to resist! Maybe vNext???

Several people also asked if the original template could be extended to support anniversaries. I’m happy to announce that I finally found time to do that as well!

The Finished Product

Anniversaries

Continue reading

SharePoint Conference 2014 Wrap-Up – Takeaways, Highlights, & Lowlights

I was fortunate enough to attend SharePoint Conference 2014 (SPC14) in Las Vegas last week. I had a little time to reflect so I put a blog post together to wrap-up the conference from my perspective. First let me give some disclaimers.

  1. I wasn’t able to attend SharePoint Conference 2012 so I don’t have that reference point. I did attend SharePoint Conference 2011 in Anaheim though.
  2. SPC 2014 wasn’t before a major release so there wasn’t a ton of new and shiny things on display.
  3. I’ve worked on a handful of SharePoint 2013 projects so my perspective of “cool” may differ from some.
  4. I mostly attended developer sessions so I didn’t see everything. If I missed something, please, please, please leave a comment below or link to your blog post. I’m really hoping that we can build a web of reflections for those who weren’t able to attend.
  5. This is a very long post. I’m sorry.

With that being said, here are the takeaways, highlights, and lowlights I left Las Vegas with. Continue reading

Office Web Apps ‘You don’t have access to this page’

Recently I had a request to show display a document in an iframe using Office Web Apps in SharePoint 2013. Pretty straightforward. In fact, Office Web Apps makes this easy. If you click the File tab in the ribbon > Share > and Embed the iframe html is right there for you.The iframe src attribute will look something like ‘http://yoursite/_layouts/15/WopiFrame.aspx?sourcedoc=blahblah&action=embedview.’ Sweet!

The Problem

I used the code as is and thing worked great…I thought. Randomly I would get a message stating “Sorry, you don’t have access to this page.”

Continue reading

JavaScript Templating with SharePoint 2013 (Part 3)

Update: I’ve since converted this template to a configurable web part. See http://www.lestersconyers.com/birthdays-and-anniversaries/ for latest.

Welcome to Part 3 of JavaScript Templating. In this post we will use the SharePoint 2013 Search API to build a Birthdays web part based on user profile data. And my procrastination worked for the good because today is actually my birthday! As in the last post I will be using jQuery to retrieve data and Handlebars to build my HTML.

The Finished Product

I’ll be building a template the renders upcoming birthdays. The display is based on Facebook’s birthday reminders. And as an added bonus, we’ll allow you to post a “Happy Birthday” message to the birthday boy’s (or girl’s) news feed.
birthdays list

Continue reading

JavaScript Templating with SharePoint 2013 (Part 2)

Welcome to Part 2 of JavaScript Templating with SharePoint 2013. In part 1 I tried to lay a foundation for the next posts. If you haven’t read it, I’d suggest you at least breeze over it so this post makes a little more sense.

As I mentioned in the first post, generally speaking when it comes to JavaScript templating there are 3 players involved: a data source, a data retrieval mechanism, and a template. I also mentioned that we SharePoint developers should also keep in mind that our code should be able to exist on any page the user chooses.

As with the remaining posts in this series, jQuery ajax will be my data retrieval mechanism and I’ll use Handlebars as my templating engine. In this post I’m going to leverage a SharePoint list named Events as my data source.

The Finished Product

Below are some screenshots of the finished product. The template lists upcoming events. Clicking the event title reveals more details.

Collapsed

Events

Expanded

events_expanded

Continue reading

JavaScript Templating with SharePoint 2013 (Part 1)

After a very long hiatus I am back hoping to contribute to the SharePoint community. It’s been too long. Today I want to touch on a subject that is getting much traction in the MVC and front end development realm: JavaScript templating. These developers have been quick to utilize client-side templating to build slick and user friendly applications. Beauty is nice but the major benefit is a no-brainer: increase performance due to a decrease in response payloads.

Although the benefits are awesome and obvious, the presence of client-side templating is rare in the SharePoint space, I don’t see it very much. I don’t even hear it talked about often. Let me say that I’m not dissing any one. I’ve been known to revert back to server side web parts in a New York minute. I think several SharePoint developers do the same. It’s because that’s what we’re comfortable with. It’s what we’ve done in SharePoint for years and it works over and over again. It’s like tradition! But a wise man once said “It’s also a tradition that times must and always do change my friend.” [2 bonus points to whoever can name that movie!]

This will be part 1 of a 4 part series involving JavaScript templating. In this post I’m going to lay a foundation for the next 3 posts. This one is heavy on text. The others will be heavy on screenshots and code…I promise!

Continue reading

How to Deploy Display Templates in SharePoint 2013

A few months ago I posted a question on an MSDN forum asking how to deploy display templates via feature. Several people had suggestions but John Ross provided many helpful comments that really made me think. Even now, I’m not 100% sure what the “best practice” is but hopefully I can lay out the options I’ve found and you can make the best decision for your situation.

Continue reading

Extending Search Web Parts

Here is code sample showing how to extend the search core results web part in SharePoint 2013. This can also be used for the content by search web part because it inherits from the search core results web part. In this sample I modify the query programmatically to retrieve items with metadata that matches a claim for the current user. This would be really helpful if you want to target content for a customer based on their demographics or browsing history. You know…like the Disneyland ads that appear in GMail a day after you research a Disneyland vacation :) .
Continue reading

Automatically created managed properties*

Story Time

Several days ago I ran across an article on MSDN that talked about the automatic creation of managed properties in SharePoint 2013. In summary, if you create a site column (not a list column), populate it with data, and run a full crawl SharePoint will create a crawled property AND a corresponding managed property. The crawled property creation isn’t new but in previous versions you had to created the managed property manually. SharePoint 2013 goes an additional step by automagically creating a managed property for that column. My first thought was, “Awesome. That’s one less step I have to take.”

But wait…it gets better. The properties that are automatically created aren’t ordinary managed properties. These properties can return specially formatted values. I immediately began to experiment. I created a site column named “Announcement Description” of type Multiline enhanced rich text. This would allow me to enter HTML. I added that column to a list and began creating list items. Next, I ran a full crawl and checked the search schema. And sure enough, SharePoint created a managed property named “AnnouncementDescriptionOWSMTXT,” just like the article said it would. I later used that managed property in a display template and it returned HTML, just like the article said it would! My next thought was, “I love SharePoint 2013!”

After developing that POC it was time to bundle everything up in a SharePoint solution and deploy at a customer site. I decided to use the declarative approach. Most of my other components had to be deployed to the 15 hive, so I had to use a farm solution. I built the solution, deployed it, and activated the necessary features. My new site column showed up as expected. I went on to use the column in several lists and several items. Afterwards I ran a full crawl. After the crawl completed I checked the search schema for the managed property and to my dismay, the managed property was not there! I ran several full crawls, but SharePoint never did it’s magic.

After days of frustration I moved on to another POC with another declarative site column. This time the solution had to be a sandbox solution. After going through a similar process as above I was stunned (and a bit frustrated) that SharePoint did create a managed property in this scenario.

Automatic*

Note the asterisk. The question is: “Does SharePoint 2013 automatically create managed properties for site columns?” The answer is: “It depends.” Below is a table of different scenarios I’ve tested for creating site columns in SharePoint 2013 and the outcomes.

Creation Approach Solution Type Managed Property Created?
SharePoint UI (browser) N/A Yes
Declarative (elements.xml) Farm No
Declarative (elements.xml) Sandbox Yes
Code (server-side api) Farm Yes
Code (server-side api) Sandbox Yes

Closing

In closing, I’m not sure if this is a bug or not. It’s certainly inconvenient and leaves me wondering why. Regardless, I hope this post helps you in your decision making process.

Ingredients Custom Field

Custom Field Rendering with JSLink

A long time knock on SharePoint has been the lack of complex field types. For example, the ability to have cascading dropdowns when setting an item’s field has been highly requested. Many used custom field types to accomplish this in SharePoint 2010. If you’ve ever tried it…I apologize on behalf of Microsoft. It’s a fairly complex task that comes with a set of administrative issues that many (including myself) didn’t want to touch. But then came SharePoint 2013 and JSLink…

In a nutshell

JSLink is a property of a field. You can use this property to override how the field renders and how its value is set. In the example I have, I create a site column based on a Multiline text field. But when I set the JSLink property, I pretty much tell SharePoint “Hey, instead of rendering this field as a text box, use this JavaScript file to render the column.” With so much control, the possibilities are pretty much endless.

Credit

I followed a few different articles and blogs to get my sample working. The most helpful was definitely David Mann’s blog post. Next in line were http://msdn.microsoft.com/en-us/library/jj163799.aspx and http://msdn.microsoft.com/en-us/library/jj220061.aspx. I kind of mashed all three together to make my script. Hopefully David won’t mind but I’m going to follow his blog post’s layout but our code is quite different. Also thanks to Andrew Connell for letting me know about JSLink.

How to make it work

In order to override the field rendering the JavaScript file you write has to have at least 4 or 5 functions:

  • ‘View’ function to render the field if it is included in a list view. In this function you return html.
  • ‘DisplayForm’ function to render the field when the user is viewing the properties of a list item. Also returns html.
  • ‘EditForm’ function to render the field when the user is editing the properties of a list item. Returns html.
  • ‘NewForm’ function to render the field when the user is adding a new list item. Again, should return html. Normally this would be the same as the ‘EditForm’ but it doesn’t have to be.
  • ‘GetValueCallBack’ function to pass the field’s value to SharePoint after the user clicks Submit. This one should return the value type of the field type. In my example, I’ll return a string value.

The first step is to determine how you want the user to enter data. In the EditForm and NewForm functions, you’ll need to render the DOM elements to capture the data. This could be the cascading dropdowns or (in my example) several text boxes to capture sections of a single ingredient. You may also want to add JavaScript events to those elements.

Next determine how you want your value passed back to SharePoint. There are a few options to handle this. One option is to render a hidden input element when you render your data capture. Then handle events on the data capture elements (e.g. onchange). Within the event handlers populate the hidden input field’s value. In the end, pass the hidden input’s value to SharePoint in the getValueCallBack function.

My favorite option is a little easier to explain. Simply render your data capture elements. Handle onclick or onchange events with functions. Use those functions to create new DOM elements with the data within them. Then within the getValueCallBack function, get the values from the DOM elements. This is how my example is done. I chose this route because it gets difficult to keep the DOM and the hidden input in synch when users can delete items. That’ll make more sense in a

Recipe Ingredients

In this sample I created a field to contain ingredients for a recipe. I want the user to be able to enter several ingredients but have those values stored in one SharePoint field. In the end it looks a little something like this:

Edit and New Form

ingredients_edit

Display Form

ingredients_display

View

ingredients_view1
Ingredients View 2

Deep Dive

To kick things off I created a Sandbox solution with an empty elements file for my custom field.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Field
ID="{D0A67455-6EBE-4665-9085-485009F0FFB3}"
Name="RecipeIngredients"
DisplayName="Ingredients"
Type="Note"
Required="TRUE"
JSLink="~site/style library/sample.js"
Group="Custom Columns"
Sealed="FALSE"
NumLines="1000"
RichText="FALSE"
RichTextMode="Text"
>
</Field>
</Elements>

Next I create an empty module to save my JavaScript file to the Style Library.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="Scripts" Url="style library">
<File Path="Scripts\Sample.js" Url="Sample.js" />
</Module>
</Elements>

I then added my JavaScript file to the module.

The Code

Near the top of the JavaScript file I create a function that will fire when the file is loaded. Within the function I associate my custom field with the functions that will render it. I then register that template to make SharePoint aware of it.

(function () {
    if (typeof SPClientTemplates === 'undefined')
        return;

    var ingredientsCtx = {};

    ingredientsCtx.Templates = {};
    //associate the various templates with rendering functions for our field.
    //when a list view is returned to the user, SharePoint will fire the function associate with 'View'.
    //when a list item is in New, SharePoint will fire the function associated with NewForm, etc.
    ingredientsCtx.Templates.Fields = {
        //RecipeIngredients is the Name of our field
        'RecipeIngredients': {
            'View': ingredientsView,
            'DisplayForm': ingredientsDisplayForm,
            'EditForm': ingredientsNewAndEdit, //using the same function for New and Edit, but they could be different
            'NewForm': ingredientsNewAndEdit
        }
    };

    //register the template to render our field
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(ingredientsCtx);

})();

The Code: Callbacks

There are several callbacks that you can listen to within your script. The most important one is the GetValueCallBack. As my comments state, this is where the magic happens! Oh you don’t believe in magic? Well this is where the field value get’s passed to SharePoint.


//registers call back functions from SharePoint
function RegisterCallBacks(formCtx) {

//when the form is initialized, call our anonymous function.
formCtx.registerInitCallback(formCtx.fieldName, function () {

//get the controls in the input form
var qtyInput = document.getElementById(ingredientQty);
var unitInput = document.getElementById(ingredientUnit);
var descInput = document.getElementById(ingredientDescription);
var prodIdInput = document.getElementById(ingredientProductId);
//add all of them to an array
var elements = [qtyInput, unitInput, descInput, prodIdInput];

//foreach element, register a keydown event to add an ingredient when the user hits enter
for (var i = 0; i < elements.length; i++) {
var input = elements[i];
if (input != null) {
AddEvtHandler(input, "onkeydown", function (e) {
//keyCode == 13 is Enter
if (e.keyCode == 13) {
addIngredient();
}
});
}
}
});

//This is where the magic happens! After the user clicks save, call this function. In this function, set the item field value.
formCtx.registerGetValueCallback(formCtx.fieldName, function () {
//get our unordered list of current ingredients
var ul = document.getElementById(ingredientsContainer);
if (ul == null)
return null;
else {
//return the values, which will be stored in the list item
return getFieldValueFromDOM(ul);
}

});

//create container for various validators
var validators = new SPClientForms.ClientValidation.ValidatorSet();

//if the field is required, make sure we handle that
if (formCtx.fieldSchema.Required) {
//add a required field validator to the collection of validators
validators.RegisterValidator(new SPClientForms.ClientValidation.RequiredValidator());
}

//if we have any validators, register those
if (validators._registeredValidators.length > 0) {
formCtx.registerClientValidator(formCtx.fieldName, validators);
}

//when there's a validation error, call this function
formCtx.registerValidationErrorCallback(formCtx.fieldName, function (errorResult) {
SPFormControl_AppendValidationErrorMessage(ingredientsContainer, errorResult);
});
}

The Code: New and Edit Forms

The meat of the rendering is handled by some helper functions I created that generate my html. In the RenderInputFields() function I render an ‘Add’ button with an onclick function of addIngredient(). When a user clicks ‘Add’ I take the user’s values, do some custom formatting, and add an LI element to the DOM.

//function called when an item with our field is in edit mode or new mode.
function ingredientsNewAndEdit(ctx) {
if (ctx == null || ctx.CurrentFieldValue == null)
return '';

var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(ctx);
if (formCtx == null || formCtx.fieldSchema == null)
return '';

//register callback functions that SharePoint will call at appropriate times
RegisterCallBacks(formCtx);

//render the Input controls for the ingredient
var html = RenderInputFields();

//render a reminder for user experience
html += '<b>Current Ingredients:</b>';

//render existing values
html += RenderExistingValues(ctx, true);

return html;
}

//render the controls that allow users to add individual ingredients
function RenderInputFields() {
var html = '<table>';
html += '<tr><td>Qty</td><td>Unit of Measure</td><td>Description</td><td>Product Id</td><td></td></tr>';
html += '<tr>';
html += '<td><input id="' + ingredientQty + '" type="text"></td>';
html += '<td><select id="' + ingredientUnit + '">';
html += '<option value=""></option>';
html += '<option value="cup">Cup</option>';
html += '<option value="gallon">Gallon</option>';
html += '<option value="oz">Oz</option>';
html += '<option value="pinch">Pinch</option>';
html += '<option value="pt">Pt</option>';
html += '<option value="lb">Lb</option>';
html += '</select></td>';
html += '<td><input id="' + ingredientDescription + '" type="text"></td>';
html += '<td><input id="' + ingredientProductId + '" type="text"></td>';
//add a button with an onclick event for addIngredient. this will add a li element to the ingredients container UL
html += '<td><input id="btnAdd" type="button" onclick="addIngredient()" value="Add"></td>';
html += '</tr></table>';

return html;
}

//render the value from the current item
function RenderExistingValues(ctx, includeDelete) {
var html = '';
html += '<form action="javascript:return;">';
html += '<ul id="' + ingredientsContainer + '">';
//call a helper function to retrieve the fields value
var fieldValue = getValue(ctx);

var ingredients = fieldValue.split(ingredientDelimiter);

for (var i = 0; i < ingredients.length; i++) {
var ingredient = ingredients[i];
var qty = getAttributeFromFieldValue('qty', ingredient);
var unit = getAttributeFromFieldValue('unit', ingredient);
var desc = getAttributeFromFieldValue('desc', ingredient);
var prodId = getAttributeFromFieldValue('prodId', ingredient);

if (ingredient != '') {
html += '<li>';
html += getLIInnerHtml(qty, unit, desc, prodId, includeDelete);
html += '</li>';
}
}

html += '</ul></form>';

return html;
}

The Code: View

This function was a little fun. When the field is shown on a view I render a ‘Show Value’ button (stole that idea from David). I also render a hidden DIV that contains an unordered list of current ingredients which is generated by RenderExistingValues. When the user clicks the button, I open a SharePoint dialog to display the contents of that DIV.

//function called when our field is shown in a View
function ingredientsView(ctx) {
var currentVal = '';
//from the context get the current item and it's value
if (ctx != null && ctx.CurrentItem != null)
currentVal = ctx.CurrentItem[ctx.CurrentFieldSchema.Name];

var currentItemValueId = 'ingredientValue_' + ctx.CurrentItem['ID'];

//create a hidden div to store the current item's value within the View
var html = '<div id="' + currentItemValueId + '" style="display:none">';
html += RenderExistingValues(ctx, false);
html += '</div>';
//render a 'Show Me' button. When clicked the value from the Div above will be cloned, then shown in dialog window
html += '<input type="button" value="Show Value" onclick="showIngredientsValue(\'' + currentItemValueId + '\')" />';

return html;
}

//opens a sharepoint dialog window to display value
function showIngredientsValue(ingredientsDisplayDivId) {
//calling the showModalDialog function with a DOM element.
//by default, that DoM element is destroyed when the dialog closes so
//we must clone the div we want to show. Otherwise the dialog would only work once

//establish a clone id
var cloneDiv = ingredientsDisplayDivId + '_clone';

//get the div with the value
var divWithValue = document.getElementById(ingredientsDisplayDivId);

//create a clone DOM element
var clone = document.createElement('DIV');

divWithValue.appendChild(clone);

//use the same innerhtml for the clone
clone.innerHTML = divWithValue.innerHTML;

SP.UI.ModalDialog.showModalDialog({
title: 'Current Ingredients',
html: clone, //pass in the clone which can be destroyed. Next time the function is called, we'll create another clone.
width: 450,
height: 350
});
}

The Code: Display Form

This uses the RenderExistingValues() function to generate an unordered list. The RenderExistingValues() function is used by the display form, the view form, and the edit/add forms.


//opens a sharepoint dialog window to display value
function showIngredientsValue(ingredientsDisplayDivId) {
//calling the showModalDialog function with a DOM element.
//by default, that DoM element is destroyed when the dialog closes so
//we must clone the div we want to show. Otherwise the dialog would only work once

//establish a clone id
var cloneDiv = ingredientsDisplayDivId + '_clone';

//get the div with the value
var divWithValue = document.getElementById(ingredientsDisplayDivId);

//create a clone DOM element
var clone = document.createElement('DIV');

divWithValue.appendChild(clone);

//use the same innerhtml for the clone
clone.innerHTML = divWithValue.innerHTML;

SP.UI.ModalDialog.showModalDialog({
title: 'Current Ingredients',
html: clone, //pass in the clone which can be destroyed. Next time the function is called, we'll create another clone.
width: 450,
height: 350
});
}

Wrapping Up

So that’s about it. Feel free to download the solution. The Sample.js file has about 350 lines of code but I have at least 100 lines of comments and several blank lines. Hopefully you’ll find it useful.

Here’s the Visual Studio project -> CustomFields.zip