Field Types / Select field
Note: You are currently reading the documentation for Bolt 5.0. Looking for the documentation for Bolt 5.2 instead?
Choose from Preset values¶
This field provides a drop-down list to make a pre-defined selection from. This field has many options and many possibilities but is less complicated than it might seem at first glance.
Basic Configuration¶
somevalue:
type: select
values: [ none, foo, bar ]
Example usage in templates¶
{{ record.somevalue }}
Defining values as a hash¶
The options in the list can be defined as either a 'map' or a 'hash'. If you use a list (like above), the options visible in the drop-down list will be the values stored in the database. If you want to store other values, you can use a so-called 'hash'.
In the following example, 'yes', 'no' and 'undecided' will be stored in the database:
somevalue:
type: select
values:
yes: Yes
no: No
undecided: Well, it can go either way…
Populating the values from a ContentType¶
You can also get the values from the records of a particular ContentType.
somevalue:
type: select
values: mycontenttype/[formatting]
To display multiple values simply separate them with commas. For example to display both the id and title of 'pages':
somevalue:
type: select
values: pages/{id},{title}
A simple substition is performed for all {something}
placeholders. You can
insert the name of a field, but also {id}
, {status}
and {contenttype}
. You
can also use the magic attributes {title}
and {excerpt}
.
If you leave the second part blank, like values: entries/
, the formatting
will default to {title} (№ {id}, {status})
.
If the list is growing longer, there are a few ways to make it more manageable:
somevalue:
type: select
values: programme/{title}
sort: name
autocomplete: true
limit: 1000
- The sort-option allows you to specify the sorting of the items in the select field. You can use any field, and to reverse the sort use a minus: -title, for example.
- Enabling autocomplete will allow the user to use autocomplete typing to select a value from the field.
- Use limit to limit the amount of items. Note that the default is 200, so if you have a long list, and you need to show them all to the user, raise this limit.
Tip: See the section below for details and examples on how to Outputting selected options from another ContentType.
Populating the values from multiple ContentTypes¶
To output multiple ContentTypes in the select list, use:
somevalue:
type: select
values: (events,news,pages)/{title} - {contenttype} № {id} ({status})
You can then use this to fetch the selected record by using the following code:
{% setcontent linkeditem = '(events,news,pages)' where { id: record.somevalue } %}
In practice, you'll often want to fetch the selected records. See the section on Outputting selected options from another ContentType for details and an example on how to easily do this.
Populating the values from services¶
Option 1: Static callable¶
Example contenttypes.yaml configuration:
books:
type: select
values: App\Books::getOptions
Allows you to implement an App\Books class like so (where the $field
argument is optional):
<?php
declare(strict_types=1);
namespace App;
use Bolt\Entity\Field\SelectField;
class Books
{
public static function getOptions(SelectField $field): iterable
{
return [
'Animal Farm',
'1984',
];
}
}
Option 2: Callable as a Symfony service (with autowiring and autoloading)¶
Example contenttypes.yaml
configuration:
books:
type: select
values: App\Books
Allows you to implement an App\Books
class like so (where the $field
argument is optional):
Important: the App\Books
service must explicitly be public, so that it does not get automatically removed from the container if unused
<?php
declare(strict_types=1);
namespace App;
class Books
{
public function __construct(SomeNiceService $service)
{
$this->service = $service;
}
public function getOptions(SelectField $field): iterable
{
// $this->service is available here
return $this->service->getBooks();
}
}
Note: the method name getOptions
is significant in this case.
Additional options¶
Selecting multiple values¶
You can also allow the user to select multiple values by setting the options
multiple
to true like this:
somevalues:
type: select
values: [ none, foo, bar ]
multiple: true
If you set it to multiple you will also have some different ways to use it in the templates.
For example if you want to see if bar
was one of the selected values:
{% if 'bar' in record.somevalues.selected %}
..
{% endif %}
Or if you want to print out the selected values in an ul
:
<ul>
{% for values in record.somevalues.selected %}
<li>{{ values }}</li>
{% endfor %}
</ul>
Or if you just want to print them out after one another separated by commas:
{{ record.somevalues|join(', ') }}
Making the selected values sortable¶
If you want to control the order that selected values are saved and displayed
in then you can use the sortable
option. This is especially useful when
linking to other ContentTypes since it can give an ordered relation. Usage:
pages:
type: select
values: pages/
multiple: true
autocomplete: true
sortable: true
Link to edit record¶
If you have select lists populated with Records you can add a link to the Record by adding the option:
link_to_record: true
. This feature works on single and multiple select lists. It will add the pencil
icon to the selected items.
pages:
type: select
values: pages/
link_to_record: true
Set a default value¶
If you want to have a default option selected you can use the default
option.
somevalue:
type: select
values:
yes: Yes
no: No
undecided: Well, it can go either way…
default: undecided
Usage in templates¶
The most basic usage of this field in templates, is simply:
{{ record.fieldname }}
Where it'll output the (key of) the selected value. If there's more than one selected item, they're output as a comma separated string. In practice, this is often not very useful. If you're using a key/value hash, or selecting items from another ContentType, you'll want to output more information.
Outputting selected options¶
When using a Select field with a number of options, you can output them like this:
{% for value in record.selectfield.selected %}
<li>{{ value }}</li>
{% endfor %}
In this case, record
is the current Record, selectfield
is the name of the
field. The additional .selected
method is used to get the actual selected
items, instead of an object that contains them all.
If you're using a key/value hash, it's sometimes useful to be able to access either of them:
<ul>
{% for key, value in record.selectfield.selected %}
<li>{{ value }} <small>(key: <code>{{ key }}</code>)</small></li>
{% endfor %}
</ul>
If you wish to access all the possible defined options for the field,
regardless of whether they were selected or not, use select_options
function to get key/value
pairs for all the options:
{{ dump(select_options(record.selectfield)) }}
To read more on using select_options
, check the documentation for that function.
Outputting selected options from another ContentType¶
If you're using the Select Field to select items from a different ContentType,
you might've noticed that outputting {{ record.selectfield }}
will simply
output the ID of the selected record(s). Normally, you'll want to be able to
output something with those selected records. In order to do that, you need to
fetch the records using the selected
filter.
<ul>
{% for record in record.selectfield|selected %}
<li><a href="{{ record|link }}">{{ record|title }}</a></li>
{% endfor %}
</ul>
Warning: If the select field has
multiple: false
(the default), then the selected
filter will only return one record. If you have enabled multiple: true
,
then selected
will return an array of records.
Bolt does not automatically fetch all linked Records this in the background, because it's better for performance to only do this when needed.
To read more about this filder, check the selected filer documentation.
Couldn't find what you were looking for? We are happy to help you in the forum, on Slack or on Github.