This is great! Thanks for posting this. This is a great guide for people that want to implement some of PW's form controls outside of the admin template. It looks like you've got all the parts covered. Since this thread is turning into a helpful tutorial and reference, I want to cover the different ways of getting and setting values to Inputfields:
$inputfield->name = value; // same as set() above, but shorter
$value = $input->attr('name');
$value = $inputfield->get('value');
$value = $inputfield->value; // same as get() above, but shorter
The attr() method is designed for explicitly setting setting/getting attributes that should go with the form input. For instance, 'name', 'class', 'id', 'value', 'checked', 'type', or whatever other attributes you want to go with the input. It should not be used for anything else because whatever you pass to it will end up as an attribute on the markup that gets output.
Whereas the set(), get() and direct reference methods are designed for setting/getting other properties, like field configuration options. They also work with attributes like the attr() method, but it's better to use the attr() method when setting an attribute just to be clear to PW that you intend that to be an actual attribute with the markup that gets output.
If you look in PW's code, you might also see it using these two functions in some instances:
$inputfield->setAttribute('name', 'value'); // same as $inputfield->attr('name', 'value');
$value = $inputfield->getAttribute('name'); // same as $value = $inputfield->attr('name');
These are the same thing as the attr() method, and the preferred syntax is to use the attr() method in your code. Internally, PW translates the attr() method to either setAttribute() or getAttribute(), depending on the number of arguments. The reason setAttribute() and getAttribute() exist is for people creating new Inputfield classes... it's easier to override single purpose methods rather than multi-purpose methods (like attr). But on a public interface, it's easier to use a multi-purpose method like attr(), so I recommend ignoring setAttribute() and getAttribute() unless you are developing new Inputfields.
Variations of attr()
In addition to getting and setting single attributes, the attr() method can also set multiple attributes at the same time. Below are all the possible variations (some repeated from above):
// set single attribute (same as example above)
// get single attribute (same as example above)
$value = $inputfield->attr('name');
// set multiple attributes with same value
// set multiple attributes with different values
$attrs = array(
'name' => 'value',
'name' => 'value',
Inputfields that contain other Inputfields
One type of Inputfield is the InputfieldWrapper, and it's designed solely to contain other Inputfields. Examples of InputfieldWrappers also include InputfieldForm and InputfieldFieldset (all are derived from InputfieldWrapper). On these Inputfields, the get() and direct reference can be used to retrieve any one of the fields by name:
$inputfield = $form->get('your_field_name');
$inputfield = $form->your_field_name; // direct reference works as alternate syntax
Internally, the two calls above translate to this:
$inputfield = $form->find("name=your_field_name")->first();
What that means is it'll find any field in the form, not just direct children of the field you are checking. So a call to $form->get('your_field_name') will return the associated field, regardless of of many fieldsets it's wrapped under. This is just to keep things simple. After all, the form fields are all living in the same namespace when the form gets output.
By the way, that find() method mentioned above can be used with any selector, just like with pages. It will return all inputfields in the form that match the properties you give it. But in practice, I've not ever needed it in my forms, so not sure how useful it really is.
You can add/remove Inputfields as children using these methods. In the example below, we'll assume that $form is an instance of InputfieldForm:
$form->append($inputfield); // append an inputfield to the form
$form->prepend($inputfield); // prepend an inputfield to the form
$form->add($inputfield); // same as append()
$form->remove($inputfield); // remove inputfield from the form
Built in properties
All Inputfields have these built-in properties that you can set or get:
$inputfield->label = "The clickable label that appears above this field. Should only be a few words.";
$inputfield->description = "A longer description that appears below the label. Can be any length.";
$inputfield->notes = "A extra highlighted area that appears under the field. Can be any length.";
$inputfield->head = "Headline that appears below label/above description. "; // PW 2.1 only!
$inputfield->id; // HTML 'id' attribute. Auto-generated if you don't set it.
$inputfield->name; // HTML 'name' attribute, required
$inputfield->value; // HTML 'value' attribute, if applicable
$inputfield->class; // HTML 'class' attribute, optional
$inputfield->required = 0; // value not required for this inputfield
$inputfield->required = 1; // value IS required for this inputfield
$inputfield->collapsed = Inputfield::collapsedNo; // Field will display open (this is the default)
$inputfield->collapsed = Inputfield::collapsedYes; // Field will display collapsed, requiring a click to open
$inputfield->collapsed = Inputfield::collapsedBlank; // Field will display collapsed only if blank
$inputfield->collapsed = Inputfield::collapsedHidden; // Field will not be rendered in the form