The Kevin Dolan » javascript http://thekevindolan.com Putting the Kev in Dolan since 2009! Sun, 15 Aug 2010 00:40:56 +0000 en hourly 1 http://wordpress.org/?v=3.0 Nerdy Lifestyle Changes: Google Chrome http://thekevindolan.com/2010/03/google-chrome/ http://thekevindolan.com/2010/03/google-chrome/#comments Thu, 25 Mar 2010 23:24:31 +0000 Kevin http://thekevindolan.com/?p=854 zdnet-google-chrome-logo

I’ve always been a Firefox guy, but for one reason or another, I’ve been more and more tempted to try out Google Chrome.  I nervously gave it a shot, and after a couple of days, changed it to my default browser.So I’m not sure why I was so resistant to making this nerdy lifestyle change… I’ve always loved Google and think that most of their products are just amazing.  Most people would agree, I think.

Perhaps the biggest thing holding me back was the Firefox extension, Firebug.  I understand this is a common sentiment, but Google’s built-in developer tools are similar, and even have some more powerful unique features of its own.

But there are two reasons I mainly made the switch:

1) Screen Real Estate: Simple removing all the bulk of typical web browsers gives chrome a light, feel to it.  It puts a far-greater focus on the website itself.  For heavy web-apps, this means a more natural application experience, and in general, just provides a greater amount of content that can fit on the screen at one time.

2) JavaScript Execution Speed: It’s just faster.  It might not be as fast as Safari, but it’s faster than Firefox, and I like speed.

And here’s a little something I just discovered!  There’s a feature in most browsers that allows you to warn users when they are about to leave your website.  This can be useful for sites such as Google Docs, but also can be used by scammy sites to confuse their users into staying longer.

I’ve always had a problem with those popups, because the options of what to click are OK and CANCEL.  It’s not immediately obvious which one you click to do what, so when I discovered that Chrome chose different buttons for this popup, I was very pleased.  Why didn’t anybody else think of this before?

Firefox popup:

Screenshot-2

Chrome Popup:

Screenshot-1

]]>
http://thekevindolan.com/2010/03/google-chrome/feed/ 0
OrganizeIt! Phase Two http://thekevindolan.com/2009/08/organizeit-phase-two/ http://thekevindolan.com/2009/08/organizeit-phase-two/#comments Fri, 14 Aug 2009 06:44:49 +0000 Kevin http://thekevindolan.com/?p=465 blueprint

Back to working on the example application for the State Model, OrganizeIt!  For this phase, we will be preparing to actually write the UI code, by handling the layout.

Layout Work

Naturally, I wanted to start by creating the images.  I went ahead and chose 8 colors for the labels, and made a big and small .png for each color.  Also did the logo, the add label button, and the expand/collapse buttons.  I stole the favorite/unfavorite icon from my CourseTopia work.  This layout is incredibly simple, so there’s not much in terms of graphics other than these.

logo

I think those are all we will need.

The next step, I suppose, would be to actually do a sample layout in HTML/CSS, so that we can get the styling right… About an hour later: the layout.

There we have it.  For the next step, I will be taking this layout and recreating it mostly on the fly, using uiComponents.

———————————————–

NOTE FROM THE FUTURE:

As of February 7, 2010 (actually much earlier), I have no intention of taking this project any further.

]]>
http://thekevindolan.com/2009/08/organizeit-phase-two/feed/ 1
State Model Test: OrganizeIt! Planning Stage http://thekevindolan.com/2009/08/state-model-test/ http://thekevindolan.com/2009/08/state-model-test/#comments Fri, 07 Aug 2009 17:50:07 +0000 Kevin http://thekevindolan.com/?p=451 mini-file-cabinet

This is the first test of the State Model for User Interface Development.  We will be creating a simple application, called OrganizeIt!

Again, this post is part of the State Model Development series.

Abstract

The basic idea of the application will be similar to a problem encountered working on CouseTopia.  Consider the idea of there are three different classes of items, say Food, Movies, and Bands.

You will be able to select which class of items you want to view, and then a list will appear showing you just that.  For each item in the list, you will be able to expand it and get some more information.

There will also a labeling system and a favorites system.  For any item in any list, you will be able to label it with any of your custom-created labels.

For this test, the server will only be maintaining the lit of items and their descriptions.  Example requests will be sent to the server, but will not actually cause anything to stick.  To test error handling however, occasional random errors will be sent back!

This test will force me to examine certain issues regarding the State Model.  It will allow me to recognize certain things that need changed, things that I forgot (such as a navigation module, and undos!), and will be a test of whether or not this is a viable model for creating UI’s.

Stage 1: Planning

layout

I threw together the mock layout above in Illustrator real quick to show how I want everything to be laid out.  It’s all a really simple interface, with no bells-and-whistles.  Doing a mock like this might be beneficial for you. I generally always do them, at least on paper, before I even begin planning in detail.  Individual methods may vary.

