Reputation: 23
This is a follow-up of Change CSS on AJAX request in Wicket.
I implemented the possibility to change CSS on an AJAX request by making the <style>
a proper Wicket component. This is used inside my container component (FontContainerComponent
) as follows:
<wicket:head>
<style wicket:id="css"></style>
</wicket:head>
The model of this CSS label (read: the content of my CSS) is added like this:
@Override
protected void onBeforeRender() {
String fontCss = someProvider.getFontCss();
addOrReplace(new Label("css", fontCss));
super.onBeforeRender();
}
This is added to the Ajax update inside another component's onClick
method:
@Override
public void onClick(AjaxRequestTarget target) {
// Irrelevant code left out here...
target.add(getFontContainer());
}
This worked fine in Wicket 7. I've now upgraded my code to Wicket 9 and now an exception is being thrown when my container component is added to an AjaxRequestTarget
. It still works fine when the page is initially rendered. The exception only appears in development mode also appeared in Wicket 8.
The exception comes from Page::checkRendering
, which thinks that the style label (id = css
) is not added to the response:
org.apache.wicket.WicketRuntimeException: The component(s) below failed to render. Possible reasons could be that:
1) you have added a component in code but forgot to reference it in the markup (thus the component will never be rendered),
2) if your components were added in a parent container then make sure the markup for the child container includes them in <wicket:extend>.
1. [Component id = css, page = com.example.component.page.MyPage, path = fontContainerComponent:css, type = org.apache.wicket.markup.html.basic.Label, isVisible = true, isVersioned = true]
So, my questions are:
For 2: Obviously, I could turn off the check (application.getDebugSettings().setComponentUseCheck(false)
) or use the different approach from the original question (render the CSS not as a label, but using renderHead
and then use JavaScript code to remove previously added CSS in each AJAX update), but I'm searching for a solution using my current approach (if possible).
Upvotes: 0
Views: 62
Reputation: 17533
I think the problem is in the usage of <wicket:head>
. It does its magic (logic) to move the inner HTML to the <head>
of the page and somehow breaks the Wicket Component tree.
IMO it would be better to re-work your code to use header contribution:
@Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
response.render(CssHeaderItem.forCSS("...", "my-generated-styles"));
}
my-generated-styles
will be used as an element id for the <style>
element, so Ajax repaints will replace its body.
Upvotes: 0