Multiple Google Calendars

Using multiple Google calendars is a terrific way to share and maintain separate schedules for different groups of people. It’s easy to create them, and you can share them by specifying a list of people, providing a link, or simply making the calendar public/searchable. In this post, I’ll walk you through the steps necessary to create a new public calendar, retrieve its URL, and create events for your subscribers.

Create a New Calendar

All of your calendar management needs can be found in Google Calendar Settings. Calendar Settings are accessed by clicking the gear drop-down and selecting Settings. Then, go to the Calendars tab and click the Create new calendar button to create a new calendar.

GoogleCalendar_Settings

There are a few important settings related to sharing when creating a new calendar. The first is whether you’d like the calendar to be public. Public calendars are visible to everyone and can be found by searching, so you shouldn’t use a public calendar for anything you don’t want to be public. (Duh.) Note, however, that there is a sub-option to hide the event details on your public calendar. This allows you to publicly share your availability without letting the world know exactly what you’re up to. You can also list specific people you wish to share your calendar with and specify what permissions they have. If you have a large group, this can be cumbersome, but it’s your bet for sharing a non-public calendar.

Share Your Public Calendar

So, you’ve created your public calendar, and you want to share it with the world. Your easiest option is to provide people with the URL. Getting the URL is simple but not so obvious. Head back to the Calendars tab in Calendar Settings, and click your public calendar to edit its details. Toward the bottom, you’ll see a section labeled Calendar Address with colored buttons for XML, ICAL, and HTML. Each button is a link to the calendar in a different format.

GoogleCalendar_Url

Click the desired link, and you’ll get a pop-up with the URL for you to distribute. If you’re sharing with other Google Calendar users, I suggest using the HTML link. When users browse to the calendar, there’s a little + Google Calendar button in the bottom-right corner. Clicking the button will prompt them to add the calendar to their own Google Calendar.

GoogleCalendar_AddToCalendars

(Pro tip! Use a URL shortener like bit.ly or goo.gl to make your gnarly calendar link more palatable.)

Create Events

You’ve got the calendar. You’ve got subscribers. What’s left? How ’bout some events!?

Adding an event to one of your many calendars is as easy as you’d hope: click the drop-down indicator next to the calendar and choose Create event on this calendar. Enter the event details and save. Boom. Done.

GoogleCalendar_AddEvent

Animated Add & Remove with jQuery and Knockout

I’ve been doing so many cool things with jQuery and Knockout lately that have my developer soul bursting with glee. One of the things that I did most recently was to implement a small search application that allows a user to execute multiple searches and display the results as a collection of results. (That’s a little confusing. What I mean is that when you do one search, you get a box with the results. If you do another search, you get another box with another set of results.)

I wanted the interface to feel really fluid, and I figured the best way to do this would be to animate the appearance of the search results. I was using Knockout to databind results to the page, but this caused a problem: the results would appear on the page as soon as they were added to the collection.

Let’s look at an example of what I’m talking about so far:

var gcounter = 0;

var viewModel = function () {
    var self = this;
    self.items = ko.observableArray();
    
    self.add = function () {
        self.items.push(new itemViewModel("item " + ++gcounter));
    }
    
    self.remove = function (item) {
        self.items.remove(item);
    };
};

var itemViewModel = function(data) {
    var self = this;
    self.text = ko.observable(data);
};

ko.applyBindings(new viewModel());
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

<div class="inline clickable" data-bind="click: add">
    <span class="ui-icon ui-icon-plus inline"></span>
    <span>Add</span>
</div>
<div data-bind="foreach: items">
    <div class="bigredbox clickable" data-bind="click: $parent.remove">
        <span class="ui-icon ui-icon-minus inline"></span>
        <span data-bind="text: text"></span>
    </div>
</div>

This example allows you to click ‘Add’ to add items, and remove items by clicking them. It’s very responsive, but it lacks a certain je ne sais quoi since items simply appear and disappear instantly. My first thought on addressing this was to make items fade into existence as they are added. We can do this in two steps. First, change the template for the data item to be hidden by default. Then, use jQuery to fade-in after the item is added to the collection. (Note that my hidden class contains just display: none and is defined in my css.)

var gcounter = 0;

var viewModel = function () {
    var self = this;
    self.items = ko.observableArray();
    
    self.add = function () {
        self.items.push(new itemViewModel("item " + ++gcounter));
        $(".bigredbox.hidden").fadeIn();
    }
    
    self.remove = function (item) {
        self.items.remove(item);
    };
};