Components

The first part of State Model planning is to consider what uiComponents will be needed.  It’s okay if you forget some at this point, because the State Model is designed for modularity.  It’s easy to come back and add more later, as you see fit.  For this application, I will start with:

Navigation : the navigation in the top-right.

NavItem : the individual items in the navigation, which can be selected.

LabelList : the list of all available labels

Label : an individual label to appear in the LabelList

TabSet : a set of tabs to display the different categories/labels on a page.

Tab : an individual tab, which can be selected.

ResultList : a list of results of items for a given search (or more specifically, category choice/label/favorites)

ResultItem : a single row in the ResultList, might contain more information

Navigations

One of the things I realized I forgot to create is the navigation module.  So I went ahead and put together a simple place-holder module navigation.js.  This module doesn’t handle the back button the way I’d like it to eventually, but that’s an eventual improvement.  When I develop this module further, I will explain it further.

There will only be three navigations involved in the OrganizeIt application, View Items, View Labels, and View Favorites.  I considered whether or not selecting a certain category or label should be a navigation or an action, and decided it should be an action.  Someone else might have wanted to call it a navigation, but that’s just my design decision.  What these navigations show is pretty simple.

Whenever a navigation is activated, it simply changes from black to red.  That’s all.

Actions

There will be several available actions:

addLabel : add a new label.  Show a text box requesting a name, set a color.  No server call.

doAddLabel : confirm label creation.  Send request to server to notify of label creation.

removeLabel : delete a label.  Not in mock layout, so we need to find some way to display this.  Display confirmation box.  No server call.

doRemoveLabel : actually delete the label. Send request to server to notify.

labelItem : label an item with any given label.  Send request to server to notify.

unlabelItem : remove an item’s label.  Send request to server to notify.

favorite : mark an item as a favorite.  Send request to server to notify.

unfavorite : remove favorite mark.  Send request to server to notify.

query : send a query to the server for a new list of items.

expand : get more info about a given item.

Data Model

There will be a piece of data storing the list of labels, by some incremental id.

For each label, there will be a piece of data, storing information like name, color, and a list of item ids for which the label applies.

Similarly, there will be a piece of data storing the item ids that have been favorited.

For each item category query, we can cache the result list with a piece of data storing the query results.

For each item with a given id, we can store all kinds of info like name, moreInfo, labels, and inFavorites.

Issues to Deal With:

It’s always good to consider some possible issues.  Figuring out how to deal with them, when you get there, is up to you.

What if someone deletes a label while they’re viewing it?

What if someone removes a label/favorite while viewing the labels/favorites?

Possible Modification to the State Model

After this excercise, I have recognized that some changes may need to be made to the state model.

  1. Navigation back button support should be implemented.
  2. A lot of actions had two parts, maybe this should all be implemented in the action object.  For instance, some kind of a confirm call-back.
  3. I should work on some standardized vocabulary for discussing the plans.  For instance, Data Model was very confusing.

That’s about it for the planning phase.  Stay tuned for the next step!

]]>
http://thekevindolan.com/2009/08/state-model-test/feed/ 1
UI Components and Actions in the State Model http://thekevindolan.com/2009/08/ui-components-and-actions-in-the-state-model/ http://thekevindolan.com/2009/08/ui-components-and-actions-in-the-state-model/#comments Fri, 07 Aug 2009 16:33:57 +0000 Kevin http://thekevindolan.com/?p=441 interrelated components

So I just got back home to Ithaca a couple days ago and have been working hard on CourseTopia.  I finally had a chance this morning to get back to the State Model.  I’ve written the final two example files for the state model, the uiComponent and the action.

Again, this post is part of the State Model Development series.

The example source files for this part can be found here: uiComponent.js and action.js.

These two parts of the State Model, I feel, might not be as well developed as the other ones, so they will likely change more drastically when I do the practice run.  I plan on creating a sample application today or tomorrow to test the State Model, and we’ll see what needs changed during/after production.

I’ll start by discussing the action paradigm.

An action will generally be anything that can occur.  In the example source file, there’s barely any code to it at all.  It’s really just a holder for a couple different functions.

There are three difference callbacks for an action:

commit(params) – This function takes an object as parameters, and performs the initial setup of the action.  Generally, it would be possible for this to be the only callback set, as the uiComponents created through commit could handle automatically updating to reflect data changes after a response has been made.

onSuccess(params) – However, if there is some part of an action you’d like to perform after a call has been made successfully, this could be managed by the onSuccess function.  This will be called after a response has been received for the action and no errors occurred.

onError(params) – This function will receive a set of parameters and an array of error objects.  This should be set up for any action that might receive an error from the server, and should be able to effectively handle any errors.

