Formstack Yahoo and Dashboard Widgets

Written by Ade Olonoh on November 14, 2007

Posted in Form Hacks

Now that Formstack has an API, the fun part begins. How do we use it?

One of the things I like to do is monitor my forms to see if any new data has been collected. I’d kind of like something that just hangs around in the background, watching the form, and if someone submits a form, it lets me know.

Widgets are a perfect application for this, and I put together both a Yahoo Widget as well as a Mac OS X Dashboard widget that does just what I need.

widget.png

If you’re interested in how the widgets were built so you can customize them on your own, keep reading and I’ll give a quick overview.

The Yahoo Widget

Yahoo Widgets are, essentially, a combination of XML and Javascript. You bundle these files together, and they make up your widget (Full Yahoo Widget documentation can be found here).

The file Formstack.kon contains the XML that defines the widget. I have 2 frames, or views, one to display the form information and the other to allow you to enter your API key. In this file, I also define a timer:

<timer>
    <name>timer</name>
    <interval>30</interval>
    <ticking>true</ticking>
    <onTimerFired>fetchFormInformation();</onTimerFired>
</timer>

I use this so that every 30 minutes, the widget calls the fetchFormInformation() function and, as you can guess from the name, fetches the form information. I’ve defined that function in the main.js file, and it looks something like this:

function fetchFormInformation() {

	// get the Form ID and the API Key
	var apiKey = preferences.apiKey.value;
	var formID = preferences.selectedFormID.value;

	// build url for the call
	var location = 'https://www.formstack.com/api/form?api_key=' + apiKey + '&id=' + formID + '&type=json';

	// get that information asynchronously
	var url = new URL();
	url.location = location;
	url.fetchAsync(fetchFormInformationHandler);
}

Here, I’m doing a couple of things. First, I get the API Key and the selected Form ID from the preferences (these are stored elsewhere in the widget). I then build the URL for the call, and then grab the information. You’ll notice I use type=json in the URL so that I get back JSON data.

Yahoo Widgets have a very nice URL object that does most of the heavy lifting for me, and I create a new URL object to do so. As you can see, I’m fetching this information asynchronously, and I define a handler function (fetchFormInformationHandler) that gets called once the information has been retrieved. Here is an excerpt:

function fetchFormInformationHandler(url) {

	var data = url.responseData.parseJSON();

	var formData = data.response;

	// populate the form with the new values
	formName.data = formData.name;
	formSubmissionTotal.data = formData.submissions;
	formViews.data = formData.views;
}

Since I’ve asked the API for JSON data (using type=json in the URL), the first thing I need to do is convert it to a format I can use. In the widget, I’ve included a file called json.js which has a nice function that does this for me. So, I get the response text from the URL object, then immediately convert that from JSON into a Javascript object.

From there, it’s trivial to update the various interface elements with the data I just fetched.

The Dashboard Widget

For the Mac OS X Dashboard widget, I did essentially the same thing. In this case, I needed to use a different method to parse the JSON data. For example, in the file Formstack.js, I have a similar method to the Yahoo Widget called fetchFormInformation(). Unlike the Yahoo Widget, though, I don’t need a handler, this one is all self contained:

function fetchFormInformation() {

	// get the Form ID and the API Key
	var apiKey = $('apiKey').value;
	var formID = $('formSelect').options[$('formSelect').selectedIndex].value;

	var url = 'https://www.formstack.com/api/form';

	// get the information for this form, then change the front of the widget
	new Ajax.Request(url,
	  {
		method:'get',
		parameters: {api_key: apiKey, id: formID, type: 'json'},
		onSuccess: function(transport) {

			// get the JSON data array
			data = transport.responseText.evalJSON();

			// use the response data to populate the widget
			formData = data.response;

			$('formResponses').innerHTML = formData.submissions;
			$('formName').innerHTML = formData.name;

			if (formData.views)
				$('formViews').innerHTML = formData.views;
		},
		onFailure: function(){ alert('Something went wrong...') }
	  });
}

Here, I’m using an Ajax request method to get the form information. Once I have it, I do the same thing as with the Yahoo Widget: I parse the JSON data (with evalJSON()), then update the interface with the information.

Once you get the hang of it, it’s pretty easy. Yahoo and Apple both have excellent documentation and plenty of examples. In addition, you can download the source code (Yahoo Widget source here and Dashboard widget here) of these widgets, crack them open, and try your hand at creating your own.

Have fun, and feel free to add any comments or questions below.