Category Archives: Random Whatnot

IQParts – Cloud App Compatible Web Parts using AngularJS and Bootstrap

We are in the process of releasing three free SharePoint Add-ins from IQApp Central: Absence and Vacation Request Management Site, Board of Directors Site, and AngularJS 1.4 and Bootstrap 3.3 Web Parts. We’ll release all three as side-loaded apps over the next couple weeks for host webs and the first two as SharePoint hosted apps will be available via the Office store. Until then, you can get all three using Free SharePoint Add-Ins page in IQApp Central.

Today I am pleased to introduce AngularJS 1.4 and Bootstrap 3.3 Web Parts. This is a sample created using IQApp Central​. It is a framework that allows for user configurable Web Parts built using SharePopint, AngularJS 1.4 and Bootstrap 3​. ​This sample contains two Web Parts, six sample apps, an extensible configuration system, a template to help you get started with your own apps, and some handy functions to make integrating with SharePoint pages and services easy.

This sample started as an exercise to attempt an ideal design based on the 8 Characteristics of an Ideal SharePoint Customization. Integrating AngularJS and Bootstrap with SharePoint while trying to maximize the 8 ideals is a great challenge because SharePoint and AngularJS are both very assertive, demanding frameworks that want total control over a page and Bootstrap wants to completely own the base styles.

For example, here is a SharePoint page.

And here is the same page with Bootstrap 3’s CSS loaded.

Most projects that use Bootstrap start with a custom master page and end with a complete theme. Naturally this is not an option when you are creating components that, like Web Parts, are expected to work on any site.

Here is one of the sample pages included in AngularJS 1.4 and Bootstrap 3.3 Web Parts. It contains three of the sample apps and has a theme applied. Note how the parts do not break the containing page or the site’s style.

Configurability

There are a few projects out there that have tackled the configurable Web Part problem including this very good one by Rachid Bouzalmat. This approach works, but it is less than ideal on a couple of counts (based on the 8 Characteristics of an Ideal SharePoint Customization). Specifically it uses jQuery to target particular elements in a SharePoint page. It also depends on the ability to hijack SharePoint’s JavaScript. In the interest of full disclosure, we have code that does both of those things for different reasons. I am just as guilty, just not in the case of this sample!

I will write more about how we implemented our Web Part containers and the configuration system in a future post. In the meantime you can see for yourself how it works by installing the sample. Until then here is a shot of the sample page in design mode.

–Doug Ware

8 Characteristics of an Ideal SharePoint Customization

I’ve been working with SharePoint for the last eight years. In that time I’ve built many SharePoint solutions using nearly every available approach. Eight years is a long time. It’s long enough to give, hear, and read a ton of ‘best practices’ advice. It’s long enough to learn from the lifetime of too many design choices to count.

This post is my attempt to enumerate the qualities of an ideal SharePoint customization based on what I’ve learned. Keep in mind that these are ideals and the real world involves trade-offs. What do you think?

  1. It meets the needs of the people who use it without limitations imposed by the platform
  2. It doesn’t interfere with the operation of the underlying platform
  3. It uses SharePoint functionality as much as possible
  4. It depends on things other than SharePoint as little as possible
  5. It cedes runtime control to SharePoint as little as possible
  6. The other things it depends on are provided only by using supported mechanisms other than directly editing SharePoint Master Page or ASP.NET files
  7. Runtime or configuration faults in a customization can only impact the customization
  8. It is manageable and governable

Ideal #1: It meets the needs of the people who use it without limitations imposed by the platform

This is the most important thing. Does it do what people need it to do? If someone asks if the system can be made to do something is the answer ‘yes, it will cost x‘ or ‘we can’t do that because…’? Is it available when they need it?

Sometimes what people need will be the underlying factor that drives decisions that result in successful but far from ideal customizations.

Ideal #2: It doesn’t interfere with the operation of the underlying platform

SharePoint is built to be a shared resource. It’s in the name. Customizations should be polite and let the shared services do their work unhindered by external customizations. Customizations that integrate directly with runtime processes have the potential to cause general denial of service conditions for an entire SharePoint property. Customizations that directly integrate with the platform might not cause issues in the present, but are later discovered to be significant obstacles to moving or upgrading a farm or site.

Ideal #3: It uses SharePoint functionality as much as possible

This may seem to go without saying, but often people recreate the wheel. Creating custom functions for out of the box features directly affects a system’s ROI by increasing the investment required and potentially its ongoing cost. SharePoint is a rich resource. Ideal customizations marshal the available resources to full effect.

Ideal #4: It depends on things other than SharePoint as little as possible

Sometimes people try to fit a square peg into a round hole. The more a customization requires things other than SharePoint the more likely a customization is a square peg. Of course it is often necessary in the real world to integrate with other systems and it is even more common to use third party components. Just the same, a customization that meets Ideal #1 by using nothing but out of the box functionality is, by definition, an ideal SharePoint customization.

