You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Jürgen Lind <Ju...@iteratec.de> on 2012/06/04 19:21:42 UTC

Component-specific javascript in Ajax-Calls

Hi,

for some time now, I've been trying various methods to add javascript code, that works
just on the components that are updated during an ajax call. A classic example for this
kind of stuff is to add some jQuery enhancements to existing html-elements. The simplest
way of doing this is obviously to include the Javascript code in the component markup and
have it being executed every time the component is rendered.

While this works as it should, the only problem that remains is that I would like the
javascript to work on the smallest part of the DOM tree as possible. Thus, instead of

       <script>
          $(document).ready(function() {
            $("#.ttr").tipTip({defaultPosition: "right"});
          });
       </script>

which traverses the entire DOM tree to find elements with the respective class, I would
like to include the markup id of the parent component, such that only the elements below
this node are traversed. The problem for me was, how to get this markup id and how to
inject it into javascript code.

As I have said above, I have tried several ways of achieving this and every method had
it's pros and cons. My current favorite is that I have written a special wicket tag that
determines the markup id of the enclosing component and rewrites it's body such that the
id winds up in the javascript code. The above code becomes the following:

       <wicket:script>
          $(document).ready(function() {
            $("#markupId .ttr").tipTip({defaultPosition: "right"});
          });
       </wicket:script>

with the placeholder being replaced by the actual markup id of the component upon rendering
the tag.

Now, my question is, whether this approach is somewhat reasonable or did I prehaps miss
something obvious here? The code for the new tag is added below. I would also like to know
about any mistakes in there.

Thanks for reading until this point ;-)

J.


import org.apache.commons.lang.StringUtils;
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.MarkupException;
import org.apache.wicket.markup.MarkupStream;
import org.apache.wicket.markup.WicketTag;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.parser.filter.WicketTagIdentifier;
import org.apache.wicket.markup.resolver.IComponentResolver;


public class ScriptResolver implements IComponentResolver {

   private static final String tagname = "script";

   static {
     WicketTagIdentifier.registerWellKnownTagName(tagname);
   }

   public Component resolve(final MarkupContainer container, MarkupStream markupStream,
                            ComponentTag tag) {
     if ((tag instanceof WicketTag) && tagname.equalsIgnoreCase(tag.getName())) {
       final String id = "_" + tagname + "_" + container.getPage().getAutoIndex();

       WebMarkupContainer c = new WebMarkupContainer(id) {
         @Override
         public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) {
           WicketTag wtag = (WicketTag) openTag;
           String parentId = StringUtils.trimToNull(wtag.getAttribute("parent"));

           String markupId = null;
           if (parentId != null) {
             Component parent = ScriptResolver.this.findParent(container, parentId);
             if (parent != null) {
               markupId = parent.getMarkupId();
             }
           } else {
             markupId = container.getMarkupId();
           }
           if (markupId == null) {
             throw new MarkupException("Parent with id '" + parentId + "' not found in hierarchy");
           }
           getResponse().write("<script>");
           String body = "";
           while (markupStream.hasMore()) {
             if ((openTag != null) && markupStream.get().closes(openTag)) {
               break;
             }
             body += markupStream.get();

             markupStream.next();
           }

           String tmp = body.replaceAll("#markupId", "#" + markupId);
           getResponse().write(tmp);

           getResponse().write("</script>");
         }
       };
       container.autoAdd(c, markupStream);

       return c;

     }
     return null;
   }

   protected Component findParent(Component c, String parentId) {
     if (c != null) {
       if (c.getId().equals(parentId)) {
         return c;
       } else {
         return findParent(c.getParent(), parentId);
       }
     } else {
       return null;
     }
   }
}




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


Re: Component-specific javascript in Ajax-Calls

Posted by Jürgen Lind <Ju...@iteratec.de>.
Martin,

ok, I will think about going to one of the ideas Thomas suggested. I still like the
idea that I have my javascript only in the markup file and nothing in the Java class,
though...

Thanks again,

J.


