I’m on a mission. And that mission is to build SharePoint apps without dropping code on the server. Why would anyone want to do this? Well, in many enterprise or hosted environments you don’t have the ability to drop DLLs into a shared SharePoint environment. This has often limited the types of applications we can build to out of the box features or SharePoint designer. But with some Javascript and the WSS web services, we can build a more complex app all with AJAXy goodness.

This code sample uses the Prototype Javascript library. When you see Ajax.Request, that’s using prototype’s Ajax framework. The great thing about prototype is that everything is cross-browser compatible.

First we need some code that formats a simple SOAP envelope. SOAP is the required protocol for communicating with the SharePoint web service.


var Soap = {
  createEnvelope: function(action, ns, parameters)
  {
    var soap = '<?xml version="1.0" encoding="utf-8"?>
        <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
        <soap12:Body>';
    soap += '<' + action + ' xmlns="' + ns + '">';
    soap += Soap.__parseParameters(parameters);
    soap += '</' + action + '></soap12:Body></soap12:Envelope>';
    return soap;
  },

  __parseParameters: function(parameters)
  {
    var params = "";
    if (typeof parameters == 'object')
    {
      // check if we were provided an array or an object
      if (typeof parameters.push == 'function')
      {
        for (var i = 0, length = parameters.length; i < length; i += 2)
        {
          params += "<" + parameters[i] + ">" + parameters[i+1] +
              "</" + parameters[i] + ">";
        }
      }
      else
      {
        $H(parameters).each(
          function(pair)
          {
            params += "<" + pair.key + ">" + pair.value + "</" + pair.key + ">";
          });
      }
    }
    return params;
  }
}

Okay, so now we can make a SOAP envelope as simple as this:

var mySoap = Soap.createEnvelope(
  "MyAction",
  "http://schemas.microsoft.com/sharepoint/soap/",
  { param1: "value", param2: "value" });

Simple enough. Now let’s call a SharePoint web service. We’ll use the Lists web service and create a new list item. The UpdateListItems method allows us to pass in some XML defining the items to create. So first I’m going to build that XML.

var batch = '
  <Batch OnError="Continue">
    <Method ID="1" Cmd="New">
      <Field Name="ID">New</Field>
      <Field Name="Title">Hello World</Field>
    </Method>
  </Batch>';

Next we’ll call the web service using the Ajax.Request object:

// build parameter object
var parameters =
{
  listName: "My List",
  updates: batch       // xml created earlier
}

// create soap envelope
var soap = Soap.createEnvelope(
  "UpdateListItems",
  "http://schemas.microsoft.com/sharepoint/soap/",
  parameters);

// call web service
new Ajax.Request(
  "http://myserver/mysite/_vti_bin/lists.asmx",
  {
    method: "post",
    contentType: "application/soap+xml",
    postBody: soap,
    onSuccess: function(transoprt) { alert("Success: " + transport.responseText); },
    onFailure: function(transport) { alert("Error: " + transport.responseText); }
  });

If all goes according to plan, I should have a new list item with the title of “Hello World” in the list called “My List”.

A couple of points about the javascript above:

  1. It’s certainly not the greatest Javascript in the world. I plan to clean it up and hopefully release a Javascript library for working with all of SharePoint’s web services.
  2. The user’s browser must already be authenticated for this to work. Prototype doesn’t have a way to pass credentials to the web service so make sure you run this from a machine joined to the same domain as the sharepoint site. Ideally this is running within a sharepoint site so that should take care of the authentication problem.
  3. FireFox has an issue because it doesn’t pass domain credentials automatically. This makes debugging hard from your workstation, but if it’s running on a SharePoint site where the user has already authenticated, it works fine.
  4. I cheat in the example above and break strings onto multiple lines. That’s for the purpose of formatting only. If you copy and paste this code directly it won’t work.

You can download the code here: wsswebservice.js.

Advertisements

Well, I’ve been skeptical about what Google is trying to do. I love Gmail but I’ve held off really trying out their other products. But recently I was running a beta of Excel 2007 and it expired so I was left without a spreadsheet program. I decided to give Google spreadsheets a try.

At first I got what I expected – much of Excel’s basic functionality while feeling a little less responsive than a desktop app. I mean, for a web app they’ve done a remarkably good job, but it’s still not the same as a rich desktop application. But then I discovered two excellent features that I didn’t expect.

