SlideShare a Scribd company logo
1 of 53
Download to read offline
MONTREAL 1/3 JULY 2011




Ajax.framework:
Under the Hood
Chuck Hill
Global Village Consulting, Inc.
WOWODC 2011
Session Overview
•   My Goals

•   Outline:

    •   Ajax vs Classical WebObjects

    •   How Things Work vs Just Works

    •   Building Blocks

    •   Case Study

•   No JSON
A Word on our Sponsors

•   Jean-Francois Veillette

•   Anjo Krank

•   Mike Schrag

•   the rest of us

•   you
A Word on JavaScript
•   Not a toy scripting language

•   NOT Java, “Lisp in C’s clothing”

•   functional programming

•   loose “duck” typing and prototypal inheritance

•   dynamic objects

•   Douglas Crockford and Yahoo
Classical Request/Response Loop
Ajax R-R in a Nutshell
New R-R Loop Phase
•   handleRequest

•   replaces action method

•   returns response for Ajax request

•   called by invokeAction

    •   ... at the right time!

•   takeValues→invokeAction→handleRequest→appendToResponse?’

•   returns AjaxResponse (important!)
Ajax Action R-R Loop
•   “The Basic”

•   takeValues

•   invokeAction

•   handleRequest

•   whatever

•   can return JS, HTML, or nothing

•   client-side result varies
Ajax Update R-R Loop
•   “The Meat Lover’s”

•   ...?_u=MyContainerID&1239887663

•   invokeAction

•   handleRequest

•   AjaxResponse.generateResponse

•   invokeAction (yes! again!)

•   handleRequest (on AUC)

•   appendChildrenToResponse (AUC)
Ajax Submit, Action, & Update
•   “All Dressed”

•   takeValuesFromRequest

•   invokeAction

•   handleRequest

•   AjaxResponse.generateResponse

•   invokeAction (yes! again!)

•   handleRequest (on AUC)

•   action method (result discarded)

•   appendChildrenToResponse (AUC)
Ajax Replace R-R Loop
•   “Poutine Pizza”

•   ...?_r=true&1239887663

•   takeValuesFromRequest

•   invokeAction

•   handleRequest

•   action method (component) returned as replacement)

•   intuitive, but may be dangerous
Special Ajax Classes

•   AjaxRequestHandler: don’t store page

•   ERXAjaxApplication: no takeVlaues for ?_u=xxx&2309482093

•   ERXAjaxSession: Ajax Page Caching

•   ERXAjaxContext: partial form submits

•   AjaxResponse: generateResponse→invokeAction for AUC
Classical Page Caching
Ajax Page Caching
Support Classes

•   AjaxComponent

•   AjaxDynamicElement

•   AjaxUtils

•   AjaxOptions, AjaxOption, AjaxConstantOption, AjaxValue
AjaxComponent

•   WOComponent replacement

•   Stateful

•   Mostly familiar usage

•   handleRequest

•   addRequiredWebResources
AjaxDynamicElement
•   WODynamicGroup replacement

•   Stateless

•   Harder to use than WOComponent

•   Binding and template access

•   handleRequest

•   addRequiredWebResources
AjaxUtils
•   createResponse

•   javascriptResponse

•   Add JS and CSS resources (via ERXResponseRewriter)

•   shouldHandleRequest

•   binding convenience with JSON parsing

•   response generation

•   updateDomElement

•   redirecting

•   etc. seek and ye shall find
JavaScript/JSON Value Encoding


new Ajax.Request('/some_url', {
   method: 'get',
   parameters: {company: 'example', limit: 12}
 });
AjaxValue

•   converts to JavaScript/JSON format

•   type-aware value

•   type guessing ability
•   javascriptValue


•   [a, b, ...], {a:b; ...}, escaping in strings etc.
AjaxOption.Type


•   simple enumeration

•   AjaxValue data types

•   update if you extend AjaxValue
AjaxOption
•   named for Prototype parameter “options”

•   bridge from bindings to JavaScript

•   component or dynamic element

•   Parameters

    •   JavaScript Name

    •   Type

    •   Binding Name

    •   Default Value
AjaxConstantOption

•   Used for computed values
    public AjaxConstantOption(
        String    javaScriptName,
        Object    constantValue,
        Type      type)
AjaxOptions
•   with an S

•   collection of key-value pairs

•   used as component* or class

•   *component usage likely buggy

•   works with StringBuffer and WOResponse

•   works best with
    AjaxOption.createAjaxOptionsDictionary
AjaxOptions Usage

  public NSDictionary createAjaxOptions(WOComponent component) {
	 NSMutableArray<AjaxOption> list = new NSMutableArray<AjaxOption>();
	 list.addObject(new AjaxOption("frequency", AjaxOption.NUMBER));
	 list.addObject(new AjaxOption("onLoading", AjaxOption.SCRIPT));
	 list.addObject(new AjaxOption("evalScripts", Boolean.TRUE, AjaxOption.BOOLEAN));
  ...
	 NSMutableDictionary<String, String> options =
   AjaxOption.createAjaxOptionsDictionary(list, component, associations());
	 return options;
}

response.appendContentString("AUC.registerPeriodic('" +
id + "'," + canStop + "," + stopped + ",");
AjaxOptions.appendToResponse(options, response, context);
response.appendContentString(");");
Part II



