Gone fishing

Well it doesn’t happen very often (it’s over two years since I last took a proper holiday), but I’m off on holidays for the next two weeks. This weekend we’re heading up to Suffolk to the Latitude Festival and then later next week it’s off to Madeira for a family trip where we’ll be celebrating important birthdays for my parents amongst other things.

When I get back from holidays I literally switch airports and fly straight off to St Louis for the IamLUG conference. (If you’ve not registered for it and the Tack It On day which follows then what have you been doing?)

So all in all it’s going to be a fun few weeks. But if I don’t respond to your email you’ll know why.

Forcing a file name when downloading a dynamically generated csv file

Over the last couple of weeks I’ve been working on a customisation project using IQJam as a starting point and then making it better fit a particular customer’s requirements. It’s worth mentioning as I finally had the justification to spend a little time investigating a problem which has been bugging me.

One of the features I added to IQJam was the ability to export data to Excel, a common enough feature that you’ve been able to do in Domino for ever. Simply print data out to the browser in simple HTML format and change the content-type of the page to “application/vnd.ms-excel”. That’s not the point of this posting really.

The problem I’ve been trying to work around is that if your user is using Excel 2007 or later (I’m only on the beta of Office 2010 but it still seems to be a problem for me anyway) and you use the printing HTML technique, Excel raises an error for the user when they load the page, something like:

The file you are trying to open, ‘name.ext’, is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file. Do you want to open the file now?

According to various technotes and blog posts there is no work around for this, it is a deliberate security feature of Excel. Fair enough I can live with this, though it’s not acceptable to the end user, so instead of generating an Excel file I reverted to generated CSV formatted data.

The thing I learned from my investigations into the Excel problem was that there is this header which you can add to the data being generated which tells the browser that the page being opened is actually a file attachment and what the name of the file you want to download should be. So in my example, I’m able to create a unique file name every time the page is generated and also specify that it should be saved as a CSV file, not .XSP which is what it would be thanks to the page being loaded being an XPage. See this example:

    var exCon = facesContext.getExternalContext();
    var writer = facesContext.getResponseWriter();
    var response = exCon.getResponse();
    response.setHeader(“Content-disposition”, “attachment; filename=export_” + DateConverter.dateToString(@Now(), “yyyyMMddhhmm”) + “.csv”);
    response.setHeader(“Cache-Control”, “no-cache”);

So this server side javascript sits in the afterRenderResponse of my XPage and is using the “web agents XPages style” technique which Stephan first documented to generate non HTML content from an XPage. The key line for this blog post is where the “Content-disposition” header is set, hopefully you can see where the filename is being created (I’m also using Tommy Valand’s DateConverter SSJS code to get the current date / time formatted into a nice string).

Anyway, not a new technique looking at the dates on some of the internet postings out there, but a new one on me and worth passing on I thought.

Ten days into the iPad

Of course it’s shiny and built by Apple so there was no question that I’d end up buying one. The big question was whether to go for the Wifi or 3G version. In the end, the lack of availability of the 3G informed the decision somewhat, so I ended up with a 64gb Wifi model. The reason I was so undecided is that since I have Froyo installed on my Nexus One phone, it’s so easy to make that a Wifi hotspot that I was finding it hard to justify getting yet another sim card and the associated costs that go with it.

So ten days into owning the device and I’m really liking it. Not to say it’s perfect in any way, the things that I am hanging out for when iOS4 is released (in the Autumn for the iPad as far as I can tell) are the pseudo multi tasking and a better notification system. Having been an Android user for a few months now, there’s certainly no way I could leave that as my primary mobile device, the multi tasking, notifications and general geekiness of that phone really make it a wonderful handset for me.

The main point of this post was to mention that I had also purchased an InCase iPad case at the same time as the iPad. For the first couple of days it was superb, felt high quality and worked really well. Unfortunately within 4 days the case no longer worked properly as, in landscape mode (which is how I seem to operate mainly) the iPad would slide out of the case so that the bottom half inch of the screen wasn’t visible. Not very good. So yesterday I took it back to the Apple store and got a refund.

This is the first time I’ve ever tried to get a refund for anything from Apple and it wasn’t an easy process. Initially the guy I was dealing with wouldn’t offer me a refund as I didn’t have the original packaging. My protestations that they had sold me faulty goods were falling on deaf ears. In the end the only reason I got the right to swap the case for other goods to the same value was because, as ever, the store was packed and after five minutes of arguing I had a little bit of an audience, all of whom were on my side and telling the guy he should give me a refund. So the lesson is make sure you go in to the store when it’s busy and then stick to your guns!

