ajaxwicketwicket-7

Change CSS on AJAX request in Wicket


I have a component A that should dynamically change the font size of some of it's contents. I currently use CSS variables to do that and the component will contribute some CSS String containing these CSS variables:

public void renderHead(IHeaderResponse response) {
  String fontCss = // dynamically fetch CSS cariables
  response.render(CssHeaderItem.forCSS(fontCss, "font-css"));
}

On the same page I have the possibility to change these font sizes using an AJAX update within another component B. This will add the component A to the AjaxRequestTarget, which will cause the renderHead method to be executed with updated values for the font CSS variables.

However, I don't see an updated font size in my browser as the old CSS variables still seem to be present. How can I enforce the new CSS to overwrite the old one?

So far I found 2 solutions, that seem like dirty workarounds to me:

  1. Add the whole page to the AjaxRequestTarget, so the whole page will be refreshed.
  2. Add JavaScript to the AJAX update to remove the old styling with:
var allStyles = document.getElementsByTagName("style");
for (var style of allStyles) {
  if (style.getAttribute("id").includes("font-css")) {
    style.remove();
  }
}

Is there a cleaner solution to this problem?


Solution

  • You found the problem with workaround 2.

    response.render(CssHeaderItem.forCSS(fontCss, "font-css"));
    

    adds <style id="font-css"> ... </style> to the page. Later when the Ajax response contributes the new content the JavaScript logic finds that there is an HTML element with id font-css and assumes that there is nothing to do.

    A simple solution is to use dynamic id, e.g. by using UUID in #renderHead(). Another solution is to make this <style> a proper Wicket Component, a Label, that could be added to the AjaxRequestTarget with an updated Model when needed.