That really covers actions.  I think there will likely be some major changes in the next revision, after the test-run.

The uiComponent paradigm is only marginally more complicated.

uiComponents objects are instantiated on document ready.  They actually refer to types of components than individual components.  For instance, you might create a uiComponent for Label, but not Label Id #543.  After you have instantiated the various types of uiComponents, you can then make calls to uiComponent.create(…) to make specific components.

There are up to four parameters passed into the uiComponent constructor, in record form:

dataManager : This is simply a reference to the data manager to be used.

initialize(id, params) : This callback function is called to create a component, with a given id and parameters.  The id refers to an internal identifier for the component, but for consistency, you might want to make the top-level element of the component have the same id.

The initialize(…) function should take advantage of uiComponent.data(name, field) for getting data, because this automatically adds to the list of dependencies, and throws an exception if data is not set, which can be used to automatically call not_ready.

Also, to insert an element into the DOM, you can also take advantage of the uiComponent.append function(element, target), which will append the element to the target.  If the ID of the element already exists, that object will be replaced.  This can be used to make writing an update method unnecessary, for code simplicity or rapid prototyping.

onUpdate(id, params) : This callback function is used to update the component to reflect some data change.  If it is not set, initialize will be called.  This should take advantage of a knowledge of the component, using document.getElementById(…)’s and setting values rather than recreating DOM elements.

notReady (id, params) : This callback function is called AFTER either update or initialize, if any piece of data was not yet defined.  This can be used to place some kind of a not-ready or loading notification in a component.

This is really about it.  Public uiComponent methods are .create(id, params) which calls initialize, and optionally also notReady, and .update(id, params) which calls the onUpdate(..) and optionally also notReady.

At this point, it should all be a little blurry, but I think we’ll all have a better understanding after a couple of practice runs.

]]>
http://thekevindolan.com/2009/08/ui-components-and-actions-in-the-state-model/feed/ 1
Data Management in the State Model http://thekevindolan.com/2009/08/data-management/ http://thekevindolan.com/2009/08/data-management/#comments Mon, 03 Aug 2009 12:07:38 +0000 Kevin http://thekevindolan.com/?p=400 rubix

Back to the State Model, I have thought out and implemented the data management module.

Again, this post is part of the State Model Development series.

Data management is really at the heart of the State Model.  The State Model is all about maintaining a data state, and notifying the user interface of any changes to the data, so this particular module is fairly important… though that’s not to say any of the others are less important!

I have released a sample implementation of dataManager.js.  Same deal as last time, I haven’t tested it at all.  There are likely tons of bugs, even minor syntax errors!  I am just getting a skeletal implementation of everything out there so that I can test it as a whole, which I am aware is a terrible way to do things.  I have also made a couple updates to queue.js, for some bug fixes and to reflect the dataManager implementation.

Also, these files will require JSON and util.js.

The data management model is actually rather simple.  The difficult part was coming up with a solid plan for sending updates.

Within the dataManager object, all the named data fields is stored in an object called data.

The data objet’s fields are actually the named fields that this data object is managing.  It’s my understanding that objects in javascript are implemented as hashtables, so this actually seems like the most efficient way to do this.

Each of the named fields is itself an object, with two fields, dependencies- representing the list of all ui elements that depend on this object and value- yet another object with the actual fields of the data.  This means that data managed by dataManager should not be a raw piece of data, but rather named fields of data.

For example, if we have a data manager that is keeping track of only three pieces of information, the number of times I started my car today, ‘numStarts’, and some information about my computer, ‘computer’, and a list of my favorite hobbies ‘hobbies’,  the data object might look something like this:

data = {
 
  numStarts : {
    count : 5
  },
 
  computer : {
    cores : 2,
    speedGHZ : 1.86,
    memoryGB : 2.96,
    name : 'Lisa',
    monitors : 1
  },
 
  hobbies : {
    list : ['hunting', 'fishing', 'kayaking', 'recreational sandwich eating']
  }
 
}

It might seem at first a little unnecessary, and I did consider alternatives, but in the end I thought this was the best way to go.  Your own implementation of the State Model may behave differently, if you think that’s not reasonable.

We will now discuss updates.  Updates can be made to the data by a call to the public method, update(name, updates, [wait]).  Name is the name of the piece of data being referenced, and updates is an object containing one or more updateRequests.  Wait is an optional value.  If wait is set to true, ui components will not be notified of any changes until the next call to notifyDependencies();.

Wait was implemented so that when the queueManager is processing a series of updates, the same piece of data may get updated several times.  It doesn’t make sense to re-render the same UI components until the data is actually a current reflection of the system state.  It generally should not be used in the application code, but I suppose it may be useful.

Each field in the updates object should take one of the following forms:

