The following tutorial is based upon the Formlister "Add Multiselect Options" tutorial.
In this tutorial we use DocLister to populate the multiple select options found in the "Add Multiselect Options" tutorial.
This may sound easy, but, for a non-developer it isn't an easy task to do, especialy if you want the form fields to be remembered (using Formlisters "formcontrols") in case the form has to be re-submitted.
If you don't care about remembering the options if the form has to be re-submitted, you can call Doclister directly in your template, something like this:
<select name="multiselect[]" id="multiselect" multiple="multiple">
[[Doclister?
&id=`blah`
&parents=`5`
&orderBy=`pagetitle ASC`
&tvList=`number`
&renderTV=`number`
&tpl=`@CODE:<option value="[+number+]" [+s.multiselect.[+number+]+]>Test [+number+]</option>`
&addWhereList=`hidemenu=1 AND published=1`
]]
</select>
This way Doclister will populate the options on the fly, but Formlister won't remember the users selected options in case the user has to re-submit the form.
A special "thank you" goes out to @Pathologic for creating the snippet that is used in this tutorial, without his help this tutorial wouldn't be here.
Where to start ?
We need to create a variety of elements:
- A snippet for Formlister to tell Doclister to render the options in our "select" area
- An additional parameter for our Formlister call
- An additional placeholder for our Formlister form template (
&tpl
)
We will start with the snippet that was kindly created by the developer of FormLister, @Pathologic.
Snippet code:
Login and create a new snippet, call it whatever you want, now copy and paste the following code into the code block / area.
<?php
$values = $FormLister->getField('multiselect');
if (!is_array($values)) {
$values = empty($values) ? [] : [$values];
}
$options = $modx->runSnippet('DocLister', [
'parents' => 5,
'orderBy' => 'pagetitle ASC',
'tvList' => 'number',
'renderTV' => 'number',
'addWhereList' => 'hidemenu=1 AND published=1',
'tpl'=>'@CODE:<option value="[+id+]-[+longtitle+]-blah-[+tv.number+]" [+selected+]>[+longtitle+] Blah [+tv.number+]</option>',
'prepare' => function($data) use ($values){
$value = "{$data['id']}-{$data['longtitle']}-blah-{$data['tv.number']}";
$data['selected'] = in_array($value, $values) ? 'selected' : '';
return $data;
}
]);
$FormLister->setPlaceholder('options', $options);
As I am not a PHP developer the code breakdown will be simple, it contains the elements that need to be modified so that it can be used for any HTML form.
Snippet Code Breakdown
$values = $FormLister->getField('multiselect');
This tells formlister the name of the field that we wish to populate with Doclister, in this case the "select" tag is named "multiselect"
$options = $modx->runSnippet('DocLister', [
DocLister is now told to call the documents using the named parameters. The parameters are self explanatory, if you have already used DocLister anywhere else in your website
'parents' => 5,
'orderBy' => 'pagetitle ASC',
'tvList' => 'number',
'renderTV' => 'number',
'addWhereList' => 'hidemenu=1 AND published=1',
parents - the ID of the parent where the docs are to be found
orderby - order the options using alphanumeric in ascending order
tvList - all of the TVs that are to be used within the "option" tpl
renderTV - copy and paste the TVs from "tvList" - this renders the list of TV's
addWhereList - gets documents that are hidden from the menu and are published - can be whatever you want
These options / parameters are not mandatory, they can be whatever you like. Look at the format they are written in and add or remove what you require.
Example:
in a normal Doclister call the parents are called like this: &parents=`5`
In the snippet they are called like this: 'parents' => 5
'tpl'=>'@CODE:<option value="[+id+]-[+longtitle+]-blah-[+tv.number+]" [+selected+]>[+longtitle+] Blah [+tv.number+]</option>',
The template for the "option" values.
The elements in "value" are the most important for the snippet, as they are required in the prepare parameter
$value = "{$data['id']}-{$data['longtitle']}-blah-{$data['tv.number']}";
What we need to look at here is everything between the inverted commas, these elements are the equivalents from the option value.
[+id+]
= {$data['id']}
- - = -
[+longtitle+]
= {$data['longtitle']}
- -blah- = -blah-
[+tv.number+]
= {$data['tv.number']}
So when you add your own elements to the option value, you have to add their equivalents to $value = ""
So if your call uses [+menutitle+]
the equivalent is {$data['menutitle']}
If you only have an option value of [+tv.number+]
your $value
eqivalent will only contain {$data['tv.number']}
Hopefully this is understandable, if not, please post your question in the general forum
Formlister call addition:
Now that we have the snippet installed, we need to add it to our Formlister call.
Here we use the "prepare" parameter (snippets used in the prepare parameter are run before form validation) for more information, please read the documentation.
Note: the name required is the name of the snippet you just created.
[!FormLister?
&prepare=`yoursnippetname`
...
!]
If you already have the "prepare" parameter in your Formlister call, you can add the new snippet by using a comma e.g snippet1,snippet2
Form TPL addition:
When calling your Formlister form, you need to add the "options" placeholder.
<select name="multiselect[]" id="multiselect" multiple="multiple">
[+options+]
</select>
The "options" placeholder is defined via the snippet, you simply have to add the placeholder tag into your "select" tag, found in your template and the options will be rendered in that placeholder.