On 04.06.2012 21:25, Martin Grigorov wrote:
> On Mon, Jun 4, 2012 at 10:22 PM, Jürgen Lind<Ju...@iteratec.de>  wrote:
>> Thanks Martin,
>>
>> maybe I should have asked before trying to invent my own stuff... Anyway,
>> developing
>> a new wicket tag was some kind of fun as well...
>
> I'm glad you have fun but I highly recommend staying away from
> IComponentResolver if you can afford that.
> Many of the unresolved tickets in Wicket's Jira are related to this.
>
>>
>> J.
>>
>>
>> On 04.06.2012 21:10, Martin Grigorov wrote:
>>>
>>> On Mon, Jun 4, 2012 at 10:01 PM, Jürgen Lind<Ju...@iteratec.de>
>>>   wrote:
>>>>
>>>> Thomas,
>>>>
>>>> thanks for this hint, didn't know about that... So the script is executed
>>>> every time the
>>>> component is updated in an ajax call, correct? If so, it would surely
>>>> solve
>>>
>>>
>>> For every rerender of the component. That includes non-Ajax (whole
>>> page) requests as well.
>>>
>>>> some of my
>>>> issues. For longer scripts, I would still prefer to have them in the
>>>> markup
>>>> file (might be
>>>> different if we had multiline strings in Java, btw)
>>>
>>>
>>> For longer scripts you can create JS helpers like:
>>>
>>> in some.js:
>>> var helper = function(selector) {
>>>    // something longer here
>>> }
>>>
>>> is Some.java:
>>>
>>> response.renderOnDomReadyJavaScript("helper($('#" + getMarkupId() +"');");
>>>
>>>>
>>>> J.
>>>>
>>>>
>>>> On 04.06.2012 20:32, Thomas Götz wrote:
>>>>>
>>>>>
>>>>> What about this?
>>>>>
>>>>>
>>>>> public class MyComponent extends Panel {
>>>>>
>>>>>      public MyComponent(String id) {
>>>>>          super(id);
>>>>>          setOutputMarkupId(true);
>>>>>      }
>>>>>
>>>>>      @Override
>>>>>      public void renderHead(IHeaderResponse response) {
>>>>>          response.renderOnDomReadyJavaScript(
>>>>>                  "$('#" + getMarkupId() + "
>>>>> .ttr').tipTip({defaultPosition:
>>>>> 'right'});");
>>>>>      }
>>>>>
>>>>> }
>>>>>
>>>>>     -Tom
>>>>>
>>>>>
>>>>> On 04.06.2012, 19:21 Jürgen Lind wrote:
>>>>>
>>>>>> […]
>>>>>>       <wicket:script>
>>>>>>          $(document).ready(function() {
>>>>>>            $("#markupId .ttr").tipTip({defaultPosition: "right"});
>>>>>>          });
>>>>>>       </wicket:script>
>>>>>> […]
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>>>>> For additional commands, e-mail: users-help@wicket.apache.org
>>>>>
>>>>
>>>>
>>>> Mit freundlichen Grüßen,
>>>>
>>>> Jürgen Lind
>>>>
>>>> --
>>>> Dr. Jürgen Lind
>>>> iteratec GmbH                Fon: +49 (0)89 614551-44
>>>> Inselkammerstrasse 4         Fax: +49 (0)89 614551-10
>>>> 82008 Unterhaching           Web: www.iteratec.de
>>>>
>>>> Sitz und Registergericht der iteratec GmbH: München HRB 113 519
>>>> Geschäftsführer: Klaus Eberhardt, Mark Goerke, Inge Hanschke, Ralf Menzel
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>>>> For additional commands, e-mail: users-help@wicket.apache.org
>>>>
>>>
>>>
>>>
>>
>>
>> Mit freundlichen Grüßen,
>>
>> Jürgen Lind
>>
>> --
>> Dr. Jürgen Lind
>> iteratec GmbH                Fon: +49 (0)89 614551-44
>> Inselkammerstrasse 4         Fax: +49 (0)89 614551-10
>> 82008 Unterhaching           Web: www.iteratec.de
>>
>> Sitz und Registergericht der iteratec GmbH: München HRB 113 519
>> Geschäftsführer: Klaus Eberhardt, Mark Goerke, Inge Hanschke, Ralf Menzel
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>> For additional commands, e-mail: users-help@wicket.apache.org
>>
>
>
>

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


Re: Component-specific javascript in Ajax-Calls

Posted by Martin Grigorov <mg...@apache.org>.
On Mon, Jun 4, 2012 at 10:22 PM, Jürgen Lind <Ju...@iteratec.de> wrote:
> Thanks Martin,
>
> maybe I should have asked before trying to invent my own stuff... Anyway,
> developing
> a new wicket tag was some kind of fun as well...