•   Being the Second Part
Twenty Steps to WO-Ajax

•   Who loves ya baby?

•   From discovery to commit

•   slowly

•   in 20 steps
Step 1: Review and Plan

•   Find something

•   See if it is worth using

•   Plan how you will use it
Step 2: Check that License


•   Licenses like the GPL are best avoided

•   For Wonder: BSD, MIT or Apache 2 are preferred

•   For your own projects consider the terms
Step 3: Download Source Files

•   Determine JavaScript files needed

•   Often component specific and supporting
Step 4: Download Resources

•   Get example HTML from demo source

•   CSS files

•   Image resources

•   License file

•   Other resources?
Step 5: Start Small
•   AjaxComponent or
    AjaxDynamicElement?

•   Ajax, ERCoolComponents, or
    private?

•   Create class and/or .wo

•   Add JS, CSS, images, etc to
    WebServerResources
Step 6: addRequiredWebResources

protected void addRequiredWebResources(WOResponse response, WOContext context) {

    addScriptResourceInHead(context, response, "Ajax", "controls.js");
    addScriptResourceInHead(context, response, "Ajax", "prototype.js");

    addScriptResourceInHead(context, response,
        "ERCoolComponents", "Rating/livepipe.js");
    addScriptResourceInHead(context, response,
        "ERCoolComponents", "Rating/rating.js");
    addStylesheetResourceInHead(context, response,
        "ERCoolComponents", "Rating/rating.css");

}
Step 7: Static appendToResponse

public void appendToResponse(WOResponse response, WOContext context) {

    super.appendToResponse(response, context);

    response.appendContentString("<div id="rating_one" class="rating_container">");
    response.appendContentString("</div>");

    response.appendContentString("<script type="text/javascript">");
    response.appendContentString("var rating_one = new Control.Rating('rating_one');");
    response.appendContentString("</script>");

}
Step 8: handleRequest

public WOActionResults handleRequest(WORequest request, WOContext context) {

    System.out.println("CCRating " + request.headers());

    return null;
}
Step 9: Initial Testing

•   Smoke Test Time!

•   Is control rendered correctly?

•   Does CSS load?

•   Are images visible?

•   Does it “work” client side?
Step 10: Check Client Side Errors

•   Use FireBug or Safari Web Inspector

•   Look for errors in JavaScript console

•   Look for resources that fail to load
Step 11: Update Paths in CSS
Resource paths in CSS are likely wrong:

background-image:url(/stylesheets/rating.gif);

These are resolved (by Wonder) relative to the CSS
file’s location:

background-image:url(rating.gif);
Step 12a: First Dynamic Steps
public void appendToResponse(WOResponse response, WOContext context) {

 super.appendToResponse(response, context);

 String id = (String) valueForBinding(
     "id",
     ERXWOContext.safeIdentifierName(context, false),
     context.component());

 response.appendContentString("<div ");

 appendTagAttributeToResponse(response, "id", id);
 appendTagAttributeToResponse(response, "class", "rating_container");

 response.appendContentString("></div>");
Step 12b: First Dynamic Steps
appendToResponse continued...



response.appendContentString("<script type="text/javascript">");
response.appendContentString("var ");
response.appendContentString(id);
response.appendContentString(" = new Control.Rating('");
response.appendContentString(id);
response.appendContentString("'); </script>");
}
Step 13a: Rating Options
<script type="text/javascript">

  var e_1_0_0_1_3_7 = new Control.Rating('e_1_0_0_1_3_7',
          {value: 5,
           min:   2,
           max:   8}
       );

</script>
Step 13b: Rating Options
      response.appendContentString("'); </script>");

    response.appendContentString("', ");
    AjaxOptions.appendToResponse(createOptions(context), response, context);
    response.appendContentString("); </script>");
}

protected NSMutableDictionary createOptions(WOContext context) {
    NSMutableArray ajaxOptionsArray = new NSMutableArray();
    ajaxOptionsArray.addObject(new AjaxOption("min", AjaxOption.NUMBER));
    ajaxOptionsArray.addObject(new AjaxOption("max", AjaxOption.NUMBER));
    ajaxOptionsArray.addObject(new AjaxOption("value", AjaxOption.NUMBER));
    return AjaxOption.createAjaxOptionsDictionary(
            ajaxOptionsArray, context.component(), associations());
}
Step 14: Rest of Bindings
  ajaxOptionsArray.addObject(new AjaxOption("capture", AjaxOption.BOOLEAN));
ajaxOptionsArray.addObject(new AjaxOption("classNames", AjaxOption.DICTIONARY));

ajaxOptionsArray.addObject(
    new AjaxOption("input", "inputId", null, AjaxOption.STRING));

ajaxOptionsArray.addObject(new   AjaxOption("multiple", AjaxOption.BOOLEAN));
ajaxOptionsArray.addObject(new   AjaxOption("rated", AjaxOption.BOOLEAN));
ajaxOptionsArray.addObject(new   AjaxOption("reverse", AjaxOption.BOOLEAN));
ajaxOptionsArray.addObject(new   AjaxOption("updateOptions", AjaxOption.DICTIONARY));

ajaxOptionsArray.addObject(
    new AjaxOption("updateParameterName", "formValueName", null, AjaxOption.STRING));
Step 15a: Server Interaction
  ajaxOptionsArray.addObject(
  new AjaxOption("updateParameterName", "formValueName", null, AjaxOption.STRING));

