Skip to content

Commit 0196a8f

Browse files
committed
Keep edited articles in place
1 parent b2cb500 commit 0196a8f

21 files changed

+310
-1057
lines changed

articles/flow/create-ui/basic-features.adoc

Lines changed: 252 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@ order: 10
88

99

1010
= Basic Component Features
11+
:toclevels: 2
1112

12-
You can use the basic features listed here with all of the Vaadin components that extend [classname]`com.vaadin.flow.component.Component`.
13+
All Vaadin components extend the [classname]`com.vaadin.flow.component.Component` base class. It provides the following basic features:
1314

1415

1516
== Setting Id
1617

17-
You can set an `Id` for any component. The `Id` is passed to the client side as the `id` of the corresponding element. However, an `Id` must be unique within the page.
18+
You can set an `Id` for any component. The `Id` is passed to the client side as the `id` of the corresponding element. However, an `Id` must be unique within the page, as it can be used to select the element in JavaScript code or CSS rules.
1819

19-
Ids can be used to select the element in JavaScript code or CSS rules. Below is an example using the [methodname]`setId()` method to set a component `Id`:
20+
*Example*: Setting a component `Id`:
2021

2122
[source,java]
2223
----
@@ -26,16 +27,16 @@ component.setId("my-component");
2627

2728
== Element
2829

29-
Every component is associated with a root `Element`. You can use the `Element` to access low-level functionality by using the [methodname]`component.getElement()` method.
30+
Every component is associated with a root `Element`, which is accessible from the [methodname]`component.getElement()` method.
3031

31-
See <<{articles}/flow/create-ui/element-api/properties-attributes#,Element Properties & Attributes>> for more information on this.
32+
You can use the Element API to access low-level functionality, such as manipulating attributes, properties, styles, and event listeners. See the <<element-api/#,Element API>> for more information.
3233

3334

3435
== Visibility
3536

36-
You can set a component to invisible by using the [methodname]`component.setVisible(false)` method. If you do this, invisible components are no longer displayed in the UI. They won't receive updates from the client side. Transmission of server-side updates resumes when the component is made visible again.
37+
Invisible components are no longer displayed in the UI, nor do they receive updates from the client side. You make a component invisible by calling [methodname]`component.setVisible(false)`. Transmission of server-side updates resumes when you make the component visible again.
3738

38-
Below is an example using the [methodname]`component.setVisible()` method:
39+
*Example*: Making a component invisible, and visible again:
3940

4041
[source,java]
4142
----
@@ -45,21 +46,20 @@ label.setVisible(false);
4546
label.setText("Changed my label");
4647
4748
Button makeVisible = new Button("Make visible", evt -> {
48-
// makes the label visible - only now the
49-
// "Changed my label" text is transmitted
49+
// makes the label visible - only now is the
50+
// "Changed my label" text transmitted
5051
label.setVisible(true);
5152
});
5253
----
5354

54-
[NOTE]
55-
If you set a container to invisible (e.g., a `Div` or `Vertical/HorizontalLayout`) -- a container that has child components -- all inner components are also made invisible. No server-side updates are sent to them, and no client updates are received from them. When the container becomes visible again, updates to the children also resume.
55+
If you make a container with child components invisible (e.g., a `Div` or `Vertical/HorizontalLayout`), the child components are also made invisible. No server-side updates are sent to them, and no client updates are received from them. When the container becomes visible again, updates to the children also resume.
5656

5757

58-
=== Client-Side Consequences
58+
=== Hiding before Rendering
5959

60-
The invisible settings have different consequences, depending on whether the component has been rendered. If a component is set to invisible before it's rendered for the first time, the corresponding element in the DOM isn't created, but the server-side structure is maintained. When the component is set to visible, the DOM is updated.
60+
If you make a component invisible before it's rendered for the first time, the corresponding element in the DOM won't be created. However, the component still exists on the server-side. When you make the component visible again, the corresponding DOM element is created.
6161

62-
Here's an example in which an unrendered component is set to invisible:
62+
*Example*: Making a component invisible before it's rendered:
6363