I'm glad you have fun but I highly recommend staying away from
IComponentResolver if you can afford that.
Many of the unresolved tickets in Wicket's Jira are related to this.

>
> J.
>
>
> On 04.06.2012 21:10, Martin Grigorov wrote:
>>
>> On Mon, Jun 4, 2012 at 10:01 PM, Jürgen Lind<Ju...@iteratec.de>
>>  wrote:
>>>
>>> Thomas,
>>>
>>> thanks for this hint, didn't know about that... So the script is executed
>>> every time the
>>> component is updated in an ajax call, correct? If so, it would surely
>>> solve
>>
>>
>> For every rerender of the component. That includes non-Ajax (whole
>> page) requests as well.
>>
>>> some of my
>>> issues. For longer scripts, I would still prefer to have them in the
>>> markup
>>> file (might be
>>> different if we had multiline strings in Java, btw)
>>
>>
>> For longer scripts you can create JS helpers like:
>>
>> in some.js:
>> var helper = function(selector) {
>>   // something longer here
>> }
>>
>> is Some.java:
>>
>> response.renderOnDomReadyJavaScript("helper($('#" + getMarkupId() +"');");
>>
>>>
>>> J.
>>>
>>>
>>> On 04.06.2012 20:32, Thomas Götz wrote:
>>>>
>>>>
>>>> What about this?
>>>>
>>>>
>>>> public class MyComponent extends Panel {
>>>>
>>>>     public MyComponent(String id) {
>>>>         super(id);
>>>>         setOutputMarkupId(true);
>>>>     }
>>>>
>>>>     @Override
>>>>     public void renderHead(IHeaderResponse response) {
>>>>         response.renderOnDomReadyJavaScript(
>>>>                 "$('#" + getMarkupId() + "
>>>> .ttr').tipTip({defaultPosition:
>>>> 'right'});");
>>>>     }
>>>>
>>>> }
>>>>
>>>>    -Tom
>>>>
>>>>
>>>> On 04.06.2012, 19:21 Jürgen Lind wrote:
>>>>
>>>>> […]
>>>>>      <wicket:script>
>>>>>         $(document).ready(function() {
>>>>>           $("#markupId .ttr").tipTip({defaultPosition: "right"});
>>>>>         });
>>>>>      </wicket:script>
>>>>> […]
>>>>
>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>>>> For additional commands, e-mail: users-help@wicket.apache.org
>>>>
>>>
>>>
>>> Mit freundlichen Grüßen,
>>>
>>> Jürgen Lind
>>>
>>> --
>>> Dr. Jürgen Lind
>>> iteratec GmbH                Fon: +49 (0)89 614551-44
>>> Inselkammerstrasse 4         Fax: +49 (0)89 614551-10
>>> 82008 Unterhaching           Web: www.iteratec.de
>>>
>>> Sitz und Registergericht der iteratec GmbH: München HRB 113 519
>>> Geschäftsführer: Klaus Eberhardt, Mark Goerke, Inge Hanschke, Ralf Menzel
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>>> For additional commands, e-mail: users-help@wicket.apache.org
>>>
>>
>>
>>
>
>
> Mit freundlichen Grüßen,
>
> Jürgen Lind
>
> --
> Dr. Jürgen Lind
> iteratec GmbH                Fon: +49 (0)89 614551-44
> Inselkammerstrasse 4         Fax: +49 (0)89 614551-10
> 82008 Unterhaching           Web: www.iteratec.de
>
> Sitz und Registergericht der iteratec GmbH: München HRB 113 519
> Geschäftsführer: Klaus Eberhardt, Mark Goerke, Inge Hanschke, Ralf Menzel
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>



-- 
Martin Grigorov
jWeekend
Training, Consulting, Development
http://jWeekend.com

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


Re: Component-specific javascript in Ajax-Calls

Posted by Jürgen Lind <Ju...@iteratec.de>.
Thanks Martin,

maybe I should have asked before trying to invent my own stuff... Anyway, developing
a new wicket tag was some kind of fun as well...

J.

