Removing the zone surrounding the textarea fixes the save issue but of course breaks the update functionality.

This is the code:

public class LoopWithZoneIssue {

    private final Logger logger = LoggerFactory.getLogger(Feedback.class);
    @Inject
    private Request request;
    @Property
    private String currentLink;
    @Property
    private String currentCriteria;
    @Property
    private int linkIndex;
    @Property
    private int criteriaIndex;
    @InjectComponent
    @Property
    private Zone textareaZone;
    @Persist
    private Map<String, String> criteria;
    @Persist
    private Map<String, String> links;
    private String ajaxLink;
    private String ajaxCriteria;

    void onActivate() {
        if (criteria == null) {
            criteria = new HashMap<String, String>();
criteria.put("Research", "Systematic identification and investigation of appropriate sources"); criteria.put("Communication and Presentation", "Clarity of purpose; skills in the selected media; " + "awareness and adoption of appropriate conventions; sensitivity to the needs of the audience"); criteria.put("Analysis", "Examination and interpretation of resources"); criteria.put("Personal and professional development", "Management of learning through reflection, " + "planning, self direction, subject engagement and commitment");
        }
        if (links == null) {
            links = new HashMap<String, String>();
            links.put("A", "Default value for A");
            links.put("B", "Default value for B");
            links.put("C", "Default value for C");
            links.put("D", "Default value for D");
            links.put("E", "Default value for E");
        }
    }

    public void onSelectedFromSaveFeedback() {
        logger.debug("Saving feedback form");
    }

    public Object onActionFromLink(String linkId, String criteriaId) {
        ajaxLink = links.get(linkId);
        ajaxCriteria = criteria.get(criteriaId);
        return textareaZone.getBody();
    }

    public String getUniqueZoneId() {
        return "uniqueZoneId_" + criteriaIndex;
    }

    public Collection<String> getCriteria() {
        return criteria.keySet();
    }

    public Collection<String> getLinks() {
        return links.keySet();
    }

    public ValueEncoder<String> getCriteriaEncoder() {
        return new ValueEncoder<String>() {

            public String toValue(String value) {
                for (String key : criteria.keySet()) {
                    if (criteria.get(key).equals(value))
                        return key;
                }
                return "unknown";
            }

            public String toClient(String key) {
                String value = criteria.get(key);
                return value;
            }
        };
    }

    public String getTextareaValue() {
        logger.debug("called getTextareaValue");
        if (request.isXHR()) {
            return ajaxLink;
        }
        else {
            return criteria.get(currentCriteria);
        }
    }

    public void setTextareaValue(String textareaValue) {
logger.debug("called setTextareaValue '{}' for criteria '{}'", textareaValue, currentCriteria);
        criteria.put(currentCriteria, textareaValue);
    }

}

And the tml:

<t:form>
  <t:loop t:id="criteria" value="currentCriteria" source="criteria"
  encoder="criteriaEncoder" index="criteriaIndex">
    <h3>${currentCriteria}</h3>
    <t:loop t:id="links" value="currentLink"
    source="links" index="linkIndex">
      <t:actionlink t:id="link" zone="prop:uniqueZoneId"
      context="[currentLink,currentCriteria]">${currentLink}
      </t:actionlink>
      <span>&nbsp;&nbsp;&nbsp;</span>
    </t:loop>
    <t:zone t:id="textareaZone" id="prop:uniqueZoneId">
      <t:textarea value="textareaValue"
      style="width:100%;height:9em;" />
    </t:zone>
    <br />
    <br />
  </t:loop>
  <t:submit value="Save" t:id="save" />
</t:form>

Thanks,
Alex

On 24.06.2011 17:27, Taha Tapestry wrote:

Can you share the code of the event handler for the action.
I think all the textareas are getting bound to the last object of the loop's 
source


Regards
Taha

On Jun 24, 2011, at 7:35 PM, Alexander Rosemann<alexander.rosem...@gmail.com>  
wrote:

Hi Taha,

I should have put more thought in my example. The zone gets its unique id and 
is updated by a set of actionlinks that I have omitted in my previous example. 
This is the full one:

<t:form>

  <t:loop t:id="criteria" value="currentCriteria" source="criteria"
    encoder="cEncoder">

    <t:loop t:id="links" value="link" source="links">
      <t:actionlink t:id="linkId" zone="prop:uniqueZoneId">some
        text</t:actionlink>
    </t:loop>

    <t:zone t:id="textareaZone" id="prop:uniqueZoneId">
      <t:textarea value="textareaValue" />
    </t:zone>

  </t:loop>

  <t:submit value="Save" t:id="save"/>
</t:form>

The actionlinks fill the textarea with default data which can then be altered 
by the user and finally saved.

Regards,
Alex



On 24.06.2011 15:48, Taha Hafeez wrote:
Hi

Whenever you use a zone in a loop, you should provide the javascript id
yourself. You can use the index to create a unique one

e.g.

<t:zone t:id='textareaZone' id='textareaZone_${index}'>
</t:zone>

If you are using a non-ajax form, what is the use of zone here ??

regards
Taha

On Fri, Jun 24, 2011 at 7:01 PM, Alexander Rosemann
<alexander.rosem...@gmail.com>   wrote:

Hi,

I asked this before but couldn't resolve the issue based on the information 
that Taha forwarded me.
(http://tapestry.1045711.n5.nabble.com/loops-zones-and-encoders-td4425814.html#a4425945)

I have a loop that creates textareas within a form. Each textarea is wrapped by 
a zone. Outside the loop is a submit button to save the form. No matter whether 
I set the submit defer attribute to false or true, my code only persists the 
information of the last texarea in the loop.

That's how the form part of the tml looks like:

<t:form>
  <t:loop t:id="criteria" value="currentCriteria" source="criteria"
    encoder="cEncoder">
    <t:zone t:id="textareaZone">
      <t:textarea value="textareaValue" />
    </t:zone>
  </t:loop>
  <t:submit value="Save" t:id="save"/>
</t:form>

The odd thing is that the encoder (cEncoder) for the loop gets called n times 
before the setter of the currentCriteria field gets called n times. Removing 
the zone brings back the normal behaviour of calling first the encoder and 
second, the setter of the corresponding field.

Any hints and pointers to fix this are much appreciated.

Regards,
Alex








--
DI(FH) Alexander Rosemann
open source based software solutions
Naunspitzweg 3 | 6341 Ebbs | Austria
mobile: +43-681-10337082 | email: alexander.rosem...@gmail.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to