You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Joel Hill <hi...@michigan.gov> on 2009/07/13 21:28:38 UTC

Javascript Header Contribution via Ajax

I have a custom behavior that contributes Javascript to the header.  In order to prevent collisions with other components that may also be using that behavior, I include it using TextTemplateHeaderContributor.  Like so:

public class CustomBehavior extends AbstractBehavior {

  private Component component;

  . . .

  @Override
  public void bind(Component component) {
    this.component = component
    component.setOutputMarkupId(true);

    . . .

    component.add(TextTemplateHeaderContributor.forJavaScript(getClass(), "javascriptSource.js", variables));
  }

}


This works great, unless I add this behavior to a component that gets added to the page as part of an Ajax request.  In that case, the Javascript does not get added to the page, so when the component looks up the Javascript it needs to function, it's not there.

I'm not sure if this is related to https://issues.apache.org/jira/browse/WICKET-618 or not, but that bug was resolved 'Won't Fix'.

I tried tracing through the Ajax code, and if I understand it properly, the issue seems to come down to line 1445 of wicket-ajax.js:

1441    var text = Wicket.DOM.serializeNodeChildren(node);
1442
1443    var id = node.getAttribute("id");
1444
1445    if (typeof(id) == "string" && id.length > 0) {					
1446      // add javascript to document head
1447      Wicket.Head.addJavascript(text, id);
1448    } else {
1449      try {
1450        eval(text);
1451      } catch (e) {
1452        Wicket.Log.error(e);
1453      }
1454    }


It would appear that because the script tag generated by TextTemplateHeaderContributor does not contain an 'id' attribute, the javascript is not rendered on the page.  (However it is still evaluated, via line 1450, which explains why when I added an alert() call to my javascript file, it got executed.  Imagine my initial confusion.)

Is this expected behavior?  A bug?  Is there a workaround?  Am I even interpreting the issue correctly?  If I were using a static Javascript file, I think there are calls I can use to include an 'id' attribute, and I may have to rewrite my javascript so I can make it static (if possible).

Picking up on suggestions I read on the mailing list archives, I also tried:

  public void renderHead(IHeaderResponse response) {
    response.renderOnDomReadyJavascript(TextTemplateHeaderContributor.forJavaScript(getClass(), "popupBehavior.js", variables).toString());
  }

and:

  public void onRendered(Component component) {
    if(RequestCycle.get().getRequestTarget() instanceof AjaxRequestTarget) {
      AjaxRequestTarget target = (AjaxRequestTarget) RequestCycle.get().getRequestTarget();
      target.appendJavascript(TextTemplateHeaderContributor.forJavaScript(getClass(), "popupBehavior.js", variables).toString());
    }
  }

Neither alternative worked.  At this point I'm not even sure they make sense, but I tried them before I had dug in and (hopefully) traced down the problem.

Thank you for any help that anyone can provide on this issue.

Joel


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


Re: Javascript Header Contribution via Ajax

Posted by hillj2 <Hi...@michigan.gov>.
Then perhaps I'm not understanding the code in wicket-ajax.js properly.  If
you refer to code I copied into my first post, it appears that if the script
tag has an id attribute, then wicket-ajax.js calls
Wicket.Head.addJavascript() -- which I assume is what renders it on the page
-- but if it doesn't have an ID it calls eval() -- which wouldn't render it
to the page, but WOULD cause an alert() call in the javascript to be
executed.

If I could give it an ID, I would, but it's not a component and the script
tag is added by TextTemplateHeaderContributor (specifically through
JavaScriptTemplate).  I suppose I could wrap my own solution that would
allow for the inclusion of an ID.  I do understand that the ID is being used
to prevent duplicate javascript.

My Javascript isn't vary complex, basically it's in the form:

var ${var1} = default_value;
var ${var2} = default_value;
. . .

function ${function1}() {
  . . .
}

function ${function2}() {
  . . .
}

. . .

