Harvest and Seed

If you just want to use formwidgets, you can skip this section. If you want to extend or create formwidgets, you should also read the xbl source. Below, I will explain the general idea of harvest() and seed().

Every element of class formwidget should implement harvest() and seed(). Both method take an array of seeds, which I will call a bucket, as input parameter. One seed is an object with at least three properties: name, value and label.

A formwidget's harvest() method examines the contents of the element and adds seeds to the bucket. Most elements only add one seed, but some, like multiple select listboxes, may add more.

A formwidget's seed() method tries to do the reverse: it takes a (filled) bucket, and examines every seed in it to see if it matches the element, eg, if the "name" of the seed matches it's own "name" attribute. If it finds a match, it changes the it's own value and/or label accordingly and removes the seed from the bucket. But you can imagine the exact behaviour differs from element to element, given the different nature of elements.

The formbutton

The formbutton's harvestForm() method takes an additional XUL element as parameter. It optionally creates an empty bucket, and traverses the given element recursively, down the XML dom. To every formwidget it finds, It passes the bucket and lets it harvest() itself. In the end, the bucket contains 'the state of the form' as an array of seeds.

The formbutton's seedForm() method takes a XUL element and a filled bucket as parameter.It traverses the given element recursively, down the XML dom. It passes the bucket to every formwidget it finds and lets it seed() itself. In the end, the bucket might be empty.

When using harvestCGI() for HTTP, labels and other properties of a seed are discarded. The query string is comprised of simple name/value pairs. If you want the other properties to, check the "extendedcgi" attribute on the formbutton.

harvest!=inv(seed)

harvest() and seed() are not completely complementary: if you harvestForm(), store the bucket, and seedForm() it later with the stored bucket, the form does generally not return to its original state. There are differences due to ambiguous use of label vs. value, naming schemes, the behaviour of checkboxes, etc.