Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Proposal: Form Control #82

Open
LucasHaines opened this issue Dec 14, 2018 · 18 comments
Open

Feature Proposal: Form Control #82

LucasHaines opened this issue Dec 14, 2018 · 18 comments
Labels
feature proposal New feature proposal proposal-NewControl This proposal might involve creating a new control team-Controls Issue for the Controls team wct

Comments

@LucasHaines
Copy link

LucasHaines commented Dec 14, 2018

Proposal: Form Control

Summary

The Form control enables layout, alignment, and grouping of form elements. Form elements are different control types associated with data input.

Rationale

Creating a form is a very common scenario for Enterprise and LOB applications. Easily creating a form that is evenly spaced, appropriately sized, semantically grouped, accessible, and contains the needed actions is a manual process using Grid (or other layout controls). While this is not difficult, it can be time consuming and cumbersome.

When creating a form using any of the layout panels provided today, Narrator support is only provided at the control level. No context is provided to user. Example: if the field is required, how many, which section, etc. by creating a Form layout control this can be provided to user for free and allow developers to focus on functionality and not layout.

Note: Data/Input validation will be tracked in a separate issue.

Functional Requirements

# Feature Priority
1 Able to create sections with headers Must
2 Able to support multiple columns Must
3 Able to define actions (Submit, Cancel, etc) Must
4 Able to group controls on one line Must
5 Able to override padding and margin per section or overall form Must
6 Support Compact density spacing rules Must
7 Support expand/collapse behavior for Form Sections Should
8 Wrap sections based on window size Should
9 Use inline actions or command bar actions Should
10 Able to add items to form dynamical Should
11 Support for data binding Should
12 Draw a line under each section Should
13 Dedicated area for grouped validation errors Could
14 Support inline actions next to input fields Could

Usage Examples

Create a single column form with inline actions

At default the control will create a single column form respecting spacing rules with actions at the bottom.

image

Create a multi-column form with sections and groups

By providing a few properties the Form control can easily adapt to more complex data input scenarios. Without the need to define row and column definitions. The spacing rules are built into the Form control.

image

Detailed Feature Design

Visual Anatomy of a Form

image

The Form control contains a three different components.

  1. FormSection: Collection of controls relative to each other in layout equally spaced across specified columns.
  2. FormGroup: Collection of controls within a section relative to each other in layout. Spaced based on parameters given.
  3. FormActions: Collection of commands associated with the overall Form control.

Default Spacing

The Forms control will provide default spacing rules but these can be overwritten in markup.
image

  • Forms maintain a 24px margin on all sides
  • Spacing between forms sections and headers is 24px
  • Spacing between a forms section header and sub title is 12px
  • Spacing between forms sections is 24px
  • Spacing between controls in a form or form section is 12px
  • Spacing between the actions associated with a form is 12px
  • Spacing between forms in the same row is 12px

Creating a Complex Form