I know the javascript file isn't the problem, because it works fine for
components that are part of the initial page render.  Just not for
components added via ajax.

I think I'm either going to rewrite my javascript so that I no longer need
to do variable replacement, therefore all instances of my custom behavior
can use the same static file without interfering with each other, or extend
TextTemplateHeaderContributor so I can include an ID on the script tag that
gets wrapped around my javascript.

Joel



Matej Knopp-2 wrote:
> 
> If the javascript is evaluated that means it's added to page. What
> exactly is the difference here? And why can't you give it id? (id is
> used to filter out duplicate javascripts).
> 
> What does the javascript look like?
> 
> -Matej
> 
> On Mon, Jul 13, 2009 at 9:28 PM, Joel Hill<hi...@michigan.gov> wrote:
>> I have a custom behavior that contributes Javascript to the header.  In
>> order to prevent collisions with other components that may also be using
>> that behavior, I include it using TextTemplateHeaderContributor.  Like
>> so:
>>
>> public class CustomBehavior extends AbstractBehavior {
>>
>>  private Component component;
>>
>>  . . .
>>
>>  @Override
>>  public void bind(Component component) {
>>    this.component = component
>>    component.setOutputMarkupId(true);
>>
>>    . . .
>>
>>    component.add(TextTemplateHeaderContributor.forJavaScript(getClass(),
>> "javascriptSource.js", variables));
>>  }
>>
>> }
>>
>>
>> This works great, unless I add this behavior to a component that gets
>> added to the page as part of an Ajax request.  In that case, the
>> Javascript does not get added to the page, so when the component looks up
>> the Javascript it needs to function, it's not there.
>>
>> I'm not sure if this is related to
>> https://issues.apache.org/jira/browse/WICKET-618 or not, but that bug was
>> resolved 'Won't Fix'.
>>
>> I tried tracing through the Ajax code, and if I understand it properly,
>> the issue seems to come down to line 1445 of wicket-ajax.js:
>>
>> 1441    var text = Wicket.DOM.serializeNodeChildren(node);
>> 1442
>> 1443    var id = node.getAttribute("id");
>> 1444
>> 1445    if (typeof(id) == "string" && id.length > 0) {
>> 1446      // add javascript to document head
>> 1447      Wicket.Head.addJavascript(text, id);
>> 1448    } else {
>> 1449      try {
>> 1450        eval(text);
>> 1451      } catch (e) {
>> 1452        Wicket.Log.error(e);
>> 1453      }
>> 1454    }
>>
>>
>> It would appear that because the script tag generated by
>> TextTemplateHeaderContributor does not contain an 'id' attribute, the
>> javascript is not rendered on the page.  (However it is still evaluated,
>> via line 1450, which explains why when I added an alert() call to my
>> javascript file, it got executed.  Imagine my initial confusion.)
>>
>> Is this expected behavior?  A bug?  Is there a workaround?  Am I even
>> interpreting the issue correctly?  If I were using a static Javascript
>> file, I think there are calls I can use to include an 'id' attribute, and
>> I may have to rewrite my javascript so I can make it static (if
>> possible).
>>
>> Picking up on suggestions I read on the mailing list archives, I also
>> tried:
>>
>>  public void renderHead(IHeaderResponse response) {
>>  
>>  response.renderOnDomReadyJavascript(TextTemplateHeaderContributor.forJavaScript(getClass(),
>> "popupBehavior.js", variables).toString());
>>  }
>>
>> and:
>>
>>  public void onRendered(Component component) {
>>    if(RequestCycle.get().getRequestTarget() instanceof AjaxRequestTarget)
>> {
>>      AjaxRequestTarget target = (AjaxRequestTarget)
>> RequestCycle.get().getRequestTarget();
>>    
>>  target.appendJavascript(TextTemplateHeaderContributor.forJavaScript(getClass(),
>> "popupBehavior.js", variables).toString());
>>    }
>>  }
>>
>> Neither alternative worked.  At this point I'm not even sure they make
>> sense, but I tried them before I had dug in and (hopefully) traced down
>> the problem.
>>
>> Thank you for any help that anyone can provide on this issue.
>>
>> Joel
>>
>>
>> ---------------------------------------------------------------------
>> 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
> 
> 
> 