I ended up with the Apple own brand case as a replacement and it seems to work a lot better, even if it does look and feel quite cheap and plastic-y. We’ll see how long it lasts.

My IamLUG Session

Yesterday Chris Miller announced the first batch of speakers and sessions for this year’s IamLUG conference in St Louis. I’m fortunate enough to have had my abstract accepted. And so I’ll be presenting an updated version of my “Ten XPages Design Patterns” session.

There is already a great list of speakers and sessions announced, so if you’ve not registered yet then get over to the IamLUG site quickly to get signed up, it’s a free conference remember!

And then, of course, there’s the Tack It On extra day of deep dive content provided by Rob Novak and the SNAPPS team, Chris Miller and myself. All in all, three days of great sessions, interesting people, and I’m sure more than a little fun as well.

Lotus UK Power of Business Applications

Darren Adams has already mentioned this day on 16th June, but I thought I’d just make sure that people know about it as well.

Basically what Darren has organised is a day all about Lotus application development in the real world. So I’m going to speak a little about the history of IdeaJam, where we are and hot we got here. Then in the afternoon I’m back on my favourite hobby horse; XPages development. This time the title for the session is “Rejuvenating Domino Web Applications with XPages”.

There looks like there’s some really great content during the day, so if you have anything to do with Domino applications (that’s development, implementation, management, or anything else really, this isn’t an overly techie day) then it will probably be worth you coming along.

And best of all, it’s free. You just need to register here.

XPages101 comes to America

I’ve been working with Chris Miller and Rob Novak over the last few weeks to put together a great extra day after IamLUG this August in St Louis. 

Basically the plan is that I’ll run my XPages101 classroom course, Chris will be running a new “Domino Optimization Tour” and Rob and the SNAPPS team will be running their iPhone Development class. Each of the courses will be running concurrently in the same rooms that IamLUG will have been in for the previous couple of days. And because we’re able to get some economies of scale by operating together, the prices for the extra training day, or “Tack It On” day can be kept as low as possible.

So if you’re interested in learning XPages, iPhone development or taking a deep dive into Domino server optimisation then visit the information site for more details.

Pleasant 8.5.2 surprise… everything works!

Well maybe that’s too bold a claim, but from the point of view of regression testing IdeaJam and IQJam for XPages issues, a vanilla application works absolutely fine. And better than that, it seems to be faster as well.

Why is this even worth commenting on you ask? Well between 8.5.0 and 8.5.1 there were some quite significant changes in the way XPages worked which meant I had to do some re-coding of my XPages apps to get them to work properly when we migrated up to the new version. But, so far, and all of the usual caveats apply here* (see below for more information), I can simply copy an NSF from my 8.5.1 VM onto my 8.5.2 VM and it works.

We’ve not done any proper testing on the performance side of things, but from my usage of the application everything feels snappier.

So, who needs new features when we’ve got stability between versions. Well OK, I’ll not turn down the spangly new development features (dragging controls into the source XML of an XPage is far and away my favourite), but even without them, I’m a happy camper this morning.

*** 8.5.2 is still in beta things may change between now and when it’s released. Let’s hope not eh?

Tracking down error 80020101 in Internet Exploder

So yesterday, after all of the travel fun and games of the few days, it was back to the real world with a bump. I had a pile of bugs to fix on various projects. Most were very simple to get through, but one has taken me several hours to track down so I thought it would be useful to record the problem and my solution.

In IdeaJam we use Mootools as I have mentioned many a time before. Mootools, when executing Ajax requests does some very funky stuff to make the request as efficient as possible. One of those things, is that will detect the content type of the page you’re requesting and try it’s best to process it as it should, that is, if you request Javascript then it will try and execute it. Unfortunately if you’re in IE, then it uses the following technique 


This is all well and good until there is an error in the Javascript it is evaluating (and it is very picky about syntax here). When there is an error you will get something like:

Could not complete the operation due to error 80020101

There are a *lot* of websites out there where people have come across this problem and then tracked it down to a specific problem with their code so they assume that this error message means you should remove comment tags from your script, or there’s a missing semi colon on the end of a line, or an array is incorrectly formed. All of these may well be true, but the error message just means “There is an error”, you can read no more into it than that.

