java - Problems encapsulating Dialog components in Tapestry 5.3 -


i'm trying build tapestry component called crudentityfield, based on textfield (core), dialoglink (tapestry5-jquery) , dialog (tapestry5-jquery) components, along zone ajax updates.

my use case quite simple:

crudentityfield render textfield. if know entity id, can enter there directly. if don't know id, can click on dialoglink button (select), pops dialog window. dialog lists available entities in table format, , lets filter criteria. once user selects entity, text field automatically refreshed related id (e.g '6'). also, related name/description printed clarity (e.g. '[gipuzkoa]'). snapshots: crudentityfield, pop-up dialog

ideally, logic can encapsulated in single tapestry component. here come issues:

  • the dialog (<div t:type="jquery/dialog" t:clientid="dialogidxxx">, see below) includes search form, , embedded within form (crud form). nested forms not allowed, try un-nest it. however, approach fail, runtime exception when inner form rendering, before have opportunity move it.

    @afterrender public void afterrender(markupwriter writer) {         element body = writer.getdocument().find("html/body");               writer.getdocument().getelementbyid("dialogidxxx").movetobottom(body);         } 
  • i tried other approaches, such @heartbeatdeferred, rendercommand, etc. found no way render dialog out of form.

component template:

<t:content>  <!-- a) entity field --> <t:zone t:id="entityzone" id="zoneidxxx">              <div class="inputelement">      <t:label for="textfield"/>     <input t:id="textfield"/>                 [<t:body/>]      <t:jquery.dialoglink t:dialog="dialogidxxx" class="dialoglink">select</t:jquery.dialoglink>     </div> </t:zone>     <!-- b) entity dialog -->   <div t:type="jquery/dialog" t:clientid="dialogidxxx" params="params" >                <table t:id="xa2grid" t:entity="inherit:entity" t:add="actions">                 <p:actionscell>                 <a t:type="eventlink" t:event="select" t:zone="zoneidxxx" t:context="entity.id" href="#">select</a>                               </p:actionscell>      </table>                       </div>    </t:content> 
  • ok, can split component in 2 pieces: entityfield (form input field) , entitydialog (placed out of form, in page template). not ellegant, though, since approach breaks abstraction.

    but approach won't work either. zone event triggered entitydialog component, , must handled or 1 of containers. zone defined in entityfield, sibling! (i can paste more code if not clear).

as you've seen, can't render form inside form need delay rendering of dialog until after form has rendered.

so, instead of rendering dialog inside component, use environmental bean. environmental store config dialogs on page

http://tapestry.apache.org/environmental-services.html

include block @ end of every page looks config environment , renders of dialogs. using layout in 1 place.

eg: layout.java

@inject environment environment;  @property private dialogconfigs dialogconfigs;  @property private dialogconfig dialogconfig;  void beforerender() {     dialogconfigs = new dialogconfigsimpl();     environment.push(dialogconfigs.class, dialogconfigs); }  void afterrender() {     environment.pop(dialogconfigs.class); } 

layout.tml

<html>     <body>         <t:body/>         <t:loop source="dialogconfigs.values" value="dialogconfig">             <div t:type="jquery/dialog" foo="dialogconfig.foo" bar="dialogconfig.bar">           </t:loop>     </body> </html> 

crudentityfield.java

@environmental private dialogconfigs dialogconfigs;  @parameter private string foo;  @parameter private string bar;  void beforerender() {     dialogconfigs.add(new dialogconfig(foo, bar)); } 

Comments