You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by amol <am...@gmail.com> on 2009/04/02 14:57:13 UTC

Re: Multiple zone updater

hi,
I m just trying to update a multiple zone but i m confused that what value I need to pass for 
parameter zoneTriggerCssIdentifiers

Thanks

Hi all,

I remember a discussion here a few weeks ago on updating multiple zones on
one request. I had such a need myself and developed a MultipleZoneUpdater
Mixin.

It is working for me now but it requires more testing. I thought I'd share
it anyway in case someone is interested or has ideas on improvements. The
idea is to add the mixing to a component which has multiple zones to update
by a single trigger (a, form, zone).

It takes two parameters. A map of zoneId's mapped to the block id's to fill
the zone with and a String of comma separated css identifiers that will
trigger the multiple zone updates. If the trigger is a zone, the other
multiple zones will only start updating once the initial zone is done, so
that any serverside processes are complete. The code follows below.

Cheers,
Joost

A few notes:
- it would be great to have a hook in the zone updating process. Now I had
to copy some of the Tapestry.js (the Zone.show method) in order to make this
work. Or maybe I'm missing something here.
- Also, is there a way to reorder the renderSupport.addScript() calls. I
couldn't find a way to load my script after the Tapestries Zone initializer
script. I had to solve it with adding an Event.observe(window, 'load',
myMethod);

PS: I've been using T5.0.14-SNAPSHOT

------------------------------- THE MIXIN JAVA -------------------------
package com.joostschouten.common.http.tapestrybase.mixins;

import java.util.Map;
import java.util.StringTokenizer;

import org.apache.tapestry5.Block;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.Link;
import org.apache.tapestry5.RenderSupport;
import org.apache.tapestry5.annotations.CleanupRender;
import org.apache.tapestry5.annotations.IncludeJavaScriptLibrary;
import org.apache.tapestry5.annotations.OnEvent;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.ioc.annotations.Inject;

@IncludeJavaScriptLibrary("MultipleZoneUpdater.js")
public class MultipleZoneUpdater {

    private static final String ZONE_UPDATE_EVENT_NAME =
"EXTRA_ZONE_UPDATE";

    /**
     * A Map of Zone id's mapped to the Block id's to update the zone
     */
    @Parameter(required = true)
    private Map<String, String> zoneBlocks;

    @Inject
    private RenderSupport renderSupport;

    /**
     * A comma seperated list of css identifiers of all elements that should
trigger the
     * multiple zone update.
     * in case of an a: onmouseup
     * in case of a zone: once loaded
     * in case of a form: onsubmit
     */
    @Property
    @Parameter(required = true, defaultPrefix = "literal")
    private String zoneTriggerCssIdentifiers;

    /**
     *
     */
    @Inject
    private ComponentResources componetResources;

    /**
     * @param blockId
     * @return
     */
    @OnEvent(value = ZONE_UPDATE_EVENT_NAME)
    private Object handleZoneUpdate(String blockId) {
        ComponentResources handle = componetResources;
        Block ret = null;
        while(ret == null && handle != null) {
            ret = handle.findBlock(blockId);
            handle = handle.getContainerResources();
        }
        return ret;
    }

    /**
     * @param writer
     */
    @CleanupRender
    private void addScripts () {
        Link link =
componetResources.createActionLink(ZONE_UPDATE_EVENT_NAME, false);
        StringBuffer buffy = new StringBuffer();
        buffy.append("'({");
        int i = 0;
        for (String key : zoneBlocks.keySet()) {
            if(buffy.length() > 4) {
                buffy.append(",");
            }
            buffy.append("\"zoneBlock_" + i + "\":{\"zone\":\"" + key +
"\",\"block\":\"" + zoneBlocks.get(key) + "\"}");
            i++;
        }
        buffy.append("})'");

        StringBuffer zoneTriggers = new StringBuffer("[");
        StringTokenizer strt = new
StringTokenizer(zoneTriggerCssIdentifiers, ",");
        while (strt.hasMoreElements()) {
            if(zoneTriggers.length() > 1) {
                zoneTriggers.append(",");
            }
            zoneTriggers.append("'" + strt.nextToken() + "'");
        }
        zoneTriggers.append("]");
        //have the call executed at window load so that the zone's are
initialized before this call is made
        renderSupport.addScript("Event.observe(window, 'load', function()
{MultipleZoneUpdater.attacheMultipleZoneUpdateTriggers('" +
link.toAbsoluteURI() + "'," + zoneTriggers.toString() + "," +
buffy.toString() +");});");
    }

}

------------------------------- THE MIXIN JAVASCRIPT
-------------------------

var MultipleZoneUpdater = {
    zoneTriggers:new Array(),
    /**
     *
     */
    attacheMultipleZoneUpdateTriggers:function(uri,
domTriggerCssIdentifiers, zoneBlocksJSON) {
        var triggers;
        for(i = 0;i<domTriggerCssIdentifiers.length;i++) {
            tempTriggers = $$(domTriggerCssIdentifiers[i]);
            if(!triggers) {
                triggers = tempTriggers;
            }
            else {
                for(t = 0;t<tempTriggers.length;t++) {
                    triggers.push(tempTriggers[t]);
                }
            }
        }
        var zoneBlocks = eval(zoneBlocksJSON);
        newZoneTrigger = new ComponentTrigger(uri, zoneBlocks);
        MultipleZoneUpdater.zoneTriggers.push(newZoneTrigger);
        for (i = 0; i<triggers.length; i++) {
            tagName = triggers[i].tagName.toLowerCase();
            if(tagName == 'a') {
                triggers[i].observe('mouseup',
newZoneTrigger.triggerUpdate.bindAsEventListener(newZoneTrigger));
            }
            else if (tagName == 'form') {
                triggers[i].observe('submit',
newZoneTrigger.triggerUpdate.bindAsEventListener(newZoneTrigger));
            }
            else if (triggers[i].hasClassName('t-zone')){
                triggers[i].zone.show = function(content) {
                        //a copy of tapestries code in the show method
                            this.updateElement.update(content);
                            var func = this.element.visible() ?
this.updateFunc : this.showFunc;
                            func.call(this, this.element);

                            //our added line
                            newZoneTrigger.triggerUpdate();
                        }
            }

        }
    }
}

function ComponentTrigger(uri, zoneBlocks) {
    this.uri = uri;
    this.zoneBlocks = zoneBlocks;
    this.triggerUpdate = triggerMultipleZoneUpdate;
}

/**
     *
     */
function triggerMultipleZoneUpdate() {
    for(var i in this.zoneBlocks) {
        var zoneToUpdate = $(this.zoneBlocks[i].zone);
        var fullUri = this.uri + '/' + this.zoneBlocks[i].block;
        var myAjax = new Ajax.Request( fullUri, {method: 'get', onSuccess:
function(transport) {
                    zoneToUpdate.update(transport.responseJSON.content);
                    Tapestry.processScriptInReply(transport.responseJSON);
                }
            } );
    }
}



-- 
View this message in context: http://n2.nabble.com/Multiple-zone-updater-tp669687p2575005.html
Sent from the Tapestry Users mailing list archive at Nabble.com.


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


Re: Multiple zone updater

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
Just remembering you that multiple zone AJAX update suppport was added
to Tapestry in 5.1.0.x (I don't remember what version exactly).

-- 
Thiago

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