SlideShare a Scribd company logo
RAD CRUD
Rapid development of form-based applications.




                      1
Where did we stop?

• This presentation follows “CRUD with
  Dojo: the bread and butter of IT.”
 • http://lazutkin.com/blog/2009/dec/2/crud-with-dojo/
• But for those who missed it, or wants to
  refresh their memory, I offer a small recap.



                                2
A short narrative of…
• …the previous episode.
 • CRUD is a big hit in IT.
 • If only we had a way to improve good
    things and reduce bad things…
 • Profit!
 • If only we knew how…
                    3
Suddenly!
• The sound of heavy breathing fills airwaves.
• Scared audience can hear how cold air
  rushes through myriad of small tubes
  almost drowning the rhythmic clicking and
  clacking of multiple valves.
• The deep voice seemingly from the guts of
  the eternal void itself says:

                       4
Come to the Client Side,
         Luke!


           5
Sorry.
• That was my bronchitis acting up.
• So, Luke, we looked at what’s available in
  browsers:
  • A sorry mess of form elements with
    different get/set value API and events.
• Good thing we have Dojo and Dijit!
                      6
Dijit and DojoX
• Dijit and DojoX form widgets are good for
  CRUD:
 • Unified API to get/set values.
 • Unified events.
 • Better visual representations for certain
    values, e.g., sliders and spinners.
 • Support validation.
                       7
Forms

• dijit.form.Form
 • Makes sure that all widgets are validated
    before submitting a form.
  • Gets/sets form widgets using a dictionary.
• More can be found in dojox.form.manager

                      8
dojox.form.manager
  The way to manage your forms.




                9
Simple data model

• The form manager is used to annotate
  complex form using simple Dojo markup.
• It views all controlled elements as a name-
  based dictionary of objects.
• It can control: form widgets, form elements
  (DOM nodes), arbitrary DOM nodes.


                     10
Simple value model

• The form manager can get/set a value to
  any controlled element using the same API.
• It can get/set a group of values at the same
  time.



                      11
Simple event model
• The form manager can observe value
  changes of any controlled element using the
  same API.
• When value has changed an observer can
  be called.
• An observer is a method, which is called
  with 4 parameters: new value, element
  name, element, and an event object.

                     12
Observer

• An element can have any number of
  observers.
• An observer can be attached to any
  number of elements.
• Observers are used to implement all value-
  change-driven functionality.


                     13
Architecture I
• The form manager is a collection of mixins
  located in dojox/form/manager/.
 • _Mixin.js provides all basic plumbing and
    can work with form widgets and simple
    DOM nodes.
 • _FormMixin.js implements functionality
    similar to dijit.form.Form.

                      14
Architecture II

•   _NodeMixin.js adds 1st-class support to
    form elements (DOM nodes).
• _ValueMixin.js adds helpers to get/set
    values.
• _ClassMixin.js adds addClass()/
    removeClass() helpers.


                      15
Architecture III

• _EnableMixin.js adds helpers to enable/
  disable form fields.
• _DisplayMixin.js adds helpers to show/hide
  DOM nodes.



                        16
Architecture IV

• Manager.js is an example widget, which
  includes all mixins and searches
  descendants to find controlled elements.
• When we talk about “the form manager”
  we usually mean a functionality provided by
  _Mixin.js, rather than actual Manager.js.


                     17
Architecture V
• Instead of using Manager.js (or a subset of
  it), you can create a normal widget derived
  from proper mixins, and place all form
  elements in a normal template.
  • This is a great way to share the same
    form in several places.
• Observers would be simple methods of
  your widget.

                      18
Practical examples
     Let’s rock and roll.




              19
Registering elements I
 <form action=”/doForm” id=”myForm”
  dojoType=”dojox.form.Manager”>
   <!-- form widgets are registered
       automatically by _Mixin.js -->
   <input type=”text” name=”name” value=””
    dojoType=”dijit.form.TextBox”><br>
   <!-- form nodes are registered
       automatically by _NodeMixin.js -->
   <input type=”text” name=”email” value=””><br>
   <!-- more to follow -->
 </form>



                        20
Registering elements II
 <form action=”/doForm” id=”myForm”
  dojoType=”dojox.form.Manager”>
   <!-- more follows -->
   <!-- attach points are registered
       automatically by _Mixin.js -->
   <div dojoAttachPoint=”more”>
     <span dojoAttachPoint=”notes”
      class=”dojoFormValue”></span>
   </div>
 </form>




                           21
Registering elements III
• Explanations:
 • All 3 types of controlled elements are
    registered:
   • “name” – a form widget.
   • “email” – a form node (_NodeMixin.js
      is needed).
   • “more” and “notes” – DOM nodes.
                     22
Registering elements IV
• More on DOM nodes:
   • By default DOM nodes cannot have
     values, but we can:
     • Show/hide them.
     • Add/remove CSS classes.
   • To indicate that a DOM node can have
     value we use “dojoFormValue” class.

                    23
Registering elements V
• “more” is a <div> node.
 • It will be used to show/hide its content.
 • Its value is unchanged and unused.
• “notes” is a <span> node.
 • It can have a value (“dojoFormValue”).
 • It is inside of “more”.
                     24
