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

Advertisements

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.

Smart Sizing for Remote Desktop Connections

I just stumbled across another life-changing morsel of knowledge: how to enable smart sizing for remote desktop connections. It sounds like this is something that’s been around since Windows XP, but it’s relatively unknown and completely undiscoverable.

Here’s the secret: you need to create a .rdp shortcut for your connection and add the following line using your favorite text editor:

smart sizing:i:1

That’s it. With this miracle-line in your file, the remote desktop will scale as you resize the window. Want to know more? Go here.

Spruce-Up Word Documents with Attractive Info Boxes

You know what I don’t love in a Word document? When it’s just a huge wall of black text. It’s not pretty to look at, and it can be difficult to know what’s important and what’s not. I’ve recently started utilizing shaded info boxes to overcome these challenges.

InfoBox

The info boxes accomplish a few things for me. In addition to giving the document a much-needed splash of color and adding some visual appeal, it gives me a way to highlight information that I think is most important for my readers. I was surprised by the number of steps it took me to create a nice looking info box. It’s not hard; it’s just a lot of steps. And that’s why I’m writing this post–to break it down and (hopefully) make it simple for you.

Here are the features you get with the info box we’re about to create:

  • Small icon to indicate the nature of the information
  • Text aligned to the right of the icon
  • Shaded background

Shouldn’t be too bad, right? So let’s get started.

Step 1: Add a one-cell table

Add a 1×1 table from the INSERT tab in the ribbon. This should create a box that spans the width of the page–just what we want–but the cell margins need to be adjusted. With your cursor in the table, click the Cell Margins button on the TABLE TOOLS – LAYOUT tab in the ribbon. Change the default cell margins to be 0.08″ on all sides.

InfoBox_Table_CellMargins

Step 2: Adjust the border and shading

Right-click the table, select Table Properties, then click the Borders and Shading… button. Change the background color of the table by selecting a fill color on the Shading tab. Choose a coordinating border color on the Border tab. I try to use a light color for the fill and a darker color from the same family as the border, but you can obviously do whatever you want.

InfoBox_BordersAndShading_Shading

InfoBox_BordersAndShading_Borders

Step 3: Add an icon

Insert an image into your table to use as the info box icon. For a quick & dirty image, search clipart for “button” or “icon.” You could also copy/paste from the internet or pick an image from your computer. For best results, make sure the image has a transparent background or the same background color as the table shading.

With the image in place, right-click it and choose Size and Position… to access its layout properties. On the Size tab, change the width to 0.35″. (The height should auto-adjust as long as the Lock aspect ratio option is enabled, which it is by default.) On the Text Wrapping tab,
select In front of text. And, finally, on the Position tab, change the horizontal and vertical positions to Alignment, Left and Top (respectively), and relative to Margin.

InfoBox_Image_Size

InfoBox_Image_TextWrapping

InfoBox_Image_Position

Step 4: Adjust paragraph settings

In order to have the text display to the right of the icon, you need to modify the paragraph properties to have a left indent. I use 0.5″.

InfoBox_Paragraph

Step 5: Add your text

Now you’re ready to add text. Do this by typing words. (Duh!) I typically give my info box a title that has a different color and slightly bigger font, but this is, of course, optional.

Step 6: Adjust the paragraph spacing after the box

This last step is an annoying one. For some reason, there is no spacing following a table. If you add another paragraph, it’s a little too much extra space. I fix this by modifying the paragraph following my info box so that it has space before equal to its space after.

But that’s all there is to it. It’s admittedly a lot of steps, but I don’t think any of them are too crazy. Once you have one box formatted the way you like, you can copy/paste it to other places in your document, too. So you only have to pay that setup and configuration cost once.