On 04.06.2012 21:10, Martin Grigorov wrote:
> On Mon, Jun 4, 2012 at 10:01 PM, Jürgen Lind<Ju...@iteratec.de>  wrote:
>> Thomas,
>>
>> thanks for this hint, didn't know about that... So the script is executed
>> every time the
>> component is updated in an ajax call, correct? If so, it would surely solve
>
> For every rerender of the component. That includes non-Ajax (whole
> page) requests as well.
>
>> some of my
>> issues. For longer scripts, I would still prefer to have them in the markup
>> file (might be
>> different if we had multiline strings in Java, btw)
>
> For longer scripts you can create JS helpers like:
>
> in some.js:
> var helper = function(selector) {
>    // something longer here
> }
>
> is Some.java:
>
> response.renderOnDomReadyJavaScript("helper($('#" + getMarkupId() +"');");
>
>>
>> J.
>>
>>
>> On 04.06.2012 20:32, Thomas Götz wrote:
>>>
>>> What about this?
>>>
>>>
>>> public class MyComponent extends Panel {
>>>
>>>      public MyComponent(String id) {
>>>          super(id);
>>>          setOutputMarkupId(true);
>>>      }
>>>
>>>      @Override
>>>      public void renderHead(IHeaderResponse response) {
>>>          response.renderOnDomReadyJavaScript(
>>>                  "$('#" + getMarkupId() + " .ttr').tipTip({defaultPosition:
>>> 'right'});");
>>>      }
>>>
>>> }
>>>
>>>     -Tom
>>>
>>>
>>> On 04.06.2012, 19:21 Jürgen Lind wrote:
>>>
>>>> […]
>>>>       <wicket:script>
>>>>          $(document).ready(function() {
>>>>            $("#markupId .ttr").tipTip({defaultPosition: "right"});
>>>>          });
>>>>       </wicket:script>
>>>> […]
>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>>> For additional commands, e-mail: users-help@wicket.apache.org
>>>
>>
>>
>> Mit freundlichen Grüßen,
>>
>> Jürgen Lind
>>
>> --
>> Dr. Jürgen Lind
>> iteratec GmbH                Fon: +49 (0)89 614551-44
>> Inselkammerstrasse 4         Fax: +49 (0)89 614551-10
>> 82008 Unterhaching           Web: www.iteratec.de
>>
>> Sitz und Registergericht der iteratec GmbH: München HRB 113 519
>> Geschäftsführer: Klaus Eberhardt, Mark Goerke, Inge Hanschke, Ralf Menzel
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>> For additional commands, e-mail: users-help@wicket.apache.org
>>
>
>
>


Mit freundlichen Grüßen,

Jürgen Lind

-- 
Dr. Jürgen Lind
iteratec GmbH                Fon: +49 (0)89 614551-44
Inselkammerstrasse 4         Fax: +49 (0)89 614551-10
82008 Unterhaching           Web: www.iteratec.de

Sitz und Registergericht der iteratec GmbH: München HRB 113 519
Geschäftsführer: Klaus Eberhardt, Mark Goerke, Inge Hanschke, Ralf Menzel

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


Re: Component-specific javascript in Ajax-Calls

Posted by Thomas Götz <to...@decoded.de>.
… or you could put your Javascript code into a template, e.g. like that:


MyComponent.js.tmpl:
--------------------
$('#${markupId} .ttr').tipTip({defaultPosition: 'right'});

// ... some looooong Javascript block ….


and in MyComponent.java you'd have:
-----------------------------------
public class MyComponent extends Panel {

    public MyComponent(String id) {
        super(id);
        setOutputMarkupId(true);
    }

    @Override
    public void renderHead(IHeaderResponse response) {
        final TextTemplate template = new PackageTextTemplate(
                MyComponent.class, "MyComponent.js.tmpl");
        final Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("markupId", getMarkupId());
        // variables.put("foo", "bar");  etc.
        response.renderOnDomReadyJavaScript(template.asString(variables));
    }

}


   -Tom


On 04.06.2012, 21:10 Martin Grigorov wrote:

> For longer scripts you can create JS helpers like:
> 
> in some.js:
> var helper = function(selector) {
>  // something longer here
> }
> 
> is Some.java:
> 
> response.renderOnDomReadyJavaScript("helper($('#" + getMarkupId() +"');");


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


Re: Component-specific javascript in Ajax-Calls

Posted by Martin Grigorov <mg...@apache.org>.
On Mon, Jun 4, 2012 at 10:01 PM, Jürgen Lind <Ju...@iteratec.de> wrote:
> Thomas,
>
> thanks for this hint, didn't know about that... So the script is executed
> every time the
> component is updated in an ajax call, correct? If so, it would surely solve

For every rerender of the component. That includes non-Ajax (whole
page) requests as well.