Registering elements VI
• We can register/unregister elements
  dynamically.
 • _Mixin.js: (un)registerWidget(),
    (un)registerWidgetDescendants().
 • _NodeMixin.js: (un)registerNode(),
    (un)registerNodeDescendants().
 • (Un)registering attach points is trivial.
                      25
Populating values I

• Logically the form manager represent its
  form as a dictionary:
  var form = {
   name: ...,
   email: ...,
   notes: ...
  };
  // our form has 3 value fields




                          26
Populating values II
• _ValueMixin.js provides all value helpers.
 • setFormValues(dict) sets values:
  var fm = dijit.byId(“myForm”);
  // set just one value:
  fm.setFormValues({name: “Bob”});
  // set other values overriding “name”
  fm.setFormValues({name: “Mike”, email: “mike@i.am”,
   debug: “clearly fake email!”});




                            27
Populating values III
• gatherFormValues(names) gets values:
 • A dictionary is returned as the result.
 • If “names” is omitted, all values are read.
 • If “names” is an array, only names from
    the array are read.
  • If “names” is a dictionary, its keys are
    read, and values are ignored.

                       28
Populating values IV
• The last form of gatherFormValues()
  compliments setFormValues():
  // create our dictionary with a subset of values
  var dict = {name: “Bob”};
  // set values (actually just one name)
  fm.setFormValues(dict);
  …
  // update values (the same subset)
  dict = fm.gatherFormValues(dict);




                              29
Populating values V

• If you want to read/write just one value use
  elementValue():
  // set value
  fm.elementValue(“name”, “Bob”);
  …
  // get value
  var name = fm.elementValue(“name”);




                         30
Observing elements I
<form action=”/doForm” id=”myForm”
 dojoType=”dojox.form.Manager”>
  <input type=”text” name=”name” value=””
   dojoType=”dijit.form.TextBox”
   observer=”obReady”><br>
  <input type=”text” name=”email” value=””
   observer=”obReady”><br>
  <input type=”submit” name=”submit”
   disabled=”disabled”>
  <!-- more to follow -->
</form>



                        31
Observing elements II
• Explanations:
 • It is a slightly modified version of the
    registration example.
  • It has two fields and one disabled button.
  • Both fields are observed by the same
    observer “obReady”.


                      32
Observing elements III
• We can attach our observer declaratively
  as a regular method:
  <script type=”dojo/method” event=”obReady”
   args=”value,name”>
    // our observer is stupid:
    // it enables the button, when value is not empty
    this.enable({submit: value != “”});
    // we will go over enable() later
  </script>




                           33
Observing elements IV

• Slightly smarter observer:
  <script type=”dojo/method” event=”obReady”
   args=”value,name”>
    // enable the button, when at least
    // one value is not empty
    var dict = this.gatherFormValues([“name”, “email”]);
    this.enable({submit: dict.name || dict.email});
  </script>




                           34
Observing elements V

• Notes:
 • Observer is invoked when a value has
    changed.
   • Some text-based widgets do not fire
      events on every key press. Force them:
      intermediateChanges=”true”


                    35
Observing elements VI

• Notes:
   • Attached DOM nodes cannot have
     “change” events. And they cannot have
     observers.
   • Elements can have several observers
     listed separated by comma.


                   36
_EnableMixin.js I

• This mixin is responsible for enabling/
  disabling form elements.
• gatherEnableState() is modeled after
  gatherFormValues() – the same
  interpolation of input values are performed.



                      37
_EnableMixin.js II

• Three ways to collect the enabled status:
  // read states of all elements as true/false values
  en = fm.gatherEnableState();
  // read states of two elements
  en = fm.gatherEnableState([“name”, “email”]);
  // read states of two elements
  en = fm.gatherEnableState({“name”: 1, “email”: 0});
  // only keys are processed, all values are ignored




                          38
_EnableMixin.js III

• Enable/disable unconditionally:
  fm.enable();          // enable all
  fm.enable(true);      // the same as above
  fm.enable(false);     // disable all
  var a = [“name”, “email”];
  fm.enable(a);         // enable two elements
  fm.enable(a, true);   // the same as above
  fm.enable(a, false); // disable two elements




                               39
_EnableMixin.js IV

• Enable/disable using a dictionary:
  var en = fm.gatherEnableState(); // get all states
  …
  // enable “name”, disable “email”
  fm.enable({name: true, email: false});
  …
  fm.enable(en);   // revert to old state




                           40
_EnableMixin.js V

• disable() compliments enable() and returns
  the previous state:
  var en = fm.disable();        // disable all
  …
  fm.disable([“name”, “email”]); // disable two elements
  …
  // now let’s revert to the old state
  fm.enable(en); // == fm.disable(en)




                           41
_DisplayMixin.js
• This mixin is responsible for showing/hiding
  controlled DOM nodes. It has the same
  semantics as _EnableMixin.js:
  • gatherDisplayState() behaves exactly like
    gatherEnableState().
  • show() is like enable().
  • hide is like disable().
                      42
_ClassMixin.js I
• This mixin is responsible for adding/
  removing CSS classes.
• Unlike other mixins, _ClassMixin.js is not
  wired for reversing states.
• While it is possible to check for presence
  of a CSS class, there is no helpers to use it.
  It can be added in the future.

                      43
_ClassMixin.js II