var itemViewModel = function(data) {
    var self = this;
    self.text = ko.observable(data);
};

ko.applyBindings(new viewModel());
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

<div class="inline clickable" data-bind="click: add">
    <span class="ui-icon ui-icon-plus inline"></span>
    <span>Add</span>
</div>
<div data-bind="foreach: items">
    <div class="bigredbox clickable hidden" data-bind="click: $parent.remove">
        <span class="ui-icon ui-icon-minus inline"></span>
        <span data-bind="text: text"></span>
    </div>
</div>

Ooh, that feels nice now, doesn’t it? But removing items still feels kinda lame. It would be really cool if items would fade away when they were removed! We can do that similarly to how we added the item. We need to employ a few tricks to make this happen, though. The click event’s second argument contains the control that was clicked in its target property. So, we can use event.target along with jQuery’s closest function to find the control we need to fade out. jQuery’s fadeOut method allows you to specify a callback to execute once it’s complete, so we’ll fade-out the selected item and remove it from the collection once the fade completes. That’s all we need to do, though; no HTML changes are needed.

var gcounter = 0;

var viewModel = function () {
    var self = this;
    self.items = ko.observableArray();
    
    self.add = function () {
        self.items.push(new itemViewModel("item " + ++gcounter));
        $(".bigredbox.hidden").fadeIn();
    }
    
    self.remove = function (item, event) {
        $(event.target).closest(".bigredbox").fadeOut(null, function() {
            self.items.remove(item);
        });
    };
};

var itemViewModel = function(data) {
    var self = this;
    self.text = ko.observable(data);
};

ko.applyBindings(new viewModel());

So that’s working great, but I still have a problem. When an item is removed, it fades away nicely, but then the results just flash together once the item disappears. It’d be nicer if that was also animated. jQuery’s slideUp method seems like it’d be perfect for this, so let’s just chain it together with fadeOut! Once again, there’s a little trick to this: you need to specify that the animations shouldn’t be queued. Luckily, that’s accomplished easily by specifying the correct option. Once again, this is a javascript-only change.

var gcounter = 0;

var viewModel = function () {
    var self = this;
    self.items = ko.observableArray();
    
    self.add = function () {
        self.items.push(new itemViewModel("item " + ++gcounter));
        $(".bigredbox.hidden").fadeIn();
    }
    
    self.remove = function (item, event) {
        $(event.target).closest(".bigredbox")
            .slideUp({queue: false})
            .fadeOut(null, function() {
                self.items.remove(item);
        });
    };
};

var itemViewModel = function(data) {
    var self = this;
    self.text = ko.observable(data);
};

ko.applyBindings(new viewModel());

Wooo, doggy! Now things are feeling very fluid. When we add an item, it fades into existence. Removing an item slides up and fades out. Everything feels really smooth and slick. Be sure to check out the jsfiddle for a working example!

Writing Maintainable Regular Expressions

If you’ve worked with regular expressions at all, you know it’s easy for them to become quite unruly. It can be hard to decipher a regular expression as you’re working on it, when you know everything you’re trying to accomplish. Imagine how hard it will be for the poor guy who has to do maintenance on that thing later!

There are a few things you can do to make it better for everybody in the long run.

Write Unit Tests

Unit tests are PERFECT for any code that uses regular expressions because you can write a test for each different scenario that you’re trying to match. You don’t have to worry about accidentally breaking something that you had working previously because the tests will regression test everything as you go.

Include Samples

I like to include samples in the code to make it as obvious as possibly what’s going on to anybody looking at the code. I don’t want developers to have to mentally process a regular expression unless they’re there to work on the regular expression itself. I like to provide simple examples like this:

// matches a field and value in quotes
// matches
//   foo = "bar"
//   foo="bar"
// doesn't match
//   foo = bar
//   foo : "bar"
var pattern = @"((\w+)\s*=\s*("".*?"")";

Include Comments in the Pattern

Another trick you can do is to include comments in the regular expression itself by using #. This can be a helpful development tool, too, because it allows you to write out what you’re trying to match in isolated chunks. Note that you’ll need to use the IgnorePatternWhitespace option for this technique to work.

var pattern = @"(
    (?:"".*?"") # anything between quotes (?: -> not-captured)
    |           # or
    \S+         # one or more non-whitespace characters
)"; 
Regex re = new Regex(pattern, RegexOptions.IgnorePatternWhitespace);