Ideal #5: It cedes runtime control to SharePoint as little as possible

While an ideal customization makes deft use of SharePoint’s functionality it should do so in a way that works independently of SharePoint. For example a customization that fully controls an area of a page is better than one that consists of many hooks into SharePoint by depending on particulars of the HTML generated by SharePoint. The former can function as an atomic unit, the later can break any time the details of the page deviate from the original. It is better to provide an entire form than to hook into a button’s click event based on the ID of the element or a class name on the day the customizer did View Source on a page.

Ideal #6: The other things it depends on are provided via supported mechanisms other than directly editing SharePoint Master Pages or ASP.NET files

Meeting Ideal #1 may require you to directly edit SharePoint master pages or ASP.NET files. Doing so has a cost and it potentially requires ongoing maintenance. At times it might violate Ideal #2 if the customization lacks as of yet un-invented elements that later will come to be expected. As it stands, SharePoint provides a large number of supported integration options out of the box including Web Parts, custom actions, and a wide variety of API’s. Be aware that some supported mechanisms are counter to Ideal #5.

Ideal #7: Runtime or configuration faults in a customization can only impact the customization

This one is simple. If your app breaks for a user does it break SharePoint? Breaking SharePoint includes denial of service conditions at the server as well as client side problems that prevent pages from rendering or operating as intended. It is possible to meet Ideal #2 but not this ideal. For example, introducing a syntax error into JavaScript in the body of the default master page will not interfere in any way with the underlying platform but will still break a site.

Ideal #8: It is manageable and governable

Once created or deployed, an ideal customization is manageable and governable. It offers appropriate configuration surfaces and respects SharePoint’s policies, throttles, and security. It isn’t obscure, but rather easily discoverable. It is possible for it to be known and accounted for to the degree that is required. One example of a customization that is not ideal in this regard is a user custom action created by hand. At present out of the box there is no way other than interrogating the SharePoint object model via one of many APIs to determine a user custom action is present or modify the user custom actions associated with given object. Conversely, a customization that includes the same user custom action can be ideal if it includes the same custom action as long as the customization provides appropriate management features such as the ability to remove the action if the customization is removed or disabled.

Why is this important?

We have more options available for creating SharePoint customizations today than we’ve ever had before. We need a framework to help evaluate these approaches to make good design choices. Over time I will be writing about our designs here at InstantQuick. IQApp Central supports a number of different design approaches. I designed it to be respectful of people’s decisions by playing well with SharePoint. Still, there are some designs I encourage that I’d like to teach you about. When I say that something is better I’d like to do so in the context of concrete criteria. That way, when someone disagrees it is easier to engage in productive dialog!

–Doug Ware

I Love My Surface 3 Pro

I’ve had a couple reminders recently that I’ve been neglecting the blog. The first was when I got an email asking if we are still in business and the second was when it took me 30 minutes to remember the username and password to edit some broken links I discovered in one of my older articles. Sorry about that, all the time has been going to make Instant Practice Manager better. We’ve got some great new features coming soon!

Today the family and I are packed into the van heading to see family for a long weekend. My wife Kim is driving and I am taking the chance to try my new Surface 3 Pro out from the road and do a little (way overdue) blogging.

Last year I did a similar exercise with my very large and heavy Lenovo W520. On that trip I used a laptop desk. The black thing under the keyboard in the photo above is a sleeve. It isn’t rigid, I just didn’t want to put it on the floor. So, I really am using it as a laptop and I find it to be perfectly comfortable.

This is my third day with the device. I was convinced to take the leap after reading this post by Corey Roth. It’s a great post and I won’t recycle it here, but I will add a few things.

Annoyances

Let me start by saying this is a great device. I’ve spent a couple of long working sessions writing code and I’ve gone to a couple meetings where I used OneNote and the stylus. I love this thing and I wholeheartedly recommend it. I don’t change hardware very often and I did a good bit of shopping and tire kicking before I made a purchase. Compared to the alternatives this device is a solid value. It isn’t cheap, but neither is it extravagant.

All that said, my first couple of days haven’t been completely issue free. The first challenge I had was when I used the traditional Remote Desktop app to connect to my W520 which runs Windows 7. For RDP into Windows 7 and 2008 there is no scaling and so I was presented with a 2160×1440 desktop on a the Surface Pro’s 12 inch screen. To my middle aged eyes it was completely unreadable. The new Windows 8 RDP app wasn’t any better and I thought, ‘this is a really nice device that I am taking back to the store.’ Fortunately my third try, Remote Desktop Connection Manager, http://www.microsoft.com/en-us/download/details.aspx?id=21101, works just fine and I still own the device.