fieldname : value
fieldname : {method: updateMethod.set, value : value}
fieldname : {method: updateMethod.append, value : value}
fieldname : {method: updateMethod.remove, value : value}
fieldname : {method: updateMethod.increment, amount : value}

The first two forms are actually the same thing: set a field to something else. For instance, if I wanted to change my computers name to Sammie and set up dual monitors, I might send a request like:

dataManager.update('computer', {
  name : 'Sammie',
  monitors  :  {method : updateMethod.set, value : 2}
}

The second two require the field to be an array.  If the field is not set, it will become an array.  If it is set, and it is not an array, an exception will be thrown.  If I recently discovered painting I make send a request like:

dataManager.update('hobbies', {
  list  :  {method : updateMethod.append, value : 'painting'}
}

If on the other hand, I joined PETA, I might send:

dataManager.update('hobbies', {
  list  :  {method : updateMethod.remove, value : 'hunting'}
}

Note that remove will actually remove all elements from the array equal to certain value.  I am considering other ways to handle this so that it is not necessary to send the entire object to have it removed.  One reasonable method would be to pass some type of a filter function or maybe an object to check fields against.  Not quite sure yet, but this is one place where I will be updating the code before a final release.

The last form is useful for updating a numeric value without having to access it.  You can increment by any value, positive or negative.  So if I go back in time and start my car one less time today, I might send

dataManager.update( 'carStarts',
  { count  :  {method : updateMethod.increment, amount : -1}
}

These updates can be sent by the application using the update method directly, but this actually brings me to how the server-side code should be sending data updates.  The method is very similar.  Keep in mind that the updateMethod values are actually enums with integer equivalents that should be set server-side as well as follows (set : 0, append : 1, remove : 2, increment : 3).  An example response from the server to do some of the things we mentioned above might look something like:

[
  {
    name : 'carStarts',
    update : { count  :  {method : updateMethod.increment, amount : -1} }
  },
 
  {
    name : 'computer',
    update : {
      name : 'Sammie',
      monitors  :  {method : updateMethod.set, value : 2}
    }
  }
]

That basically covers setting values.  Anytime a value is upated without the wait parameter set, the changes will automatically be propogated to the appropriate UI components, forcing the UI to be an accurate reflection of the system state.

Getting values from the data manager is actually more simple.

This is accomplished by the dataManager.get(name, [src]) .  Name is the named field being requested, and src is an optional parameter, representing the UI component making the call.  If the src parameter is set, the dependencies of this piece of data will be updated to include it.

At this particular moment, source is implemented as an action object paired with a parameters object.  The dependencies list is an array containing these pairs.  I think this is the wrong way to do this, and when I implement uiComponent, I might create some uiComponent id by which to reference it.  This would make things a bit easier, and would also improve performance.  Expect this to change.

An example call, if I wanted to know what my computer’s name was, might be like:

computer = dataManager.get('computer');
name = computer.name;

Well that’s about everything I have to say about data manager.  Love to hear what anyone thinks.  Email me.

]]>
http://thekevindolan.com/2009/08/data-management/feed/ 1
Queueing in the State Model http://thekevindolan.com/2009/08/queueing-state-model/ http://thekevindolan.com/2009/08/queueing-state-model/#comments Sun, 02 Aug 2009 09:29:24 +0000 Kevin http://thekevindolan.com/?p=382 url

I recently wrote an article about Abstracting Data in JavaScript.  While that post was really just a vague collection of ideas, I have since had some time to formalize the idea a little more.  For the time being, I will be referring to this UI paradigm as the State Model of User Interface Development.  This article discusses the queueing system in the State Model.

I will be releasing a series of articles regarding my development of this theory from the ground up, and I will be compiling it in one place on The Kevin Dolan.  After I have formalized the theory into some coherent framework, I will publish it on its own domain somewhere, so that it can be made most publicly available.

The current project page can be found here.

With past projects, each request usually consists of a call to some server-side script, along with parameters, and a callback function.  Whenever a call is being made, and another is requested, it waits in the queue until the request is done.  With this technique, a new request needs to be made for every single action.  There is also no polling to get real-time data updates.  The only time a connection is made to the server is when a request is made.

Enter State Model Queueing.  State model queueing has the ability to queue requests in a reasonable way, chaining multiple requests if more than one exists in the queue.  There is also an idea of priority, which can be a clever efficiency boost, reducing the total number of unnecesary calls being made.

To see my example implementation of this mechanism, refer to queue.js v0.1.  Please note that this script is virtually untested, and has several gaps due to the fact that I have not formalized all other parts of this model just yet.

The flowchart below summarizes the State Model queue system:

queue

The best way to understand how this works, is to consider the three possible entrance points, and examine what can happen from each.

Let us begin with some of the terminology I will use.  I have adopted some words I’ve seen flaoting around in my CS days, though I may not be using them correctly.  I apologize if that is the case, but this is what I mean when I use these terms.

server request is a call made to the server-side file that mediates all data transfer.

An action request is sent to the queue for an action or navigation to occur.

nonImmediate action request is an action request that does not immediately need a response, and can wait until the next call to the server.  An example of this might be classifying something into a group.  It is easy enough to update the UI dataManager without receiving a response from the server for something like this.  The call to the server simply notifies that this has occurred.

priority action request is an action that does immediately need a response.  An example of this would be a request for some content, which the user expects to see quickly.

Data polling refers to the act of periodically sending requests to the server, even when no server requests are being made, to check for any possible data updates.

The dataManager object refers to the object which maintains the state of the UI’s data at all times, as discussed informally in the last article.

Initialization

The queue must first be initialized.  Technically, it is possible to instantiate multiple queues, but keep in mind that internet explorer only allows 2 simultaneous instances of xmlHTTP.

The queue is initialized, in the example script, with 3 parameters, call, dataManager, and pollTimeout.

The call parameter is a string representing the URL of the server-side file to manage all communications. We will discuss this portion of the code in a bit more detail, later.

The dataManager parameter is a reference to the dataManager object that will be updated by calls made through this queue.  The actual implementation of the dataManager is the most currently undeveloped portion of this project, so most parts of code in queue.js that would reference the dataManager have not yet been written.

The pollTimeout is an optional parameter, representing the time between idle calls when polling the server for data.  If pollTimeout is not set, or is false, there will be no polling.  Only when a priority request (more on this later) is sent will a server request be made.

When we initialize the queue, we set all the appropriate state variables, and then if the pollTimeout is set, a timeout is set for a call to another function, the poll function.  The poll function checks if the xmlHTTP object is busy, and if it is not, sends a request to the server whether or not there is anything in the queue.

Adding Requests

Making action requests to the queue is accomplished by the public queue.addRequest(..) method, which takes three arguments, request, params and optionally nonImmediate.

The request parameter is a reference to an action or navigation object, as discuess briefly in the last article.  This object maintains what type of action is being performed.

The params is basically any object that can be encoded in a JSON string that represents the specifics of the action being performed.  It could even be null.

If nonImmediate is true, the request will be added to the queue and wait for the next call to the server.  If it is false, or undefined, it will send the request, along with the rest of the queue, as soon as the xmlHTTP object is no longer busy.

When an aciton request is received, the queue automatically adds it to the end of the queue.  If the action request is a priority request and the xmlHTTP object is not busy, the server request will be sent.

The Server Request

So far, I’ve vaguely mentioned what occurs in the server request.  It’s rather simple, actually.

When the server request is made, the queue may have none, one, or several requests lined up.  A call is made to the server-side call file with a single post parameter, param.  This post parameter contains a JSON encoded string representing the time of the last update, and an array of all requests in the queue.

It is then the responsibility of the server-side file to manage and process all requests.  Requests do not expect to receive any input directly.  Rather, the server-side file simply writes a JSON encoded string representing all data that was requested.  It also has the ability to notify actions of failures of any kind, so that they can be handled appropriately.  Errors can include actual errors in processing, but should also be used to validate any parameters sent to the server.

Processing the Response

The response from the server request is a JSON encoded string representing an array of several objects.  The objects are either error notifications, which specify a request identifier and error-specific information, or data-update commands, which ask data in the dataManager to be updated.  As data in the dataManager is updated, UI elements automatically begin responding to the data changes, according to their dependencies.

Data fields are updated first, and the queue keeps track of which requests had errors, and which ones did not.  Currently, the queue can only handle a single error for each call, but it seems reasonable to expect that more than one error could be thrown.  So this should be updated in version 0.2.

After all data updates have been made, the action request objects are notified, in the order they were sent, either that they were performed successfully, in which case any necessary updates can be made, or that something went wrong, in which case, they should be able to respond.

Once the response has been processed, the queue then checks if there are any priority action requests waiting in the queue.  If there are, a new server request is sent.  Otherwise, a call to the poll timeout function mentioned in the first section is made.

That’s basically the jist of State Model Queueing… thoughts?

]]>
http://thekevindolan.com/2009/08/queueing-state-model/feed/ 1
Facebook Mass Friend Selector Greasemonkey Script http://thekevindolan.com/2009/08/facebook-mass/ http://thekevindolan.com/2009/08/facebook-mass/#comments Sat, 01 Aug 2009 23:38:15 +0000 Kevin http://thekevindolan.com/?p=341 spam

