Model-based switching with switch

From W3C XForms Group Wiki (Public)


NOTE: This page should no longer be edited as the requirement has now been applied to the XForms 2.0 spec.

Requirement : We need an easy authoring method for tracking the selected case of a switch using a node of data.

It is possible to use an xforms-ready handler and a pile of xforms-select handlers to track the selected case of a switch, except it is not guaranteed to work correctly. For example, if a setvalue or UI binding modifies the data node, there is no way to set a listener for changes to a data node, so the data and the switch case will be out of synch, a difference that is obvious across a save/reload. Therefore, the requirement cannot be met with correctness with XForms today.

To achieve data model drive switching, form authors are therefore strongly inhibited from using switch. Since that is the XForms container control for UI switching, it is a language flaw that must be fixed.

The working group discussed the issue and the following is the result of the discussions:

  • a new attribute called "caseref", which takes single-node UI binding attributes.
  • when "caseref" is present, the indicated data node selects the first case on startup if the node exists and its content matches a case.
  • the usual edge cases are to be worked out in the strawman proposal for spec-ready text, such as what if the node doesn't exist, is readonly, or has a value that doesn't match a case ID
  • The toggle action would continue to be able to toggle cases.
  • The toggle would change the case, which would cause the "caseref" node to push the new selection into data using a setvalue action.
  • Any change of the caseref data node would cause a switch case selection.

Here is a simple markup example based on the ideas expressed so far:

<select1 ref="/path/to/cart/@phase">
    <label>Stage:</label>
    <item>
        <label>Order</label>
        <value>order</value>
    </item>
    <item>
        <label>Ship</label>
        <value>ship</value>
    </item>
    <item>
        <label>Pay</label>
        <value>pay</value>
    </item>
</select1>

<switch ref="/path/to/cart" caseref="@phase">
    <case id="order">
        <label>Order Information</label>

        <group ref="orderDetails">
            <input ref="product">
                <label>Which of our fine edges do you need?</label>
            </input>

            <range ref="quantity">
                <label>How many of our fine widgets do you need?</label>
            </range>
        </group>
    </case>

    <case id="ship">
        <label>Shipping Information</label>

        <group ref="shippingDetails">
            <input ref="name">
                <label>Name</label>
            </input>

            <input ref="address">
                <label>Address</label>
            </input>

            <input ref="zone">
                <label>Zone</label>
            </input>

            <input ref="sector">
                <label>Sector</label>
            </input>
        </group>
    </case>

    <case id="pay">
        <label>Payment Information</label>

        <group ref="paymentDetails">

            <input ref="card">
                <label>Card Number</label>
            </input>

            <input ref="date">
                <label>Expiration Date</label>
            </input>

            <input ref="cvv">
                <label>CVV Code</label>

                <hint>A three-digit number they put on the back of the card to make 99.9% sure you really have the card
                    and didn't steal the data from someone whom was previously told that number.
                </hint>
            </input>
        </group>
    </case>
</switch>

The working group also considered the fact that the UI control that drives the case selection is separate from the switch, so the relationship between the two controls is not well-established by the declared UI.

Notes

It has been pointed out that we need a CSS pseudo-class equivalent of repeat-item for the selected switch case.

This feature is related to the case() function feature. User:Jboyer