The second issue was that the device would not reliably wake from sleep mode. If you da a search you will find that this is an issue that has plagued Surface users since v1 and that Microsoft has done a really poor job communicating with users. There is a full 26 page thread on the MSDN forums lasting over a year with some very disillusioned folks and not a Microsoftie to be found. Fortunately there is Twitter and Marc D Anderson let me know there is a firmware update. For some reason it didn’t show up in Windows Update for me and I had to download and install it manually. So far, so good and my sleep mode issues are solved.

Astonishment

The thing that impressed me most was how well the whole MS ecosystem is coming together and how well the integration works. I signed into the device the first time using my Microsoft account and was shocked at how well it pulled in everything with almost no effort on my part. It took me less than an hour to get Visual Studio and Office 2013 up and running and I didn’t have to blow a day setting up my environment. This is my first new machine since I really made the move to OneDrive and Office 365 and I just hadn’t noticed how seamless the integration really is.

I give the Surface Pro 3 two snaps and a circle.

Code Samples for Basic Client-Side Operations

Every once in a while I write a blog post to help myself find certain information later. This is one of those – even though I knew these articles existed, I had a hard time finding them the other day with Google and Bing.

SharePoint 2010 CSOM and JavaScript

SharePoint 2013 CSOM, JavaScript, and REST

Author: Doug Ware

 

Code Camp Wrap Up

This year’s code camp is a wrap! I’d like to thank my fellow organizers: Dan Attis, Sergey Barskiy, Mark Rowe, and Jim Wooley. It is such a pleasure to work with people who do what they say they will do! I especially want to thank Jim because he did all of his work knowing that he would not be able to attend the event, the speaker dinner, or the after party! Truly selfless.

We will have the speaker’s decks on the code camp web site as soon as possible. In the meantime, you can download my JavaScript deck here: http://www.elumenotion.com/Downloads/CC%202012%20Better%20JavaScript.pptx

Of course I would be very remiss if I forgot to thank the speakers, sponsors, and volunteers that made the event possible. Y’all are awesome!

 

 

–Doug

Correctly Provisioning Managed Metadata Columns

Last year I was brought in to help rescue a large and badly floundering project. The system in question made use of managed metadata in several areas and the original developers used Ari Bakker’s blog and code as their basis, specifically the code and in this excellent blog post. Ari began his journey with this excellent blog post from Wictor Wilén. Over time we had sporadic issues with upgrade scenarios and duplicate hidden note fields, but these were pretty low on the list of issues we needed to deal with before the system could go live (it was a real mess) and I never had the chance to dig in and figure it out.

Recently my friend and fellow MVP Dan Attis asked me to take a look at a similar issue he was facing with a sandbox solution. For whatever reason, the sandbox’s behavior was slightly different from the equivalent farm code. It had the same sort of problem I’d seen on the rescue project, but in the sandbox case it was worse as it prevented his affected features from activating. Together, Dan and I found the issue which was an error in Ari’s post. Before I get into that, having a look at the post in question is definitely worthwhile as what I have written here and my sample code is based upon his good work (which in turn is based on Wiktor’s), and I won’t be rehashing everything he wrote.

The Mistakes

Ari’s mistake comes with his step 3.

You should not do this. SharePoint will do it for you. If you do, SharePoint will create a duplicate with a different internal name in a farm solution and fail when you try to use an associated content type in a sandbox solution. Instead you need to provide enough information for SharePoint to create the required hidden note field as follows.

The Value attribute above will cause SharePoint to automatically provision a hidden note field with an ID of {2702cde3-3435-0227-be7b-e86d5f1250cc}.

Later in his post Ari writes about the creation of a Content Type that contains the metadata column and includes the hidden note field as one of the field references. You should not do this! Below is a sample content type inherits from the Document content type and includes the Color field shown above.

At this point my sample diverges from Ari’s because instead of using a list definition I use a ListInstance, a ContentTypeBinding, and a feature event receiver instead of a list definition. I do so because I think it’s easier, I am lazy, and I need the receiver anyway as my sample illustrates the use of metadata navigation in the resulting library. More on that later…

Timing is Everything

For my example to work I need to control the order of events so that:

  1. SharePoint provisions the Field and Content Type
  2. A feature event receiver connects the field to the correct term set
  3. The Content Type is bound to the list

If step 3 happens before step 2, the resulting list field(s) will not be connected to the term store. In Dan’s case this didn’t matter because in sandbox mode you have to wire up the metadata by hand as the required DLLs are not available in the sandbox.

The Sample

You can download the sample code from http://www.elumenotion.com/Downloads/MetadataSample.zip. It contains three features.