You probably remember my first experimentation with Greasemonkey, my Follow All on Page Script for Twitter. Well  I decided to approach another common problem with Greasemonkey… introducing my script to automatically select 200 of your friends at a time in Facebook.

Whenever we throw parties in Ithaca, it ends up being somebody’s (usually my) job to mass invite all of their friends on Facebook.  Because there is no select all button, this means manually clicking each and every name, which can get quite boring.

Also, you can only invite 200 people at a time!

What this script does is add a feature to allow you to select 200 friends at a time, automatically.  You can use it on any Facebook page with a friend selector for activities like sending messages, or whatever.  It’s incredibly useful.

I have to say, I am a huge fan of Greasemonkey.  I’m not going to show you how to install it again; for instructions, look at the Twitter script, or UserScripts.org.

Again, same agreement as last time, I will not support this script, but you are welcome to use it.  It works for me.

Instructions:

Make sure you have Greasemonkey installed.

Install my Facebook Mass Friend Selector Script.

Now whenever you are on Facebook, the MFS window will appear in the top left, as seen below:

step1

Whenever you find yourself on a page with a Friend Selector box, click the MFS window and voila! it will expand, as shown:

step2

You then have the option of clicking one of the numbered groups.  Clicking group #2 for instance, is identical to clicking friends 200-399, in a matter of a few seconds!  It will even toggle, so if you accidentally click Group #1 when you wanted Group #3, you can click Group #1 again to unselect the group!