6464
[source,java]
6565
----
@@ -69,40 +69,263 @@ label.setVisible(false);
6969
Div container = new Div();
7070
// the label isn't transmitted to the client side.
7171
// The corresponding element is created in the
72-
// DOM only when it becomes visible
72+
// DOM only when it becomes visible.
7373
container.add(label);
7474
7575
// prints 1 - the server-side structure is preserved
76-
// no matter if the component is visible or not
76+
// regardless of whether the component is visible or not
7777
System.out.println("Number of children: "
7878
+ container.getChildren().collect(
7979
Collectors.counting()));
8080
----
8181

82-
If a component that has already been rendered is set to invisible, the corresponding element in the DOM is marked with the `hidden` attribute. The component isn't removed from the DOM. DOM elements of invisible components don't receive updates from the server. Server-side components don't react to RPCs (Remote Procedure Calls) if the component is set to invisible.
8382

84-
This is also true for components used in a [classname]`PolymerTemplate` mapped by the `@Id` annotation. When set to invisible, the component is marked with the `hidden` attribute on the client side. The DOM structure isn't altered.
83+
=== Hiding after Rendering
8584

86-
Below is an example setting a rendered component mapped by the `@Id` annotation to invisible:
85+
If you make an already rendered component invisible, the corresponding element is not removed from the DOM. Instead, it is marked with the `hidden` attribute. Furthermore, the element won't receive any updates from the server. Likewise, the server will ignore any RPCs (Remote Procedure Calls) made from the element.
86+
87+
88+
89+
== Enabled State
90+
91+
Components that allow user interaction, such as `TextField` or `Button`, can have three different enabled states:
92+
93+
* *Enabled*: An enabled component allows the user to interact with it.
94+
This is the default state.
95+
96+
* *Explicitly disabled*: A component is explicitly disabled when [methodname]`setEnabled(false)` is called directly on it.
97+
The user can't interact with the component, and communication from the client to the server is blocked.
98+
99+
* *Implicitly disabled*: A component is implicitly disabled when *it's a child of an explicitly disabled container*.
100+
The component behaves exactly like an explicitly disabled component, except that it's automatically enabled again as soon as it detaches from the disabled container.
101+
102+
=== Explicitly Enabling and Disabling Components
103+
104+
Any component that implements the [interfacename]`HasEnabled` interface can be explicitly enabled or disabled.
105+
106+
*Example*: Disabling a component using the [methodname]`component.setEnabled()` method:
87107

88108
[source,java]
89109
----
90-
@Id("my-component")
91-
private Component mappedComponent;
110+
TextField name = new TextField("Name");
111+
name.setEnabled(false);
112+
// Users can no longer interact with the name field.
113+
// The server doesn't handle status updates or events from the component,
114+
// even if the component is changed manually in the browser
115+
// (for example by a client-side script or via a developer console).
116+
----
117+
92118