• Three ways to collect the class status:
  // read presence of a CSS class from all
  cs = fm.gatherClassState(cls);
  // read states of two elements
  cs = fm.gatherClassState(cls, [“name”, “email”]);
  // read states of two elements
  cs = fm.gatherClassState(cls, {“name”: 1, “email”: 0});
  // only keys are processed, all values are ignored




                           44
_ClassMixin.js III

• Three ways to add class:
  // add a CSS class to all elements
  fm.addClass(cls);
  // add a class to two elements
  fm.addClass(cls, [“name”, “email”]);
  // add a class to two elements
  fm.addClass(cls, {“name”: 1, “email”: 0});
  // only keys are processed, all values are ignored




                            45
_ClassMixin.js IV

• Three ways to remove class:
  // remove a CSS class from all elements
  fm.removeClass(cls);
  // remove a class from two elements
  fm.removeClass(cls, [“name”, “email”]);
  // remove a class from two elements
  fm.removeClass(cls, {“name”: 1, “email”: 0});
  // only keys are processed, all values are ignored




                           46
Hints and tips
 And advanced techniques.




            47
Do you need it? I
• You have a multipart complex form.
 • It is unwise to show a huge form to end
    users. It is better to structure it so only a
    part is shown at any given time.
 • A part should have well defined logically
    entry and exit points with an
    intermediate validation.

                      48
Do you need it? II
• A possible way to structure a form (the
  shopping basket style):
 • Split in logically independent blocks.
 • Organize blocks as a chain of screens
    validating each screen independently.
 • At the end of a chain – a summary
    screen, which allows to re-start edits.

                     49
Do you need it? III
• Field values interact with each other.
 • You have complex validation rules
    involving several form fields.
  • Variant: you can auto-suggest a value of
    one field using values of other fields.
  • Variant: a value of one field restrict
    possible values of other fields.

                      50
Do you need it? IV
• Working with form involves I/O, which
  depends on already entered values.
 • When chaining screens, screen
    boundaries can be used to do an
    intermediate I/O.
 • Variant: asynchronous server-side
    validation.

                    51
Do you need it? V
• Working with form involves I/O, which
  depends on already entered values.
 • When chaining screens, screen
    boundaries can be used to do an
    intermediate I/O.
 • Variant: asynchronous server-side
    validation.

                    52
Do you need it? VI

• Try to simplify as much as possible:
 • Use validating widgets whenever possible.
 • Carefully weigh in if you need to use
    _DisplayMixin.js or just proper layout
    widgets.



                     53
Resetting values I

• Frequently end user realizes that the
  changes were not good and want go back.
• Simple and well-known technique is to
  “reset a form” reverting to previous values.
• Use gatherFormValues() to make a
  snapshot before editing.


                     54
Resetting values II

• Restore the snapshot with setFormValues()
  when user wants to “reset”.
• This technique works well for a part of
  form – just use a proper subset when
  taking a snapshot.



                     55
Suspending a form I
• Typical way to submit a form is:
 • Collect all necessary data fields.
   • In some cases you pre-process them.
   • In some cases you produce new
      synthetic fields.
 • Submit it using XHR to a server.
                     56
Suspending a form II
• Analyze a return value from the server.
 • If errors were encountered:
   • Notify user about them.
   • Allow to re-edit a form so it can be
      resubmitted again.
 • Redirect, or reset, if success.
                      57
Suspending a form III
• While you are busy doing I/O and waiting
  for a server, it makes sense to “suspend a
  form”, so no editing can be done.
• Use disable() to disable all visible fields
  while waiting.
  • Save a snapshot returned by disabled() –
     it can be used later to recreate the
     previous state.

                       58
Suspending a form IV

• Obviously it helps that you inform an end
  user what is going on using a proper
  message.
• Less elegant way to do the same is to use a
  modal message visible until you get results
  from a server.


                     59
Suspending a form V
• Soft version of “suspending a form”
  happens when you want to update some
  elements dynamically by loading values
  from a server.
• In this case you should disable only affected
  elements, show a proper message next to
  them while waiting.
• After the update was done, enable them.
                      60
Suspending a form VI
• In the same category of “soft suspension” is
  a server-side validation.
  • Disable involved fields.
  • Tell user what is going on.
  • Wait for a response.
  • Update messages and enable fields back.
                      61
Field interactions I
• First you need to define what is an ultimate
  result of validation looks like.
• Example: city, state, and zip should match,
  otherwise we cannot advance to the next
  screen.
• In this example we have 3 input fields and
  one output: enabled/disabled “Next”
  button.

                       62
Field interactions II
• The example can be solved by one
  observer attached to all three fields.
• Every time it is called, it reads 3 values,
  does its magic, sets a proper enabled/
  disabled flag on the button, and updates
  error messages.
• The same way we can solve most validation
  problems.

                       63
Field interactions III

• One form of field interaction is to show
  unobtrusive error/warning messages
  depending on input values.
• Usually such messages go to DOM nodes,
  and effectively are pseudo-fields.



                     64
Pseudo-fields
• Pseudo-fields:
 • They are not originated in a database.
 • Frequently they are not transmitted at all.
 • They are purely for UI convenience.
• Pseudo-fields are a powerful tool, but
  cannot be generalized.

                     65
That’s all folks!
  Questions? Suggestions?




            66
About me

• I am an independent software developer.
• My web site:
 • http://lazutkin.com
• Follow me on Tweeter:
 • http://twitter.com/uhop
                    67

