Hello,

I have 3 nested object. A survey, a section and a question. A survey will
contain sections and a section will contain questions. I want to create a
single page editor for this nested object using ajax.

In add survey page i have created two zone, survey zone and
sectionListZone. The survey zone content will depend on a flag. It can show
an input form for the survey or a view of the survey data. The
sectionListZone content is a SectionHolder component (custom component for
handling the section).

The SectionHolder component also contains two zone, sZone and qZone. The
sZone content also depend on a flag, to show an input form for the section
or to view the section data. The qZone content is a QuestionHolder
component (custom component for handling the questions).

I've managed to create the add survey page to add & view the survey data. I
also manage to create the section holder component by using the same
pattern as the add survey page (using ajax response renderer to render both
zone when the form is submitted). The problem is in the SectionHolder
component i can't render multiple zone using ajax renderer. Returning a
block from onSuccess will work. But using ajax renderer to render the zone
will result this error :

Element 'sZone' does not have an associated Tapestry.ZoneManager object.

Communication with the server failed: TypeError: Cannot call method
'getStorage' of null

Here's my code for the Add Survey page & the Section Holder.
Thanks

=== Add Survey TML ===

<t:zone t:id="surveyZone" id="surveyZone">
 <form t:type="form" t:id="frmCreateSurvey" t:zone="^">
 <div>
 <t:delegate to="surveyBlock"/>
</div>
 <div>
<t:errors/>
</div>
 </form>

<hr/>
</t:zone>

<div>
<t:zone t:id="sectionListZone" id="sectionListZone">
 <t:delegate to="sectionListBlock"/>
</t:zone>
</div>

        <t:block id="addSurveyBlock">
<t:label for="title"/>
<t:textfield t:id="title" value="survey?.title" t:validate="required,
maxlength=35" size="35"/>
 <input type="submit" value="Save"
class="btn btn-sm btn-primary"/>
 </t:block>
 <t:block id="viewSurveyBlock">
 SURVEY BLOCK <br/>
Title : ${survey?.title}
 <a t:type="actionlink" t:id="editSurvey" t:zone="surveyZone" href="#"
class="btn btn-sm btn-primary">Edit</a>
 </t:block>

<t:block id="viewSectionListBlock">
<t:section.SectionHolder t:id="sectionHolder"/>
 </t:block>

<t:block t:id="emptyBlock"/>

====== Add Survey.Java =========
        @Inject
private AjaxResponseRenderer ajaxRenderer;
 @Inject
private Block addSurveyBlock, viewSurveyBlock, viewSectionListBlock,
emptyBlock;

    @Inject
    private Request request;

    @InjectComponent
    private Zone surveyZone, sectionListZone;

@Property
 @Persist // TODO erase this when we use database
private Survey survey;

@Persist
 private boolean isReadyToPublish;
 @Persist
private boolean isEditSurvey;
 @Persist
private boolean isSectionShown;

void onSuccess() {
isEditSurvey = false;
isSectionShown = true;
 if(request.isXHR()) {
ajaxRenderer.addRender(surveyZone).addRender(sectionListZone);
 }
}
 public Object getSurveyBlock() {
 return isEditSurvey ? addSurveyBlock : viewSurveyBlock;
}
 public Object getSectionListBlock() {
return isSectionShown? viewSectionListBlock : emptyBlock;
}

void onActionFromEditSurvey() {
isEditSurvey = true;
if(request.isXHR()) {
 ajaxRenderer.addRender(surveyZone);
}
}


=== SectionHolder Component tml ===
<t:content>
<h4>Section</h4>
 <t:zone t:id="sZone" id="sZone">
<form t:type="form" t:id="frmCreateSection" t:zone="^">
 Section 1
<div id="sectionDiv">
<t:label for="name"/>
 <t:textfield t:id="name" value="name" />
 <input class="btn btn-sm btn-primary" type="submit" value="Save"/>
 </div>
<div>
<t:errors/>
 </div>
</form>
 </t:zone>

<div>
<t:zone t:id="qZone" id="qZone">
 Question Block
</t:zone>
</div>
</t:content>

=== Section Holder.java ===

    @Inject
    private Request request;

    @Inject
    private AjaxResponseRenderer ajaxRenderer;

    @InjectComponent
    private Zone sZone, qZone;

@Property
private String name;
 void onSuccess() {
System.out.println("Success!");
 if(request.isXHR()) {
ajaxRenderer.addRender(sZone).addRender(qZone);
 }
}

-- 
http://www.mreunionlabs.net/ <http://www.mreunion-labs.net/>
twitter : @mreunionlabs
page : https://plus.google.com/104168782385184990771

Reply via email to