:Notice: 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.

The `associateWith` element specifies an action has a relationship with another property or another collection of the domain class.

* For properties, the association (currently) is used solely for layout purposes, so that the action will by default be rendered close to the property.
+
This can of course be overridden using `@ActionLayout` or the layout file

* For collections, the association is also used for layout purposes, rendering the action near to the collection.
+
However, it is also used at a deeper level, because the action may have a collection parameter which is the same type as the collection elements.
In the Wicket viewer, the collection is rendered with checkboxes; those selected objects are used as defaults for the action collection parameter.

++++
include::overview.svg[]
++++
////
caption Demo Classes

class "ActionAssociateWithVm" as PARENT
class "ActionAssociateWithChildVm" as CHILD

PARENT : addChild(..) // factory, associate with 'children'
PARENT : removeChild(..) // single choice from 'children', associate with 'children'
PARENT : removeChildren(..) // multiple choices from 'children', associate with 'children'
PARENT : makeFavorite(..) // single choice from 'children', associate with 'favorites'
PARENT : noLongerFavorite(..) // single choice from 'favorites', associate with 'favorites'
PARENT : noLongerFavorites(..) // multiple choices from 'favorites', associate with 'favorites'
PARENT : String text

CHILD : String value

PARENT --> CHILD : "children\n(0..n)"
PARENT --> CHILD : "favorites\n(0..n)"
////

== Associated with Properties

The `AssociateWithVm` class defines two properties, `text` and `anotherProperty`:

[source,java]
----
include::ActionAssociateWithVm.java[tags=class-properties]
----

The regular `updateText` action is associated with the `text` property:

[source,java,indent=0]
----
include::ActionAssociateWithVm.java[tags=action-associateWith-property]
----
<.> indicates the property to associate with
<.> if there are multiple actions associated with the property, indicates their order in the UI

Meanwhile the mixin `updateOtherProperty` is associated with the `otherProperty` property:

[source,java,indent=0]
----
include::ActionAssociateWithVm_updateOtherProperty.java[tags=class]
----
<.> indicates the property to associate with
<.> indicates their order in the UI


== Collection

The `AssociateWithVm` class also defines the `children` collection:

[source,java]
----
include::ActionAssociateWithVm.java[tags=class-collections-children]
----

There are three actions associated with this collection:

* the `addChild` action:
+
[source,java,indent=0]
----
include::ActionAssociateWithVm.java[tags=action-associateWith-children-1]
----
<.> associates with the "children" collection
<.> positioned first in the UI

* the `removeChild` action.
+
[source,java,indent=0]
----
include::ActionAssociateWithVm.java[tags=action-associateWith-children-2]
----
<.> associates with the "children" collection
<.> positioned second in the UI
<.> because this action is associated with a collection, no supporting `choices()` or `autoComplete(...)` is required to provide the parameter.
Instead, the elements in the collection are automatically used.

+
TIP: an explicit `choices()` or `autoComplete(...)` supporting method can be provided to override the default usage of the collection elements if required.

* the `removeChildren` action, which allows multiple children to be removed:
+
[source,java,indent=0]
----
include::ActionAssociateWithVm.java[tags=action-associateWith-children-3]
----
<.> associates with the "children" collection
<.> positioned third in the UI
<.> again, no supporting `choices()` or `autoComplete(...)` method is required.
Instead, the elements of the collection are used as options.
Also, each row in the collection is rendered with a checkbox, and those selected are used as the default for the parameter.

== Mixin Actions

The `AssociateWithVm` class also defines the `favorites` collection:

[source,java]
----
include::ActionAssociateWithVm.java[tags=class-collections-favorites]
----

There are three mixin actions associated with this collection:

* the `makeFavorite` action.
This takes a element from the "children" collection and also adds to the "favorites" collection:
+
[source,java]
----
include::ActionAssociateWithVm_makeFavorite.java[tags=class]
----
<.> associates with the "favorites" collection
<.> positioned first in the UI
<.> choices are taken from the "children" collection

* the `noLongerFavorite` action.
This just removes a selected element from the "children" collection:
+
[source,java]
----
include::ActionAssociateWithVm_noLongerFavorite.java[tags=class]
----
<.> associates with the "children" collection
<.> positioned second in the UI
<.> because this action is associated with a collection, no supporting `choices()` or `autoComplete(...)` is required to provide the parameter.
Instead, the elements in the collection are automatically used.

* the `noLongerFavorites` action.
This is similar to the previous action, but for multiple favorite elements:
+
[source,java]
----
include::ActionAssociateWithVm_noLongerFavorites.java[tags=class]
----
<.> associates with the "favorites" collection
<.> positioned third in the UI
<.> because this action is associated with a collection, no supporting `choices()` or `autoComplete(...)` is required to provide the parameter.
Instead, the elements in the collection are automatically used.