Again, your welcome.

]]>
http://thekevindolan.com/2009/08/facebook-mass/feed/ 13
Abstracting Data in JavaScript http://thekevindolan.com/2009/08/abstracting-data-in-javascript/ http://thekevindolan.com/2009/08/abstracting-data-in-javascript/#comments Sat, 01 Aug 2009 07:22:11 +0000 Kevin http://thekevindolan.com/?p=329 data-center-t01

I have recently been considering developing a framework to radically simplify the development of user-interfaces.  Warning: This post is long and nerdy.  You probably won’t want to read it.  There are no pictures.

The History

I’ve been working as lead UI developer for CourseTopia for about two years now.  It has been by-far the largest and most involved project I have ever worked on.  I am also planning on developing several simple web apps over the next year as portfolio work to be used in internship-seeking.

As such, it seems reasonable to come up with a solid planning process for creating web apps.  Creating CourseTopia was a great learning experience, but going into it, I had no idea exactly what kind of work user interfaces can be.

We toyed around with implementing a system like this for CourseTopia a while ago, but ultimately decided to continue working on the site as we were.  Someday, the site may be rewritten with this technique, but we are unsure.

I am going to describe the essential design behind this application creation framework.  The actual code necessary to write the framework would be minimal.  It’s really more of a way to think about user interface development.  Please note that this has not been worked out in its entirety, so suggested modifications are welcomed.

The Problem

The main problem that I faced time and time again, is a lack of abstraction in my code.  It seems to be a process of figuring out exactly what parts of the interface need to be modified when some action occurs.  This is also a source of a great number of bugs in the code, which may or may not show themselves for a long time after the initial code has been written.

User interfaces, in general, are a way to display and interact with data.  The basic principle behind this paradigm is abstracting away data dependencies so that the user interface is, at all times, a current reflection of the data state itself.

Traditionally, the way we handled this with CourseTopia was to say, I want to perform an action, from which I expect a certain response.  When I perform this action, I will make some immediate changes to the page, and then when I get the response, I will update everything in the UI that could possibly be affected.

The problem with this, is that it is very difficult to conceptually organize all the dependencies of a certain change in data.  This makes performing simple actions incredibly difficult, while at the same time a source of many bugs which are not immediately discoverable.

Introducing State

So to solve this problem, we introduce the idea of data state.  It is no radical new programming concept.  State is merely the current value of all pieces of information in existence in the system.

The main idea behind this paradigm is abstracting away the work of making the interface a real-time reflection of the state of the system.

For this we can create a class of objects, called dataObjects.  dataObjects would be responsible for maintaining some type of data.  The data could be anything from a true/false value, to a big chunk of text, to a list of items.

This data would also maintain which obects depended on it, so that when any change was made to the data, those objects could be updated.

Data inside the object could be accessed by some convenient method, for now .get().  They could also be modified by the .set(obj) method.  It’s all fairly intuitive, but behind the scenes, a call to .set(obj) is making a call to all things that depend on this piece of data.

I have also considered creating some type of templating system for these dataObject, so that you can expect certain pieces of information to be included.  On the other hand, this might not be necessary.  Another possible consideration is the situation where one piece of data might depend on another.  In that case, there might need to be some kind of an update() method…

The UI Elements

In general, user interfaces are composed of several high-level components.  The components can very easily by hierarchical, a component being made of several other smaller components.  For this reason, we introduce the concept of the uiComponent.

uiComponents are things that might be updated by a change in data.  They are generated entirely on the fly, so they are intended to be used for things that a search-engine might not necessarily be interested in crawling.

I am currently thinking that the actual code used to create uiComponents should be the responsibility of the UI developers, according to some interface.