Visual Studio activates them in the order indicated above because of the way I’ve configured the package, but in real life I’d have a fourth feature to control the order of activation.

  • FieldsAndTypes includes the Field and ContentType elements shown in the screen shots above.
  • TermSetConfig creates a term set named Colors and connects the Color field to the new term set. This code is stolen borrowed directly from Ari and Wiktor with some minor changes and so I won’t cover it here.
  • SampleDocumentLibrary creates the sample library, binds my content type and then executes code to configure the metadata navigation settings for the new library.

The ListInstance and ContentTypeBinding look like this:

The feature event receiver does the following steps.

  1. Delete the original document content type from the library.
  2. Configure the metadata navigation settings.
  3. Configure the default view to display the Color column

public class SampleDocumentLibraryEventReceiver : SPFeatureReceiver

{

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPWeb web = (SPWeb)properties.Feature.Parent;
SetupSampleDocumentLibrary(web);
}

private void SetupSampleDocumentLibrary(SPWeb web)
{
SPList docs = web.Lists["Library with Metadata"];

    docs.ContentTypes[0].Delete();

    var navSettings = MetadataNavigationSettings.GetMetadataNavigationSettings(docs);
navSettings.ClearConfiguredHierarchies();
navSettings.ClearConfiguredKeyFilters();
AddKeyFilter(docs, navSettings, "Color");
AddHierarchy(docs, navSettings, "Color");
MetadataNavigationSettings.SetMetadataNavigationSettings(docs, navSettings, true);

    docs.RootFolder.Update();
SPView view = docs.DefaultView;
view.ViewFields.DeleteAll();
view.ViewFields.Add("DocIcon");
view.ViewFields.Add("LinkFilename");
view.ViewFields.Add("Color");
view.Query = @"<OrderBy><FieldRef Name='FileLeafRef' Ascending='TRUE' /></OrderBy>";
view.Update();
}

private static void AddHierarchy(SPList matters, MetadataNavigationSettings navSettings, string fieldName)
{
MetadataNavigationHierarchy hierarchy = new MetadataNavigationHierarchy(matters.Fields[fieldName]);
navSettings.AddConfiguredHierarchy(hierarchy);
}

private static void AddKeyFilter(SPList matters, MetadataNavigationSettings navSettings, string fieldName)
{
MetadataNavigationKeyFilter filterNavigation = new MetadataNavigationKeyFilter(matters.Fields[fieldName]);
navSettings.AddConfiguredKeyFilter(filterNavigation);
}

 

Finally the screen shots below show the sample in action.

Adding a document


Metadata Navigation


 

Happy SharePointing!!!
–Doug

Author: Doug Ware

Atlanta Code Camp is this Weekend, Saturday May 19th

For the last few weeks the organizing committee for this year’s Atlanta Code Camp (including myself!) has been busily planning and organizing this year’s Atlanta Code Camp. This year’s event is once again on the campus of Southern Polytechnic State University in Marietta. You can read more and register for the event here: http://www.atlantacodecamp.org/default.aspx.

If you’re not familiar with code camps, they are free community‐focused events by and for the .NET developer community. The Atlanta Code Camp draws upon the expertise of local and regional developers, architects, and experts who come together to share their real world experiences, lessons learned, best practices, and general knowledge with other interested individuals.

This event is unique in that it is "for the community, by the community" and is free for all that desire to attend. In past years, the Atlanta Code Camp has provided free training and networking opportunities for 300 of the best, most motivated development professionals. With our larger facility, we’re expecting this year to be even bigger and better.

This is a free event and we provide lunch. I hope to see you there!

–Doug

I am a SharePoint Server MVP!

The last couple of months have been extremely busy for me; a demanding client, Cub Scout den leader activities, user group stuff, and life in general!

The best proof of this? I was awarded the MVP award for SharePoint Server while on a Cub Scout camping trip at the beginning of October and I am just now blogging about it. Not a good way to start… 😉

I am extremely grateful to be an MVP again! This is the second product for which I have been awarded; Access was the first waaay back in the late ’90s. I am humbled to be in such excellent company!

Hiding a SharePoint Ribbon Button with CSS

I spent far too long this morning trying to hide a single ribbon button on a single page. The page is part of a sandbox solution so I couldn’t do the work server side, and because the page was a one-off in a library I didn’t want to use a HideCustomAction.

My first attempt was CSS, but that didn’t work. I assumed (incorrectly) that the reason my style didn’t stick was because the ribbon’s JavaScript was toggling the display. The problem turned out to be that I didn’t understand CSS quite as well as I thought!

The ribbon’s various elements use ID attribute values that contain periods. The values correspond to the cmdui.xml file that defines the ribbons for SharePoint Foundation. To affect the elements by via their ID’s with CSS you have to use an escape (backslash) before the period. For example, to hide the New Item button, use the following syntax:

#Ribbon.ListItem.New.NewListItem-Large
{
display:none;
}

 

This is why I love software development! Frustration turns to joy!

–Doug

Author: Doug Ware