0

We are writing an AJAX-heavy Wicket application and have panels that are contributing CSS via renderHead(). However, when panels are being replaced via AJAX - say, via an AjaxTabbedPanel, the header contributions of the old panels remain and pollute the rest of the application. Apart from response bloat, this causes issues when CSS declarations are overly generic and thus result in rendering issues in other areas of the application.

Is there a way around this? Say, a mechanism to re-create the IHeaderReponse when a panel has been replaced / is no longer visible?

For what it's worth, an example of our header contributor is:

@Override
public void renderHead(IHeaderResponse response) {
    response.renderCSSReference(new SharedResourceReference(SearchMainPanel.class, "Search.css"));
}

We're using Wicket 1.5.3.

I have had success with a custom label which renders a <link rel="stylesheet" ... /> in the Panel's <body> markup (i.e., not using header contributors), however IE8 refuses to acknowledge the presence of this CSS - hence having to rethink our strategy.

nullPainter
  • 2,676
  • 3
  • 22
  • 42
  • Not sure if this will work, maybe you could move those contributions to a `Behavior` and override [`isTemporary`](http://wicket.apache.org/apidocs/1.5/org/apache/wicket/behavior/Behavior.html#isTemporary%28org.apache.wicket.Component%29) to return true on it. – Xavi López Jun 15 '12 at 05:59

1 Answers1

2

Each AjaxRequestTarget will receive a new IHeaderResponse that is specifically for that request. The problem you are seeing is due to the fact that a previous request responded with a stylesheet that you no longer want present for that page. The only way to get the browser to disregard a stylesheet that you've already rendered on the page is to re-render the page without that file.

In this case, you can depend on cascading of styles for the first time that you render each tab, because Wicket will load the associated stylsheet when you render that Panel. However, when you return to a tab (Panel) that has previously been rendered, Wicket will not re-render the stylesheet as it has already been loaded. this means that you need to have a way to overcome the limitations of cascading styles.

The best way to do this is to namespace your styles... meaning you should wrap each panel in a tag with a namespace class (like "tab1" or something more contextually accurate), then you will base all your styles off that class:

.tab1 .heading {
    font-weight: bold;
}

.tab1 .description {
    background: blue;
}

.tab2 .heading {
    font-size: 1.3em;
}

.tab2 .description {
    background: lightblue;
}

This will ensure that you are able to distinguish between each tabs individual styles and that any cascading you may need will still work for namespaced selectors

Daniel Semmens
  • 461
  • 2
  • 4
  • 1
    Thanks; namespacing is certainly one approach. I understand though that one can remove externally-referenced CSS files via Javascript (although I haven't tested this), so was hoping that there'd be a handy 'cleanup' style functionality built into Wicket's AJAX that works in a similar fashion. In fact, this would seem to be sensible default behaviour across the board. – nullPainter Jun 16 '12 at 03:32
  • That could be helpful under some circumstances, however in this case it enables a performance issue (loading the same files multiple times). Additionally, you'd get a flash of unstyled content (FOUK) when you make your changes because no matter what order you load your new styles, replace your DOM, and remove the old styles, there is overlap of bad rendered content. – Daniel Semmens Jun 16 '12 at 11:45
  • Also, I know of no way to remove JS/CSS files from DOM in Wicket – Daniel Semmens Jun 16 '12 at 11:46
  • Very good points; thank you. I will adopt the namespacing approach, as it's elegant, straightforward and doesn't 'work around' the framework. – nullPainter Jun 16 '12 at 21:55