I'm working on a site using the new jQuery module and I've run into a
bit of a problem trying to select elements by id when using ajax
because I end up with something like this.

<div id="slider_1315d440ac6" type="any" class="ui-slider
ui-slider-horizontal ui-widget ui-widget-content ui-corner-all"><a
href="#" class="ui-slider-handle ui-state-default ui-corner-all"
style="left: 50%; "></a></div>

for <div t:id="slider" t:mixin="slider"/>

Including a clientId helps by adding name="slider" but that does not
really solve the problem because name does not have to be unique. So I
decided to create a selector binding so I could say something like
this and have everything work.

<t:label for="size" />
        <t:any element="div" t:type="any" t:id="slider"
t:mixins="jquery/ui/slider,slidechange"
                slidechange.event="${event}"
                slidechange.zone="${zone}"
                slidechange.callback="function (event,ui,url) {url.addContext(
${selector:size}.val() )}"
                slider.options="{min:1, max: 5, value: ${selector:size}[ 0
].selectedIndex + 1,
                        slide: function( event, ui, url ) {
                                ${selector:size}[ 0 ].selectedIndex = ui.value 
- 1;
                        }
                }" >
        </t:any>
        <t:select t:id="size"
                model="literal:GreetingPanel,Small,Medium,Large,Jumbo"
                t:mixins="change,jquery/selector"
                change.callback="function(event,ui,url) {
                        ${selector:slider}.slider( 'value',
${selector:size}[0].selectedIndex + 1);
                } "/>

At first it seemed easy enough but then I ran into the label problem.
In the example above the t:any element needs the size client id before
its rendered, that's a problem and I don't think the label solution
@HeartbeatDeferred can work here. In order to solve that I created the
selector mixin. The two work together like this.

Relevant selector binding code just uses the client id if there is one
otherwise outputs a global variable reference.

public Object get() {   
                Component c = componentResources.getEmbeddedComponent(tid);
                String id = null;
                if ( ClientElement.class.isAssignableFrom(c.getClass())) {
                        ClientElement ce = (ClientElement) c;
                        id = ce.getClientId();
                }
                
                if ( id != null ) {
                        return String.format("jQuery('#%s')",id);
                }
                return String.format("jQuery(selector%s)",tid);
        }

Relevant selector mixin code adds a global variable with the real client id

void afterRender() {
                
javaScriptSupport.addScript(InitializationPriority.EARLY,"selector%s
= '#%s'", resources.getId(),clientElement.getClientId());
        }

That all works but it seems a bit complicated, error prone and uses
global javascript variables. Can anyone think of a better way to do
this, is this just difficult or can @HeartbeatDeferred solve this?

Thanks
Barry

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

Reply via email to