Have you seen our new video tutorials? Check it out!

Multiple Field Type

The multiple field type provides a multi-select relation input.

Introduction

anomaly.field_type.multiple

The multiple field type provides a multi-select / lookup relation input.

Configuration

Below is a list of available configuration with default values:

"example" => [
    "type"   => "anomaly.field_type.multiple",
    "config" => [
        "min"            => null,
        "max"            => null,
        "related"        => null,
        "mode"           => "lookup",
        "key_name"       => null,
        "title_name"     => null,
        "value_table"    => null,
        "selected_table" => null,
        "lookup_table"   => null,
        "handler"        => "\Anomaly\MultipleFieldType\Handler\[email protected]"
    ]
]
Configuration
Key Example Description

min

1

The minimum selections allowed.

max

10

The maxium selections allowed.

related

\Anomaly\UsersModule\User\UserModel

The related model.

mode

tags

The input mode. Valid options are lookup and tags.

key_name

slug

The name of the key field. Default is id. Only applies to tags mode.

title_name

name

The name of the title field. Default is the title_column. Only applies to tags mode.

value_table

\App\Example\MyValueTable

The builder for the value table.

selected_table

\App\Example\MySelectedTable

The builder for the selections table.

lookup_table

\App\Example\MyLookupTable

The builder for the lookup table.

handler

\App\Example\[email protected]

The options handler.

Option Handlers

Option handlers are responsible for setting the available options on the field type. You can define your own option handler to add your own logic to available options.

You can define custom handlers as a callable string where @handle will be assumed if no method is provided:

"handler" => \App\Example\MyOptions::class // Assumes @handle

Option handlers can also a handler with a closure:

"example" => [
    "config" => [
        "handler" => function (MultipleFieldType $fieldType, ExampleRepositoryInterface $entries) {
            $fieldType->setOptions($entries->getCustomEntries()->pluck('title', 'id')->all());
        }
    ]
]
Remember: Closures can not be stored in the database so your closure type handlers must be set / overridden from the form builder.

Writing Option Handlers

Writing custom option handlers is easy. To begin create a class with the method you defined in the config option.

"handler" => "[email protected]"

The handler string is called via Laravel's service container. The MultipleFieldType $fieldType is passed as an argument.

Pro Tip: Handlers are called through Laravel's service container so method and class injection is supported.
<?php namespace App/Example;

class MyOptions
{
    public function handle(MultipleFieldType $fieldType, ExampleRepositoryInterface $entries) {
        $fieldType->setOptions(
            $entries->getCustomEntries()->pluck('title', 'id')->all()
        );
    }
}

Hooks

This section will introduce you to the hooks registered by this addon and how to use them.

EntryModel::newMultipleFieldTypeLookupTableBuilder()

The new_multiple_field_type_lookup_table_builder hook binding returns an instance of the lookup table builder.

This hook let's you override the table builder for the lookup UI.

Returns: \Anomaly\MultipleFieldType\Table\LookupTableBuilder
Example
public function newMultipleFieldTypeLookupTableBuilder() {
    return app(\App\Example\MyLookupTable::class);
}
Automatically detected lookup tables

Lookup tables that are picked up automatically do not require you defining the hook method on your related model.

The lookup table builder location format is:

{\Your\Related\Model\Namespace}\Support\MultipleFieldType\LookupTableBuilder;

Consider the example in the Pages module:

\Anomaly\PagesModule\Page\PageModel
\Anomaly\PagesModule\Page\Support\MultipleFieldType\LookupTableBuilder
Writing Lookup Table Builders

Writing custom option handlers is easy. Simply create your class and extend the base lookup table builder:

<?php namespace App\Example;

class LookupTableBuilder extends \Anomaly\MultipleFieldType\Table\LookupTableBuilder
{

    protected $filters = [
        'title',
    ];

    protected $columns = [
        'title',
        'path',
    ];
}

If you are not relying on automatic detection then all you need to do next is define the hook method on your related model:

public function newMultipleFieldTypeLookupTableBuilder() {
    return app(\App\Example\LookupTableBuilder::class);
}

EntryModel::newMultipleFieldTypeValueTableBuilder()

The new_multiple_field_type_value_table_builder hook binding returns an instance of the value table builder.

This hook let's you override the table builder for the value UI.

Returns: \Anomaly\MultipleFieldType\Table\ValueTableBuilder
Example
public function newMultipleFieldTypeValueTableBuilder() {
    return app(\App\Example\MyValueTable::class);
}
Automatically detected value tables

Value tables that are picked up automatically do not require you defining the hook method on your related model.

The value table builder location format is:

{\Your\Related\Model\Namespace}\Support\MultipleFieldType\ValueTableBuilder;

Consider the example in the Pages module:

\Anomaly\PagesModule\Page\PageModel
\Anomaly\PagesModule\Page\Support\MultipleFieldType\ValueTableBuilder
Writing Value Tables Builders

Writing custom value tables is easy. Simply create your class and extend the base value table builder:

<?php namespace App\Example;

class ValueTableBuilder extends \Anomaly\MultipleFieldType\Table\ValueTableBuilder
{

    protected $filters = [
        'title',
    ];

    protected $columns = [
        'title',
        'path',
    ];
}

If you are not relying on automatic detection then all you need to do next is define the hook method on your related model:

public function newMultipleFieldTypeValueTableBuilder() {
    return app(\App\Example\ValueTableBuilder::class);
}

EntryModel::newMultipleFieldTypeSelectedTableBuilder()

The new_multiple_field_type_selected_table_builder hook binding returns an instance of the selected table builder.

This hook let's you override the table builder for the selected options UI.

Returns: \Anomaly\MultipleFieldType\Table\SelectedTableBuilder
Example
public function newMultipleFieldTypeSelectedTableBuilder() {
    return app(\App\Example\MySelectedTable::class);
}
Automatically detected selected tables

Selected tables that are picked up automatically do not require you defining the hook method on your related model.

The selected table builder location format is:

{\Your\Related\Model\Namespace}\Support\MultipleFieldType\SelectedTableBuilder;

Consider the example in the Pages module:

\Anomaly\PagesModule\Page\PageModel
\Anomaly\PagesModule\Page\Support\MultipleFieldType\SelectedTableBuilder
Writing Selected Tables Builders

Writing custom selected tables is easy. Simply create your class and extend the base selected table builder:

<?php namespace App\Example;

class SelectedTableBuilder extends \Anomaly\MultipleFieldType\Table\SelectedTableBuilder
{

    protected $filters = [
        'title',
    ];

    protected $columns = [
        'title',
        'path',
    ];
}

If you are not relying on automatic detection then all you need to do next is define the hook method on your related model:

public function newMultipleFieldTypeSelectedTableBuilder() {
    return app(\App\Example\SelectedTableBuilder::class);
}

Usage

This section will show you how to use the field type via API and in the view layer.

Setting Values

You can set the multiple field type value with a model instance:

$entry->example = $entry;

You can set the value with a collection of instances too:

$entry->example = $collection;

Lastly you can set the multiple field type value with an array of entry IDs:

$entry->example = [7, 8];

Basic Output

The multiple field type always returns an \Anomaly\Streams\Platform\Entry\EntryCollection instance of related models.

Example
$entry->example; // Collection of models.
Twig
{% for related in entry.example %}
    {{ related.id }}
{% endfor %}

Presenter Output

When accessing the field value from a decorated entry model the collection will contain instances of \Anomaly\Streams\Platform\Entry\EntryPresenter.

Example
$decorated->example->first()->id;
Twig
{{ decorated.example.first().id }}