93-
// sets the attribute "hidden" of the element on the
94-
// client-side
95-
mappedComponent.setVisible(false);
119+
*Example*: Disabling all components in a container by using the same API:
120+
121+
[source,java]
96122
----
123+
FormLayout form = new FormLayout();
97124
125+
TextField name = new TextField("Name");
126+
TextField email = new TextField("E-mail");
127+
Button submit = new Button("Submit");
98128
99-
== Enabled State
129+
form.add(name, email, submit);
130+
// all children are implicitly disabled
131+
form.setEnabled(false);
132+
System.out.println(name.isEnabled()); // prints false
133+
----
134+
135+
[IMPORTANT]
136+
There are restrictions when using the enabled state and Lit templates. See <<templates/limitations#,Template Limitations>> for details.
137+
138+
139+
=== Implicitly Enabled and Disabled Components
140+
141+
When an implicitly disabled component is detached from a disabled container, it's automatically enabled again.
142+
Similarly, if an enabled component is attached to a disabled container, it's automatically implicitly disabled.
143+
144+
*Examples*: Implicitly enabled and disabled components
145+
146+
[source,java]
147+
----
148+
FormLayout form = new FormLayout();
149+
form.setEnabled(false); // the entire form is disabled
150+
151+
TextField name = new TextField("Name");
152+
// prints true, since it isn't attached yet
153+
System.out.println(name.isEnabled());
154+
155+
Button submit = new Button("Submit");
156+
// the submit button is explicitly disabled
157+
submit.setEnabled(false);
158+
System.out.println(submit.isEnabled()); // prints false
159+
160+
form.add(name, submit); // attaches children
161+
162+
System.out.println(name.isEnabled()); // prints false
163+
System.out.println(submit.isEnabled()); // prints false
164+
165+
form.remove(name); // the name field gets detached
166+
System.out.println(name.isEnabled()); // prints true
167+
168+
form.remove(submit); // the submit button gets detached
169+
170+
// prints false, since it was explicitly disabled
171+
System.out.println(submit.isEnabled());
172+
----
173+
174+
=== Overriding Default Disabled Behavior
175+
176+
// TODO Edit this section and remove the deprecated Polymer example. Any template-related examples should go into the Templates guide, not here. Keep things as simple as possible.
177+
178+
By default, disabled components don't allow user interaction from the client side.
179+
However, it's sometimes necessary for complex (composite) components to remain partially functional, even in the disabled state.
180+
For example, you may want to fully enable a registration form only after a user selects a checkbox to accept a license agreement.
181+
182+
=== Enabling Property Changes
183+
184+
You can override the default disabled behavior by enabling certain client-side Remote Procedure Calls (RPC) that would normally be blocked for disabled components.
100185

101-
You can disable user interaction with a component using the [methodname]`component.setEnabled(false)` method on the server. This method blocks any interaction from the client to the server for the disabled component and its children, and it adds a `disabled` property to any client elements.
186+
The first way to do this is by providing the property that should be synchronized to the server in the [methodname]`addPropertyChangeListener()` call.
102187

