Metalanguage to define workflow of HTML application

813 views Asked by At

I'm searching for an way to language independently express the workflow of an HTML application. If a user fills in certain values in a form, another form should be displayed. Further if values are filled in, in this child-forms new parts of these child-forms should be shown.

I want to express relationships between HTML forms, HTML elements in these forms and values of these elements.

Based on database information, like table fields and table relationships, I manage via Doctrine, I generate ExtJS forms.

Now I have to introduce some flow logic into my ExtJS forms, in a way that I don't hard code the application flow with ExtJS (JavaScript) code directly.

I want to generate the appropriate JavaScript code on runtime, based on a predefined configuration file.

For instance:

I have X forms

FORM 1. (displayed on startup)
 |
 |-> FROM 1.1 (only display after values have been inserted into FORM 1.)
 |
 |-> FROM 1.2 (only display after values have been inserted into FROM 1.1)
 |
FROM 2. (display when something inserted into FORM 1.)
 |
 |-> FROM 2.1 (layout and elements of this form depend upon what has been 
     inserted into FROM 1.)
 ....  

Furthermore I only want to display parts of the forms if the user filled something in an input field

FORM 1. (displayed on startup)
 |
 |-> LAYER 1. (only display/activate after field <count> of FROM 1. 
 |   has been filled in)
 |
 |-> LAYER 2. (only display/activate after field <count> of LAYER 1. 
 |   has been filled in)
 |
 ....

Then I want to display forms only if the value the user filled in a form element passes a predefined condition

FORM 1 (displayed on startup)
 |
 |-> FROM 1.1 (only display if field <count> of FROM 1. is greater that 10
 |   count > 10)
 |
 |-> FROM 1.2 (if count < 10 display this form)
 |
 ....  

Last I want, based on values the user inserted in a parent form, set rules for input elements to restrict their input range (possible values)

Here is a example workflow

enter image description here

Is there already a metalanguage to define relationships like that?

What would be your approach to realize something like that?

Regards,

J.

2

There are 2 answers

0
Rob Boerman On BEST ANSWER

What I would do is start from other tools/projects that use a similar setup in another domain and see if you can apply techniques of it to your own domain.

For instance, take a look at Cucumber (http://cukes.info/). Cucumber is a behaviour driven development tool that is aimed at functional testing of an application. It uses a human readable test syntax. Another one is Selenium (http://seleniumhq.org/) in which Interface interactivity is described in a domain specific language.

Hope these two give you some inspiration for your solution, good luck

Rob

0
Jeremy S. On

first of all thanks @Rob for your answer. I finally decided to go with a custom solution.

I therefore looked over some other javascript flow controll implementations

Namely:

Flow
https://github.com/bemson/Flow/wiki/Flow-Use-Cases

Where you can define application flow (javascript function call order) in a predefined syntax.

I especially liked the idea of pre- and post-condition functions (_in and _out) in Flow that are executed before entering a state in the application flow, and exiting a state. Furthermore the idea of a _vars array attached to a specific flow state was kind of interesting.

See https://github.com/bemson/Flow/wiki/Using-Flow#s3-1 for more information.

James Mc Parlane, developed a Finite State Machine (FSM) in JavaScript where he described the application flow in XML rather than in plain JavaScript. I found this a good idea, but what he does is to parse XML on the client side rather than on the server side. Which is a downside for me.

Anyways. He describes states like this

<fsm>
  <states>
    <state name="Start">
      <enter call="initApp();" />
      <exit call="exitApp();" />
      <to>
        <from state="" call="displayStartPage();" />
        <from state="loggedOut" call="showLogoutMessage();displayStartPage();" />
       </to>
    </state>
    <state name="loggedIn">
      <include state="authenticated" />
      <exclude state="loggedOut" />
      <negate state="loggedOut" />
    </state>       
  </states>
</fsm>

He uses the following possible tags

<fsm>       ... the root node of the fsm (I renamed it to better reflect the purpose)
<states>    ... a collection of possible states (a state can have sub-states)
<state>     ... a possible state
<exclude>   ... if a state is active excluded one should be inactive
<include>   ... if a state is active the included state should also be active
<require>   ... should check that a javascript condition is true
<unrequire> ... the negation of <require>
<negate>    ... negate a state if you enter another state
<affirm>    ... make another state active, if entering a specific state
<enter>     ... fire a trigger when state gets active
<exit>      ... fire a trigger when state gets in-active
<from>/<to> ... specify state transitions and actions according to these transitions
<lock>      ... lock state, until state machine is reset

Furthermore some convenience functions could be necessary. To name a view:

testState   ... to test the state of the FSM
negateState ... negate a state 
affirmState ... set a new state and issue according transition events
flipState   ... set state from active to inactive and vice versa 
determine   ... determine current state


See
http://blog.metawrap.com/2008/07/21/javascript-finite-state-machinetheorem-prover/
and
http://blog.metawrap.com/2008/09/25/practical-applications-of-finite-state-machines-in-web-development/
for more information.

Some other solution that I found from Camilo Azula, is kind off a mix between the observer and the command pattern.

http://camiloazula.wordpress.com/2010/10/14/fsm/

Where he uses named constants to define the states and notify observers about state changes.

Michael Schuerig, wrote about this topic but unfortunately his sources are not online any more. Anyways his concept is based on method chaining how you probably know it from jQuery and other JS Frameworks.

Lastly IBM has also a tutorial concentrating on this topic

http://www.ibm.com/developerworks/library/wa-finitemach1/ http://www.ibm.com/developerworks/library/wa-finitemach2/ http://www.ibm.com/developerworks/library/wa-finitemach3/

But to be honest I didn't like it so much.

Right now I'm diving into Spring's Web Flow, which uses Springs expression language, which I find very interesting.

Anyways my final product will be based on a flow definition similar to that of James Mc Parlane, but in contrast to his approach I will parse the XML that defines the application flow on the server side.

Based on this XML I will attach a javascript to each page (each page has its own XML) that contains the according application flow. Because our system is based on ExtJS I will use the

http://docs.sencha.com/ext-js/4-0/#/api/Ext.EventManager-method-addListener

addListener 

function to steer the application flow based on user events.

I hope this will help somebody in the future.

Regards

JS