The first came after I had been working on a spreadsheet for a while and realized that I had it so screwed up I wanted to go back to the beginning. I was just about to close and re-open the spreadsheet when I noticed the “Revisions” tab at the top. I clicked on this and – hey what do you know – just about every change I made was automatically saved as a revision. I flipped through the revisions, found the place I wanted, and overwrote my f’d up version with a clean version. Now that’s something you don’t get in Excel.

The next thing that happened (which prompted me to write this blog post) is that I was making a change when all of a sudden I lost my internet connection (damn netgear wireless crap). Now I’m thinking “ugh – lots of rework” but all of a sudden Google pops up a little box that says “uh hey – you don’t have connection. you want to work offline or try and reconnect?”. Wow – ok, let’s see how this works. I reboot my router, get my connection back, click the “try and reconnect” option, and I’m back and running. No lost data – nothing. Everything is exactly as if I had never lost connection in the first place. Now that’s slick!

So I’m not sure if I’m completely sold on giving up Excel but I have to say that if Google keeps going the way they are going with innovative features and solid design, I might just be tempted.

MicroISVs and their blogs

February 4, 2007

It seems like every small software company out there has a blog these days. It’s become a requirement. In fact, most times these days the blog shows up before the actual product. But if you ask me, by and large it’s a waste of time. If you’re blogging in the hopes that it will attract potential customers or keep customers interested then you need to look long and hard at the kind of content you’re publishing.

Look, marketing is important – critically important to the success of your company. But if your blog is going to be a marketing tool, it’s got to be targeted at your potential customers. Your customers don’t care that you really liked some Joel on Software post. Your customers don’t care that you’re putting the finishing touches on some feature or that you contributed to some open source project over the weekend. Your customers want to read things they care about – not things you care about.

The key to a successful blog for a software company is one that truly provides value and connects with your customer base. If you are passionate about the subject of your software, then you have a good chance of writing a compelling blog which adds value on top of the software you sell. If you’re not that passionate, or if you suck at writing, a better approach would be to try and aggregate news articles or other industry/subject related blog postings.

At the end of the day, look at everything you do through the eyes of your customer. Is it valuable to them? If not, then you should stop and put that valuable time into something else.

Mr. Angry over at Angry 365 Days a Year wrote a post titled Idiot users and how to deal with them. I think he starts off in a good way but I’d like to add a few comments to his overall message.

Whenever you encounter an “idiot” user, think about this. What if you were asked to drive a forklift? What if you were asked to replace the spark plugs in your car (are there even spark plugs in a car)? What if you were asked to field strip a M-16?

I had an experience as a kid that sticks with me to this day. I was staying with a great uncle of mine and was hanging out downstairs. He had a fireplace and at some point the fire died down to basically nothing. I didn’t even notice it – I was probably playing with legos or something. Anyway, at one point he comes downstairs and exclaims “You let the fire go out!? Boy how you been raised?” I’d never started a fire in my life much less understood that it was expected that I should keep it going in someone else’s house. But from his point of view I was stupid for not realizing what was a basic, fundamental part of life. Me on the other hand, I was upset that his opinion of me was now colored by what was really an unfair expectation/assumption on his part.

The point is, there are plenty of things we don’t know. And it’s not because we’re stupid, it’s just because we haven’t been exposed to them. Or maybe we’ve been exposed to them at a very superficial level, but we don’t interact with them with enough regularity to be comfortable. This is how many “idiot” users are with computers. It’s not that they’re stupid, they just aren’t as comfortable with computers.

And it’s more than just knowing enough about browsers to know that “Google” isn’t the “Internet” (it’s just the page that shows up by default Dad). It’s a very fundamental difference in language. Have you ever used the term GUI to a non-technical user? While they’re sitting there politely nodding their head they’re thinking “uh, why did this guy just refer to his program as having a rich GOOEY AJAX (when did cleaning products enter into the picture) driven interface?” And how about the term “interface”? To us, this is a no-brainer. It’s so common that everyone should understand it. But you know what, when you look at the definition for the word interface, our version is number 6 on the list.

So cut those “idiot” users some slack. Try and remember that they are probably very far out of their element and their comfort zone. Try and remember what it feels like to be out of your comfort zone and having someone judge you based on their standards – not yours. Try and remember that while they might not get computers, they are probably extremely good at something you suck at.

