Sunday, August 28, 2005

State machine implementation

I’ve implemented state machine logic into the web application. One or more state machines can be used within the application – user access state, group states, event states etc – with the current state of each state machine stored within the Session object.
A generic JavaScript function has been added to invoke an action upon a state machine upon the server. The call back result, like nearly all server-side requests, can return updates to one or more elements on the web page.
For example, if the User Access state changes from Anonymous to Authenticated User:
  • The User Login panel will be updated

  • All buttons on the screen that would have prompted the user to login or register will change such that they actually perform their intended function

  • Modules will update to show data etc that was not viewable by unknown users.
Each state machine can have dependent elements, which are notified upon changes to the current state. These dependents will then have the chance to update sections of the website, as suggested above, based upon the change in state.
For example, an Event will have an Event Membership state machine for each user that view the event. By default, when a user first views the Event it will start at the Non-member state. When they join the Event, the state will change to Member. This change will trigger an update upon the Event’s views. The Event must then republish its views to the HtmlResponse object based upon the user’s changed membership state.
The possible changes between states of a state machine are coded within each individual state class. The changes between states are triggered by actions upon the state machine. The state machine first asks the current state if it supports the requested action, e.g. the Login action upon the User Access state machine. If the current state is Anonymous User, and the requested action is Login, then the state will accept the action. The state will then process the action, and return the resulting state (possibly returning itself).
In the initial implementation, the state objects can update the HtmlResponse object themselves. I believe that corresponding UI views should be coded to handle UI changes. For example, there would be a Login View at the top of the webpage. This view will be a dependent of the User Access state machine, but will also be able to invoke actions upon the state machine when the user attempts to login or logout. But, at the UI level, it is just another dependent view that will be triggered when there is a state change.

Tuesday, August 23, 2005

Current development - 2005/8/24

Current development priorities are:
  • List builder interface

  • User management and sessions

  • Inline event modification

  • Create new event in 3 minutes wizard
List builder interface
Currently only small RSS elements can be directly stored into the database via Enterprise Mgr. Even then, there is a 8000 character limit on the size due to the use of varchar as the list storage type.
So, we need to revamp the list storage mechanism to allow:
  • Unlimited list items per list

  • List items can be enabled for viewing or hidden

  • List items can have dynamic number of elements, though within a list the elements are the same (following a schema). Initially all lists follow the RSS 2.0schema, though the Atom schema might be worth implementing too.