ajaxOptionsArray.addObject(
    new AjaxConstantOption("updateParameterName", "formValueName",
        formValueName(context), AjaxOption.STRING));

ajaxOptionsArray.addObject(new AjaxConstantOption("updateUrl",
    AjaxUtils.ajaxComponentActionUrl(context), AjaxOption.STRING));

protected String formValueName(WOContext context) {
    return (String)valueForBinding(
    "formValueName",
    id(context) + "_value",
    context.component());
Step 15b: Server Interaction
    public WOActionResults handleRequest(WORequest request, WOContext context) {
      System.out.println("CCRating " + request.headers());
      System.out.println("CCRating " + request.uri());
      System.out.println("CCRating " + request.formValues());

     Object ratingValue = request.formValueForKey(formValueName(context));

     if (ratingValue instanceof String) {
         ratingValue = Integer.valueOf((String)ratingValue);
     }

     setValueForBinding(ratingValue, "value", context.component());

     return null;
}
Step 16: WO Integration: action Binding
public WOActionResults handleRequest(WORequest request, WOContext context) {
    Object ratingValue = request.formValueForKey(formValueName(context));
    if (ratingValue instanceof String) {
        ratingValue = Integer.valueOf((String)ratingValue);
    }
    setValueForBinding(ratingValue, "value", context.component());

    // Nothing gets returned to the client from the CCRating action so we
    // discard any result from firing the action binding
    if (hasBinding("action")) {
        valueForBinding("action", context.component());
    }

    return null;
}
Step 17a: WO Integration: Form Input
    protected boolean actAsInput(WOContext context) {
      return booleanValueForBinding("actAsInput", true, context.component());
}

protected NSMutableDictionary createOptions(WOContext context) {
...
    if ( ! actAsInput(context)) {
        ajaxOptionsArray.addObject(new AjaxConstantOption("updateUrl",
            AjaxUtils.ajaxComponentActionUrl(context), AjaxOption.STRING));
    }
    else {
        ajaxOptionsArray.addObject(new AjaxConstantOption("input",
            id(context) + "_input", AjaxOption.STRING));
    }
Step 17b: WO Integration: Form Input
  public void appendToResponse(WOResponse response, WOContext context) {
...
if (actAsInput(context)) {
    response.appendContentString("<input ");

      appendTagAttributeToResponse(response, "type", "hidden");

      appendTagAttributeToResponse(response, "id", id + "_input");
      appendTagAttributeToResponse(response, "name", formValueName(context));

      appendTagAttributeToResponse(response, "value",
          valueForBinding("value", context.component()));

      response.appendContentString("/>");
...
}
Step 17c: WO Integration: Form Input
    public void takeValuesFromRequest(WORequest request, WOContext context) {
      if (actAsInput(context)) {
          setValueFromFormValue(request, context);
      }
      super.takeValuesFromRequest(request, context);
}

protected void setValueFromFormValue(WORequest request, WOContext context) {
    Object ratingValue = request.formValueForKey(formValueName(context));
    if (ratingValue instanceof String) {
        ratingValue = Integer.valueOf((String)ratingValue);
    }
    setValueForBinding(ratingValue, "value", context.component());
}
Step 18: Clean and Document

•   Remove debugging code

•   General code clean-up and refactoring

•   JavaDocs for class

•   JavaDocs for methods, @param, @return
Step 19: @binding JavaDocs
  * @binding value the value to show in the ratings widget and the value set
                 when the user selects a different rating

* @binding actAsInput optional, default is <code>true</code>, if false updates
                      the value binding when clicked and optionally calls action
                      method

* @binding action optional, action method to fire when rating changed.   Ignored
                  if actAsInput is <code>true</code> or unbound

* @binding min optional, the value sent to the server when the lowest rating is
               selected, indirectly controls the number of rating points displayed
Step 20: Create .api File
MONTREAL 1/3 JULY 2011




Q&A
Ajax.framework: Under the Hood

Chuck Hill
Global Village Consulting

More Related Content

What's hot

Getting started with jQuery
Getting started with jQueryGetting started with jQuery
Getting started with jQueryGill Cleeren
 
Specification-Driven Development of REST APIs by Alexander Zinchuk
Specification-Driven Development of REST APIs by Alexander Zinchuk   Specification-Driven Development of REST APIs by Alexander Zinchuk
Specification-Driven Development of REST APIs by Alexander Zinchuk OdessaJS Conf
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Robert DeLuca
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQueryZeeshan Khan
 
Pascarello_Investigating JavaScript and Ajax Security
Pascarello_Investigating JavaScript and Ajax SecurityPascarello_Investigating JavaScript and Ajax Security
Pascarello_Investigating JavaScript and Ajax Securityamiable_indian
 
Elasticsearch for SQL Users
Elasticsearch for SQL UsersElasticsearch for SQL Users
Elasticsearch for SQL UsersAll Things Open
 
Hidden Treasures in Project Wonder
Hidden Treasures in Project WonderHidden Treasures in Project Wonder
Hidden Treasures in Project WonderWO Community
 
BDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web TestingBDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web TestingJohn Ferguson Smart Limited
 
Top 10 HTML5 features every developer should know!
Top 10 HTML5 features every developer should know!Top 10 HTML5 features every developer should know!
Top 10 HTML5 features every developer should know!Gill Cleeren
 
Ajax Overview by Bally Chohan
Ajax Overview by Bally ChohanAjax Overview by Bally Chohan
Ajax Overview by Bally ChohanWebVineet
 
Building AOL's High Performance, Enterprise Wide Mail Application With Silver...
Building AOL's High Performance, Enterprise Wide Mail Application With Silver...Building AOL's High Performance, Enterprise Wide Mail Application With Silver...
Building AOL's High Performance, Enterprise Wide Mail Application With Silver...goodfriday
 
Crafting Evolvable Api Responses
Crafting Evolvable Api ResponsesCrafting Evolvable Api Responses
Crafting Evolvable Api Responsesdarrelmiller71
 
Lille2010markp
Lille2010markpLille2010markp
Lille2010markpCh'ti JUG
 

What's hot (20)

Getting started with jQuery
Getting started with jQueryGetting started with jQuery
Getting started with jQuery
 
Xml http request
Xml http requestXml http request
Xml http request
 
ERGroupware
ERGroupwareERGroupware
ERGroupware
 
Ajax
AjaxAjax
Ajax
 
Specification-Driven Development of REST APIs by Alexander Zinchuk
Specification-Driven Development of REST APIs by Alexander Zinchuk   Specification-Driven Development of REST APIs by Alexander Zinchuk
Specification-Driven Development of REST APIs by Alexander Zinchuk
 
AJAX Crawl
AJAX CrawlAJAX Crawl
AJAX Crawl
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
 
Pascarello_Investigating JavaScript and Ajax Security
Pascarello_Investigating JavaScript and Ajax SecurityPascarello_Investigating JavaScript and Ajax Security
Pascarello_Investigating JavaScript and Ajax Security
 
Ajax
AjaxAjax
Ajax
 
Elasticsearch for SQL Users
Elasticsearch for SQL UsersElasticsearch for SQL Users
Elasticsearch for SQL Users
 
Hidden Treasures in Project Wonder
Hidden Treasures in Project WonderHidden Treasures in Project Wonder
Hidden Treasures in Project Wonder
 
BDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web TestingBDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web Testing
 
Top 10 HTML5 features every developer should know!
Top 10 HTML5 features every developer should know!Top 10 HTML5 features every developer should know!
Top 10 HTML5 features every developer should know!
 
Ajax3
Ajax3Ajax3
Ajax3
 
Ajax Overview by Bally Chohan
Ajax Overview by Bally ChohanAjax Overview by Bally Chohan
Ajax Overview by Bally Chohan
 
Building AOL's High Performance, Enterprise Wide Mail Application With Silver...
Building AOL's High Performance, Enterprise Wide Mail Application With Silver...Building AOL's High Performance, Enterprise Wide Mail Application With Silver...
Building AOL's High Performance, Enterprise Wide Mail Application With Silver...
 
Web2.0 with jQuery in English
Web2.0 with jQuery in EnglishWeb2.0 with jQuery in English
Web2.0 with jQuery in English
 
Crafting Evolvable Api Responses
Crafting Evolvable Api ResponsesCrafting Evolvable Api Responses
Crafting Evolvable Api Responses
 
Lille2010markp
Lille2010markpLille2010markp
Lille2010markp
 

Viewers also liked

Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.WO Community
 
Troubleshooting D2W Rules
Troubleshooting D2W RulesTroubleshooting D2W Rules
Troubleshooting D2W RulesWO Community
 
Contributing to the Community
Contributing to the CommunityContributing to the Community
Contributing to the CommunityWO Community
 
Advanced Apache Cayenne
Advanced Apache CayenneAdvanced Apache Cayenne
Advanced Apache CayenneWO Community
 
COScheduler In Depth
COScheduler In DepthCOScheduler In Depth
COScheduler In DepthWO Community
 

Viewers also liked (6)

Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
 
Troubleshooting D2W Rules
Troubleshooting D2W RulesTroubleshooting D2W Rules
Troubleshooting D2W Rules
 
Contributing to the Community
Contributing to the CommunityContributing to the Community
Contributing to the Community
 
Advanced Apache Cayenne
Advanced Apache CayenneAdvanced Apache Cayenne
Advanced Apache Cayenne
 
WOdka
WOdkaWOdka
WOdka
 
COScheduler In Depth
COScheduler In DepthCOScheduler In Depth
COScheduler In Depth
 

Similar to Ajax Under The Hood

Ajax tutorial
Ajax tutorialAjax tutorial
Ajax tutorialKat Roque
 
Introduction to ajax
Introduction to ajaxIntroduction to ajax
Introduction to ajaxNir Elbaz
 
Building Applications Using Ajax
Building Applications Using AjaxBuilding Applications Using Ajax
Building Applications Using Ajaxs_pradeep
 
How to make Ajax work for you
How to make Ajax work for youHow to make Ajax work for you
How to make Ajax work for youSimon Willison
 
API Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationAPI Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationRouven Weßling
 
Barcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentationBarcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentationSociable
 
Soa development using javascript
Soa development using javascriptSoa development using javascript
Soa development using javascriptDsixE Inc
 
jQuery and Rails: Best Friends Forever
jQuery and Rails: Best Friends ForeverjQuery and Rails: Best Friends Forever
jQuery and Rails: Best Friends Foreverstephskardal
 
Plone Interactivity
Plone InteractivityPlone Interactivity
Plone InteractivityEric Steele
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous JavascriptGarrett Welson
 
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...mfrancis
 
OSGi and Spring Data for simple (Web) Application Development
OSGi and Spring Data  for simple (Web) Application DevelopmentOSGi and Spring Data  for simple (Web) Application Development
OSGi and Spring Data for simple (Web) Application DevelopmentChristian Baranowski
 
Ajaxtechnicalworkshopshortversion 1224845432835700-8
Ajaxtechnicalworkshopshortversion 1224845432835700-8Ajaxtechnicalworkshopshortversion 1224845432835700-8
Ajaxtechnicalworkshopshortversion 1224845432835700-8anuradha raheja
 

Similar to Ajax Under The Hood (20)

Ajax tutorial
Ajax tutorialAjax tutorial
Ajax tutorial
 
Introduction to ajax
Introduction to ajaxIntroduction to ajax
Introduction to ajax
 
Building Applications Using Ajax
Building Applications Using AjaxBuilding Applications Using Ajax
Building Applications Using Ajax
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
 
How to make Ajax work for you
How to make Ajax work for youHow to make Ajax work for you
How to make Ajax work for you
 
React js
React jsReact js
React js
 
API Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationAPI Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API Documentation
 
27javascript
27javascript27javascript
27javascript
 
Barcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentationBarcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentation
 
Soa development using javascript
Soa development using javascriptSoa development using javascript
Soa development using javascript
 
Javascript
JavascriptJavascript
Javascript
 
Ajax Lecture Notes
Ajax Lecture NotesAjax Lecture Notes
Ajax Lecture Notes
 
jQuery and Rails: Best Friends Forever
jQuery and Rails: Best Friends ForeverjQuery and Rails: Best Friends Forever
jQuery and Rails: Best Friends Forever
 
Plone Interactivity
Plone InteractivityPlone Interactivity
Plone Interactivity
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
 
OSGi and Spring Data for simple (Web) Application Development
OSGi and Spring Data  for simple (Web) Application DevelopmentOSGi and Spring Data  for simple (Web) Application Development
OSGi and Spring Data for simple (Web) Application Development
 
Ajax
AjaxAjax
Ajax
 
Ajaxtechnicalworkshopshortversion 1224845432835700-8
Ajaxtechnicalworkshopshortversion 1224845432835700-8Ajaxtechnicalworkshopshortversion 1224845432835700-8
Ajaxtechnicalworkshopshortversion 1224845432835700-8
 
J query resh
J query reshJ query resh
J query resh
 

More from WO Community

In memory OLAP engine
In memory OLAP engineIn memory OLAP engine
In memory OLAP engineWO Community
 
Using Nagios to monitor your WO systems
Using Nagios to monitor your WO systemsUsing Nagios to monitor your WO systems
Using Nagios to monitor your WO systemsWO Community
 
Build and deployment
Build and deploymentBuild and deployment
Build and deploymentWO Community
 
Reenabling SOAP using ERJaxWS
Reenabling SOAP using ERJaxWSReenabling SOAP using ERJaxWS
Reenabling SOAP using ERJaxWSWO Community
 
Chaining the Beast - Testing Wonder Applications in the Real World
Chaining the Beast - Testing Wonder Applications in the Real WorldChaining the Beast - Testing Wonder Applications in the Real World
Chaining the Beast - Testing Wonder Applications in the Real WorldWO Community
 
D2W Stateful Controllers
D2W Stateful ControllersD2W Stateful Controllers
D2W Stateful ControllersWO Community
 
Deploying WO on Windows
Deploying WO on WindowsDeploying WO on Windows
Deploying WO on WindowsWO Community
 
Unit Testing with WOUnit
Unit Testing with WOUnitUnit Testing with WOUnit
Unit Testing with WOUnitWO Community
 
Apache Cayenne for WO Devs
Apache Cayenne for WO DevsApache Cayenne for WO Devs
Apache Cayenne for WO DevsWO Community
 
Migrating existing Projects to Wonder
Migrating existing Projects to WonderMigrating existing Projects to Wonder
Migrating existing Projects to WonderWO Community
 
iOS for ERREST - alternative version
iOS for ERREST - alternative versioniOS for ERREST - alternative version
iOS for ERREST - alternative versionWO Community
 
"Framework Principal" pattern
"Framework Principal" pattern"Framework Principal" pattern
"Framework Principal" patternWO Community
 
Filtering data with D2W
Filtering data with D2W Filtering data with D2W
Filtering data with D2W WO Community
 
Localizing your apps for multibyte languages
Localizing your apps for multibyte languagesLocalizing your apps for multibyte languages
Localizing your apps for multibyte languagesWO Community
 
D2W Branding Using jQuery ThemeRoller
D2W Branding Using jQuery ThemeRollerD2W Branding Using jQuery ThemeRoller
D2W Branding Using jQuery ThemeRollerWO Community
 

More from WO Community (20)

KAAccessControl
KAAccessControlKAAccessControl
KAAccessControl
 
In memory OLAP engine
In memory OLAP engineIn memory OLAP engine
In memory OLAP engine
 
Using Nagios to monitor your WO systems
Using Nagios to monitor your WO systemsUsing Nagios to monitor your WO systems
Using Nagios to monitor your WO systems
 
Build and deployment
Build and deploymentBuild and deployment
Build and deployment
 
High availability
High availabilityHigh availability
High availability
 
Reenabling SOAP using ERJaxWS
Reenabling SOAP using ERJaxWSReenabling SOAP using ERJaxWS
Reenabling SOAP using ERJaxWS
 
Chaining the Beast - Testing Wonder Applications in the Real World
Chaining the Beast - Testing Wonder Applications in the Real WorldChaining the Beast - Testing Wonder Applications in the Real World
Chaining the Beast - Testing Wonder Applications in the Real World
 
D2W Stateful Controllers
D2W Stateful ControllersD2W Stateful Controllers
D2W Stateful Controllers
 
Deploying WO on Windows
Deploying WO on WindowsDeploying WO on Windows
Deploying WO on Windows
 
Unit Testing with WOUnit
Unit Testing with WOUnitUnit Testing with WOUnit
Unit Testing with WOUnit
 
Life outside WO
Life outside WOLife outside WO
Life outside WO
 
Apache Cayenne for WO Devs
Apache Cayenne for WO DevsApache Cayenne for WO Devs
Apache Cayenne for WO Devs
 
Migrating existing Projects to Wonder
Migrating existing Projects to WonderMigrating existing Projects to Wonder
Migrating existing Projects to Wonder
 
iOS for ERREST - alternative version
iOS for ERREST - alternative versioniOS for ERREST - alternative version
iOS for ERREST - alternative version
 
iOS for ERREST
iOS for ERRESTiOS for ERREST
iOS for ERREST
 
"Framework Principal" pattern
"Framework Principal" pattern"Framework Principal" pattern
"Framework Principal" pattern
 
Filtering data with D2W
Filtering data with D2W Filtering data with D2W
Filtering data with D2W
 
WOver
WOverWOver
WOver
 
Localizing your apps for multibyte languages
Localizing your apps for multibyte languagesLocalizing your apps for multibyte languages
Localizing your apps for multibyte languages
 
D2W Branding Using jQuery ThemeRoller
D2W Branding Using jQuery ThemeRollerD2W Branding Using jQuery ThemeRoller
D2W Branding Using jQuery ThemeRoller
 

Recently uploaded

UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 

Recently uploaded (20)

UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 

Ajax Under The Hood

  • 1. MONTREAL 1/3 JULY 2011 Ajax.framework: Under the Hood Chuck Hill Global Village Consulting, Inc. WOWODC 2011
  • 2. Session Overview • My Goals • Outline: • Ajax vs Classical WebObjects • How Things Work vs Just Works • Building Blocks • Case Study • No JSON
  • 3. A Word on our Sponsors • Jean-Francois Veillette • Anjo Krank • Mike Schrag • the rest of us • you
  • 4. A Word on JavaScript • Not a toy scripting language • NOT Java, “Lisp in C’s clothing” • functional programming • loose “duck” typing and prototypal inheritance • dynamic objects • Douglas Crockford and Yahoo
  • 6. Ajax R-R in a Nutshell
  • 7. New R-R Loop Phase • handleRequest • replaces action method • returns response for Ajax request • called by invokeAction • ... at the right time! • takeValues→invokeAction→handleRequest→appendToResponse?’ • returns AjaxResponse (important!)
  • 8. Ajax Action R-R Loop • “The Basic” • takeValues • invokeAction • handleRequest • whatever • can return JS, HTML, or nothing • client-side result varies
  • 9. Ajax Update R-R Loop • “The Meat Lover’s” • ...?_u=MyContainerID&1239887663 • invokeAction • handleRequest • AjaxResponse.generateResponse • invokeAction (yes! again!) • handleRequest (on AUC) • appendChildrenToResponse (AUC)
  • 10. Ajax Submit, Action, & Update • “All Dressed” • takeValuesFromRequest • invokeAction • handleRequest • AjaxResponse.generateResponse • invokeAction (yes! again!) • handleRequest (on AUC) • action method (result discarded) • appendChildrenToResponse (AUC)
  • 11. Ajax Replace R-R Loop • “Poutine Pizza” • ...?_r=true&1239887663 • takeValuesFromRequest • invokeAction • handleRequest • action method (component) returned as replacement) • intuitive, but may be dangerous
  • 12. Special Ajax Classes • AjaxRequestHandler: don’t store page • ERXAjaxApplication: no takeVlaues for ?_u=xxx&2309482093 • ERXAjaxSession: Ajax Page Caching • ERXAjaxContext: partial form submits • AjaxResponse: generateResponse→invokeAction for AUC
  • 15. Support Classes • AjaxComponent • AjaxDynamicElement • AjaxUtils • AjaxOptions, AjaxOption, AjaxConstantOption, AjaxValue
  • 16. AjaxComponent • WOComponent replacement • Stateful • Mostly familiar usage • handleRequest • addRequiredWebResources
  • 17. AjaxDynamicElement • WODynamicGroup replacement • Stateless • Harder to use than WOComponent • Binding and template access • handleRequest • addRequiredWebResources
  • 18. AjaxUtils • createResponse • javascriptResponse • Add JS and CSS resources (via ERXResponseRewriter) • shouldHandleRequest • binding convenience with JSON parsing • response generation • updateDomElement • redirecting • etc. seek and ye shall find
  • 19. JavaScript/JSON Value Encoding new Ajax.Request('/some_url', { method: 'get', parameters: {company: 'example', limit: 12} });
  • 20. AjaxValue • converts to JavaScript/JSON format • type-aware value • type guessing ability • javascriptValue • [a, b, ...], {a:b; ...}, escaping in strings etc.
  • 21. AjaxOption.Type • simple enumeration • AjaxValue data types • update if you extend AjaxValue
  • 22. AjaxOption • named for Prototype parameter “options” • bridge from bindings to JavaScript • component or dynamic element • Parameters • JavaScript Name • Type • Binding Name • Default Value
  • 23. AjaxConstantOption • Used for computed values public AjaxConstantOption( String javaScriptName, Object constantValue, Type type)
  • 24. AjaxOptions • with an S • collection of key-value pairs • used as component* or class • *component usage likely buggy • works with StringBuffer and WOResponse • works best with AjaxOption.createAjaxOptionsDictionary
  • 25. AjaxOptions Usage public NSDictionary createAjaxOptions(WOComponent component) { NSMutableArray<AjaxOption> list = new NSMutableArray<AjaxOption>(); list.addObject(new AjaxOption("frequency", AjaxOption.NUMBER)); list.addObject(new AjaxOption("onLoading", AjaxOption.SCRIPT)); list.addObject(new AjaxOption("evalScripts", Boolean.TRUE, AjaxOption.BOOLEAN)); ... NSMutableDictionary<String, String> options = AjaxOption.createAjaxOptionsDictionary(list, component, associations()); return options; } response.appendContentString("AUC.registerPeriodic('" + id + "'," + canStop + "," + stopped + ","); AjaxOptions.appendToResponse(options, response, context); response.appendContentString(");");
  • 26. Part II • Being the Second Part
  • 27. Twenty Steps to WO-Ajax • Who loves ya baby? • From discovery to commit • slowly • in 20 steps
  • 28. Step 1: Review and Plan • Find something • See if it is worth using • Plan how you will use it
  • 29. Step 2: Check that License • Licenses like the GPL are best avoided • For Wonder: BSD, MIT or Apache 2 are preferred • For your own projects consider the terms
  • 30. Step 3: Download Source Files • Determine JavaScript files needed • Often component specific and supporting
  • 31. Step 4: Download Resources • Get example HTML from demo source • CSS files • Image resources • License file • Other resources?
  • 32. Step 5: Start Small • AjaxComponent or AjaxDynamicElement? • Ajax, ERCoolComponents, or private? • Create class and/or .wo • Add JS, CSS, images, etc to WebServerResources
  • 33. Step 6: addRequiredWebResources protected void addRequiredWebResources(WOResponse response, WOContext context) { addScriptResourceInHead(context, response, "Ajax", "controls.js"); addScriptResourceInHead(context, response, "Ajax", "prototype.js"); addScriptResourceInHead(context, response, "ERCoolComponents", "Rating/livepipe.js"); addScriptResourceInHead(context, response, "ERCoolComponents", "Rating/rating.js"); addStylesheetResourceInHead(context, response, "ERCoolComponents", "Rating/rating.css"); }
  • 34. Step 7: Static appendToResponse public void appendToResponse(WOResponse response, WOContext context) { super.appendToResponse(response, context); response.appendContentString("<div id="rating_one" class="rating_container">"); response.appendContentString("</div>"); response.appendContentString("<script type="text/javascript">"); response.appendContentString("var rating_one = new Control.Rating('rating_one');"); response.appendContentString("</script>"); }
  • 35. Step 8: handleRequest public WOActionResults handleRequest(WORequest request, WOContext context) { System.out.println("CCRating " + request.headers()); return null; }
  • 36. Step 9: Initial Testing • Smoke Test Time! • Is control rendered correctly? • Does CSS load? • Are images visible? • Does it “work” client side?
  • 37. Step 10: Check Client Side Errors • Use FireBug or Safari Web Inspector • Look for errors in JavaScript console • Look for resources that fail to load
  • 38. Step 11: Update Paths in CSS Resource paths in CSS are likely wrong: background-image:url(/stylesheets/rating.gif); These are resolved (by Wonder) relative to the CSS file’s location: background-image:url(rating.gif);
  • 39. Step 12a: First Dynamic Steps public void appendToResponse(WOResponse response, WOContext context) { super.appendToResponse(response, context); String id = (String) valueForBinding( "id", ERXWOContext.safeIdentifierName(context, false), context.component()); response.appendContentString("<div "); appendTagAttributeToResponse(response, "id", id); appendTagAttributeToResponse(response, "class", "rating_container"); response.appendContentString("></div>");
  • 40. Step 12b: First Dynamic Steps appendToResponse continued... response.appendContentString("<script type="text/javascript">"); response.appendContentString("var "); response.appendContentString(id); response.appendContentString(" = new Control.Rating('"); response.appendContentString(id); response.appendContentString("'); </script>"); }
  • 41. Step 13a: Rating Options <script type="text/javascript"> var e_1_0_0_1_3_7 = new Control.Rating('e_1_0_0_1_3_7', {value: 5, min: 2, max: 8} ); </script>
  • 42. Step 13b: Rating Options response.appendContentString("'); </script>"); response.appendContentString("', "); AjaxOptions.appendToResponse(createOptions(context), response, context); response.appendContentString("); </script>"); } protected NSMutableDictionary createOptions(WOContext context) { NSMutableArray ajaxOptionsArray = new NSMutableArray(); ajaxOptionsArray.addObject(new AjaxOption("min", AjaxOption.NUMBER)); ajaxOptionsArray.addObject(new AjaxOption("max", AjaxOption.NUMBER)); ajaxOptionsArray.addObject(new AjaxOption("value", AjaxOption.NUMBER)); return AjaxOption.createAjaxOptionsDictionary( ajaxOptionsArray, context.component(), associations()); }
  • 43. Step 14: Rest of Bindings ajaxOptionsArray.addObject(new AjaxOption("capture", AjaxOption.BOOLEAN)); ajaxOptionsArray.addObject(new AjaxOption("classNames", AjaxOption.DICTIONARY)); ajaxOptionsArray.addObject( new AjaxOption("input", "inputId", null, AjaxOption.STRING)); ajaxOptionsArray.addObject(new AjaxOption("multiple", AjaxOption.BOOLEAN)); ajaxOptionsArray.addObject(new AjaxOption("rated", AjaxOption.BOOLEAN)); ajaxOptionsArray.addObject(new AjaxOption("reverse", AjaxOption.BOOLEAN)); ajaxOptionsArray.addObject(new AjaxOption("updateOptions", AjaxOption.DICTIONARY)); ajaxOptionsArray.addObject( new AjaxOption("updateParameterName", "formValueName", null, AjaxOption.STRING));
  • 44. Step 15a: Server Interaction ajaxOptionsArray.addObject( new AjaxOption("updateParameterName", "formValueName", null, AjaxOption.STRING)); ajaxOptionsArray.addObject( new AjaxConstantOption("updateParameterName", "formValueName", formValueName(context), AjaxOption.STRING)); ajaxOptionsArray.addObject(new AjaxConstantOption("updateUrl", AjaxUtils.ajaxComponentActionUrl(context), AjaxOption.STRING)); protected String formValueName(WOContext context) { return (String)valueForBinding( "formValueName", id(context) + "_value", context.component());
  • 45. Step 15b: Server Interaction public WOActionResults handleRequest(WORequest request, WOContext context) { System.out.println("CCRating " + request.headers()); System.out.println("CCRating " + request.uri()); System.out.println("CCRating " + request.formValues()); Object ratingValue = request.formValueForKey(formValueName(context)); if (ratingValue instanceof String) { ratingValue = Integer.valueOf((String)ratingValue); } setValueForBinding(ratingValue, "value", context.component()); return null; }
  • 46. Step 16: WO Integration: action Binding public WOActionResults handleRequest(WORequest request, WOContext context) { Object ratingValue = request.formValueForKey(formValueName(context)); if (ratingValue instanceof String) { ratingValue = Integer.valueOf((String)ratingValue); } setValueForBinding(ratingValue, "value", context.component()); // Nothing gets returned to the client from the CCRating action so we // discard any result from firing the action binding if (hasBinding("action")) { valueForBinding("action", context.component()); } return null; }
  • 47. Step 17a: WO Integration: Form Input protected boolean actAsInput(WOContext context) { return booleanValueForBinding("actAsInput", true, context.component()); } protected NSMutableDictionary createOptions(WOContext context) { ... if ( ! actAsInput(context)) { ajaxOptionsArray.addObject(new AjaxConstantOption("updateUrl", AjaxUtils.ajaxComponentActionUrl(context), AjaxOption.STRING)); } else { ajaxOptionsArray.addObject(new AjaxConstantOption("input", id(context) + "_input", AjaxOption.STRING)); }
  • 48. Step 17b: WO Integration: Form Input public void appendToResponse(WOResponse response, WOContext context) { ... if (actAsInput(context)) { response.appendContentString("<input "); appendTagAttributeToResponse(response, "type", "hidden"); appendTagAttributeToResponse(response, "id", id + "_input"); appendTagAttributeToResponse(response, "name", formValueName(context)); appendTagAttributeToResponse(response, "value", valueForBinding("value", context.component())); response.appendContentString("/>"); ... }
  • 49. Step 17c: WO Integration: Form Input public void takeValuesFromRequest(WORequest request, WOContext context) { if (actAsInput(context)) { setValueFromFormValue(request, context); } super.takeValuesFromRequest(request, context); } protected void setValueFromFormValue(WORequest request, WOContext context) { Object ratingValue = request.formValueForKey(formValueName(context)); if (ratingValue instanceof String) { ratingValue = Integer.valueOf((String)ratingValue); } setValueForBinding(ratingValue, "value", context.component()); }
  • 50. Step 18: Clean and Document • Remove debugging code • General code clean-up and refactoring • JavaDocs for class • JavaDocs for methods, @param, @return
  • 51. Step 19: @binding JavaDocs * @binding value the value to show in the ratings widget and the value set when the user selects a different rating * @binding actAsInput optional, default is <code>true</code>, if false updates the value binding when clicked and optionally calls action method * @binding action optional, action method to fire when rating changed. Ignored if actAsInput is <code>true</code> or unbound * @binding min optional, the value sent to the server when the lowest rating is selected, indirectly controls the number of rating points displayed
  • 52. Step 20: Create .api File
  • 53. MONTREAL 1/3 JULY 2011 Q&A Ajax.framework: Under the Hood Chuck Hill Global Village Consulting