Edited 2/4/07 – added Mr. Angry’s name and link.

This year for new years eve instead of doing the same old tired Champagne (which I hate anyway) I decided to buy a nice bottle of wine. I like Australian Shiraz and have found a few really good wines for $10 per bottle or less that I drink fairly regularly. So I went to a local wine shop and got a recommendation for a really good bottle of Shiraz. The bottle cost $45 and it is definitely good – but is it 4 times as good as the $10 bottles I drink regularly? No.

I’ve found this trend quite a bit with Shiraz. Less than $10 is usually bad news (although check out JackaRoo at Trader Joe’s – $3.99 a bottle so get a case), some good ones at $10/bottle, a few really nice ones at $15-$20/bottle – but above that, no substantial increase in quality.

Now I certainly can’t say I’ve tried everything and I wouldn’t call myself a sophisticated wine connoisseur, but so far in all the bottles of Shiraz I’ve tried, I just haven’t found a wine above $20 that just knocks my socks off. Maybe that’s just the way Shiraz is. Someone who knows more about wine can let me know. But until further notice, $20 is the most I plan on spending for a bottle of Australian Shiraz.

BTW, if you’re interested, here are some great bottles for $10 or less:

  • Jacob’s Creek Reserve Shiraz ($10)
  • Rosemount Estate Diamond Label Shiraz ($10)
  • Lindemans Reserve Shiraz ($9)
  • JackaRoo Shiraz ($4 at Trader Joe’s)

A colleague and I were talking today about project management, agile projects and I got to thinking about the point at which it is clear that a project has failed. What struck me was that I believe this point is actually much sooner than most would acknowledge. I believe there comes a point when most, if not all people on a project realize at some level that this project has failed – or will definitely fail without serious course correction. However, this point rarely leads to any serious action or course correcting – in fact most people won’t even acknowledge (publicly) that the project has reached this point.

Now, I am certainly not above this phenomenon. In fact, it’s one of my weakest traits as a project manager. When I look back at some of the projects I’ve been involved in, I can identify the point at which it became clear that we were not on a path to success. This is the point at which I begin to wake up in the middle of the night plagued by the endless list of to-dos and the bewildering feeling that we’re no where near where we need to be (or where we say we are). However, rarely did I take the steps necessary to correct this situation. Instead, I found myself doing what a lot of managers do in these situations:

  • Cutting Corners – every time a new situation we hadn’t thought of rears it’s ugly head, we come up with a hack (i mean workaround) to eliminate it. We know that it isn’t really in the best interest of the project, but if we do it this way we don’t have to miss a deadline. And of course we can always fix it on the next phase (right – when was the last time you had the time on a project to go back and fix a hack from the previous phase??).
  • Calling Meetings – what do we do if we feel like a project is spiraling out of control?? Call lots of meetings of course. Require everyone involved to provide you with a full status report and a list of all open issues and roadblocks. These meetings become an opportunity for the project manager to start distributing responsibility for failure to the various members of the team. They become a way to passively distribute blame and offload personal responsibility on others. Rarely are these meetings constructive, positive experiences where everyone works together in the spirit of getting things on track. Instead they become a forum for the managers to issue broad statements and ultimatums while immediately silencing anyone who voices an alternate viewpoint or tries to interject reality into the conversation.
  • Issuing Ultimatums – the first time you hear “no matter what happens, we WILL ship on time” you know you’re in trouble. In fact, I would suggest that as soon as one feels the need to issue an ultimatum like that, the project has failed. Hearing statements like this tell you two things: 1) the person issuing the statement knows that the goals are unrealistic and 2) he doesn’t give a damn and would rather burn out the team than deal with reality.
  • Adding People – this is probably the worst thing you can do. The only thing worse for productivity than bringing in a bunch of new people with no context and no background in the project is to ask for more frequent status reports. Adding people just means that all your current team members will have to spend half their time training the new people and the other half of their time correcting their mistakes.

The crazy thing about these activities is that they are a clear signal to everyone on the project team that the project is doomed. These actions effectively broadcast downward the trouble the project is in. This is the point (I believe) at which it becomes clear that the project has failed. Everyone knows it. Everyone feels it and while they still say “yes – it’ll be tough but i think we can do it”, what they are thinking is “there’s no way in hell”.

