My New Surface 3 Pro Travellin’ Machine

Surface 3 ProI picked up a Surface 3 Pro over the weekend. If you want to read a *very* thorough review of the Surface 3, take a look at Corey Roth’s (@coreyroth) excellent write-up Complete Surface Pro 3 Review – 3 days later.

I went with the I5 256Gb model (just as Corey did), as it has 8Gb of RAM and will be able to run pretty much anything I need.

Since I can install just about anything that I use on my “real” laptop, I think it will be an excellent travel machine. My go-to apps are things like SharePoint Designer 2007-2010-2013, Office, Sublime Text, and a number of applications (not apps) that help me with the little chores in design and such. I’m cautiously optimistic about this machine. I also have a Surface 2 RT, and I just couldn’t get it’s form factor into the rotation between my monster laptop and my iPhone. I’m really going to try to do it with my Surface 3. I use exactly zero “modern” apps on my Surface 2 RT, and I can’t see that changing, except maybe to watch movies with Netflix in hotel rooms.

I connected the Surface 3 to my home office display rig (all via a single USB connection) and everything fired up great after a few minutes of installing drivers and screen flickers.

So I’m thinking of travelling *only* with my Surface 3. My work laptop is a hefty 10.5lb ASUS. I love it, but it’s a bit excessive. My next travel fun is to Australia and New Zealand for the highly popular Australia SharePoint Conference (#AUSPC) and New Zealand SharePoint Conference (#NZSPC) conferences. I hope if you’re reading from Down Under that I’ll see you there!

I think that presenting and demoing will work great from the Surface, as all the slides and demos are cloud-based at this point. Can anyone think of any reason I’d have difficulties?

I’ve picked up two accessories from Amazon that I think are required for successful travelling with the Surface 3:

so I should be good for USB, Ethernet, and projector connections. Can anyone think of anything I’m missing?

SharePoint List Settings Issue: “Internet Explorer is required to use this feature.”

This one belongs firmly in the “things that make you go hmm…” department.

Let’s say you are a good do-be like me and you use all of the Microsoft products that you can get your hands on. You’ve got email and SharePoint running on Office 365, you use all the Office applications and tools, you’re up to date on your version of Internet Explorer… You get the picture.

Well, sometimes all that good behavior doesn’t pay. Today I wanted to edit an InfoPath form attached to a list in SharePoint 2013 on premises. (You won’t run into this problem on Office365, at least it doesn’t happen in my tenant. Office365 seems to know IE11.) I went to the List Settings and clicked on the Form Settings link. I’m using Internet Explorer 11, so I’m as up to date as I can be without getting into beta territory.

Lo and behold:

Internet Explorer is required to use this feature.

Internet Explorer is required to use this feature.

Yup. I’m using Internet Explorer and the message says “Internet Explorer is required to use this feature.” The issue is that the on premises install that I’m working with doesn’t understand Internet Explorer 11. It *should* see it as Internet Explorer, though, and give me a better message. I’m not exactly sure what patch level we’re on, but I think it’s pretty close to current.

Fortunately, there is an easy fix for this. Simply hit F12 to bring up the Developer Tools and scroll all the way down to the bottom of the left side icon list.The one you want to click on looks like this:

Emulation

That will give you access to the Emulation settings. Change the User agent string setting to Internet Explorer 10.

2014-06-18_10-21-10

Fixing the issue by changing the User agent string

The page will reload and now SharePoint will understand that you are the good do-be that you are, speaking IE10ish instead of IE11ish. After you do your work, it’s a good idea to switch back to default so that you are speaking IE11ish again.

The Emulation settings give you a bunch of other nice tools (want to act like an XBox360?), so if you have interest in testing things in different browsers types, etc., be sure to check out the rest of the settings as well.

Uploading Attachments to SharePoint Lists Using SPServices

Easy!For years people have been asking me how they could upload files using SPServices. I’ve dodged the questions every time because I simply didn’t know how.

On a current client project,  I’m building a slick Single Page Application (SPA) to manage tasks in SharePoint 2010. It’s basically a veneer over the clunky out-of-the-box task list experience. Rather than hopping from page to page, the team using the application can accomplish everything they need to do on a single page.

Every project has specific needs, and for this one I’m using KnockoutJS. But the code snippets I give below are generic enough that you should be able to use them in any context with a little thinking.

It’s been going well, but I had been putting off implementing adding attachments because…well, as I said, I didn’t know how.

One of the benefits of the shift from all server side development to a much more significant focus on client side techniques is that some of the bright minds in the SharePoint development community have turned their eyes toward solving these things, too. Usually it’s on SharePoint 2013 or SharePoint Online at Office 365. However, at least now when I search for “SharePoint JavaScript xxx”, there are likely to be some great hits I can learn from.

In this case, there were two excellent posts, one from James Glading and one from Scot Hillier. (See the Resources section below for links.)

The first step is to enable HTML5 capabilities in IE10. This requires two small changes to the master page. This seems simple, but it can have effects that you don’t expect. In other words, don’t consider this just a “no brainer”. You need to plan for the change across your Site Collection and any impacts it may have.

The first change is to switch from using “XHTML 1.0″ to “HTML” as the DOCTYPE. This is what “turns on” HTML5.

<!DOCTYPE html>

Then, in this project we set the content meta tag to IE=10 because we want to aim for IE10.

<meta http-equiv="X-UA-Compatible" content="IE=10"/>

If your browser base is different, you can, of course, set this differently. In this project, we will require all users of the application to be running IE10 or greater. Firefox and Chrome have supported the bits of HTML5 we need for so long, that there’s little concern about people who choose to use those browsers.

Once we have those two small changes in the master page (we are using a copy of v4.master with no other customizations at the moment), we “have HTML5″. It’s most obvious because some of the branding flourishes I’ve put in like rounded corners show up in IE10 now, rather than just square boxes.

Once we have HTML5 enabled, we can start to use the File API, a.k.a. the FileReader. This is such a simple little thing, that it’s hard to believe it gives us the capability it does.

<input type="file" id="attachment-file-name"/>

That’s it. That simple HTML gives us a file picker on the page. Depending on your browser, it will look something like this:

File Picker

When you make a file selection with this very familiar widget, you can query the element using jQuery.

var file = $("#attachment-file-name").files[0];

Note that we’re after a single file, so we grab the first object in the file list array. We get an object that looks something like this screen shot from Firebug:

File object from the File Picker

Once we have the file object, we can look at what the Lists SOAP Web Service needs to get in order to upload the file. Again, it’s pretty simple. Here is the list of inputs and output from the MSDN documentation page for the Lists.AddAttachment Method.

Parameters

listName
A string that contains either the title or the GUID for the list.
listItemID
A string that contains the ID of the item to which attachments are added. This value does not correspond to the index of the item within the collection of list items.
fileName
A string that contains the name of the file to add as an attachment.
attachment
A byte array that contains the file to attach by using base-64 encoding.

Return Value

A string that contains the URL for the attachment, which can subsequently be used to reference the attachment.

The first three inputs are straightforward. We pass in the name of the SharePoint list, the ID of the list item, and the name of the file we want to attach. It’s that last input parameter called “attachment” that’s a bit tricky.

When we upload a file via an HTTP POST operation – which is what all of the SOAP Web Services use – we have to pass text. But the files we want to upload are as likely as not to be binary files. That’s where the Base64 format comes in. Believe me, you don’t need to know exactly what the format actually is, but you should probably understand that it enables us to send binary files as text bytes. Those bytes are then decoded on the server end so that the file can be stored in all of its original, pristine glory.

Here’s the code I ended up with, skinnied down as much as possible to make it a little clearer to follow. I draw heavily from Scot and James’ posts for this, but nuanced for SPServices. I’ve also stripped out all of the error handling, etc.

  • First, the getFileBuffer function reads the contents of the file into the FileReader buffer. readAsArrayBuffer is an asynchronous method, so we use a jQuery Deferred (promise) to inform the calling function that the processing is done.
  • The contents of the buffer are then converted from an ArrayBuffer – which is what the FileReader gives us – into a Base64EncodedByteArray. This works by passing the buffer through a Uint8Array along the way.
  • Finally, we use the toBase64String method to convert the SP.Base64EncodedByteArray to a Base64String.

Yeah, that’s a lot to swallow, but again, you don’t really need to understand how it works. You just need to know that it does work.

Finally, we call Lists.AddAttachment using SPServices to do the actual upload.

/* From Scot Hillier's post:
http://www.shillier.com/archive/2013/03/26/uploading-files-in-sharepoint-2013-using-csom-and-rest.aspx */
var getFileBuffer = function(file) {

  var deferred = $.Deferred();
  var reader = new FileReader();

  reader.onload = function(e) {
    deferred.resolve(e.target.result);
  }

  reader.onerror = function(e) {
    deferred.reject(e.target.error);
  }

  reader.readAsArrayBuffer(file);

  return deferred.promise();
};

getFileBuffer(file).then(function(buffer) {
  var bytes = new Uint8Array(buffer);
  var content = new SP.Base64EncodedByteArray(); //base64 encoding
  for (var b = 0; b < bytes.length; b++) {
    content.append(bytes[b]);
  }

  $().SPServices({
    operation: "AddAttachment",
    listName: "Tasks",
    listItemID: taskID,
    fileName: file.name,
    attachment: content.toBase64String()
  });

});

Very cool! And as I tweeted yesterday, far easier than I ever would have expected. Yes, it took me a good chunk of a day to figure out, but it definitely works, and pretty fast, too.

If you use this example as a base, you could fairly easily build out some other file uploading functions. Combined with the other attachment-oriented methods in the Lists Web Services, you can also build the other bits of the attachment experience:

  • GetAttachmentCollection – Returns a list of the lit item’s attachments, providing the full path to each that you can use in a list of links.
  • DeleteAttachment – Once you’ve uploaded an attachment and realized it was the wrong one, this method will allow you to delete it.

Moral of the story: Fear not what you do not know. Figure it out.

Resources

What’s the Story for HTML5 with SharePoint 2010? by Joe Li

Uploading Files Using the REST API and Client Side Techniques by James Glading

Uploading Files in SharePoint 2013 using CSOM and REST by Scot Hillier

Lists.AddAttachment Method

This article was also posted at ITUnity on Jun 02, 2014. Visit the post there to read additional comments.

Update 2014-05-28 11:55 GMT-5

Hugh Wood (@HughAJWood) took one look at my code above and gave me some optimizations. Hugh could optimize just about anything; he is *very* good at it. I *think* I can even see the difference with larger files.

getFileBuffer(file).then(function(buffer) {
  var binary = "";
  var bytes = new Uint8Array(buffer);
  var i = bytes.byteLength;
  while (i--) {
    binary = String.fromCharCode(bytes[i]) + binary;
  }
  $().SPServices({
    operation: "AddAttachment",
    listName: "Tasks",
    listItemID: taskID,
    fileName: file.name,
    attachment: btoa(binary)
  });
});

Feminism in Tech – Be a Part of the Solution

My friend (and client) Dan Antion (@dantion) tweeted a link to an excellent article this morning entitled An Open Letter on Feminism In Tech. The subtitle is “We are tired of pretending this stuff doesn’t happen.” I’m right there with this.

My role models about feminism were my mother Christina Bellamy and my paternal Grandfather Denton (of all people!).
Mom and Me18800
Their type of feminism wasn’t the radical feminism of the early 70s with all of it’s harsh demands and in-your-face rhetoric. It was exactly the type of feminism described in this excellent article by a group of women technologists.

Feminism is not a dirty word. Feminism is the radical notion that women are people, and that we want to be treated as equals.

As more eloquently said in the article, we can’t allow the sorts of bad behavior that occur in tech, or anywhere else. In the article, the writers point out that these tenets should apply to *any* group within tech that isn’t the mainstream, white male group that has dominated the industry historically.

But it goes much further than that.

At our son Calder’s school they have a zero tolerance rule about bullying. It causes some uncomfortable moments, but the effect is virtually zero bullying, creating a nurturing, healthy learning environment. Here’s a Wordle that shows many of the words that describe what this leads to. Take out the obviously unaligned ones, and I’d say that this is how we should make tech feel to women, or anyone else.

Runkle Olweus

Each of us should be a part of the solution. In SharePointlandia (aka the SharePoint Community), we have far less of the bad behavior than what I’ve seen in other technologies. So on some levels, we’re lucky. Working with SharePoint to some degree means a sort of self-selection for people who see collaboration and group work as a useful, productive thing. The characteristics of who is a part of those activities becomes less important. But we aren’t perfect either.  There is always room for improvement and collective enlightenment. (Yeah, that sounds a little sappy, but even when you get really good at something, you can strive to be great.)

To borrow a phrase, “If you see something, say something”. Let’s make sure that SharePointlandia is a land of openness and opportunity for all of us, no matter who or what we are.

Addendum: I would be remiss if I didn’t mention Women in SharePoint, which “is dedicated to helping women working as SharePoint professionals reach their career objectives through a variety of community, training and mentoring programs.”

SharePoint Conference .ORG Reston 2014 Wrap Up

I want to thank everyone in the SharePoint practice at Protiviti for another stellar SharePoint Conference .ORG. This was one of the first “big time” conferences at which I was asked to speak four years ago, and it’s always one of my favorites. The Protiviti folks are some of the nicest and most talented people in SharePointLandia.

On Sunday, Kyle Schaeffer (@kyleschaeffer) and I did a workshop on SharePoint 2013 Branding & Responsive Design. Just being in the room with Kyle is an honor; having the opportunity to teach with him is truly a joy. We’ll be repeating our act at the Dallas incarnation of the conference in October.

For the main part of the conference, I talked about Creating a Great User Experience in SharePoint. My slides for the session are available on SlideShare, and also embedded below.

Finally, here’s a photo of the five SharePoint MVPs who spoke at the conference. I’m in some truly esteemed company here, from left to right: Liam Cleary (@helloitsliam), me, Benjamin Naiulin (@bniaulin), Dan Usher (@binarybrewery),  and Doug Hemminger (@DougHemminger).

All 5 #SharePoint MVPs from @SPC_ORG 2014!

All 5 #SharePoint MVPs from @SPC_ORG 2014!