-- 
View this message in context: http://www.nabble.com/Javascript-Header-Contribution-via-Ajax-tp24467837p24485598.html
Sent from the Wicket - User mailing list archive at Nabble.com.


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


Re: Javascript Header Contribution via Ajax

Posted by Matej Knopp <ma...@gmail.com>.
If the javascript is evaluated that means it's added to page. What
exactly is the difference here? And why can't you give it id? (id is
used to filter out duplicate javascripts).

What does the javascript look like?

-Matej

On Mon, Jul 13, 2009 at 9:28 PM, Joel Hill<hi...@michigan.gov> wrote:
> I have a custom behavior that contributes Javascript to the header.  In order to prevent collisions with other components that may also be using that behavior, I include it using TextTemplateHeaderContributor.  Like so:
>
> public class CustomBehavior extends AbstractBehavior {
>
>  private Component component;
>
>  . . .
>
>  @Override
>  public void bind(Component component) {
>    this.component = component
>    component.setOutputMarkupId(true);
>
>    . . .
>
>    component.add(TextTemplateHeaderContributor.forJavaScript(getClass(), "javascriptSource.js", variables));
>  }
>
> }
>
>
> This works great, unless I add this behavior to a component that gets added to the page as part of an Ajax request.  In that case, the Javascript does not get added to the page, so when the component looks up the Javascript it needs to function, it's not there.
>
> I'm not sure if this is related to https://issues.apache.org/jira/browse/WICKET-618 or not, but that bug was resolved 'Won't Fix'.
>
> I tried tracing through the Ajax code, and if I understand it properly, the issue seems to come down to line 1445 of wicket-ajax.js:
>
> 1441    var text = Wicket.DOM.serializeNodeChildren(node);
> 1442
> 1443    var id = node.getAttribute("id");
> 1444
> 1445    if (typeof(id) == "string" && id.length > 0) {
> 1446      // add javascript to document head
> 1447      Wicket.Head.addJavascript(text, id);
> 1448    } else {
> 1449      try {
> 1450        eval(text);
> 1451      } catch (e) {
> 1452        Wicket.Log.error(e);
> 1453      }
> 1454    }
>
>
> It would appear that because the script tag generated by TextTemplateHeaderContributor does not contain an 'id' attribute, the javascript is not rendered on the page.  (However it is still evaluated, via line 1450, which explains why when I added an alert() call to my javascript file, it got executed.  Imagine my initial confusion.)
>
> Is this expected behavior?  A bug?  Is there a workaround?  Am I even interpreting the issue correctly?  If I were using a static Javascript file, I think there are calls I can use to include an 'id' attribute, and I may have to rewrite my javascript so I can make it static (if possible).
>
> Picking up on suggestions I read on the mailing list archives, I also tried:
>
>  public void renderHead(IHeaderResponse response) {
>    response.renderOnDomReadyJavascript(TextTemplateHeaderContributor.forJavaScript(getClass(), "popupBehavior.js", variables).toString());
>  }
>
> and:
>
>  public void onRendered(Component component) {
>    if(RequestCycle.get().getRequestTarget() instanceof AjaxRequestTarget) {
>      AjaxRequestTarget target = (AjaxRequestTarget) RequestCycle.get().getRequestTarget();
>      target.appendJavascript(TextTemplateHeaderContributor.forJavaScript(getClass(), "popupBehavior.js", variables).toString());
>    }
>  }
>
> Neither alternative worked.  At this point I'm not even sure they make sense, but I tried them before I had dug in and (hopefully) traced down the problem.
>
> Thank you for any help that anyone can provide on this issue.
>
> Joel
>
>
> ---------------------------------------------------------------------
> 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