103-
The enabled state of the component cascades to the child components of the element when it's disabled, but it doesn't override the enabled state of the children. For example, suppose you have a layout with children A and B, and B is disabled. Calling [methodname]`layout.setEnabled(false)` marks both A and B as disabled. If you later enable the layout by calling [methodname]`layout.setEnabled(true)`, child B remains disabled, because it was disabled at the component level.
188+
*Example*: This Polymer template component controls its own enabled state via the checkbox.
189+
The checkbox is never disabled, and it enables and disables the component.
190+
191+
[source,java]
192+
----
193+
@Tag("registration-form")
194+
@JsModule("./src/registration-form.js")
195+
public class RegistrationForm
196+
extends PolymerTemplate<TemplateModel>
197+
implements HasEnabled {
198+
199+
@Id
200+
private TextField name;
201+
202+
@Id
203+
private TextField email;
204+
205+
@Id
206+
private Button submit;
207+
208+
@Id
209+
private Element enable;
210+
211+
public RegistrationForm() {
212+
enable.addPropertyChangeListener("checked", "checked-changed",
213+
this::handleEnabled);
214+
setEnabled(false);
215+
}
216+
217+
private void handleEnabled(
218+
PropertyChangeEvent event) {
219+
setEnabled((Boolean) event.getValue());
220+
}
221+
222+
@EventHandler
223+
private void register() {
224+
String userName = name.getValue();
225+
String userEmail = email.getValue();
226+
System.out.println("Register user with name='"
227+
+ userName
228+
+ "' and email='" + userEmail + "'");
229+
}
230+
}
231+
----
232+
233+
Here is its template file:
234+
235+
[source,javascript]
236+
----
237+
class RegistrationForm extends PolymerElement {
238+
239+
static get template() {
240+
return html`
241+
<vaadin-text-field id="name" value="{{name}}"></vaadin-text-field>
242+
<vaadin-text-field id="email" value="{{email}}"></vaadin-text-field>
243+
<vaadin-button id="submit" on-click="register">Register</vaadin-button>
244+
<vaadin-checkbox
245+
id="enable"
246+
label="Accept License Agreement"
247+
></vaadin-checkbox>
248+
`;
249+
}
250+
251+
static get is() {
252+
return 'registration-form';
253+
}
254+
}
255+
256+
customElements.define(RegistrationForm.is, RegistrationForm);
257+
----
258+
259+
* The checkbox is implicitly disabled if the template (which is its parent) is disabled.
260+
As a result, no RPC is allowed for the checkbox.
261+
* The [methodname]`addPropertyChangeListener()` method (with the extra "checked-changed" argument) is used to synchronize the `checked` property.
262+
263+
* The following RPC communications are blocked for the disabled element:
264+
** Property changes
265+
** DOM events
266+
** Event handler methods (annotated with `@EventHandler`).
267+
For example, the [methodname]`register()` method is an event handler method that's blocked when the component is disabled.
268+
** Client delegate methods (annotated with `@ClientCallable`)
269+
270+
271+
As an alternative, you can use the `@Synchronize` annotation with the `DisabledUpdateMode.ALWAYS` argument value.
272+
273+
*Example*: Using the `@Synchronize` annotation for the property getter in your component.
274+
275+
[source,java]
276+
----
277+
@Synchronize(property = "prop", value = "prop-changed",
278+
allowUpdates = DisabledUpdateMode.ALWAYS)
279+
public String getProp() {
280+
return getElement().getProperty("prop");
281+
}
282+
----
283+
284+
=== Enabling DOM Events
285+
286+
You can enable DOM events in two ways:
287+
288+
. with an [methodname]`addEventListener()` overload method in the `Element` API, or
289+
. with the `@DomEvent` annotation.
290+
291+
*Example*: Unblocking a DOM event for a disabled element using the [methodname]`addEventListener()` overload method that accepts the `DisabledUpdateMode.ALWAYS` parameter.
292+
293+
[source,java]
294+
----
295+
public Notification() {
296+
getElement().addEventListener("opened-changed",
297+
event -> System.out.println("Opened"))
298+
.setDisabledUpdateMode(DisabledUpdateMode.ALWAYS);
299+
}
300+
----
301+
302+
*Example*: Unblocking a DOM event for a disabled component using the `@DomEvent` annotation with the parameter value `allowUpdates = DisabledUpdateMode.ALWAYS`:
303+
304+
[source,java]
305+
----
306+
@DomEvent(value = "click",
307+
allowUpdates = DisabledUpdateMode.ALWAYS)
308+
public class CustomEvent
309+
extends ComponentEvent<Component> {
310+
}
311+
----
312+
313+
=== Enabling Server-Handler Methods
314+
315+
If there are server-handler methods annotated with `@ClientCallable` or `@EventHandler`, you can unblock them for disabled components by specifying `DisabledUpdateMode.ALWAYS` as a value.
316+
317+
*Example*: Specifying `DisabledUpdateMode.ALWAYS`
318+
319+
[source,java]
320+
----
321+
@EventHandler(DisabledUpdateMode.ALWAYS)
322+
private void eventHandler() {
323+
}
324+
325+
@ClientCallable(DisabledUpdateMode.ALWAYS)
326+
private void clientRequest() {
327+
}
328+
----
104329

105-
[NOTE]
106-
Disabling a component in a template isn't the same as disabling it on the server. This is because the server doesn't know about client elements. Any `@Id` bound template components are handled as if they're normal child components, and receive enabled state changes. See <<enabled-state#,Component Enabled State>> for more on this.
107330

108331
[discussion-id]`4DE87AF2-2DFA-49FE-81FD-EAFF02FD5644`

articles/flow/create-ui/creating-components/index.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
---
2-
title: Creating Components
2+
title: Server-Side Components
33
page-title: How to create custom components in Vaadin
44
description: How to create components using the Element API.
55
meta-description: Master the process of creating custom components to extend the functionality of your Vaadin applications.
6-
order: 70
6+
order: 30
77
---
88

99

0 commit comments

Comments
 (0)