class biz
Contract
Parameter keyDefault valueType
styleoptopt
onloadopttype.<one_of string hypertext.script/>
onunloadopttype.<one_of string hypertext.script/>
onchangeopttype.<one_of string hypertext.script/>
layoutoptlayout
ui_viewopt
accepts_drops_ofoptwob
draggableoptboolean
resizeablefalseboolean
cachetrueboolean
Parameter kindDefault valueType
Other unkeyed argumentsopt with ekind of mixedwob
Water Contract
<class biz
  style         =opt=style
  onload        =opt=<type.one_of string script/>
  onunload      =opt=<type.one_of string script/>
  onchange      =opt=<type.one_of string script/>
  layout        =opt=layout
  ui_view       =opt=ui_view
  accepts_drops_of=opt=wob
  draggable     =opt=boolean
  resizeable    =false=boolean
  cache         =true
  _wrapper_class=div
  _other_unkeyed=opt=wob=ekind.mixed="_add_to_environment"
/>

See also: opt, , layout

Introduction

AJAX is a process by which a browser can communicate with the server without loading a new page or reloading the current page. This allows a substantially richer user interface within the context of a given page, because the page may be dynamically updated in response to information received from the server. In general, manual programming of AJAX requires a lot of tedious mucking about in Javascript.

In Water, AJAX is instead written using biz objects, which use AJAX but do so in a manner by which you, the programmer, do not have to deal with the gory details of Javascript. The biz object also provides several other features relating both to user interface development and to organization of code. To outline some of its benefits, it:

  1. Enables nearly effortless integration of AJAX functionality into your application,
  2. Applies your specified styling properties to its content,
  3. Allows you to position content on the screen with pixel-level precision,
  4. Enables nearly effortless creation of drag-and-drop interfaces with automatic updating of associated data in the server-side data model,
  5. Facilitates automatic layout of objects and object hierarchies, and
  6. Encourages use of the desirable "model/view/controller" programming pattern which separates business logic from user interface.

The biz class helps you create complex web applications that behave more like non-web applications in that you can "refresh" just part of a page rather than refresh the whole page when it changes, as is common in web applications. This is quicker and gives the user a more graphically "solid" experience. It also gives you a lot more power, especially as your application grows in complexity.

By sticking to this technique of building an application you can avoid having to know the details of how the client and server communicate and keep all of your code in Water rather than resorting to Javascript, as is common for dynamic web pages.

A biz application consists of water classes which you write that all inherit from the 'biz' class. Usually, each of the classes will have:

Understanding Model/View/Controller

Model/View/Controller (MVC) is a programming pattern in which data, presentation, and business logic are kept separate. The "model" is your business data, as structured in objects. The "view" is the presentation code which outputs your data in a useful format, such as HTML. The "controller" is the business logic, represented as program source, which alters or updates the model. When used, the user interacts with the view, which causes a controller to update the model, and then updates the view. We'll get back to how this relates to biz objects.

Related objects

The biz object uses ui_view objects to position content on the web page, style objects to apply color and font formatting to the content, and layout objects to position objects with respect to each other. We'll get back to those objects, you don't have to know how they work to get started.

AJAX: Communication with the browser

In Water, AJAX may be programmed integrally, so that no herculean effort is required to make AJAX work. However, a specific programming pattern is required.

Programming Pattern for AJAX in Water

Subclass biz

You'll generally create a subclass of biz for your purpose:

<class biz.boat name="Titanic"=string/>

Where to put your content

In your class, there must be a method htm_inst which returns the content which is to represent the object on the page. This outputs the "view" part of the MVC pattern. An example:

<class biz.boat name="Titanic"=string>
  <method htm_inst>
    <P>The name of the boat is <do .name/></P>
  </method>
</class>

A default htm_inst method is provided for you that fulfills this requirement, so you don't always have to write one yourself if you don't want to. It returns the content of all the vector keys of the biz object.

Please note that when subclassing the biz object, you generally shouldn't shadow the default htm_inst method, which does much of the work of the biz object for you.

Separating logic from presentation