Instead, you need to look very closely at whatever is being returned and evaluate it manually yourself to track down the issue.

What was especially galling for me, is that my problem was entirely my own fault. I had set the content type of the page I was requesting using Ajax to be text/javascript when it actually it should have been text/html. So Mootools was trying to evaluate some “code” which could never possibly work. So my fix was simply to change the content type of my response page.

The point is that your problem may be something entirely different, and you’d still get exactly the same error message from IE. Thanks for that Microsoft.

The great geek escape

As you may know if you follow Warren or myself on Twitter, we reached the point on Saturday morning where it became fairly obvious (to us at least) that we weren’t going to get home by plane from Copenhagen any time soon. The only option that was available to us was a Eurostar journey from Paris to London on Monday evening. So after booking various train tickets (Thalys from Brussels to Paris, Eurostar from Paris to London), extending the car hire and making it a one way rental that we could drop in Brussels, buying supplies for the trip, we set out early on Sunday morning for the #greatgeekescape.

The plan was simple, drive from Copenhagen to Brussels, drop the car there, sleep, train to Paris, train to London and then home (for me at least, Warren still has to get to Edinburgh from there). So Sunday was spent driving… a long way. 1050km (650 miles). In a Fiat 500. It took us 12 hours, but we finally made it at around 8pm, absolutely exhausted, but a lot closer to home.

This whole episode has raised several points and questions…

  1. Danish drivers are scarily aggressive, for such a relaxed nation I have no idea where this trait comes from.
  2. “East bound and down”, the theme from Smokey and the Bandit, is a perfect tune to play loud while blatting along German autobahns in an Italian car while trying to get to Belgium.
  3. It is inconsiderate of the Dutch road building authorities to redesign their road system without checking with us first, we saw entirely too much of the Eindhoven ring road. 🙂
  4. When you have two laptops, two smartphones, and a GPS system you can navigate your way around unexpectedly changed Dutch roads in a pinch!
  5. It’s useful having Twitter and SMS to help us out with support from friends, and also people to answer questions for us.
  6. We were very very lucky that we had the funds and opportunity to decide to get ourselves home. Not everyone was in the same position and I can’t imagine how bad this would have been otherwise.
  7. There is absolutely no way I could do any serious amount of travel on a regular basis. Even before this whole escapade I was knackered from trips to Belgium, Amsterdam and Newcastle earlier in the month. I really just want to get home.
  8. In all of the people we encountered on phones, in hotels, in bars, across multiple countries, the single common factor was unfailing helpfulness and, given the stress some were under, a cheerful response to questions. Sometimes your faith in humanity can get a welcome boost.

All being well, and I hope I’m not tempting fate here, the Eurostar will get us back to St Pancras at 10pm this evening. I can get home in 30 minutes from there and Warren has another night away from home with friends as he continues up to Edinburgh.

All in all it’s been an eventful and memorable trip away from home. Not one I’d like to repeat any time soon though!

Dannotes and a long journey home

I’ve been in Denmark for a couple of days now at the wonderful Dannotes event. It’s a slightly different setup compared to other user groups that I’ve been to, but as with all user groups, the organisation behind the scenes is amazing, the people are interesting and good company, and there are interesting conversations happening everywhere you look.

I ended up presenting the full version of Tim Clark and my Lotusphere session. If you saw it in Florida then you’ll know that we had too much content to get through. Well luckily here I had three hours to speak so was able to finish the entire presentation for the first time. It seemed to go pretty well with some interesting questions and only one mistake from me. My lesson from the afternoon is that talking and coding for three hours is really hard work, though I suppose I should have been able to guess that beforehand.

We’ve been looked after by the organisers here really well. The hotel is ideal for a user group meeting, the restaurant was very nice and the beer and wine flowed freely (possibly a little too freely judging by some people this morning).

And then we get onto the volcanic eruption. The upshot of several hours on the phone and internet is that we’re stuck here until Saturday. So given that I am travelling with Warren “Mr Lego” Elsmore, I’m sure you won’t be too surprised to find we’re heading to Legoland after Dannotes wraps up for an impromptu visit. Then tomorrow it’s into Copenhagen before, hopefully, heading home on Saturday. At the moment that is all entirely theoretical as the airlines don’t know when they’ll be able to operate again. I suppose you just have to make the most of an unexpected opportunity.