We need an inline UI for creating and modifying a list. That is, if an event is being designed and they add a list field, then they can select a current list or create a new list right there and then. The list does not have to exist beforehand. I hate systems that force you to create the list first before using it.
Future: There should also be a list repository – for viewing and modifying your own set of lists, lists you have access to via the events and groups you are a member of, and other public lists.
User management and sessions
Currently I have a TEST_USER = 1 within the code ( At the top of the page is the “Hi Nic Williams | Settings | Log Out” menu that is taken from the LinkedIn website.
  1. Add UI at the top of the page for users to log in, and then after they login show their name etc, using AJAX. The current text can be used for the latter html. Provide a New User link.

  2. Connect this to a User database table, and manually add user Nic Williams as user 1. Change the name and test that it is displaying at the top of the page after login.

  3. Remove all instances of TEST_USER from the code. Provide session support to pass the logged in UserId, or an AnonUserId if the person is not yet logged in.

  4. Add another user to DB manually. Login as one user. Log out and login as the other.

  5. Allow new users to register from any page, at any time. Login should happen within the same page they were already viewing, so they do not need to fear losing track of where they were. Also, email validation automatically updates the website (via a callback).

  6. Logging in or creating new accounts or logging out all change the level of access a user has to different sections of the site. Upon changing the user access level, the site should automatically update. The client function that changes the access level (LogOut, LogIn, SubmitNewAcct) receives a callback that updates the different panels on the screen.

  7. Collect information about new users before they have officially registered and logged in. E.g. email address, location, preferred name, events they are interested in (allowing a guess at their location), groups they are interested in, and allow them to retain this information Amazon.com style once they join.
Inline event modification

  • Create a “button” div and css code. It is a slightly orange background with border, that is lighter orange when cursor over it, and very light orange when clicked. The text is in a <span> tag, this it is possible for the css to hide the text and show a background image in the div instead. Implement this in a utility class such that it calls some client JS upon clicking. The button retains its “clicked” colour until the desired functionality is completed. All references to a “button” use this button.

  • Place an Edit button on the top right corner of an Event/Object (only show if user is Owner/Manager of object)

  • Open a new view of the Object to the left of the Object List.

  • The new view should contain Attribute edit controls instead of the Name and Input/View controls that are normally shown. For example:

  • Each Attribute name should be in a transparent text box thus allowing it to be modified in place.

  • (future) Each Attribute value should allow the user to change the input/value/view combination.

  • Attributes can be deleted (except core attributes like Name, Date, Location) via a Delete button

  • For non-votable values:

  • The value can be changed. (updated as a new DE entry, not an update)

  • Can be changed to “votable” via a “Allow vote” button.

  • For votable values:

  • Can manually close the vote via a “Close vote” button.

  • Can cancel the vote via a “Cancel vote” button.

  • A “Delete Event” button is added to the Object Edit Header (where the “Edit” button might have been).

  • Changes are dynamically shown in the original Object View immediately after they are made by the user. These changes are temporary though, and not committed until the “Accept Changes” button (at the bottom of the Object Edit view) is pressed. The Object Edit view is then closed and the Object View shows the live, committed view of the Object and its attributes.

  • The Object Edit view can be closed and changes undone via the “Cancel” button which is next to the “Accept Changes” button.
Q: should the dynamic view of the Object + its attributes show both the Data Entry/Input view of attributes – e.g. a drop down list; AND the attributes’ view states – e.g. an example of a winning vote or 3.5 stars.
Create new event in 3 minutes wizard
Whilst its nice to be able to change an Event, we want users to be able to have a new event up and running within 3 minutes or faster. This will be aided via templates for standard sets of attributes and attribute styles, and a lazy registration of the user.
Like the Inline Event Modification requirement above, whilst creating the event, a dynamic view of the event is available.
User Access to sections (and fields)
  • There are 3 states of user site access: Anonymous, Unauthenticated User, and Authenticated User.

  • There are 4 basic states of user event access and user group access: Guest, Member, Manager, and Owner.

  • There is also a notion of time-based access for an event: Before Event, During Event and After Event. Some attributes may not be accessible nor visible before an event, such as Post-Event Rating nor Attendance attributes.
Every control on the site can be invisible or visible based upon the user site access and user event/group access status.

Users that are not Authenticated Users will be able to use the site happily and easily without requiring them to log in nor authenticate until the absolutely must.

Opening and collapsing popouts now works!

Opening and collapsing popouts now works! Thanks to yesterday’s revisions of the IAttrInput and IAttrView subclasses to allow them to directly write to the HtmlResponse object:
  • The Popout is uniquely created from an AttrId (thus possibly multiple popouts could be shown on a page and handled easily),

  • The input/view server code knows exactly where to place its HTML (by deriving the InlineAttr999 and PopoutContentAttr999 tags, for an AttrId of 999) and

  • They know how to tell the client to close the popout by passing the PopoutAttr999 tag via the CloseAction table.
Ultimately we want the Popout to be able to Slide out.

Refactored the model of returning HTML to client

Previously, the IAttrInput and IAttrView objects only had a ToHtml() method. The caller of these methods needed to determine which DOM id (e.g. ‘xxx’ is the DOM id of <div id=”xxx”>) should have its HTML replaced with the ToHtml() return value.
This limited the ability of input and view objects to control the changes to the client. It could only return one HTML block and could not request the client “close popout window”.
Now, the HtmlResponse object is passed into these objects, and they can add multiple Content and Close actions. That is, they can tell the client to change the Content of multiple DOM ids, and tell the client to Close other DOM ids (remove the id from the parent).
Also, instead of passing returnIDs between the client and the server, now the appropriate DOM id is calculated/derived from the atttrId.