More Related Content

Similar to RAD CRUD

Practical JavaScript Programming - Session 4/8
Practical JavaScript Programming - Session 4/8Practical JavaScript Programming - Session 4/8
Practical JavaScript Programming - Session 4/8
Wilson Su
 
Vb6.0 intro
Vb6.0 introVb6.0 intro
Vb6.0 intro
JOSEPHINEA6
 
My Very First Zf App Part One
My Very First Zf App   Part OneMy Very First Zf App   Part One
My Very First Zf App Part One
isaaczfoster
 
Extjs
ExtjsExtjs
Client-side JavaScript
Client-side JavaScriptClient-side JavaScript
Client-side JavaScript
Lilia Sfaxi
 
javascript Event Handling and introduction to event.ppt
javascript Event Handling and introduction to event.pptjavascript Event Handling and introduction to event.ppt
javascript Event Handling and introduction to event.ppt
Lalith86
 
LEARNING  iPAD STORYBOARDS IN OBJ-­‐C LESSON 1
LEARNING	 iPAD STORYBOARDS IN OBJ-­‐C LESSON 1LEARNING	 iPAD STORYBOARDS IN OBJ-­‐C LESSON 1
LEARNING  iPAD STORYBOARDS IN OBJ-­‐C LESSON 1
Rich Helton
 
CRUD with Dojo
CRUD with DojoCRUD with Dojo
CRUD with Dojo
Eugene Lazutkin
 
Presenting Data – An Alternative to the View Control
Presenting Data – An Alternative to the View ControlPresenting Data – An Alternative to the View Control
Presenting Data – An Alternative to the View Control
Teamstudio
 
UKLUG 2009 - Extending Domino Designer on Eclipse
UKLUG 2009 - Extending Domino Designer on EclipseUKLUG 2009 - Extending Domino Designer on Eclipse
UKLUG 2009 - Extending Domino Designer on Eclipse
René Winkelmeyer
 
08ui.pptx
08ui.pptx08ui.pptx
08ui.pptx
KabadaSori
 
CS101- Introduction to Computing- Lecture 32
CS101- Introduction to Computing- Lecture 32CS101- Introduction to Computing- Lecture 32
CS101- Introduction to Computing- Lecture 32
Bilal Ahmed
 
Introduction of Xcode
Introduction of XcodeIntroduction of Xcode
Introduction of Xcode
Dhaval Kaneria
 
Record Automated Integration Tests through the UI
Record Automated Integration Tests through the UIRecord Automated Integration Tests through the UI
Record Automated Integration Tests through the UI
Odoo
 
D2 k word_format
D2 k word_formatD2 k word_format
D2 k word_format
Bharath Chowdhary
 
Jquery dojo slides
Jquery dojo slidesJquery dojo slides
Jquery dojo slides
helenmga
 
Alloy Simple App Demonstration
Alloy Simple App DemonstrationAlloy Simple App Demonstration
Alloy Simple App Demonstration
Aaron Saunders
 
Ms vb
Ms vbMs vb
Ms vb
sirjade4
 
Test02
Test02Test02
Test02
testingPdf
 
WOdka
WOdkaWOdka

Similar to RAD CRUD (20)

Practical JavaScript Programming - Session 4/8
Practical JavaScript Programming - Session 4/8Practical JavaScript Programming - Session 4/8
Practical JavaScript Programming - Session 4/8
 
Vb6.0 intro
Vb6.0 introVb6.0 intro
Vb6.0 intro
 
My Very First Zf App Part One
My Very First Zf App   Part OneMy Very First Zf App   Part One
My Very First Zf App Part One
 
Extjs
ExtjsExtjs
Extjs
 
Client-side JavaScript
Client-side JavaScriptClient-side JavaScript
Client-side JavaScript
 
javascript Event Handling and introduction to event.ppt
javascript Event Handling and introduction to event.pptjavascript Event Handling and introduction to event.ppt
javascript Event Handling and introduction to event.ppt
 
LEARNING  iPAD STORYBOARDS IN OBJ-­‐C LESSON 1
LEARNING	 iPAD STORYBOARDS IN OBJ-­‐C LESSON 1LEARNING	 iPAD STORYBOARDS IN OBJ-­‐C LESSON 1
LEARNING  iPAD STORYBOARDS IN OBJ-­‐C LESSON 1
 
CRUD with Dojo
CRUD with DojoCRUD with Dojo
CRUD with Dojo
 
Presenting Data – An Alternative to the View Control
Presenting Data – An Alternative to the View ControlPresenting Data – An Alternative to the View Control
Presenting Data – An Alternative to the View Control
 
UKLUG 2009 - Extending Domino Designer on Eclipse
UKLUG 2009 - Extending Domino Designer on EclipseUKLUG 2009 - Extending Domino Designer on Eclipse
UKLUG 2009 - Extending Domino Designer on Eclipse
 
08ui.pptx
08ui.pptx08ui.pptx
08ui.pptx
 
CS101- Introduction to Computing- Lecture 32
CS101- Introduction to Computing- Lecture 32CS101- Introduction to Computing- Lecture 32
CS101- Introduction to Computing- Lecture 32
 
Introduction of Xcode
Introduction of XcodeIntroduction of Xcode
Introduction of Xcode
 