I really, really like regular expressions, but they can definitely be maintenance land mines. So, when you use them, do future developers a solid and use tips like these to make them as maintainable as possible.

Convert JSON to XML in .NET

I was working on a project where we were receiving data in a JSON-like format, and we needed the ability to extract values by field name. After doing just a bit of research, I found that the .NET Framework has a JsonReaderWriterFactory class that allows you to create an XmlDictionaryReader that processes JSON data.

Converting JSON to XML is perfect for my needs because it allows me to use LINQ to XML to query and retrieve the values I’m looking for. So, I wrote a few regular expressions to transform the JSON-like format into actual JSON. Then I used the JsonReaderWriterFactory to do the conversion and loaded the resulting XML into an XDocument.

Here’s an example.

const string json = @"{
    ""foo"":""bar"",
    ""complexFoo"": {
        ""subFoo"":""subBar""
    }
}";
byte[] bytes = Encoding.ASCII.GetBytes(json);
using (var stream = new MemoryStream(bytes))
{
    var quotas = new XmlDictionaryReaderQuotas();
    var jsonReader = JsonReaderWriterFactory.CreateJsonReader(stream, quotas);
    var xml = XDocument.Load(jsonReader);
    Console.WriteLine(xml);
}

/*--------
 Output:
 <root type="object">
   <foo type="string">bar</foo>
   <complexFoo type="object">
     <subFoo type="string">subBar</subFoo>
   </complexFoo>
 </root>
--------*/

Submit a Knockout-Bound jQuery Dialog when Enter is Pressed

There I was, happily coding an awesome logon prompt using the technique previously discussed here, when I ran into a problem: my form wasn’t submitting when I pressed the ‘enter’ key. That’s annoying. No self-respecting logon prompt should require you to move the mouse to a button and click!

So what to do?! Step one: don’t panic. Okay, good. Now you can use a few easy tricks to force the dialog to submit when enter is pressed.

Let’s look at the example that doesn’t work. I have a simple Knockout view model hooked up to a jQuery dialog. When I click the dialog’s “Login” button, it calls a login function. If I press the enter key, though, nothing happens. I take that back; one thing happens: you become annoyed that nothing happened.

var loginViewModel = function() {
    var self = this;
    self.password = ko.observable();
    self.username = ko.observable();
};

$("#loginDialog").dialog({
    buttons: {
        "Login": login
    }
});

function login() {
    // login stuff
}
<div id="loginDialog" title="Login">
    <form id="loginForm">
        <fieldset>
            <label for="user">Username</label>
            <input type="text" id="user" data-bind="value: username" />
            <label for="password">Password</label>
            <input type="password" id="password" data-bind="value: password" />
        </fieldset>
    </form>
</div>

The first thing we need to do is to bind our form to our view model using Knockout’s submit binding. With the submit binding in place, we can use jQuery to submit the form.

var loginViewModel = function() {
    var self = this;
    self.password = ko.observable();
    self.username = ko.observable();
    self.login = function() {
        // login stuff
    };
};

$("#loginDialog").dialog({
    buttons: {
        "Login": function () {
            $("#loginForm").submit();
        }
    }
});
<div id="loginDialog" title="Login">
    <form id="loginForm" data-bind="submit: login">
        <fieldset>
            <label for="user">Username</label>
            <input type="text" id="user" data-bind="value: username" />
            <label for="password">Password</label>
            <input type="password" id="password" data-bind="value: password" />
        </fieldset>
    </form>
</div>

Now we’re equipped to handle the enter keypress. So let’s do that…

var loginViewModel = function() {
    var self = this;
    self.password = ko.observable();
    self.username = ko.observable();
    self.login = function() {
        // login stuff
    };
};

$("#loginDialog").dialog({
    buttons: {
        "Login": function () {
            $("#loginForm").submit();
        }
    }
});
$("#loginDialog").keypress(function(event) {
    if (event.which == 13) {
        event.preventDefault();
        $("#loginForm").submit();
    }
});

That might seem like that should be it, but it’s not quite working. It seems to submit just fine, but login only succeeds when the button is pressed. What gives!? It’s a subtle thing that took me a little bit of time to realize. Databound values are only updated by default when focus leaves the control. So, if you enter a username, press tab, enter a password, then press enter, the password value in the view model hasn’t been updated yet! Argh!

