Home > jQuery-State-Widget

jQuery-State-Widget

JQuery-State-Widget is a project mainly written in JavaScript, it's free.

State transitioning widget framework plus a lot of conventions (including jquery template integration and asynchronous loading/transitioning)

See live demo at http://jsfiddle.net/donabrams/txpdk/

SHORT DESCR: This is an html embeddable widget that changes state depending on actions done to a widget.

LONG DESCRIPTION: At the api level, there are stores, states, and the widget: States:

  • Determine what the next state will be asynchronously (synchronous wrapper provided).
  • Can be loaded. By default, this will go through a function stack (either strings assumed to be this-local function name or actually functions) and wrap them so they are called asynchronously in turn. Store:
  • Can be used to asynchronously get/put data. Widget can:
  • Locally get/save data synchronously (stored in the local instance)
  • Use a store to asynchronously get/put data.
  • Do actions, which transition a state or not. By default, while the action is being processed, no further actions can be processed. Using the queueAfterIfChangingState flag can allow actions to be chained but does not stop the current state from loading.
  • Save the current state.

At the implementation level, I have many conventions, all of which can be overridden: States

  • Default function stack is: delayActionSupport, init, loadTemplate, decorateTemplate, onTemplateLoad. By default init, decorateTemplate and onTemplateLoad are blank wrappers around the synchronous _init, _decorateTemplate and _onTemplateLoad functions respectively (if defined).
  • loadTemplate uses the data stored on the widget to decorate a jquery template wrapper ($.udel.template) stored in the widget keyed by this.templateName asynchronously. It also respects the flag this.keepPreviousTemplate which by default is false.
  • decorateTemplate decorates all nodes with the class stateWidgetAction to bind to click to doAction (node.attr('action'). This is useful for buttons since the widget is usually inaccessible from the view.
  • getNextState returns a state provided by the widget keyed by the stateName (keyed by the action in this.action). The reason for this double keying is twofold: limiting what states can be transitioned to and allowing the state selection to be programmatically determined (synchronous only)
  • Use delayAction rather than use a setTimeout if you want to delay an action. This also can be used for autosaves and such. If the action is changed before the delay, the delayedAction will not execute (providing the next state uses delayedActionSupport). Store:
  • preformatter and postformatter used to massage data if provided
  • Choice of ajax method (POST by default) Widget:
  • Intializes stores, templates, and states found in the options and sets them on this.
  • For stores and templates, assumes if only a string is provided it is a url.
  • For states, assumes if only a string is provided, it is the templateName (and additional assumes it is a final state with no transitions).
  • Has storeBaseUrl and templateBaseUrl options (http urls ignore these).
  • Binds saveState to document.onUnload.

TODO:

  • Add an event in addition to the this.changingState flag.

Techniques/:

  • If you want to add to initial data from input fields wrapped by a stateWidget during init, there is a useful js at https://github.com/donabrams/jQuery-Form---Object-Transforms. Include that script and call $(widget).fieldsToObj() in init and you can do whatever you want with the resulting map.
  • State objects are reused. Do not use 'this' to store mutable data in a state. If you need to keep state between states, use widget.[get/save]Data()
  • If you want to change the state during a state load, be sure to use the queueAfterIfChangingState flag!

LICENSE: Although this project's source is open (since it is javascript after all), all of its content is copyright of University of Delaware and we have no policy on what license we can release things under without a lot of calling around. If you really want a license to use this, I'll try and help, but it will likely be low priority-- so good luck. I'd personally recommend extracting the principles from this code and doing something similar.

Donald Abrams [email protected] Programmer/Analyst University of Delaware