I think the only real necessary methods would be render() and update().  render() would be used to render the component initially, building DOM elements on the fly according to however the developer chooses.  update(), on the other hand, would be use to make changes to the data.

It is reasonable not to force developers to declare an update() method, if the act of updating is not necessarily different than the initial render.

It is also necessary to somehow collect a list of dependencies, which dataObjects this object depends on.  This list might need to be declared in the constructor, or perhaps could even be built dynamically as pieces of data are used.  That would be ideal.  Either way, the dataObjects that this component depends on should be notified somehow so that they can update when necessary.  Perhaps this could be done by adding a parameter to the dataObject.get() method…

I have also considered the performance advantages of building the dependency list as not just a list of strings, but a list of string, function fields.  The idea would be that some pieces of data which get regularly updated might have some more specific way of updating that don’t require a potentially expensive call to the update() method.  On the other hand, however, this could also be accomplished by creating heirarchies better.

An alternative to the interface-type design would be to create anclass uiComponent that accepts render/update functions as arguments for its constructor, and then have some method to place them into the DOM somewhere.  This might make dynamic updates a little easier.

I am unsure as to what should necessarily be done for certain components which may appear several times on a page.  It might be reasonable to add a parameter, context, to the constructor method.  I am unsure at this point.  To clarify, this paradigm is still extremely early in development, more just ideas.

On Actions

If we could also abstract away the actions people can perform, it might make handling such things as queueing and error-handling a lot easier.  For instance, we might create a uiAction interface that can handle whatever occurs.

Abstracting out the things that occur in every action: we make some changes right away, this could be a parameter called doNow. This may be all that occurs, if no server communication is necessary.  However, other actions may require a server call, so a call field is necessary, along with certain post parameters.  Once a response from the server is received, there may be certain things that need changed, so a success field could be in order.  Also, in the event of some type of failure, network or otherwise, there might need to be some handleError(e) method that accepts an error object and decides what to do with it to notify the user.

These actions could be chained in such a way that every time a call is made to the server, it sends a list of all actions that need to occur.  The server will then process the actions, and return the results all at once.

Another nice feature would be to add an optional undo function to handle the ability to undo the action, in a reasonable way.

Navigation

Another nice useful interface would be a navigation interface, to control navigation items that might be handled by the back/forward button.  I have not looked into exactly how this will work, but navigation objects should only be required to have a navigate() method that simply performs whatever navigation is necessary, in a timelesss way, so that it can easily be called by a browser’s back button request.

Communication

This brings me to communication.  There is to be some single file which the system makes calls to.  Any call to the server could theoretically contain several requests for action, so this server-side file acts as an index, pointing to other files to process the requests.  Once all requests have been handled, all that will be returned is a list of dataObject names, along with associated values, serialized in some reasonable way.  Also, any request failures would also be returned so that the handleError method could respond appropritately.

To Summarize

class dataObject : used to store a piece of information, which can be accessed by the interface

  • new dataObject(name, data) : construct a new data object
    • name : the name of the data object, must be unique or else an exception can be thrown
    • data : the piece of information being stored
  • public get() : retrieve whatever data is in this object
  • public set(data) : set the data stored in this object, update all dependencies
    • data : the value to be stored
  • private dependencies : a list of all items that need updated when this data changes

interface uiComponent : used to create user interface components

  • private dependencies : list of strings representing dataObjects that this component depends on
  • public render() : initially place this object somewhere in the DOM
  • public update() : update the DOM to reflect current data, if different from render

interface action : used to perform some type of action in a standardized way

  • public doNow(): perform whatever parts of the action can be done immediately
  • public call : what call to be made
  • public parameters : what parameters to be passed along with the call
  • public success() : what to do if the call is made successfully; should not include updates to data as this will be handled automatically
  • public handleError() : how to handle any errors that might come about
  • public undo() : how to undo this action

interface navigation : used to navigate from one area to another, that would be reasonable to integrate with the back button

  • public navigate() : used to access a particular part of the application

That about covers it.  I will keep you posted as to my development of this interface development plan, whether I decide to write code for it or not.

  • name : the name to be used by this piece of data, must be unique
  • data : the information stored in the object
]]>
http://thekevindolan.com/2009/08/abstracting-data-in-javascript/feed/ 5
Twitter Follow All On Page Greasemonkey Script http://thekevindolan.com/2009/07/follow-all-on-page/ http://thekevindolan.com/2009/07/follow-all-on-page/#comments Wed, 29 Jul 2009 20:58:24 +0000 Kevin http://thekevindolan.com/?p=314 twitter_bird_follow_me

Once again, I’d just like to begin by saying you’re welcome.  I’ve recently been experiencing this odd phenomenon– a sudden burst of productivity beginning around 4:00 AM and ending around 6:30.  So last night, I put together this Greasemonkey Script to follow all unfollowed users on a twitter page.