No problem, though. We can change the value to update with each keypress.

<div id="loginDialog" title="Login">
    <form id="loginForm" data-bind="submit: login">
        <fieldset>
            <label for="user">Username</label>
            <input type="text" id="user" data-bind="value: username, valueUpdate: 'afterkeydown'" />
            <label for="password">Password</label>
            <input type="password" id="password" data-bind="value: password, valueUpdate: 'afterkeydown'" />
        </fieldset>
    </form>
</div>

Now we’re in business! The login works great whether you press the button or use the enter key.

Databinding Collections with Knockout

I’ve written a few articles about databinding using Knockout (here, here, and here), but I haven’t touched on collections yet. Collections have proved to be a little more challening and require a bit more work, but they still follow the same pattern.

In this post, I’ll work through a short example to demonstrate how to do two-way databinding with collection objects.

Create Your View Models

I’ve found that getting a collection to bind properly requires multiple view models. The applications that I’ve written have required a main, page-level view model and separate models for each item in the collection.

Let’s say we want to write an page that will manage a classroom roster. The primary model will be called rosterViewModel, and we’ll create another model to represent students, studentViewModel. When the page is initialized, we’ll create a new instance of rosterViewModel and bind it to the page using Knockout.

var rosterViewModel = function() {
    var self = this;
    self.students = ko.observableArray();
};

var studentViewModel = function() {
    var self = this;
    self.firstName = ko.observable();
    self.lastName = ko.observable();
};

ko.applyBindings(new rosterViewModel());

Allow Items to be Added

Adding new items to the databound collection is as easy as creating a new instance of the sub-item’s view model and adding it to the collection. This should be done in an event handler of the parent model. So, in our example, we’ll add an addStudent event that will add a new instance of studentViewModel to the students collection.

var rosterViewModel = function() {
    var self = this;
    self.students = ko.observableArray();
    self.addStudent = function() {
        self.students.push(new studentViewModel());
    };
};

Allow Items to be Removed

Removing items from the collection works the same way as adding. When the event is invoked from the item to be removed, you simply remove it from the collection. We create another event, removeStudent, that does this.

var rosterViewModel = function() {
    var self = this;
    self.students = ko.observableArray();
    self.addStudent = function() {
        self.students.push(new studentViewModel());
    };
    self.removeStudent = function(student) {
        self.students.remove(student);
    };
};

Populating the Collection

Populating the collection might seem like a no-brainer. You’ve got some data, just pass it to Knockout and let it do its job, right? That actually works okay if you’re not modifying the data. The problem is that the source data isn’t rigged for Knockout with ko.observables and ko.observableArrays. The result is that data populates, but changes aren’t detected.

What I’ve done to get around this is to loop through the source collection, instantiate the appropriate view model object, and add it to the parent model’s collection. To make things easier, I modify the view model to accept the source data as an input and populate properties when it’s provided.

var rosterViewModel = function(data) {
    var self = this;
    self.students = ko.observableArray();
    self.addStudent = function() {
        self.students.push(new studentViewModel());
    };
    self.removeStudent = function(student) {
        self.students.remove(student);
    };
    
    if (data != null) {
        var s = data.students;
        for (var i in s) {
            self.students.push(new studentViewModel(s[i]));
        }
    }
};

var studentViewModel = function(data) {
    var self = this;
    self.firstName = ko.observable();
    self.lastName = ko.observable();
    
    if (data != null) {
        self.firstName(data.firstName);
        self.lastName(data.lastName);
    }
};

var sourceData = {
    students: [{ firstName: "Adam", lastName: "Prescott" }]
};

ko.applyBindings(new rosterViewModel(sourceData));

Retrieving the Collection

If you need to retrieve your collection for processing, I suggest doing the opposite of what was done to populate the collection: loop through the view model and extract the data. What you do with the data is up to you. You can package it into another object to be sent to another service or method, or format it for display elsewhere on the page. To demonstrate, I created a computed property that creates an HTML list of students entered.

self.roster = ko.computed(function() {
    var result = "Students:<br/>";
    var s = self.students();
    for (var i in s) {
        var f = s[i].firstName() ? s[i].firstName() : "&lt;unknown&gt;";
        var l = s[i].lastName() ? s[i].lastName() : "&lt;unknown&gt;";
        result += l + ", " + f + "<br/>";
    }
    return result;
});

You can see the complete working example here.