Form control

A FormControl is a value of the form. It has a visual representation in the view the user can control. It can hold any type of value, but cannot have child components.

Creating a FormControl is as simple as:

import { FormControl } from '@banquette/form';

const control = new FormControl(value, validator);

The value

There are two types of values in a FormControl:

  1. value: this is the current value of the control, the one parents see and that will be used outside the form,
  2. defaultValue: this is the original value of the control, the one that was set when the control has been constructed.

To update value:

control.setValue('new value');

TIP

This will impact the control's states, like make it dirty, and maybe trigger a validation.


To update defaultValue:

control.setDefaultValue('a new default');

WARNING

This will do nothing else than storing your new default value. To set the default value as current value, you must reset the control.


To reset the control:

control.reset();

This will have the following effects:

  • Set the value back to the default value,
  • Unmark the following states: changed, touched, dirty, validated,
  • Blur the control if focused,
  • Clear validation errors.

Resetting the control does not impact the following states: disabled, busy, validating, concrete.

The view

A FormControl in itself is, in essence, just a container for a value. It has no visual representation in the browser. That's to maintain a separation of concerns and to keep it framework-agnostic.

So to get a full usable form component, you need to associate it with a view model. The view model makes the bridge between the HTML of your page and the FormControl.

Create your own view models can be a complex exercise, depending on the components you're trying to create. This is discussed in detail in the Your own views section.

But luckily, Banquette comes natively with a Vue 3open in new window implementation of the basic form components, that you can check out here.

The usage is a simple as:

<bt-form-text :control="yourControl"></bt-form-text>

to create a text input for example.

TIP

I advise you to keep reading the Form documentation first to really understand how the system works before digging into the specifics of the views.

For now, you can see the view as a way to update the value of the FormControl, nothing else matters 🎵.

Virtual control

Now that we understand that a FormControl and its views are two different things, we can discuss the concept of virtual controls.

A FormControl is virtual when it has no view associated with it.

A virtual control is (by default) invisible to most operations of the form:

  • it's ignored by the validation, so it will not produce any validation error,
  • it's disabled,
  • it's ignored by its parent component (when iterating over its children or updating its value).

To make the control concrete (inverse of virtual), you have to associate it with a view, like we've seen in the previous section.

If you use the @banquette/vue-ui package for the view components, it is as simple as doing:

<bt-form-text :control="yourControl"></bt-form-text>

The view will automatically bind with the control which will enable it and make it concrete.

TIP

If you really want to use a control without a view, you can force it to become concrete by calling:

control.markAsConcrete();

You can also make a whole form concrete in one call by selecting all components and then calling markAsConcrete on the collection:

// Get is a glob pattern that will select all child components recursively.
form.getByPattern('**').markAsConcrete();

But this is generally not advised, you should create a view for all your controls.

TIP

If you use @banquette/vue-ui, you can create an invisible form component:

<bt-form-hidden :control="yourControl"></bt-form-hidden>

If you don't use @banquette/vue-ui and want to create views by yourself (using Vue or a different framework), please refer to the dedicated documentation.

Focus / blur

The last functionality specific to FormControl is the focus() and blur() methods that are quite self-explanatory. You can call focus() to give the focus to the control, and blur() for the opposite.

But what makes it worth the talk is the way it works.

When you call focus(), the control will not change the focused state of the control.

Instead, it will only call the view to ask for focus. The view is then responsible for calling back the control when the focus have been gained to update the focused flag.

This ensures that the focused flag is trustworthy, as it will only ever be true if the view has confirmed the focus.

NOTE

You can also note that calling focus() on a FormControl with no view will do nothing, as it should because having the focus without a view makes no sense.