The example below used FormSection and FormGroup to build a Form for a new patient.

         <Form Name="NewPatient">
            <FormSection Header="Name" Columns="2">
                <TextBox Header="First name"/>

                <TextBox Header="Last name"/>

                <FormGroup Columns="Auto, *">
                    <TextBox Header="M.I." Width="40"/>

                    <ComboBox Header="Suffix" PlaceholderText="Select" HorizontalAlignment="Stretch"/>
                </FormGroup>

                <TextBox Header="Last name"/>
            </FormSection>

            <FormSection Header="Basic info" Columns="2">
                <TextBox Header="Pharmacy ID"/>

                <ComboBox Header="Emergency priorty level" PlaceholderText="Select" HorizontalAlignment="Stretch"/>

                <FormGroup>
                    <CalendarDatePicker Header="Date of birth" HorizontalAlignment="Stretch"/>

                    <TextBox Header="SSN"/>
                </FormGroup>

                <TextBox Header="Citizenship"/>

                <TextBox Header="Place of birth"/>

                <ComboBox Header="Birth state (US only)" PlaceholderText="Select" HorizontalAlignment="Stretch"/>

                <FormGroup>
                    <ComboBox Header="Gender" PlaceholderText="Select" HorizontalAlignment="Stretch"/>

                    <ComboBox Header="Ethnicity" PlaceholderText="Select" HorizontalAlignment="Stretch"/>
                </FormGroup>

                <FormGroup>
                    <ComboBox Header="Martial Status" PlaceholderText="Select" HorizontalAlignment="Stretch"/>

                    <ComboBox Header="Religion" PlaceholderText="Select" HorizontalAlignment="Stretch"/>
                </FormGroup>

                <ComboBox Header="Primary language" PlaceholderText="Select" HorizontalAlignment="Stretch"/>

                <ComboBox Header="Secondary language" PlaceholderText="Select" HorizontalAlignment="Stretch"/>
            </FormSection>

            <FormSection Header="Contact" Columns="2">
                <TextBox Header="Address 1"/>

                <TextBox Header="Address 2"/>

                <TextBox Header="City"/>

                <FormGroup>
                    <ComboBox Header="State" PlaceholderText="Select" HorizontalAlignment="Stretch"/>

                    <FormGroup Columns="*,Auto">
                        <TextBox Header="Zip"/>

                        <Button Margin="0,28,0,0" Content="..."/>
                    </FormGroup>
                </FormGroup>

                <FormGroup Columns="*,Auto">
                    <TextBox Header="Facility"/>

                    <Button Margin="0,28,0,0" Content="..."/>
                </FormGroup>

                <FormGroup>
                    <TextBox Header="Room"/>

                    <TextBox Header="Community"/>
                </FormGroup>

                <FormGroup>
                    <ComboBox Header="Aware Dx" PlaceholderText="Select" HorizontalAlignment="Stretch"/>

                    <ComboBox Header="Aware Px" PlaceholderText="Select" HorizontalAlignment="Stretch"/>
                </FormGroup>

                <TextBox Header="Mapsco #"/>

                <TextBox Header="Primary phone" PlaceholderText="123-456-7890"/>

                <TextBox Header="Email"/>
            </FormSection>
        </Form>

Rendered version of markup

image

Accessibility

State Action Narrator
User has tabbed to the first field in the form Focus is set on the first field Form 'name' section 'headervalue', section 1 of n textbox, field 1 of n, narrator begins to read the control as it does today
Form is tabbed through Tab Button: will advance to next control.

Up/Down Arrow: scroll the page up and down
standard control behavior
User tabbed to the first control in the following section Focus is set on the first field of the control Form 'name' section 'headervalue' section 2 of n, field 1 of n, narrator begins to read the control as it does today
Focus is set on action button Button is focused Form 'name' action 1 of n, narrator reads the control as it does today