Record Automated Integration Tests through the UI
Record Automated Integration Tests through the UIRecord Automated Integration Tests through the UI
Record Automated Integration Tests through the UI
 
D2 k word_format
D2 k word_formatD2 k word_format
D2 k word_format
 
Jquery dojo slides
Jquery dojo slidesJquery dojo slides
Jquery dojo slides
 
Alloy Simple App Demonstration
Alloy Simple App DemonstrationAlloy Simple App Demonstration
Alloy Simple App Demonstration
 
Ms vb
Ms vbMs vb
Ms vb
 
Test02
Test02Test02
Test02
 
WOdka
WOdkaWOdka
WOdka
 

More from Eugene Lazutkin

Service workers
Service workersService workers
Service workers
Eugene Lazutkin
 
Advanced I/O in browser
Advanced I/O in browserAdvanced I/O in browser
Advanced I/O in browser
Eugene Lazutkin
 
Streams
StreamsStreams
Functional practices in JavaScript
Functional practices in JavaScriptFunctional practices in JavaScript
Functional practices in JavaScript
Eugene Lazutkin
 
Express: the web server for node.js
Express: the web server for node.jsExpress: the web server for node.js
Express: the web server for node.js
Eugene Lazutkin
 
TXJS 2013 in 10 minutes
TXJS 2013 in 10 minutesTXJS 2013 in 10 minutes
TXJS 2013 in 10 minutes
Eugene Lazutkin
 
Practical pairing of generative programming with functional programming.
Practical pairing of generative programming with functional programming.Practical pairing of generative programming with functional programming.
Practical pairing of generative programming with functional programming.
Eugene Lazutkin
 
Optimization of modern web applications
Optimization of modern web applicationsOptimization of modern web applications
Optimization of modern web applications
Eugene Lazutkin
 
OOP in JS
OOP in JSOOP in JS
OOP in JS
Eugene Lazutkin
 
Pulsar
PulsarPulsar
SSJS, NoSQL, GAE and AppengineJS
SSJS, NoSQL, GAE and AppengineJSSSJS, NoSQL, GAE and AppengineJS
SSJS, NoSQL, GAE and AppengineJS
Eugene Lazutkin
 
Dojo for programmers (TXJS 2010)
Dojo for programmers (TXJS 2010)Dojo for programmers (TXJS 2010)
Dojo for programmers (TXJS 2010)
Eugene Lazutkin
 
Exciting JavaScript - Part II
Exciting JavaScript - Part IIExciting JavaScript - Part II
Exciting JavaScript - Part II
Eugene Lazutkin
 
Exciting JavaScript - Part I
Exciting JavaScript - Part IExciting JavaScript - Part I
Exciting JavaScript - Part I
Eugene Lazutkin
 
Dojo GFX workshop slides
Dojo GFX workshop slidesDojo GFX workshop slides
Dojo GFX workshop slides
Eugene Lazutkin
 
Dojo GFX: SVG in the real world
Dojo GFX: SVG in the real worldDojo GFX: SVG in the real world
Dojo GFX: SVG in the real world
Eugene Lazutkin
 
Dojo (QCon 2007 Slides)
Dojo (QCon 2007 Slides)Dojo (QCon 2007 Slides)
Dojo (QCon 2007 Slides)
Eugene Lazutkin
 
DojoX GFX Session Eugene Lazutkin SVG Open 2007
DojoX GFX Session Eugene Lazutkin SVG Open 2007DojoX GFX Session Eugene Lazutkin SVG Open 2007
DojoX GFX Session Eugene Lazutkin SVG Open 2007
Eugene Lazutkin
 
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
Eugene Lazutkin
 

More from Eugene Lazutkin (19)

Service workers
Service workersService workers
Service workers
 
Advanced I/O in browser
Advanced I/O in browserAdvanced I/O in browser
Advanced I/O in browser
 
Streams
StreamsStreams
Streams
 
Functional practices in JavaScript
Functional practices in JavaScriptFunctional practices in JavaScript
Functional practices in JavaScript
 
Express: the web server for node.js
Express: the web server for node.jsExpress: the web server for node.js
Express: the web server for node.js
 
TXJS 2013 in 10 minutes
TXJS 2013 in 10 minutesTXJS 2013 in 10 minutes
TXJS 2013 in 10 minutes
 
Practical pairing of generative programming with functional programming.
Practical pairing of generative programming with functional programming.Practical pairing of generative programming with functional programming.
Practical pairing of generative programming with functional programming.
 
Optimization of modern web applications
Optimization of modern web applicationsOptimization of modern web applications
Optimization of modern web applications
 
OOP in JS
OOP in JSOOP in JS
OOP in JS
 
Pulsar
PulsarPulsar
Pulsar
 
SSJS, NoSQL, GAE and AppengineJS
SSJS, NoSQL, GAE and AppengineJSSSJS, NoSQL, GAE and AppengineJS
SSJS, NoSQL, GAE and AppengineJS
 
Dojo for programmers (TXJS 2010)
Dojo for programmers (TXJS 2010)Dojo for programmers (TXJS 2010)
Dojo for programmers (TXJS 2010)
 
Exciting JavaScript - Part II
Exciting JavaScript - Part IIExciting JavaScript - Part II
Exciting JavaScript - Part II
 
Exciting JavaScript - Part I
Exciting JavaScript - Part IExciting JavaScript - Part I
Exciting JavaScript - Part I
 