So why then do we not deal with these situations? Why do we not deal with the reality that the project is simply too big or too complex or too ambitious? For me, the answers are insecurity and unrealistic optimism.

Failure is a bad word. A failure in your career is a bad thing. Nobody puts failures on their resume. Ironically, failures are what we learn the most from because they force us to really examine the situation so we can avoid it in the future. Maybe even more ironic is the fact that acknowledging failure early enough might lead to eventual success. I would submit that if all project managers publicly, loudly, and clearly stated that a project was going to fail at the point at which they realized this was the case, that 50% of those projects would go on to be successful. Another 40% would be canceled and end up saving the organization a ton of money. However, the personal and professional security required to do something like that is something that most people lack. We’re afraid we’ll be seen as a skeptic – not a team player – a nay sayer. We’re afraid our superiors will say “well if you don’t think you can do it I’ll find someone who does”. And the fact is – there are plenty of eager individuals waiting to prove themselves who will say yes after you’ve said no.

So what do we do? Do we adjust the plan for success? Do we really dig into the details to see what we can possibly do to succeed? Nope. We hope. In essence, all we do is hope. We hope that the ultimatum we gave at the status meeting earlier will be taken seriously. We hope that the extra team members will be able to get up to speed quick enough to provide value. We hope that the corners we are cutting won’t impact usability, cause data corruption, etc. We hope that our superiors won’t drill into too much detail when we tell them the project is “tight, but on track”.

The fact of the matter is that many projects simply become more complex once they get underway. New requirements surface, assumptions are proved incorrect, and a whole host of other issues seem to crop up. This is bound to happen on any project. As project managers we try to plan for this, but sometimes it’s simply more than the schedule can bear. Unless we are secure enough to be vocal about the impact these issues have, and unless our superiors are able to really hear what we are saying without seeing it as descent and lack of commitment, we can’t be successful.

So I guess in the end my point is this. When you hear an IT manager or exec bemoan the fact that they spent $1.5M and in the end got nothing for it, I believe that by the time they had spent $500,000 it was clear to everyone on that team that no matter how much money they spent they were doomed for failure. The tragedy is not the failed project, but the fact that it took another $1,000,000 before anyone had the guts to say anything about it.

I read an interesting article today that has both re-affirmed and made me question existing notions I had about user interface design and ease of use. One of the points of the article is that user interfaces which display all avaliable choices at once are easier to use than those that hide the choices behind sub pages, sub menus, etc. The point that the article makes (actually referencing another article “The Truth About Google’s So-called ‘Simplicity’,”) is:

“Why are Yahoo! and MSN such complex-looking places? Because their systems are easier to use. Not because they are complex, but because they simplify the life of their users by letting them see their choices on the home page: news, alternative searches, other items of interest.”

My first thought when reading that was “then why is the damn SharePoint Central Admin so hard to use??”.  I don’t know about you, but every time I go in there I feel like an idiot because I have to stare at the page for 5 minutes and scan each link to remember which item will take me to the options I need.  Not only that, but I frequently have to click on an item to remember “nope – that’s not the one”.

On the other hand, I think about other interfaces like Window’s control panel.  One of the first things I do when I install Windows is revert the control panel to classic mode so that I can easily see all options available to me.

Maybe the reason why Central Admin is so hard to use is that they’ve tried to show you many options at once, but still in a grouped way.  For example, first off you have the Operations and Application Management tabs.  My first challenge when I’m looking for something is to remember what tab it’s on.  I can’t tell you how many times I’ve quickly scanned the Operations page not seeing what I need, gone to the Application Management tab only to come back to the Ops tab after reading through EVERY link on that page (and clicking on quite a few).

Then, on each page you have groupings of links: Global Configuration, Topology and Services, Security Configuration, etc.  When you’re just scanning the page you tend to see the group names before the links themselves so if you don’t remember what group something is in, you might miss it on a quick pass.

Maybe a better UI would be a simple alphabetized list of all links.  I usually know the name of the link I want, I just can’t remember what group or what tab it’s on.

Or another idea would be to group related options into “Tools” similar to the control panel in Windows.  You could have

  • Security Manager – all security settings including farm accounts, farm administrators, etc
  • Site Manager – configure web apps and site collections
  • Server Manager – services, backup and restore, farm topology, etc

Anyway, all I know is that central admin is hard to use.  But on the other hand, maybe that’s inevitable when you have a product as large and with as many options as SharePoint has.