Open Questions

  • If we have a Form control, we could then use a data object to generate the markup. Is this something of interest?
  • Currently control headers are rendered on the top of the control. Are there scenarios where the control header should render on the side or possibly inline?
  • Is a Form control something of interest or would it be best focus our efforts into making Grid more flexible (#see issue 54)?
@LucasHaines LucasHaines changed the title Form Control Feature Proposal: Form Control Dec 14, 2018
@michael-hawker
Copy link
Collaborator

Interesting idea. I like the idea of gaining form consistency especially for layout, accessibility, and navigation perspectives.

I'd be nice to have an option to make sections that can be collapsed/expanded for long forms or settings pages. That may need something like the Expander control from the Toolkit though too.

It does seem to align with the Grid efforts, but I could see this using that, especially if it's a data-bound list or object. It'd be nice to see it somehow could read/consume a set of properties from an object via reflection to show the form and data-bind to the object's properties. -- I believe @mrlacey was exploring something related with Rapid XAML Toolkit though slightly different, but I could see WindowsTemplateStudio using this for their settings page, eh @crutkas?

@jevansaks jevansaks added the feature proposal New feature proposal label Dec 14, 2018
@LucasHaines
Copy link
Author

LucasHaines commented Dec 14, 2018

@michael-hawker Great feedback, really love the idea of having an expand/collapse behavior on form sections. I added it to the functional requirements. Will expand in the usage scenarios and code example. Thanks for the pointer.

Data binding is something we want to support in the long term. It's captured in the requirements as a "Should".

@michael-hawker
Copy link
Collaborator

@LucasHaines yeah, I just implemented a setting page in my app and it was long and sprawling, adding the sections collapsed really made a big impact on navigability.

Look at the spec for #79 too, as the expand/collapse parts would overlap, especially if only one section should be open at a time (an option in their scenario). Would be nice to centralize those two code pieces to another control that can be used outside or for Accordion drawers. Could be cool to have an expander type control that can act like a radio grouping where only 1 can be open at a time.

@mrlacey
Copy link
Contributor

mrlacey commented Dec 14, 2018

Some thoughts/comments

  • Having Form, FormSection and FormGroup would be beneficial even if for nothing more than increasing the semantics of the markup on a page. Adding additional functionality to each

  • The thought of (eventually) having a Form control that can be bound to a single VM and have it generate "everything" makes me wonder if you'd end up needing to apply a lot of definition (possibly via attributes) to the properties of the VM. This risks leading to presentation logic being mixed with the VM. It would also be a very big, complex control. I'd rather see this functionality working without binding. It could be added later if really needed.

  • Having seen attempts to create similar controls on other platforms, there is a fine line to be drawn between flexibility and complexity of configuration. Beware building in too much functionality that needs to be specifically configured as it won't be used.

  • Auto-generating the contents of a Section (or whole form) would create localization challenges. The ability to support localization of the UI text MUST be considered as part of this proposal.

  • Is the FormActions section for anything more than layout? Assuming, it just takes buttons, I can't think of scenarios where more than two options will be needed. Is it just a special version of a FormSection that appears at the bottom?

  • I can imagine specific Header and Footer containers within the Form as being useful for styling. Even if these just contain FormSections they could help with styling consistency where apps have multiple pages containing forms that should be styled the same way.

  • FormGroup and FormSection seem very similar. The only real difference seems to be that a Section has a Header. Do they need to be different? If they were the same it would avoid complexity over what can be can be nested within the other. (On the assumption that the current proposal doesn't nest sections but you can have multiple nested groups within a section.)

  • If any data input control (or any element--presumably) can be placed within a section/group, how will any styling applied directly to such a control interact with styling and positioning applied automatically by the section/group?

  • Will it be possible to disable the automatic layout capabilities of a section/group and add other layout containers?

  • What will the rules on automatic laying out of columns and wrapping be?

  • Will it be possible to have a section/group that uses multiple columns where there is space and puts everything in one column when the window is narrow?

  • Could "Draw a line under each section" just be part of the default styling and overridden by applying custom styling rather than being a boolean property? (Oh, I guess this is another difference between a section and a group.)

  • Having things like "line under each section" as part of the control seem very tied to a specific design style. I'd be wary of including this as it has a high risk of causing issues if a new default form layout style was wanted in the future. Try and avoid anything that may lead to the UI being tied to a specific visual look if future platform guidance changes.

@LucasHaines
Copy link
Author

@mrlacey Thanks for the feedback! We do want to strike a balance with this control of functionality and ease of use. We want to avoid bloating this control and really focus on a single consistent form experience that is great with no additional work but can support customization.

  • FormActions is about layout and readability for Narrator. It could take Button, Hyperlink, HyperlinkButton, and a few others. There are scenarios where you might want and "Accept", "Cancel", "Clear All", and maybe a link for more information.

  • Header and footer sections is an interesting idea we never considered. If the scenario is for the form to expand across pages, it seems that would best be suited as part of the page and not part of the Form. Is there another scenario these concepts might apply to?

  • Interesting thought about nesting sections and not using group. One thing that section gives us is the built in styling that can be customized. But as mentioned, we could use a boolean to help with this, Are there other difference we could use the semantics of Group?

  • Someone can still apply style overrides to the control and have it work with in the form. Such as color resources, the form control shouldn't override explicit items set on a specific control.

  • Adding custom is layout is a great scenario and something we should allow at a control level.

  • Yes, the intent is for the control to wrap columns determined by available space.

  • Yes, providing a different set of resource keys is a nice customization. Thanks for the warning, the idea is that we could build the control in a way that would allow for visual updates and customization. We don't want to be too heavy handed.

@mdtauk
Copy link
Contributor

mdtauk commented Dec 15, 2018

Might I suggest that if this control was to be built, that some consideration be made with those multi-column groups, so a narrow width will re-arrange the form elements.

  • Collapsible sections would make a lot of sense in these narrow windows/screens - perhaps with an auto-collapse behaviour, and some kind of indicator when a section with mandatory form elements have not been filled in.

  • Pagination or a flow of multiple forms which need to be completed before progressing could be useful, but making it simple and performant would need to be a must. Transitions between steps in the form should be in the best practice of Fluent Design, and the current step (Step 2 of 4) etc should be visible and clear.

  • Shared styles which would apply to all elements in a Form control, or per form group could be considered for consistency and to prevent re-templating.

@LucasHaines
Copy link
Author

I will update the feature request to call this our more detailed. I will also adda proposed list of resrouces for consistent styling. But all in all, your suggestions are spot on.

@mdtauk
Copy link
Contributor

mdtauk commented Jan 15, 2019

There is a UWP Doc page about best practice for Forms.
https://docs.microsoft.com/en-gb/windows/uwp/design/controls-and-patterns/forms

Whatever happens with this proposal, there should be consistency with the Fluent, Windows, Office, and Docs teams to clearly define how to do it.

@jamesmcroft
Copy link

How would you envision this working with custom built input controls?

One of the projects I work on is an enterprise application which relies heavily on form-based views which have heavily customized in-house input controls to support data validation and unique input experiences.

Would this control also look to handle scenarios where certain sections or input fields should be visible based on the values of other fields? I know there would be other ways of achieving this outside of the control.

@mdtauk
Copy link
Contributor

mdtauk commented Jan 16, 2019

You could have a form content panel control, which would contain the custom control/third party control - but still supports the responsive reflow, sizing, tabbing, etc

The form control would ensure consistent spacing between items, handle flow, resize and possibly pagination and multi-step forms, whilst maintaining input values from multiple pages before submitting.

@LucasHaines
Copy link
Author

I'm removing the assignee field to indicate that this proposal is going to the freezer for us to take a look at later.

@LucasHaines LucasHaines removed their assignment Jul 22, 2019
@jevansaks jevansaks added the team-Controls Issue for the Controls team label Nov 7, 2019
@quantasm
Copy link

There does not appear to be a winui PropertyGrid control yet. However, this Form Control feature proposal would go some way to allow some kind of grouped PropertyGrid. They could almost be the same control with only the layout and spacing determine if Form Control 'looks' like a form or a propertygrid.

@niels9001
Copy link
Contributor

Love this proposal!

One small comment: how would we deal with inconsistent spacing between controls?

Example
image

In this example, all input controls (ToggleSwitch / NumberBox / ToggleSwitch) have the same Margin: 0, 12, 0, 0.

As you can see this results in a consistency, as a ToggleSwitch and CheckBox make use of additional whitepace. within their controls.

@mdtauk
Copy link
Contributor

mdtauk commented Mar 25, 2021

This control proposal should be considered alongside
Aligning Control Headers to the Left (and Right) #4643
Allow on/off label placement on either side of ToggleSwitch #3696

@mdtauk
Copy link
Contributor

mdtauk commented May 22, 2021

A new Microsoft Teams UI kit has been added in Figma, and there is guidance for creating Forms, which could be useful for this discussion and proposal.

image
image

@michael-hawker
Copy link
Collaborator

michael-hawker commented Jul 13, 2021

Since this has been called out for both data entry form layouts and setting page layouts, wanted to link to this twitter thread about the latter via @niels9001:

Settings Refresh Design

Also a mention of using Expander to collapse form sections.

@mdtauk
Copy link
Contributor

mdtauk commented Jul 13, 2021

The Figma file for WinUI 2.6 has no guidance for the laying out of Forms or the best practice that is being implemented in the new Settings and Store apps.

I still think this control needs to happen, but it would be a good idea for the design teams to document best practices and redlines for spacing and positioning of these elements.

@heartacker
Copy link

any update?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature proposal New feature proposal proposal-NewControl This proposal might involve creating a new control team-Controls Issue for the Controls team wct
Projects
None yet
Development

No branches or pull requests

10 participants