> some of my
> issues. For longer scripts, I would still prefer to have them in the markup
> file (might be
> different if we had multiline strings in Java, btw)

For longer scripts you can create JS helpers like:

in some.js:
var helper = function(selector) {
  // something longer here
}

is Some.java:

response.renderOnDomReadyJavaScript("helper($('#" + getMarkupId() +"');");

>
> J.
>
>
> On 04.06.2012 20:32, Thomas Götz wrote:
>>
>> What about this?
>>
>>
>> public class MyComponent extends Panel {
>>
>>     public MyComponent(String id) {
>>         super(id);
>>         setOutputMarkupId(true);
>>     }
>>
>>     @Override
>>     public void renderHead(IHeaderResponse response) {
>>         response.renderOnDomReadyJavaScript(
>>                 "$('#" + getMarkupId() + " .ttr').tipTip({defaultPosition:
>> 'right'});");
>>     }
>>
>> }
>>
>>    -Tom
>>
>>
>> On 04.06.2012, 19:21 Jürgen Lind wrote:
>>
>>> […]
>>>      <wicket:script>
>>>         $(document).ready(function() {
>>>           $("#markupId .ttr").tipTip({defaultPosition: "right"});
>>>         });
>>>      </wicket:script>
>>> […]
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>> For additional commands, e-mail: users-help@wicket.apache.org
>>
>
>
> Mit freundlichen Grüßen,
>
> Jürgen Lind
>
> --
> Dr. Jürgen Lind
> iteratec GmbH                Fon: +49 (0)89 614551-44
> Inselkammerstrasse 4         Fax: +49 (0)89 614551-10
> 82008 Unterhaching           Web: www.iteratec.de
>
> Sitz und Registergericht der iteratec GmbH: München HRB 113 519
> Geschäftsführer: Klaus Eberhardt, Mark Goerke, Inge Hanschke, Ralf Menzel
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>



-- 
Martin Grigorov
jWeekend
Training, Consulting, Development
http://jWeekend.com

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


Re: Component-specific javascript in Ajax-Calls

Posted by Jürgen Lind <Ju...@iteratec.de>.
Thomas,

thanks for this hint, didn't know about that... So the script is executed every time the
component is updated in an ajax call, correct? If so, it would surely solve some of my
issues. For longer scripts, I would still prefer to have them in the markup file (might be
different if we had multiline strings in Java, btw)

J.

On 04.06.2012 20:32, Thomas Götz wrote:
> What about this?
>
>
> public class MyComponent extends Panel {
>
>      public MyComponent(String id) {
>          super(id);
>          setOutputMarkupId(true);
>      }
>
>      @Override
>      public void renderHead(IHeaderResponse response) {
>          response.renderOnDomReadyJavaScript(
>                  "$('#" + getMarkupId() + " .ttr').tipTip({defaultPosition: 'right'});");
>      }
>
> }
>
>     -Tom
>
>
> On 04.06.2012, 19:21 Jürgen Lind wrote:
>
>> […]
>>       <wicket:script>
>>          $(document).ready(function() {
>>            $("#markupId .ttr").tipTip({defaultPosition: "right"});
>>          });
>>       </wicket:script>
>> […]
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>


Mit freundlichen Grüßen,

Jürgen Lind

-- 
Dr. Jürgen Lind
iteratec GmbH                Fon: +49 (0)89 614551-44
Inselkammerstrasse 4         Fax: +49 (0)89 614551-10
82008 Unterhaching           Web: www.iteratec.de

Sitz und Registergericht der iteratec GmbH: München HRB 113 519
Geschäftsführer: Klaus Eberhardt, Mark Goerke, Inge Hanschke, Ralf Menzel

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


Re: Component-specific javascript in Ajax-Calls

Posted by Thomas Götz <to...@decoded.de>.
What about this?


public class MyComponent extends Panel {

    public MyComponent(String id) {
        super(id);
        setOutputMarkupId(true);
    }

    @Override
    public void renderHead(IHeaderResponse response) {
        response.renderOnDomReadyJavaScript(
                "$('#" + getMarkupId() + " .ttr').tipTip({defaultPosition: 'right'});");
    }

}

   -Tom


On 04.06.2012, 19:21 Jürgen Lind wrote:

> […]
>      <wicket:script>
>         $(document).ready(function() {
>           $("#markupId .ttr").tipTip({defaultPosition: "right"});
>         });
>      </wicket:script>
> […]


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