About this Script

If you don’t already know, Greasemonkey is an addon to Firefox that allows you to run little pieces of code called user scripts inside other websites to customize your experience.  You can find thousands of such user scripts at UserScripts.org.

This is the first Greasemonkey script I’ve written, though I’m quite familiar with JavaScript, so there was no learning curve whatsoever.  The reason I wrote the script was gaining a marketable position on Twitter requires connections, and at a fundamental level, those connections involve getting followers.

One of the best way to gain followers is to follow people somehow already connected to you.  There is a higher chance that these users will follow you back.  Compared to the paid services out there that add thousands of random followers, manually following quality users is still the best way, but it’s tedious.

This script is a middle-ground in the world of auto-twittermation?  Simply install the script, and then everytime you visit someones following/followers list, a box will pop up asking if you want to add all users on the page.  Click it, and your will shall be done.

Quick Instructions for the Impatient

If you know what you’re doing, and you already have Greasemonkey installed, here’s the userscript.

Detailed Instructions for the Incompitent

If you don’t already have Firefox, you’re an idiot.  Download and install.

step1

Once installed, add the Greasemonkey plugin.

step2

Come back here, and click on the userscript link.

When the Greasemonkey box pops up, use all the default settings.

step4

The script is now ready to use.  Go to twitter and visit someone’s following/follower list.

step5

When on a page, if there’s anyone to follow, a bar will pop out along the bottom, allowing you to do so.

step6

My Warning

I wrote this script in about 2.5 hours. It works with twitter the way it is now, but if they ever change, it’s likely it will not.  I mostly wrote it to help myself out, but if you want to use it, that’s cool.  I don’t plan on supporting it all.  Feel free to email me and tell me you like it, but I won’t answer any questions about it.  I made the directions as easy as possible, so at this point, there is nothing I can do to help you.

]]>
http://thekevindolan.com/2009/07/follow-all-on-page/feed/ 12
Thank you, Six Revisions http://thekevindolan.com/2009/07/thank-you-six-revisions/ http://thekevindolan.com/2009/07/thank-you-six-revisions/#comments Thu, 02 Jul 2009 19:51:37 +0000 Kevin http://thekevindolan.com/?p=72 sixer

As you may remember from my blog entry a couple days ago, I recently created a javascript animation library.  In the first day, it received over 2,000 visitors, thanks to StumbleUpon.  After that, it was already on the first page of the google results for ‘javascript animation ‘library’ and the ads were doing quite well.  Now, to put the cherry on this delicious sunday, someone at Six Revisions didn’t do their homework, and used the google search results to write a top ten list!

That’s right, after the initial wave of stumbleupon traffic subsided, I noticed from my Google Analytics that I was receiving a significant amount of referral traffic from this page.  I investigated to find that my brand-new virtually unused javascript library was featured second in the list of “10 Impressive  JavaScript Animation Frameworks.”  Holy crap!

Even Dan the weatherman felt this was big enough to twitter me with the words “Epic Win.”

It turns out, whoever wrote this article really didn’t do too much research.  Though my framework is definitely good, it is by no means ready to be second best material.  There are still so many bugs I need to work out before it’s this good, but I certainly appreciate the traffic!

This is what they had to say about my library

Created by web developer Kevin Dolan, jsAnim is a JavaScript animation framework for creating high-impact and slick animation sequences for web interfaces. Crafted with standards and best practices in mind, jsAnim allows you to create stunning animation effects without sacrificing web accessibility of your web projects.

Sounds nice, but oddly familiar…  And nicely they also linked to my DesignByDolan site, which has also been receiving a lot of traffic thanks to this article.  This is really doing wonderful for me.

Though, it’s not all fun and games.  I was reading through the comments, and I noticed that not all SR users were satisfied.  Dan says:

This list is bizarre. Glimmer is not a framework, it’s a GUI tool for implementing jQuery effects.

Scripty2 reference doesn’t make note that it is the second version of Scriptaculous.

Has the author even tried these tools? Or are they just randomly posting crap?

I’m leaning towards the latter, Dan.  But in response to this negativity, Justin responds in twitter fasion:

@Dan… Chill man, no one likes you

Probably true, though I think Dan is the only one to see the truth here…

All that being covered, some SEO news:

The Kevin Dolan is now on the first page for google searches of ‘kevin dolan’.  It is on the bottom, but still, we are moving up in strides.  Also, DesignByDolan is on the third page…

If you search for ‘javascript animation library’, jsAnim is not only on the first page, it is the fourth result, beating out $fx, the library which I have found to be really just awesome.  Though, I’m not going to link to it, to help my own selfish SEO whims.

]]>
http://thekevindolan.com/2009/07/thank-you-six-revisions/feed/ 0