Skip to content
Go to file

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


This is a collection of Tapestry 5 components and mixins written to enhance overall UX and, in particular, Twitter Bootstrap integration.

Initially it was created as a part of, and moved to separate open-source project as a contribution to Apache Tapestry community.


  • Clone the project and run mvn clean install inside project's directory
  • Add xmlns:t5x="tapestry-library:t5xtensions" to yor .tml root element



AJAX upload component providing basic integration with Blueimp jQuery-File-Upload. Please note that you need to persist uploadedFile parameter elsewhere so it's not lost during form submission. Currently only single-file AJAX upload is supported - feel free to fork and modify as needed.

Basic usage:

<t5x:ajaxupload t:id="ajaxFileUpload" p:value="uploadedFile"/>


Wrapper around Tapestry Hidden component that receives its value from Bootstrap drop-down. Acts very similar to standard Select component (i.e. accepts model parameter or creates model automatically if value contains enum type.

<t5x:dropdownfield p:value="currency"/>


Convenience component for formatting dates.

<t5x:formatdate p:date="dateValue" p:format="dd.MM.yyyy"/>


Similar to Tapestry Errors component, but provides different layout (each error message has its own alert box).



Integration with Bootstrap modal component. Basically, to display modal, you need to create an empty zone and update this zone with injected block body during AJAX request.

    private Block modalDialogBlock;
    Object onActionFromShowModal () {
        // do something
        return modalDialogBlock;
  <t:zone t:id="modalDialogZone" id="modalDialogZone">
  <t:actionlink t:id="showModal" p:zone="modalDialogZone">Show modal</t:actionlink>
  <t:block t:id="modalDialogBlock">
    <t5x:modaldialog p:title="literal:Modal dialog title">
        <p>Modal dialog body</p>


Segmented control backed by radio group. Looks similar to its iOS UISegmentedControl counterpart. Like select component, accepts model parameter.

<t5x:segmentedcontrol t:id="segmentedControl" p:model="valuesModel" p:value="value"/>



Allows to add attributes to elements (using JavaScript) after page rendering depending on selected conditions. For example, make a field read-only if certain condition is met.

<t:textfield p:value="value" t:mixins="t5xtensions/addattribute" 
             p:condition="someCondition" p:attrname="readonly" p:attrvalue="readonly"/>


Confirmation dialog using Bootstrap. Similar to Tapestry built-in Confirm component, but more flexible.

<button t:id="submitDelete" t:type="submit" class="btn btn-danger" p:value="message:button.delete"
        t:mixins="t5xtensions/bsconfirm" p:message="prop:removalConfirmation" p:confirmClass="btn-danger"/>


Bootstrap popover component integration. Uses Boostrap data-* attributes, doesn't require any additional parameters.

<a href="#" class="btn btn-sm btn-success" onclick="return false;"
  t:type="any" t:mixins="t5xtensions/bspopover" 
  data-toggle="popover" data-trigger="hover" data-html="true" 
  data-title="Some title" 
  data-content="Popover content" data-placement="right">
  <span class="glyphicon glyphicon-ok-sign glyphicon-white"/>


Bootstrap tooltip component integration. Uses Boostrap data-* attributes, doesn't require any additional parameters.

<span t:type="any" class="btn btn-warning btn-xs" t:mixins="t5xtensions/bstooltip" 
      title="Tooltip text" data-toggle="tooltip" data-placement="top">
  <i class="glyphicon glyphicon-exclamation-sign glyphicon-white"/>


This component lets you trigger form submit from the specified submit element to handle sitiations when user presses enter within a text form control by mistake. Triggering form submit from a specified element allows you to bypass normal form submission in your server-side code using onSelected submission handlers.

<t:form p:zone="zone" t:mixins="t5xtensions/onenter" p:submitElement="prop:defaultSubmitId">
<t:submit t:id="submitDefault" class="hidden"/>
<!-- some other form controls -->
    void onSelectedFromSubmitDefault () {
        this.skipValidation = true;


Allows to update a zone or trigger form submit on specified client event.

For example, submit the form when change event is triggered on select:

<t:select p:value="selectedValue" p:model="selectModel"
          t:mixins="t5xtensions/onevent" p:submitElement="prop:hiddenSubmitId" p:clientEvent="change"/>

Update specified zone when radio button is selected:

<t:radio p:value="someValue" t:mixins="t5xtensions/onevent" 
         p:serverevent="reloadzone" p:updatezone="prop:zoneId"/>

Check component source code for more options.


Convenience mixin that toggles off Bootstrap dropdown when dropdown action is an AJAX request (otherwise dropdown doesn't toggle).

<button class="btn btn-default dropdown-toggle" data-toggle="dropdown" id="showLinks">
  <span class="glyphicon glyphicon-plus"/>&#160;Show some links&#160;<span class="caret"/>
<ul class="dropdown-menu">
  <li><t:actionlink t:id="link1" p:zone="zone" t:mixins="t5xtensions/ToggleDropdown" p:dropdownid="showLinks">
      Ajax Action 1</t:actionlink>
  <li><t:actionlink t:id="link2" p:zone="zone" t:mixins="t5xtensions/ToggleDropdown" p:dropdownid="showLinks">
      Ajax Action 2</t:actionlink>


Replacement for built-in Tapestry Autocomplete mixin. Provides much more flexibility: allows you to specify suggestion templates, can handle list of Map objects or list of beans as completion results.

<t:textfield p:value="value" t:mixins="t5xtensions/typeahead" 
             p:keys="literal:username,email" p:template="literal:{{username}}, {{email}}"/>
    List<MyUser> onCompletionsRequestedFromUserLookupField ( String partial ) {
        return userManagerService.getUserSuggestions ( partial );

Note: when you are using list of beans or list of Map objects for suggestions, all the keys you have specified in keys parameter must be present as bean properties or map keys, respectively. Otherwise you get an error.



Ilya Obshadko

You can’t perform that action at this time.