[[choices]]
= `choices...()`

: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 `choices...()` supporting method is called for both action parameters and for properties, to find objects from a drop-down list box.
Unlike xref:refguide:applib-methods:prefixes.adoc#autoComplete[autoComplete...()], the use case is when the number of objects is comparatively small and can be selected from a drop-down without any additional filtering.

The signature of the supporting method depends on whether it is for an action parameter or a property.

== Parameters

For an action parameter in (0-based) position _N_, and of type `T`, the signature is:

[source,java]
----
public Collection<T> choicesNXxx() {
    // ...
}
----

For example:

[source,java]
----
import lombok.Getter;
import lombok.Setter;

public class ShoppingCartItem {

    @Property(editing=Editing.DISABLED)
    @Getter @Setter
    private Product product;

    @Property(editing=Editing.DISABLED)
    @Getter @Setter
    private int quantity;

    @Action(semantics=SemanticsOf.IDEMPOTENT)
    public ShoppingCartItem updateProduct(
                                Product product,
                                final Integer quantity) {
        // ...
    }
    public Collection<Integer> choices1UpdateProduct() {
        return Arrays.asList(1,2,3,5,10,25,50,100);
    }

    // ...
}
----

=== Dependent Choices

Action parameters also support the notion of dependent choices, whereby the list of choices is dependent upon the value of some other argument.

For example, consider a todo app whereby ``ToDoItem``s are categorized and then can also be subcategorized:

image::reference-methods/prefixes/choices/dependent.png[width="800px"]

If implemented as a mixin xref:userguide:fun:mixins.adoc#contributed-action[contributed action], the code would look something like:

[source,java]
----
public class ToDoItem {

    @Action(semantics = SemanticsOf.IDEMPOTENT)
    @ActionLayout(
            describedAs = "Update category and subcategory"
    )
    public class updateCategory {
        public ToDoItem act(
                final Category category,
                @Nullable
                final Subcategory subcategory) {
            item.setCategory(category);
            item.setSubcategory(subcategory);
            return ToDoItem.this;
        }
        public List<Subcategory> choices1UpdateCategory(    // <.>
                final Category category) {                  // <.>
            return Subcategory.listFor(category);
        }
    }

}
----

<.> "choices" prefix, Nth param

<.> the category selected


Dependent choices are not restricted to enums, however.
Going back to the shopping cart example shown above, the choices for the `quantity` parameter could be dependent upon the selected `Product`:

[source,java]
----
public class ShoppingCartItem {
    ...
    @Action(semantics=SemanticsOf.IDEMPOTENT)
    public ShoppingCartItem updateProduct(
                                Product product,
                                final Integer quantity) {
        // ...
    }
    public Collection<Integer> choices1UpdateProduct(Product product) {
        return productService.quantityChoicesFor(product);               // <.>
    }
    ...
}
----

<.> `productService` is a (fictitious) injected service that knows what the quantity choices should be for any given product

== Properties

For a property of type `T`, the signature is:

[source,java]
----
public Collection<T> choicesXxx() { /* ... */ }
----

For example:

[source,java]
----
import lombok.Getter;
import lombok.Setter;

public class ShoppingCartItem {

    @Property(editing = Editing.ENABLED)
    @Getter @Setter
    private Product product;

    public Collection<Product> choicesProduct() {
        // ...
    }

    // ...
}
----
