Dynamic select options using a wired template
Why
Suppose you want to wire a change event for a select box to update a another select box, i.e. you want to wire the action to use the selected value when rendering the template.
Assumptions
Readers are assumed to be comfortable editing templates and have Zotonic Scomp knowledge.
How
We want to select an image from a page in 2 steps. First we select a page from the pages that have images. Then we select an image from the selected page.
This is how the main template will look:
<div class="form-group">
{% wire id="pages" type="change" action={update
target="media_list"
template="_media_list.tpl"
}%}
<select id="pages" class="form-control">
<option value="">--Select a page--</option>
{% for page_id in m.search[{query
hasobjectpredicate='depiction'
sort='+rsc.pivot_title'
}] %}
<option value="{{ page_id }}">
{{ m.rsc[page_id].title }}
</option>
{% endfor %}
</select>
</div>
<div id="media_list">
<!- contents will be updated -->
</div>
When an item is selected (by the change event), element with id “media_list” will be replaced by _media_list.tpl
which looks like this:
{% with q.triggervalue as page_id %}
<div class="form-group">
<select class="form-control">
<option value="">--Select an image--</option>
{% for media_id in m.rsc[page_id].media %}
<option value="{{media_id}}">
{{ m.rsc[media_id].title }}
</option>
{% endfor %}
</select>
</div>
{% endwith %}
This template uses the q.triggervalue returned from the postback of the wire event, and it contains the value of the selected option.
We can go one step further to show the selected image. _media_list.tpl
also gets a wire action:
{% with q.triggervalue as page_id %}
<div class="form-group">
{% wire id="images" type="change" action={update
target="image"
template="_image.tpl"
}%}
<select class="form-control" id="images">
<option value="">--Select an image--</option>
{% for media_id in m.rsc[page_id].media %}
<option value="{{media_id}}">
{{ m.rsc[media_id].title }}
</option>
{% endfor %}
</select>
</div>
<div id="image">
<!- contents will be updated -->
</div>
{% endwith %}
And we show the image using _image.tpl
:
{% with m.rsc[q.triggervalue].medium as medium %}
<div class="form-group">
{% image medium width=300 %}
</div>
{% endwith %}