Dojo GFX workshop slides
Dojo GFX workshop slidesDojo GFX workshop slides
Dojo GFX workshop slides
 
Dojo GFX: SVG in the real world
Dojo GFX: SVG in the real worldDojo GFX: SVG in the real world
Dojo GFX: SVG in the real world
 
Dojo (QCon 2007 Slides)
Dojo (QCon 2007 Slides)Dojo (QCon 2007 Slides)
Dojo (QCon 2007 Slides)
 
DojoX GFX Session Eugene Lazutkin SVG Open 2007
DojoX GFX Session Eugene Lazutkin SVG Open 2007DojoX GFX Session Eugene Lazutkin SVG Open 2007
DojoX GFX Session Eugene Lazutkin SVG Open 2007
 
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
DojoX GFX Keynote Eugene Lazutkin SVG Open 2007
 

Recently uploaded

20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
Adtran
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
James Anderson
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
Neo4j
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
Neo4j
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
DianaGray10
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
Matthew Sinclair
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
Uni Systems S.M.S.A.
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
Neo4j
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
SOFTTECHHUB
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Vladimir Iglovikov, Ph.D.
 
Data structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdfData structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdf
TIPNGVN2
 

Recently uploaded (20)

20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
 
Data structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdfData structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdf
 

RAD CRUD

  • 1. RAD CRUD Rapid development of form-based applications. 1
  • 2. Where did we stop? • This presentation follows “CRUD with Dojo: the bread and butter of IT.” • http://lazutkin.com/blog/2009/dec/2/crud-with-dojo/ • But for those who missed it, or wants to refresh their memory, I offer a small recap. 2
  • 3. A short narrative of… • …the previous episode. • CRUD is a big hit in IT. • If only we had a way to improve good things and reduce bad things… • Profit! • If only we knew how… 3
  • 4. Suddenly! • The sound of heavy breathing fills airwaves. • Scared audience can hear how cold air rushes through myriad of small tubes almost drowning the rhythmic clicking and clacking of multiple valves. • The deep voice seemingly from the guts of the eternal void itself says: 4
  • 5. Come to the Client Side, Luke! 5
  • 6. Sorry. • That was my bronchitis acting up. • So, Luke, we looked at what’s available in browsers: • A sorry mess of form elements with different get/set value API and events. • Good thing we have Dojo and Dijit! 6
  • 7. Dijit and DojoX • Dijit and DojoX form widgets are good for CRUD: • Unified API to get/set values. • Unified events. • Better visual representations for certain values, e.g., sliders and spinners. • Support validation. 7
  • 8. Forms • dijit.form.Form • Makes sure that all widgets are validated before submitting a form. • Gets/sets form widgets using a dictionary. • More can be found in dojox.form.manager 8
  • 9. dojox.form.manager The way to manage your forms. 9
  • 10. Simple data model • The form manager is used to annotate complex form using simple Dojo markup. • It views all controlled elements as a name- based dictionary of objects. • It can control: form widgets, form elements (DOM nodes), arbitrary DOM nodes. 10
  • 11. Simple value model • The form manager can get/set a value to any controlled element using the same API. • It can get/set a group of values at the same time. 11
  • 12. Simple event model • The form manager can observe value changes of any controlled element using the same API. • When value has changed an observer can be called. • An observer is a method, which is called with 4 parameters: new value, element name, element, and an event object. 12
  • 13. Observer • An element can have any number of observers. • An observer can be attached to any number of elements. • Observers are used to implement all value- change-driven functionality. 13
  • 14. Architecture I • The form manager is a collection of mixins located in dojox/form/manager/. • _Mixin.js provides all basic plumbing and can work with form widgets and simple DOM nodes. • _FormMixin.js implements functionality similar to dijit.form.Form. 14
  • 15. Architecture II • _NodeMixin.js adds 1st-class support to form elements (DOM nodes). • _ValueMixin.js adds helpers to get/set values. • _ClassMixin.js adds addClass()/ removeClass() helpers. 15
  • 16. Architecture III • _EnableMixin.js adds helpers to enable/ disable form fields. • _DisplayMixin.js adds helpers to show/hide DOM nodes. 16
  • 17. Architecture IV • Manager.js is an example widget, which includes all mixins and searches descendants to find controlled elements. • When we talk about “the form manager” we usually mean a functionality provided by _Mixin.js, rather than actual Manager.js. 17
  • 18. Architecture V • Instead of using Manager.js (or a subset of it), you can create a normal widget derived from proper mixins, and place all form elements in a normal template. • This is a great way to share the same form in several places. • Observers would be simple methods of your widget. 18
  • 19. Practical examples Let’s rock and roll. 19
  • 20. Registering elements I <form action=”/doForm” id=”myForm” dojoType=”dojox.form.Manager”> <!-- form widgets are registered automatically by _Mixin.js --> <input type=”text” name=”name” value=”” dojoType=”dijit.form.TextBox”><br> <!-- form nodes are registered automatically by _NodeMixin.js --> <input type=”text” name=”email” value=””><br> <!-- more to follow --> </form> 20
  • 21. Registering elements II <form action=”/doForm” id=”myForm” dojoType=”dojox.form.Manager”> <!-- more follows --> <!-- attach points are registered automatically by _Mixin.js --> <div dojoAttachPoint=”more”> <span dojoAttachPoint=”notes” class=”dojoFormValue”></span> </div> </form> 21
  • 22. Registering elements III • Explanations: • All 3 types of controlled elements are registered: • “name” – a form widget. • “email” – a form node (_NodeMixin.js is needed). • “more” and “notes” – DOM nodes. 22
  • 23. Registering elements IV • More on DOM nodes: • By default DOM nodes cannot have values, but we can: • Show/hide them. • Add/remove CSS classes. • To indicate that a DOM node can have value we use “dojoFormValue” class. 23
  • 24. Registering elements V • “more” is a <div> node. • It will be used to show/hide its content. • Its value is unchanged and unused. • “notes” is a <span> node. • It can have a value (“dojoFormValue”). • It is inside of “more”. 24
  • 25. Registering elements VI • We can register/unregister elements dynamically. • _Mixin.js: (un)registerWidget(), (un)registerWidgetDescendants(). • _NodeMixin.js: (un)registerNode(), (un)registerNodeDescendants(). • (Un)registering attach points is trivial. 25
  • 26. Populating values I • Logically the form manager represent its form as a dictionary: var form = { name: ..., email: ..., notes: ... }; // our form has 3 value fields 26
  • 27. Populating values II • _ValueMixin.js provides all value helpers. • setFormValues(dict) sets values: var fm = dijit.byId(“myForm”); // set just one value: fm.setFormValues({name: “Bob”}); // set other values overriding “name” fm.setFormValues({name: “Mike”, email: “mike@i.am”, debug: “clearly fake email!”}); 27
  • 28. Populating values III • gatherFormValues(names) gets values: • A dictionary is returned as the result. • If “names” is omitted, all values are read. • If “names” is an array, only names from the array are read. • If “names” is a dictionary, its keys are read, and values are ignored. 28
  • 29. Populating values IV • The last form of gatherFormValues() compliments setFormValues(): // create our dictionary with a subset of values var dict = {name: “Bob”}; // set values (actually just one name) fm.setFormValues(dict); … // update values (the same subset) dict = fm.gatherFormValues(dict); 29
  • 30. Populating values V • If you want to read/write just one value use elementValue(): // set value fm.elementValue(“name”, “Bob”); … // get value var name = fm.elementValue(“name”); 30
  • 31. Observing elements I <form action=”/doForm” id=”myForm” dojoType=”dojox.form.Manager”> <input type=”text” name=”name” value=”” dojoType=”dijit.form.TextBox” observer=”obReady”><br> <input type=”text” name=”email” value=”” observer=”obReady”><br> <input type=”submit” name=”submit” disabled=”disabled”> <!-- more to follow --> </form> 31
  • 32. Observing elements II • Explanations: • It is a slightly modified version of the registration example. • It has two fields and one disabled button. • Both fields are observed by the same observer “obReady”. 32
  • 33. Observing elements III • We can attach our observer declaratively as a regular method: <script type=”dojo/method” event=”obReady” args=”value,name”> // our observer is stupid: // it enables the button, when value is not empty this.enable({submit: value != “”}); // we will go over enable() later </script> 33
  • 34. Observing elements IV • Slightly smarter observer: <script type=”dojo/method” event=”obReady” args=”value,name”> // enable the button, when at least // one value is not empty var dict = this.gatherFormValues([“name”, “email”]); this.enable({submit: dict.name || dict.email}); </script> 34
  • 35. Observing elements V • Notes: • Observer is invoked when a value has changed. • Some text-based widgets do not fire events on every key press. Force them: intermediateChanges=”true” 35
  • 36. Observing elements VI • Notes: • Attached DOM nodes cannot have “change” events. And they cannot have observers. • Elements can have several observers listed separated by comma. 36
  • 37. _EnableMixin.js I • This mixin is responsible for enabling/ disabling form elements. • gatherEnableState() is modeled after gatherFormValues() – the same interpolation of input values are performed. 37
  • 38. _EnableMixin.js II • Three ways to collect the enabled status: // read states of all elements as true/false values en = fm.gatherEnableState(); // read states of two elements en = fm.gatherEnableState([“name”, “email”]); // read states of two elements en = fm.gatherEnableState({“name”: 1, “email”: 0}); // only keys are processed, all values are ignored 38
  • 39. _EnableMixin.js III • Enable/disable unconditionally: fm.enable(); // enable all fm.enable(true); // the same as above fm.enable(false); // disable all var a = [“name”, “email”]; fm.enable(a); // enable two elements fm.enable(a, true); // the same as above fm.enable(a, false); // disable two elements 39
  • 40. _EnableMixin.js IV • Enable/disable using a dictionary: var en = fm.gatherEnableState(); // get all states … // enable “name”, disable “email” fm.enable({name: true, email: false}); … fm.enable(en); // revert to old state 40
  • 41. _EnableMixin.js V • disable() compliments enable() and returns the previous state: var en = fm.disable(); // disable all … fm.disable([“name”, “email”]); // disable two elements … // now let’s revert to the old state fm.enable(en); // == fm.disable(en) 41
  • 42. _DisplayMixin.js • This mixin is responsible for showing/hiding controlled DOM nodes. It has the same semantics as _EnableMixin.js: • gatherDisplayState() behaves exactly like gatherEnableState(). • show() is like enable(). • hide is like disable(). 42
  • 43. _ClassMixin.js I • This mixin is responsible for adding/ removing CSS classes. • Unlike other mixins, _ClassMixin.js is not wired for reversing states. • While it is possible to check for presence of a CSS class, there is no helpers to use it. It can be added in the future. 43
  • 44. _ClassMixin.js II • Three ways to collect the class status: // read presence of a CSS class from all cs = fm.gatherClassState(cls); // read states of two elements cs = fm.gatherClassState(cls, [“name”, “email”]); // read states of two elements cs = fm.gatherClassState(cls, {“name”: 1, “email”: 0}); // only keys are processed, all values are ignored 44
  • 45. _ClassMixin.js III • Three ways to add class: // add a CSS class to all elements fm.addClass(cls); // add a class to two elements fm.addClass(cls, [“name”, “email”]); // add a class to two elements fm.addClass(cls, {“name”: 1, “email”: 0}); // only keys are processed, all values are ignored 45
  • 46. _ClassMixin.js IV • Three ways to remove class: // remove a CSS class from all elements fm.removeClass(cls); // remove a class from two elements fm.removeClass(cls, [“name”, “email”]); // remove a class from two elements fm.removeClass(cls, {“name”: 1, “email”: 0}); // only keys are processed, all values are ignored 46
  • 47. Hints and tips And advanced techniques. 47
  • 48. Do you need it? I • You have a multipart complex form. • It is unwise to show a huge form to end users. It is better to structure it so only a part is shown at any given time. • A part should have well defined logically entry and exit points with an intermediate validation. 48
  • 49. Do you need it? II • A possible way to structure a form (the shopping basket style): • Split in logically independent blocks. • Organize blocks as a chain of screens validating each screen independently. • At the end of a chain – a summary screen, which allows to re-start edits. 49
  • 50. Do you need it? III • Field values interact with each other. • You have complex validation rules involving several form fields. • Variant: you can auto-suggest a value of one field using values of other fields. • Variant: a value of one field restrict possible values of other fields. 50
  • 51. Do you need it? IV • Working with form involves I/O, which depends on already entered values. • When chaining screens, screen boundaries can be used to do an intermediate I/O. • Variant: asynchronous server-side validation. 51
  • 52. Do you need it? V • Working with form involves I/O, which depends on already entered values. • When chaining screens, screen boundaries can be used to do an intermediate I/O. • Variant: asynchronous server-side validation. 52
  • 53. Do you need it? VI • Try to simplify as much as possible: • Use validating widgets whenever possible. • Carefully weigh in if you need to use _DisplayMixin.js or just proper layout widgets. 53
  • 54. Resetting values I • Frequently end user realizes that the changes were not good and want go back. • Simple and well-known technique is to “reset a form” reverting to previous values. • Use gatherFormValues() to make a snapshot before editing. 54
  • 55. Resetting values II • Restore the snapshot with setFormValues() when user wants to “reset”. • This technique works well for a part of form – just use a proper subset when taking a snapshot. 55
  • 56. Suspending a form I • Typical way to submit a form is: • Collect all necessary data fields. • In some cases you pre-process them. • In some cases you produce new synthetic fields. • Submit it using XHR to a server. 56
  • 57. Suspending a form II • Analyze a return value from the server. • If errors were encountered: • Notify user about them. • Allow to re-edit a form so it can be resubmitted again. • Redirect, or reset, if success. 57
  • 58. Suspending a form III • While you are busy doing I/O and waiting for a server, it makes sense to “suspend a form”, so no editing can be done. • Use disable() to disable all visible fields while waiting. • Save a snapshot returned by disabled() – it can be used later to recreate the previous state. 58
  • 59. Suspending a form IV • Obviously it helps that you inform an end user what is going on using a proper message. • Less elegant way to do the same is to use a modal message visible until you get results from a server. 59
  • 60. Suspending a form V • Soft version of “suspending a form” happens when you want to update some elements dynamically by loading values from a server. • In this case you should disable only affected elements, show a proper message next to them while waiting. • After the update was done, enable them. 60
  • 61. Suspending a form VI • In the same category of “soft suspension” is a server-side validation. • Disable involved fields. • Tell user what is going on. • Wait for a response. • Update messages and enable fields back. 61
  • 62. Field interactions I • First you need to define what is an ultimate result of validation looks like. • Example: city, state, and zip should match, otherwise we cannot advance to the next screen. • In this example we have 3 input fields and one output: enabled/disabled “Next” button. 62
  • 63. Field interactions II • The example can be solved by one observer attached to all three fields. • Every time it is called, it reads 3 values, does its magic, sets a proper enabled/ disabled flag on the button, and updates error messages. • The same way we can solve most validation problems. 63
  • 64. Field interactions III • One form of field interaction is to show unobtrusive error/warning messages depending on input values. • Usually such messages go to DOM nodes, and effectively are pseudo-fields. 64
  • 65. Pseudo-fields • Pseudo-fields: • They are not originated in a database. • Frequently they are not transmitted at all. • They are purely for UI convenience. • Pseudo-fields are a powerful tool, but cannot be generalized. 65
  • 66. That’s all folks! Questions? Suggestions? 66
  • 67. About me • I am an independent software developer. • My web site: • http://lazutkin.com • Follow me on Tweeter: • http://twitter.com/uhop 67