Friday, January 18, 2013

Fixing JavaScript Intellisense completion

If you are doing a lot of JavaScript development, especially if you are doing SharePoint Apps development, you have come to love the great script IntelliSense feature in visual studio.

This gives you great auto-completion on client side objects and members and makes your development experience much better, especially if you are used to all this goodness from working with other rich languages like C#:

image

This auto-completion is easy to achieve, all you need to do is add a “_references.js” file and reference all script libraries in it:

image

Now, once you do some real JavaScripting – you will soon start working with prototypes, defining classes and instances and so on.

Once inside a method, you will notice that if you define a member inside the method it will keep the autocomplete working:

image

But once you start declaring and using class members, you will see a strange warning message and autocomplete will show you all known objects instead of just the relevant members for this variable type:

image

“IntelliSense was unable to determine an accurate completion list for this expression.
The provided list contains all identifiers in the file.”

The reason for that is, that if you define the variable member before this point, in the class level, and set it’s value later on in a constructor or other init method – Visual Studio does not know the type of object this variable is going to be set to, so it cannot build the correct auto-complete list.

The fix is simple, you can tell visual studio what type of variable you are creating by adding a ///<field> comment just above it’s definition:

image

And now, when we try to access this member again – auto-completion will work as expected:

image

The tricky part is finding out the exact type name for each variable. here are a few that I found, hope it would come in handy:

/// <field name="context" type="SP.ClientContext">Current client context</field>
/// <field name="web" type="SP.Web">Parent web hosting the app</field>
/// <field name="webInfo" type="SP.WebInformation">Parent web info hosting hte app</field>
/// <field name="lists" type="SP.ListCollection">current web lists</field>
/// <field name="list" type="SP.List">selected list (by _ListName)</field>
/// <field name="view" type="SP.View">selected view (by _ViewName)</field>
/// <field name="defaultView" type="SP.View">default list view</field>
/// <field name="query" type="SP.CamlQuery">caml query to run</field>
/// <field name="listItems" type="SP.ListItemCollection">result list item collection</field>
/// <field name="listItem" type="SP.ListItem">current list item</field>

if you want to find out the type name of other returned objects, you can alert() their “.constructor.getName()” value.

Have a wonderful scripting day!

Monday, January 14, 2013

Building list view SharePoint hosted app part

Building a SharePoint hosted app is a simple thing, thanks to Napa.

The whole thing can take less than a day (if you know you client side API) even, but filling those gaps that Napa does not cover can be a bit tricky, and remember: once you go visual studio, I can never go back!

So, I thought I would write about a few things I found Napa was missing and I had to spend some time trying to figure out how to make them work:

1. Set the app part gallery icon:


image

As much as I tried and wanted, it turns out changing the app part icon is not currently supported! Only Microsoft built-in app parts can have different icons for now. This comes directly from Microsoft, so I stopped researching this issue and gave up… Sad smile

2. Custom web part properties:


image

A vary basic need in deed, adding customizable parameters to app parts so that the user can configure it further. Apparently this was not supported in Napa, so I had to take my app to visual studio to add them.

Adding parameters is not very difficult, and since you app part is running in an iframe, all parameters will eventually be sent to your app part as query string parameters.

In order to add the parameters to the tool part, all you have to do is add them to the ClientWebPart elements file, like so:

<Elements>
    <ClientWebPart ….>
        <Content … />
        <Properties>
            <Property Name=”PropName” Type=”string” WebBrowsable=”true” WebDisplayName=”Prop Name” WebDescription=”Property description (tooltip)” WebCategory="Prop Category" DefaultValue="" RequiresDesignerPermission="true" />
       <Properties>
    </ClientWebPart>
</Elements>

Property “Type” can be string, enum, int or boolean.
For enum types a dropdown will be rendered. You can add the available options inline in the XML like so:


<Property …>
    <EnumItems>
        <EnumItem Value=”Val1” WebDisplayName=”Value 1” />
        <EnumItem Value=”Val2” WebDisplayName=”Value 2” />
        <EnumItem Value=”Val3” WebDisplayName=”Value 3” />
    </EnumItems>
</Property>

3. Accessing information from the current site, and not from the app sub site

You may know this already, but apps are deployed to their own sub site, that runs off a different web application than the site the app was deployed to.

Well, I wanted to display information from the user’s site, not from the app site. Which means I had to get the parent web in client object model to work on. not too difficult, but here is the code examples just for quick reference (if you have a better way of doing it – leave a comment I’d love to hear!):

First run this code:
this.context = new SP.ClientContext.get_current();
this.webInfo = this.context.get_web().get_parentWeb();//return SP.WebInformation not SP.Web
this.context.load(this.webInfo);
this.context.executeQueryAsync …

On load success, run this code:
this.web = this.context.get_site().openWebById(this.webInfo.get_id());
this.lists = this.web.get_lists();

then you can start using this.web to get the parent web and get information from it’s lists.

4. Auto-complete for SharePoint objects stops working for members

One last annoying thing I learned: although in most cases visual studio can auto-complete members and functions for javascript types, when I set the object to a member in javascript (this.web = xxx) and try to use it later in a different function it loses the auto-complete for this object.

This was rather simple to fix, when defining the member in my javascript class I had to add an attribute to it defining its expected type:

/// <field name="webInfo" type="SP.WebInformation">Parent web info hosting hte app</field>
webInfo: null,

This seemed to do the trick.

I’ll post back once I have more tips,

Shai.

Speaking Engagements 2013

My 2013 speaking engagements are posted below,
If you are around – come see me!
If you were in one of my sessions, you can find links to the session code and presentation below. Also – if you have any comments on my session – feel free to post it here!

February 20 2013Toronto SharePoint User Group – How-to: SharePoint hosted list viewer app part (Had a baby girl! Bill covered this meeting. I will reschedule, sorry!)

April 18 2013Hamilton SharePoint User Group - Developer's Guide: How to enhance your SharePoint performance - Understand Caching

May 18 2013 – SharePoint Saturday LA - One Solution to rule them all: One SharePoint Solution for both 2010/2013 & All about the SharePoint ribbon for developers

June 19 2013Toronto SharePoint User Group - One Solution to rule them all: One SharePoint Solution for both 2010/2013

July 20 2013 – SPS Toronto - Developer's Guide: How to enhance your SharePoint performance - Understand Caching

October 16 2013NYC SharePoint Developers User Group - One Solution to rule them all: One SharePoint Solution for both 2010/2013

My 2012 speaking engagements can be found here.