<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file except in
compliance with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<document id="forms">
    <properties>
        <title>Forms</title>
    </properties>

    <body>
        <p>
            Forms are often used to collect related pieces of information from a user. For example,
            an application that manages a user's music collection might provide a form that allows
            the user to enter such information as song title, artist, and album name, and a content
            management system might provide a form that allows a user to specify the title, author,
            and publication date of an article.
        </p>

        <p>
            Form contents are commonly organized into sections, to make it easier for the user to
            read. A contact management application might use a form such as the one shown below to
            collect information about the user's contacts. The form is divided into four sections,
            one for each aspect of the contact record: name, addresses, phone numbers, and email
            addresses. Note the use of the <tt>&lt;Form.Section&gt;</tt> elements to define the
            sections; the <tt>Form</tt>'s skin automatically inserts
            <a href="separators.html">separators</a> to visually partition the section content and
            uses the <tt>Form.Section</tt> heading as the <tt>Separator</tt> heading:
        </p>

        <application class="org.apache.pivot.wtk.ScriptApplication"
            width="512" height="384">
            <libraries>
                <library>core</library>
                <library>wtk</library>
                <library>wtk-terra</library>
                <library>tutorials</library>
            </libraries>
            <startup-properties>
                <src>/org/apache/pivot/tutorials/layout/forms.bxml</src>
            </startup-properties>
        </application>

        <p>
            The BXML for this example is shown below:
        </p>

        <source type="xml" location="org/apache/pivot/tutorials/layout/forms.bxml">
            <![CDATA[
            <layout:Forms title="Forms" maximized="true"
                xmlns:bxml="http://pivot.apache.org/bxml"
                xmlns:layout="org.apache.pivot.tutorials.layout"
                xmlns="org.apache.pivot.wtk">
                <Border styles="{padding:6}">
                    <TablePane>
                        <columns>
                            <TablePane.Column width="1*"/>
                        </columns>

                        <TablePane.Row height="1*">
                            <Form>
                                <Form.Section>
                                    <BoxPane bxml:id="nameBoxPane" Form.label="Name">
                                        <TextInput bxml:id="lastNameTextInput" prompt="Last"/>
                                        <TextInput bxml:id="firstNameTextInput" prompt="First"/>
                                    </BoxPane>
                                </Form.Section>

                                <Form.Section heading="Addresses">
                                    <BoxPane Form.label="Home" orientation="vertical">
                                        <TextInput prompt="Street" textSize="24"/>
                                        <BoxPane>
                                            <TextInput prompt="City"/>
                                            <TextInput prompt="State" textSize="6"/>
                                            <TextInput prompt="Zip" textSize="10"/>
                                        </BoxPane>
                                    </BoxPane>

                                    <BoxPane Form.label="Work" orientation="vertical">
                                        <TextInput prompt="Street" textSize="24"/>
                                        <BoxPane>
                                            <TextInput prompt="City"/>
                                            <TextInput prompt="State" textSize="6"/>
                                            <TextInput prompt="Zip" textSize="10"/>
                                        </BoxPane>
                                    </BoxPane>
                                </Form.Section>

                                <Form.Section heading="Phone Numbers">
                                    <TextInput Form.label="Home"/>
                                    <TextInput Form.label="Work"/>
                                </Form.Section>

                                <Form.Section heading="Email Addresses">
                                    <TextInput Form.label="Home"/>
                                    <TextInput Form.label="Work"/>
                                </Form.Section>
                            </Form>
                        </TablePane.Row>

                        <TablePane.Row height="-1">
                            <Separator/>
                        </TablePane.Row>

                        <TablePane.Row height="-1">
                            <TablePane>
                                <columns>
                                    <TablePane.Column width="1*"/>
                                    <TablePane.Column width="-1"/>
                                </columns>

                                <TablePane.Row>
                                    <BoxPane styles="{verticalAlignment:'center'}">
                                        <Label bxml:id="errorLabel" styles="{color:22}"/>
                                    </BoxPane>
                                    <BoxPane styles="{horizontalAlignment:'right', verticalAlignment:'center'}">
                                        <PushButton bxml:id="submitButton" buttonData="Submit"
                                            styles="{minimumAspectRatio:3}"/>
                                    </BoxPane>
                                </TablePane.Row>
                            </TablePane>
                        </TablePane.Row>
                    </TablePane>
                </Border>
            </layout:Forms>
            ]]>
        </source>

        <p>
            Also note the use of the <tt>Form.label</tt> attribute - this is an example of an
            "attached property", also called an "attribute" in WTK. An attribute is a property that
            can be specified on a component only when it is a child of the container that defines
            the property. The same result can be achieved programmatically by calling the static
            <tt>Form.setName()</tt> method on a component after it has been added to the form.
            Several other containers, including <tt>TabPane</tt> and <tt>TablePane</tt>, define
            similar attributes.
        </p>

        <p>
            Note also that section components are not required to be typical form elements such as
            <tt>TextInput</tt> or <tt>PushButton</tt>. They can also be containers, allowing the
            arrangement of components within a section to be customized.
        </p>

        <h3>Form Validation</h3>
        <p>
            Pressing the "Submit" button performs some simple validation on the name fields,
            ensuring that the user has provided some text in each field. If either field is empty,
            an error message is displayed at the bottom of the form, and the row containing the
            text fields is highlighted with a red flag. This demonstrates the use of another
            <tt>Form</tt> attribute: the flag. A flag is an instance of <tt>Form.Flag</tt> that
            allows a user to tag a form element as requiring attention from the user. It is a
            simple class that contains a message type (error, warning, info, etc.) and a message.
            Mousing over the flag displays a tooltip containing the message.
        </p>

        <p>
            The button press handler in the code sample below shows how a flag is set on the name
            fields:
        </p>

        <source type="java" location="org/apache/pivot/tutorials/layout/Forms.java">
            <![CDATA[
            package org.apache.pivot.tutorials.layout;

            import java.net.URL;

            import org.apache.pivot.beans.Bindable;
            import org.apache.pivot.collections.Map;
            import org.apache.pivot.util.Resources;
            import org.apache.pivot.wtk.Button;
            import org.apache.pivot.wtk.ButtonPressListener;
            import org.apache.pivot.wtk.BoxPane;
            import org.apache.pivot.wtk.Form;
            import org.apache.pivot.wtk.Label;
            import org.apache.pivot.wtk.MessageType;
            import org.apache.pivot.wtk.Prompt;
            import org.apache.pivot.wtk.PushButton;
            import org.apache.pivot.wtk.TextInput;
            import org.apache.pivot.wtk.Window;

            public class Forms extends Window implements Bindable {
                private BoxPane nameBoxPane = null;
                private TextInput lastNameTextInput = null;
                private TextInput firstNameTextInput = null;
                private PushButton submitButton = null;
                private Label errorLabel = null;

                @Override
                public void initialize(Map<String, Object> namespace, URL location, Resources resources) {
                    nameBoxPane = (BoxPane)namespace.get("nameBoxPane");
                    lastNameTextInput = (TextInput)namespace.get("lastNameTextInput");
                    firstNameTextInput = (TextInput)namespace.get("firstNameTextInput");
                    submitButton = (PushButton)namespace.get("submitButton");
                    errorLabel = (Label)namespace.get("errorLabel");

                    submitButton.getButtonPressListeners().add(new ButtonPressListener() {
                        @Override
                        public void buttonPressed(Button button) {
                            String lastName = lastNameTextInput.getText();
                            String firstName = firstNameTextInput.getText();

                            Form.Flag flag = null;
                            if (lastName.length() == 0
                                || firstName.length() == 0) {
                                flag = new Form.Flag(MessageType.ERROR, "Name is required.");
                            }

                            Form.setFlag(nameBoxPane, flag);

                            if (flag == null) {
                                errorLabel.setText("");
                                Prompt.prompt("Pretending to submit...", Forms.this);
                            } else {
                                errorLabel.setText("Some required information is missing.");
                            }
                        }
                    });
                }
            }
            ]]>
        </source>
    </body>
</document>
