Search code examples
javascriptcssjsfhead

How to programmatically add JS and CSS resources to <h:head>


I need to add programmatically JavaScript and CSS resources to <h:head> of a JSF page. It isn't clear how to achieve this. How can I do it or is there a kickoff example?


Solution

  • That depends on where exactly you'd like to declare the resource. Normally, the only reason to programmatically declare them is that you've a custom UIComponent or Renderer which generates HTML code which in turn requires those JS and/or CSS resources. They are then to be declared by @ResourceDependency or @ResourceDependencies.

    @ResourceDependency(library="mylibrary", name="foo.css")
    public class FooComponentWithCSS extends UIComponentBase {
        // ...
    }
    
    @ResourceDependencies({
        @ResourceDependency(library="mylibrary", name="bar.css"),
        @ResourceDependency(library="mylibrary", name="bar.js")
    })
    public class BarComponentWithCSSandJS extends UIComponentBase {
        // ...
    }
    

    But if you really need to declare them elsewhere, such as in a backing bean method which is invoked before render response (otherwise it's simply too late), then you can do that by UIViewRoot#addComponentResource(). The component resource must be created as an UIOutput having a renderer type of javax.faces.resource.Script or javax.faces.resource.Stylesheet, to represent a fullworthy <h:outputScript> or <h:outputStylesheet> respectively. The library and name attributes can just be put in the attribute map.

    UIOutput css = new UIOutput();
    css.setRendererType("javax.faces.resource.Stylesheet");
    css.getAttributes().put("library", "mylibrary");
    css.getAttributes().put("name", "bar.css");
    
    UIOutput js = new UIOutput();
    js.setRendererType("javax.faces.resource.Script");
    js.getAttributes().put("library", "mylibrary");
    js.getAttributes().put("name", "bar.js");
    
    FacesContext context = FacesContext.getCurrentInstance();
    context.getViewRoot().addComponentResource(context, css, "head");
    context.getViewRoot().addComponentResource(context, js, "head");