Ahah Forms Framework

Ajax + FormAPI = More Responsive UI
Tao Starbow

CITRIS
The Center for Information Technology Research in the Interest of Society
UC Berkeley

Who am I? What am I doing here?

  • Web Programmer at UC Berkeley
  • Things I am not an expert in: FormAPI, JavaScript, jQuery and Ajax
  • 10 years on web applications, 2 years of Drupal
  • A guy with some working code: Ahah Forms Framework
  • Goal: to lower the bar to creating responsive forms in Drupal

Drupal 5.x JavaScript-friendly Features

  • Standardizing on jQuery library
  • drupal_add_js - for both entire scripts and setting arrays
  • Auto-attaching IDs to (almost) everything
  • FAPI: friend or foe?

jQuery - love it

  • Simple but powerful selectors: CSS and XPath
  • Example: onclick='$("#exposed_filter_fieldset.collapsed legend a").click();'
  • Chainable methods
  • Easy event binding
  • Easy DOM traversing and manipulation
  • Cool effects
  • Ajax utility functions (yay!)

What is Ajax?

  • Asynchronous JavaScript and XML (Jesse James Garrett, Feb 2005)
    • standards-based presentation using XHTML and CSS
    • dynamic display and interaction using the Document Object Model
    • data interchange and manipulation using XML and XSLT
    • asynchronous data retrieval using XMLHttpRequest
    • and JavaScript binding everything together
  • The dirty secret: it's all just JavaScript
  • Ajax the over-hyped buzzword vs Modern JavaScript
  • I am just happy not to do a full page reload every time I do something

What is Ahah?

  • Asynchronous HTML and HTTP (~May 2005)
  • Simplified subset of Ajax
  • Just grab a HTML fragment from the server and slap it into the page
  • Part of the REST Microformat spec
  • The joys of being simple:
    • progressive enhancement: must work without JavaScript
    • don't need to do much custom php work to accommodate it
    • don't need to learn JavaScript at all to use it
    • but you won't create the next Google Maps with it

Ahah Basic Concepts

  • Who: DOM element(s)
  • When: event
  • Where: wrapper/target ID
  • What: source of HTML fragment
  • How: next slide please

Ahah Forms Framework: Overview

  • A proposal for attaching Ahah swaps to Drupal form elements without custom JavaScript
  • Silly name
  • Scratching my own itch
  • Abstracted into a tutorial, then a module, then a presentation
  • Similar concept to Ruby on Rails link_to_remote tag or form_remote_tag() function
  • Leverages Drupal 5.x innovations to do a lot with just a little code

Ahah Forms: #ahah_bindings (Part 1)

Examples from views_ui.module-example: single button

$form['argument']['add']['button'] = array(
  '#type' => 'button',
  '#value' => 'Add Argument' ,
  '#ahah_bindings' => array(
    array (
    'event' => 'click', /* when */
    'wrapper' => 'views_wrapper_argument', /* where */
    'path' => 'admin/build/views/build_view_js', /* what */
    'params' => array ( 'section' => 'argument'),
    ),
  ),
); 

Ahah Forms: #ahah_bindings (Part 2)

Examples from views_ui.module-example: Entire class of buttons

$form['filter']['#ahah_bindings'][] = array (
  'selector' => 'input.expose-button', /* who */
  'event' => 'click',
  'path' => 'admin/build/views/build_view_js',
  'wrapper' => 'views_wrapper_exposed_filter',
  'params' => array ( 'section' => 'exposed_filter' ),
);

Ahah Forms: ahah_forms.module

  • ~ 40 lines of php
  • Uses hook_form_alter to add #after_build to all forms
  • After the form array is built, recursively scans all elements, looking for #ahah_binding properties
  • Sends #ahah_binding arrays to JavaScript, using drupal_add_js(..., 'settings')
  • Also adds ahah_forms.js to page

Ahah Forms: ahah_forms.js

  • ~ 80 lines of JavaScript (plus handy function from form.js - jQuery Plugin)
  • Loops through #ahah_binding array, calling a function to bind each element to it's event
  • Then when the element's event is triggered:
    • put up a visual cue that the page is updating
    • build an array of name/value pairs to post back to Drupal (form.js)
    • build return URL
    • send an HTTP request back to the server and collect the response
    • stuff the response into the current page, inside the wrapper
    • reattach all of the event bindings to the new HTML
    • and turn off the visual overlay

Simple Example (Demo)

  • Simplest thing we can imaging doing with Ahah swap
  • Demo

Simple Example (Part 1)

function ahah_simple_menu($may_cache) { ...
  $items[] = array(
    'path' => 'ahah/simple',
    'callback' => 'drupal_get_form',
    'callback arguments' => array('ahah_simple_page'),
    'type' => 'CALLBACK',
    'access' => true );
  $items[] = array(
    'path' => 'ahah/simple_js',
    'callback' => 'ahah_simple_js',
    'type' => 'CALLBACK',
    'access' => true );�
... }

Simple Example (Part 2)

function ahah_simple_page() {
  $form['target'] = array(
    '#type' => 'item',
    '#value' => "Don't do it!",
    '#prefix' => '<div id="target">',
    '#suffix' => '</div>' );
  $form['submit'] = array(
    '#type' => 'button',
    '#value' => t('Click Me'),
    '#ahah_bindings' => array ( array(
      'event' => 'click',
      'path' => 'ahah/simple_js',
      'wrapper' => 'target'
    )
  ) 
);

Simple Example (Part 3)

function ahah_simple_js() {
  print '<p>No one ever listens.</p>';
}

Firebug - best thing since sliced bread

  • FireFox extension by Joe Hewitt
  • An i nteractive JavaScript debugger
  • Spy on HTTP requests and responses
  • Inspect and edit the HTML (after updates!)
  • Edit CSS info
  • JavaScript console
  • Just get it!

Other Helpful Tools For Doing Ajax Work

  • Eclipse PDT and XDebug (RC2 - buggy)
  • JSLint - jslint.com
  • Selenium IDE
  • Pro JavaScript Techniques - learn to think like John Resig

Views Reloaded (Demo)

  • No changes to original logic in module - just tweaks and theming
  • Pure client-side could be even more responsive, but requires separate code paths
  • Demo

The Future

Thank You

This work funded by CITRIS - The Center for Information Technology Research in the Interest of Society

Check us out at: http://www.citris-uc.org

Only local images are allowed.

  • Nedjo Rodgers - Helping me out on JavaScript Group
  • Steven Wittens - DrupalCon jQuery Slides
  • Lullabot Team - Forcing FormAPI into my brain

Caution

The demo links reference localhost. The citris group has been contacted (april 2009) re: location of valid demos.