You also have to have a method that is called via AJAX to update the data model. This is the "controller" part of the MVC pattern. This method must also tell the browser what to do in response to its biz method call, even if you just want it to do nothing. (If you don't put in something to tell the browser what to do in response to its biz method call, an error will occur on the browser.) For our example, let's say that we want the user to be able to change the name of the boat, and when they do we want to update the object's representation on their browser to reflect the change:

<method change_name new_name=req=string>
  .<set name=new_name/>
  .<refresh/>
</method>

Note the use of the refresh method to update the content on the browser. That will generate fresh html using the htm_inst method, which will be sent to the browser with instructions to replace the existing content of the browser's representation of the object with the fresh content. This is how we tell the browser what to do as a response to the method call. Responses such as refresh are cumulative because they have side effects ont he server object, so you may in fact choose to refresh several objects in response to a single method call. The returned result of the method must be a response to the browser (such as a call to refresh), but due to the above mentioned side effects, not all responses must be returned by the method. For example, this would accomplish exactly the same thing as the preceding example:

<method change_name new_name=req=string>
  .<set name=new_name/>
  .<refresh/>
  .<do_nothing/>
</method>
It is required that your Water method in your biz object which is called by the browser must return a response to the browser because the browser is expecting a specifically formatted response, and any other returned value from the method would not be correctly formatted, and would therefore cause an error to occur on the browser.

Make an instance

For our example, we will need to make an instance of our object:

<set myBoat=biz.<boat/> />

Using form elements

For the user to update anything they have to have some interface elements for that, so the htm_inst method should have form elements. There are several differences between doing forms with AJAX in Water versus doing ordinary HTML forms.

No form tags in the biz content

The first is, in Water, you don't put a form tag around the content that you want to represent your "form" for the biz object. Form fields which are presented by an individual biz object are assumed to be related and act as a "virtual form" for that object instance. (If you examine the HTML output, you will find that the presentation of the biz object is wrapped in a div tag, which encloses the "virtual form".) Just present the biz object and think of its form fields as if they are their own form, distinct from others. Here is an example of how this looks to you in Water:

<method htm_inst>
  <P>The name of the boat is <do .name/>.<BR/>
  Change it to: <input type="text" id="boat_name" value=.name/> </P>
</method>

Some notes about this: It's okay to use the same field name in different classes, knowing that they'll appear on the same actual web page. Water's client-side code can determine the difference. Also, using several instances of the same class on the same page is also fine: Water's client-side code can determine the difference between those too. However, it is a bad idea to cause a single instance of a biz object to appear on the same page multiple times, as it becomes impossible to determine which copy of the instance is meant when AJAX method calls are prepared. Doing this will cause incorrect behaviors and is therefore strongly advised against.

Nested forms

The second difference is, "virtual forms" may be nested. A biz object's presentation may include as part of its content the presentation of another biz object. Each may have form elements. When the inner object's form is used and its content is refreshed, the outer object is not affected. When the outer object's form is used and its content is refreshed, the inner object's complete representation is refreshed as part of the content of the outer object.

No submit buttons, use handlers instead

The third difference is, instead of using a submit button to cause the web page to submit and retrieve a new page, handler attributes on hypertext elements are used to cause the action of an AJAX method call to the Water server, and the Water server determines which, if any, parts of the page should be altered or refreshed. The submit element should not be used. A special method called h2o is used to wrap around the method call that you wish to use when the action is performed on the browser. Here is an example of an HTML button which emulates the behavior of a submit button in the Water AJAX context, for our boat example:

<INPUT type="button" value="Submit" onClick=.<h2o> .<change_name new_name=boat_name/> </h2o> />

In the above example, new_name is the key of the parameter of the call to change_name for which we are setting a value, and boat_name is the id of the html form element from which the value to be set is to be retrieved. Instead of the id of an html form element, a literal value may also be used if the literal is a string or a number.

Serving your page with biz: minimum page requirements

When you use a biz object in a web page, there are some requirements which must be fulfilled in order for the biz functionality to work.

Requirements of HTML output

First, there is a required method call for the page head which imports required Javascript. Then, specific handlers must be placed in the body tag of the page. Finally, the content of the page must be wrapped in a form tag, which should be configured not to automatically submit. Here is a sample of the bare minimum html page required to use biz objects in Water, as it would be seen by the browser:

<HTML>
  <HEAD>
    <do biz.<include_scripts/> />
    <TITLE>Example</TITLE>
  </HEAD>
  <BODY 
    onMouseDown="handleMouseDown(event);" 
    onMouseUp="handleMouseUp(event);" 
    onMouseMove="handleMouseMove(event);"
  >
    <FORM action="foo" onSubmit="return false;">
      Content here
    </FORM>
  </BODY>
</HTML>
Relax: You don't have to remember that!

There are two methods by which you can generate a page which has all these requirements in it without having to do it manually. First, there is an object which will make the required alterations to an HTML page for you, so you don't have to worry about accidentally forgetting a detail. Instead of using the plain html object, just use the biz.html object instead, as shown in this corresponding example:

biz.<html>
  <HEAD>
    <TITLE>Example</TITLE>
  </HEAD>
  <BODY>
    Content here
  </BODY>
</html>

Please note that the two preceding examples output approximately identical HTML to the browser. Also, the biz.html class applies basic HTML formatting for you, so if you didn't care about the title, the preceding example could be represented as follows:

biz.<html>
  Content here
</html>
An even easier method

There's an easier way to get the benefits of biz.html without having to call it directly: simply make sure that the object that is served which represents the page is a biz object, and its output will be wrapped with a biz.html for you.

Keep in mind that because the entire contents of the page as output to the browser are contained within a form tag, you can't use the form object in your page content. However, it's unnecessary when using biz objects, so please don't be concerned.

Complete example

Finally, we make a page with our object in it. Here is a complete example showing our working boat object, using the biz.html method. Please note that when we display the object, we need to call its htm_inst method.

<class biz.boat name="Titanic"=string>    
  <!-- The structure of the class represents the model -->
  <method change_name new_name=req=string>   <!-- This is the controller method -->
    .<set name=new_name/>                    <!-- This updates the model -->
    .<refresh/>                              <!-- This updates the view -->
  </method>
  <method htm_inst>                       <!-- This method creates the view -->
    <P>The name of the boat is <do .name/>. <BR/>
      Change it to: <input type="text" id="boat_name" value=.name/> 
      <INPUT type="button" value="Submit" 
             onclick=.<h2o> .<change_name new_name=boat_name/> </h2o> 
      /> <!-- Notice the use of "button" -->
    </P>
  </method>
</class>
<set a_Boat=biz.<boat/> />                   <!-- Here we have created an instance -->
<!-- Next we'll make our page -->
wob.<set a_page=biz.<html>
    <do a_Boat />
  </html>
/> <!-- That's the end of the set statement for "a_Page" -->
<server root=wob port=8080/>  <!-- That starts the server -->
<open_browser_window "http://localhost:8080/a_page"/>  
<!-- That opens the browser to view our page -->

Now, here's the same example using the method of serving up a biz object.

<class biz.boat name="Titanic"=string>    
  <!-- The structure of the class represents the model -->
  <method change_name new_name=req=string>   <!-- This is the controller method -->
    .<set name=new_name/>                    <!-- This updates the model -->
    .<refresh/>                              <!-- This updates the view -->
  </method>
  <method htm_inst>                       <!-- This method creates the view -->
    <P>The name of the boat is <do .name/>. <BR/>
      Change it to: <input type="text" id="boat_name" value=.name/> 
      <input type="button" value="Submit" 
             onclick=.<h2o> .<change_name new_name=boat_name/> </h2o> 
      /> <!-- Notice the use of "button" -->
    </P>
  </method>
</class>
biz.<boat/>                   <!-- Here we have created an instance -->
<server root=wob port=8080/>  <!-- That starts the server -->
<open_browser_window "http://localhost:8080/biz/boat/of/0.htm"/>  
<!-- That opens the browser to view our page -->

This example demonstrates how the biz object works, but does not show many of the advantages of using it, because it has only one object. A large advantage of using biz objects on a more complex page is that objects can update small parts of the user interface without necessarily needing to update the whole thing. This is advantageous because it provides a smoother experience for the user (their page is not constantly being re-written in whole) and because it reduces load on the server (the server is not constantly generating entire pages, just small snippets).

Related Methods

method biz.make
Contract
Return typewob
No input parameters.
Water Contract
<method biz.make/>

The make method must call .<next_method/> to perform caching of the instance. instances are cached in the 'of' field of their class under a field key of a unique integer. As usual the make method should do any initialization of state variables and return its subject.
method biz.htm_inst
Contract
Return typewob
No input parameters.
Water Contract
<method biz.htm_inst/>

Displays, sequentially in order of key, the content of the vector keys of the object.

In many cases you will shadow (override) this method with a method that outputs your desired content. The default behavior is useful for use with drag and drop interfaces, or if you want to manage content through the vector keys.

method biz.htm_large
Contract
Return typewob
No input parameters.
Water Contract
<method biz.htm_large/>

Calls htm_inst to obtain the content to be output, and wraps this in a div formatted with appropriate CSS to give it such properties as have been specified for the object. Depending on attributes, it may or may not also output some Javascript to the browser to enable features such as draggability or drop areas.

This method should not be shadowed.

method biz.include_scripts
Contract
Return typewob
No input parameters.
Water Contract
<method biz.include_scripts/>

Inserts script tags which link to required Javascript library files used to provide client-side functionality for biz objects.

method biz.h2o
Contract
Return typestring
Parameter keyDefault valueType
a_path_or_callreq with ekind of expressionwob
Water Contract
<method biz.h2o
  a_path_or_call=req=wob=ekind.expression
  _return_type  =string/>

Wraps around a method call which is to be performed at a later time in response to an action which takes place on the browser.

In regard to actual output to the browser, biz.h2o outputs a Javascript function call which, when called, uses Water's browser-side code to send an AJAX method call back to the water server, potentially including certain data values collected from the user interface, as specified.

method biz.refresh
Contract
Return typewob
Parameter keyDefault valueType
a_key"whole_content"string
a_valueopt
Water Contract
<method biz.refresh
  a_key  ="whole_content"
  a_value=opt/>

The most frequent action taken in response to an AJAX method call from the browser is to update the content on the browser which represents the object in response to updates to the model based on information provided by the browser in the call. To update the browser's view of a biz object's content, call the refresh method on the object. refresh calls the htm_inst method on the biz object, and sends the results to the browser to be substituted in place of the previous content. This action updates an object's content representation without altering the content's container: in other words, this doesn't change its position, visibility, size, opacity, etc.

Refresh is usually used to refresh just a piece of the page. But if you would like to change the entire contents of the browser window, you can call refresh on the biz.window object. Here are some examples:

biz.window.<refresh a_value=<uri "http://www.ibm.com"/>/>
biz.window.<refresh a_value=<uri "/biz.htm"/>/>
biz.window.<refresh a_value=<H1>hello</H1> />
biz.window.<refresh a_value=biz />
biz.window.<refresh a_value="hello" />
method biz.ui_refresh
Contract
Return typewob
Parameter keyDefault valueType
ui_viewopt
Water Contract
<method biz.ui_refresh
  ui_view=opt/>

In some cases, in response to an AJAX method call from the browser, you may wish to alter properties of a biz object's container, such as its size or position or visibility. To do so, you would alter attributes of its ui_view, and then call its ui_refresh method. ui_refresh alters properties of an object's container without actually altering its content.

method biz.do_nothing
Contract
Return typewob
No input parameters.
Water Contract
<method biz.do_nothing/>

An incoming method call from a user's browser to a biz object via AJAX requires a response. Even if you don't desire the browser to do anything, a response must be supplied because the browser is waiting for one. In some cases, you may not want the browser to do anything in reaction to having made an AJAX call to the server, such as in cases where the browser is merely providing information to update state on the server. The do_nothing method allows you to explicitly provide a response to the browser which does nothing. This also clarifies your code by showing that you deliberately intended to do nothing. Note that do_nothing does not actually cancel any other actions you have queued for the browser: for example, if you call refresh followed by do_nothing, the refresh will still take place.

Positioning and layout

You may use CSS positioning to precisely position the output of a biz object on a web page to the precise pixel you desire, and to set its size to the precise size you desire. This is easily accomplished with the ui_view object. Simply create a ui_view with the properties you desire and pass it into the biz object's ui_view attribute, and the biz object will use the ui_view for positioning and sizing.

<class biz.position_example/>
biz.<position_example ui_view=<ui_view x=200 y=100/> >Hello World</position_example>
<server root=wob port=8080/>
<open_browser_window "http://localhost:8080/biz/position_example/of/0.htm"/>

To arrange the contents of the vector keys of a biz object, create an instance of layout or one of its subclasses and pass this into the biz object's layout attribute. The contents of the vector keys will be arranged according to the specifications of the layout used.

<class biz.layout_example _other_unkeyed=opt/>
biz.<layout_example layout=layout.<column/>>
  <H1>Water</H1>
  <H1>rocks</H1>
</layout_example>
<server root=wob port=8080/>
<open_browser_window "http://localhost:8080/biz/layout_example/of/0.htm"/>

Note that if you shadow the default htm_inst method for your biz object, objects which are not biz or ui_view objects may not appear in their correct places, because the default ui_view method is part of the process of wrapping such objects in ui_views. A solution to this is to place any such objects which you're placing in the vector keys of the biz object in a ui_view. Here's another version of our previous example with a new htm_inst, which will work in this manner:

<class biz.layout_example _other_unkeyed=opt=span>
  <method htm_inst>
    .<for_each combiner=join>
      <if>
        value.<is_a ui_view/>
          <do value.<htm_inst/> />
        else
          <do value/>
      </if>
    </for_each>
  </method>
</class>
biz.<layout_example layout=layout.<column/>>
  <ui_view><H1>Water</H1></ui_view>
  <ui_view><H1>rocks</H1></ui_view>
</layout_example>
<server root=wob port=8080/>
<open_browser_window "http://localhost:8080/biz/layout_example/of/0.htm"/>

Related fields

a wob

Each biz object has a ui_view for positioning the content on the page. If you do not supply a ui_view, one will be instantiated for you. (A ui_view with no specified parameters doesn't do much, so don't worry about it.)

Details of how the ui_view functions can be found in its documentation. For purposes of use with a biz object, the ui_view will behave as if the content of the biz is the content of the ui_view.

a wob

Holds a layout object. A layout's purpose is to arrange the objects in the vector keys of the biz object. Details of how the layout functions can be found in its documentation. For purposes of use with a biz object, the layout will behave as if the content of the biz is the content of the layout.

Drag and Drop

For a biz object to be draggable, it must be positioned using a ui_view as described in the above section on positioning. Then, set its draggable attribute to true. The user will be able to drag the object's HTML representation around the page, and it will stay where it is put, unless you've done something to alter this behavior (as described below).

For a biz object to be a drop area, it must be positioned using a ui_view as described in the above section on positioning. Then, set its accepts_drops_of attribute to either a class or a vector of classes which are the parents of whatever types of objects you want the drop area to accept. If you want it to accept drops of all draggable objects, set accepts_drops_of to biz .

In this example, we create a grey drop area and three colorful blocks which may be dropped on it. This illustrates default behaviors of draggable and drop area objects. We also make the drop area draggable, to illustrate that a drop area itself may be a draggable (and drop-able) object.

<class biz.color_box acolor=req=color draggable=true>
  <method htm_inst>
    <span>
      <TABLE border=0 cellpadding=0 cellspacing=0 bgcolor=.acolor>
        <TR><TD width=50 height=50>&nbsp;</TD></TR>
      </TABLE>
    </span>
  </method>
</class>
        
<class biz.drop_area/> <!-- That defines our drop area. -->
        
<class biz.drag_drop>
  <method make>
    .<set a_drop_area=biz.<drop_area 
                            draggable=true 
                            style=<style background-color="#ddeedd"/> 
                            accepts_drops_of=biz.color_box 
                            ui_view=<ui_view x=10 y=100 width=300 height=300/> 
                          /> 
      /> <!-- end of set a_drop_area -->
    .<set red_box=biz.<color_box acolor=<color 255 0 0/> ui_view=<ui_view x=100 y=10/> /> />
    .<set green_box=biz.<color_box acolor=<color 0 255 0/> ui_view=<ui_view x=200 y=10/> /> />
    .<set blue_box=biz.<color_box acolor=<color 0 0 255/> ui_view=<ui_view x=300 y=10/> /> />
    .<next_method/>
    _subject
  </method>

  <method htm_inst>
    <BODY>
      <do .a_drop_area />
      <do .red_box />
      <do .green_box />
      <do .blue_box />
    </BODY>
  </method>
</class>
        
biz.<drag_drop/> <!-- That creates our instance. -->
        
<server root=wob port=8080/>
<open_browser_window "http://localhost:8080/biz/drag_drop/of/0.htm"/>

Related fields

a wob
Parameter keyDefault valueType
draggableoptboolean

a wob
draggable=true
If other requirements are met, the object's html representation on the page will be draggable and will be eligible to be dropped on any dropareas which accept drops of items of its class.

a wob
draggable=false
The object's html representation on the page will appear in a fixed position. This is the same as the default behavior.

a wob
draggable=opt
The object's html representation on the page will appear in a fixed position. This is the default.

a wob
Parameter keyDefault valueType
accepts_drops_ofoptwob

May be set to a class or a vector of classes. Instances of these classes will be accepted as "drops" by this biz object, making this biz object a droparea.

Related methods

method biz.moving
Contract
Return typewob
No input parameters.
Water Contract
<method biz.moving/>

The moving method is called when the user begins to drag a draggable biz item. Its default action is to do nothing, as shown:

<method moving>
  .<do_nothing/>
</method>
method biz.moved
Contract
Return typewob
Parameter keyDefault valueType
xoptnumber
yoptnumber
Water Contract
<method biz.moved
  x=opt=number
  y=opt=number/>

The moved method is called when the user releases a dragged item from a drag action, regardless of whether or not the item has been dropped in a drop area. Its default action is to set the new location of the object according to where it was placed by the user, as shown:

<method moved x=opt=number y=opt=number> 
  <if>
    x.<is opt/>.<not/>
    .ui_view.<set x=x/>
  </if>
  <if>
    y.<is opt/>.<not/>
    .ui_view.<set y=y/>
  </if>
  .<do_nothing/>
</method>

A common use scenario would be that you wish the user to be able to reposition objects but not store their new locations on the server, because multiple people may be using the same object in their view of the UI and it isn't important to show one user where another user put an object. In this case, you could shadow this method to do nothing:

<method moved x=opt y=opt>
  .<do_nothing/>
</method>

Another common use scenario is that you want the user to be able to drag an object so that they may be able to drop it in a drop area, but you don't want the object to stay where it's put: you want it to snap back to its original location when they're done dragging. In this case, you could shadow this method to reset the ui_view of the object and then refresh its ui, as shown:

<method moved x=opt y=opt>
  .ui_view.<reset/>
  .<ui_refresh/>
</method>
method biz.dropped
Contract
Return typewob
Parameter keyDefault valueType
onoptstring
Water Contract
<method biz.dropped
  on=opt=string/>

The dropped method is called when the object has been dropped in a droparea. It has one attribute, on, which is the path of the object which it was dropped on. Its default action is to do nothing:

<method dropped on=opt=string>
  .<do_nothing/>
</method>
method biz.accept_drop
Contract
Return typewob
Parameter keyDefault valueType
droppedreqstring
Water Contract
<method biz.accept_drop
  dropped=req=string/>

The attribute dropped must be equal to the path of an object. The path is executed to obtain the dropped object itself. This dropped object is inserted into the vector keys of the biz object on which accept_drop was called, and then refresh is called on the biz object on which accept_drop was called, as shown:

<method accept_drop dropped=req=string>
  .<insert <execute source=dropped/> />
  .<refresh/>
</method>

In other words, the dropped object is added to the droparea's vector keys, and then the droparea is refreshed.

If you want the droparea to do something with the dropped object other than add it to its vector keys, you should shadow this method.

Subwindows

A subwindow is an HTML construct that has the appearance and behaviors of a window, but which appears inside the display area of a web browser. To cause a biz to be represented as a subwindow, set the chrome attribute of its ui_view to true.

<!-- First we'll define an object which lets us select a color and shows a sample. -->
<class biz.color_picker a_color="7777ff"=string draggable=true>
  <method change_color new_color=req=string> 
    <!-- This method is the controller that updates our model. -->
    .<set a_color=new_color/>
    <!-- As usual, it ends by refreshing the content. -->
    .<refresh/>
  </method>
  <!-- To illustrate altering the presentation, here's a controller method that makes
    the subwindow jump to the X position of 500 from wherever it is. -->
  <method jump>
    <!-- This is another controller method that updates our model. -->
    .ui_view.<set x=500 />
    <!-- In this case, we want to update the formatting of the content, not the content itself. 
      We do that using the ui_refresh method. -->
    .<ui_refresh/>
  </method>
  <method htm_inst>
    <!-- This method presents our view. -->
    <v
      <TABLE border=1 cellpadding=0 cellspacing=0 bgcolor=.a_color>
        <TR><TD width=50 height=50>&nbsp;</TD></TR>
      </TABLE>
      <INPUT type="text" id="the_color" value=.a_color/>
      <INPUT type="button" value="save" onclick=.<h2o> .<change_color new_color=the_color/> </h2o> />
      <INPUT type="button" value="jump" onclick=.<h2o> .<jump/> </h2o> />
    />
  </method>
</class>
<!-- Next we'll make an instance of our class. -->
biz.<color_picker 
        draggable=true 
        style=<style background-color="#dddddd"/> 
        ui_view=<ui_view x=350 y=100 width=200 height=100 chrome=true resizeable=true/> 
      />
<server root=wob port=8080/>
<open_browser_window "http://localhost:8080/biz/color_picker/of/0.htm"/>

a wob
Parameter keyDefault valueType
resizeablefalseboolean

a wob
resizeable=true
If all other requirements are met, the object's html representation on the page will be resizeable by dragging its lower left corner.
a wob
resizeable=false
The object's html representation on the page will appear with fixed size. This is the default .

Related methods

method biz.closed
Contract
Return typewob
No input parameters.
Water Contract
<method biz.closed/>

The closed method is called when a subwindow is closed. Its default action is to do nothing:

<method closed>
  .<do_nothing/>
</method>
method biz.resized
Contract
Return typewob
Parameter keyDefault valueType
woptnumber
hoptnumber
Water Contract
<method biz.resized
  w=opt=number
  h=opt=number/>

The resized method is called when the user resizes a subwindow in the user interface. Its default action is to set the new size of the object in the object's ui_view according to the size it was given by the user. A common use scenario would be that you wish the user to be able to resize the object but not store its new size on the server, because multiple people may be using the same object in their view of the UI and it isn't important to allow one user to resize subwindows for another user. In this case, you could shadow this method to do nothing:

<method resized w=opt h=opt>
  .<do_nothing/>
</method>

Other parameters

The parameters onload, onunload, and onchange are presently unused by biz. They are included for planned future functionality.

Example: hierarchical selection

In this example, we'll create a system by which the user may select something from a hierarchical list, one leval at a time. When they've made their final selection, we'll display a message indicating what it is.

<class biz.selection 
    title=req=string <!-- That will store the name of this selection -->
    selected=opt=number <!-- That will store the item they've selected -->
    _other_unkeyed=opt=wob=ekind.code <!-- That will store sub selections -->
>
  <!-- This controller method allows the user to update the model. -->
  <method change_to chosen=req>
    .<set selected=<execute source=chosen/> />
    .<refresh/>
  </method>
    
  <!-- Our view method first constructs the SELECT item, then displays stuff. -->
  <method htm_inst>
    <!-- First we create an instance of hypertext.select -->
    <set a_select=<select 
      size=5
      id="choice" 
      <!-- This will update the server when the user makes a selection -->
      onchange=.<h2o> .<change_to chosen=choice/> </h2o>
      /> <!-- end of select -->
    /> <!-- end of set -->
    <!-- Now we'll insert options into it for each sub choice after this. -->
    .<for_each>
      <if>
        value.<is_a biz.selection/>
          a_select.<insert <option 
                              value=key 
                              selected=<if> 
                                          key.<equal .selected/> 
                                            true 
                                          else 
                                            false 
                                       </if>
                              <!-- That sets the default selection. -->
                            >
                              <do value.title/>
                            </option> 
                    /> <!-- end of insert -->
        else
          a_select.<insert <option 
                              value=key 
                              selected=<if> 
                                          key.<equal .selected/> 
                                            true 
                                          else 
                                            false 
                                       </if>
                              <!-- That sets the default selection. -->
                            >
                              <do value/>
                            </option> 
                    /> <!-- end of insert -->
      </if>
    </for_each>
    <!-- now that we've constructed the select, we'll output some hypertext. -->
    <span>
      <!-- Show the current selection title -->
      <h1><do .title/></h1>
      <!-- Next, show the selections if there is a next level of choices. -->
      <if>
        .<length/>.<more 0/>
          <do a_select/>
      </if>
      <!-- Now show the selected item. -->
      <if>
        .selected.<is_not opt/>
          <if>
            .<get .selected/>.<is_a string/>
              <blockquote><h1>You selected <do .<get .selected/> /></h1></blockquote>
            else
              <blockquote><do .<get .selected/> /></blockquote>
          </if>
      </if>
    </span>
  </method>
</class>
    
    
<!-- Here's a sample structure to toy with. -->
<set structure=biz.<selection title="Restaurant Supplies">
        biz.<selection title="For the Office">
            biz.<selection title="Paper">
              "Note pads"
              "Printer paper"
              "Envelopes"
              "Yellow stickies"
            </selection>
            biz.<selection title="Pens">
              "Disposable ball point"
              "Permanent marker"
            </selection>
        </selection>
        biz.<selection title="For the Kitchen">
          "flour"
          "sugar"
          biz.<selection title="Milk">
            "whole"
            "2%"
            "skim"
          </selection>
          "chicken"
        </selection>
    </selection>
/>
    
<!-- Finally, we'll serve our example to the browser. -->
<server root=structure port=8080/>
<open_browser_window "http://localhost:8080/.htm"/>

Debugging

Debugging a biz object can be a bit unusual, because you're viewing the application through the browser rather than the development environment. Three error messages are included in the browser-side code which handles biz objects on the browser to assist you in understanding problems. The language of these error messages is written to try to sound unthreatening to an average web user, rather than to directly be highly informative, so you may find it helpful to be familiar with the errors so you know what causes them. The first:

We're sorry, but the browser is not compatible with the web standards required by the page you are viewing.

If the above message appears on the browser, the browser was unable to create an AJAX connection object as required by biz. This generally indicates that the browser used is not supported. In other words, it's not your fault.

We're sorry, but the server has experienced a difficulty, and this page is consequently unable to perform one of its tasks. Please try again later.

If the above message appears on the browser, an error has occurred on the Water server, and the problem must be diagnosed in the Water code being executed.

We're sorry, but an unusual status message was received from the server. This may be unimportant and everything may be fine, or it may indicate that there has been a problem which may require you to try again later. Should the web site administrators request further detail, they may wish to know the following information:

The above message indicates that a status code other than the usual 200 was received by the browser in response to its AJAX request to the browser as part of its biz functionality. This would normally be caused by a problem not directly related to the Water server or the browser itself, such as an error generated by the web host on which the Water server resides or a communication error. Should this type of error occur, the preceding error text would be followed by the response code number received from the server, the response name text received from the server, and finally any additional response text received from the server.

When you get this message, a good first step is to insert an echo at the beginning of your controller method to ensure that it's actually getting called. If it is, if you can't see the problem in it immediately, then you may wish to try commenting out sections of it to see what part of it the error is taking place in. If it is not, you should examine the call to h2o to ensure nothing is misspelled, that variable names are all correct, and that you're serving the page in a manner appropriate to meet the page requirements outlined above.

If you get an error with error code 404, a good quick first test is to look in the make method of your biz subclass, if you wrote a make method. If you did write a make method but forgot to call .<next_method/> , that would cause this problem.