How to Programmatically Add Js and CSS Resources to <H:Head>

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

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");

Inserting script and link tag inside the header tag

HTML:

<head>
<script src="Scripts/Generate.js"></script>
</head>

Scripts/Generate.js:

if(!document.getElementById('id1')) {
var script = document.createElement('script');
script.id = 'id1';
script.src = 'Scripts/Script1.js';
document.head.appendChild(script);
}
if(!document.getElementById('id2')) {
var link = document.createElement('link');
link.id = 'id2';
link.rel = 'stylesheet';
link.href = 'CSS/Css1.cs';
document.head.appendChild(link);
}

Afterwards, the HTML is:

 <head>
<script src="Scripts/Generate.js"></script>
<script id="id1" src="Scripts/Script1.js"></script>
<link id="id2" rel="stylesheet" href="CSS/Css1.cs">
</head>

Dynamically load a JavaScript file

You may create a script element dynamically, using Prototypes:

new Element("script", {src: "myBigCodeLibrary.js", type: "text/javascript"});

The problem here is that we do not know when the external script file is fully loaded.

We often want our dependant code on the very next line and like to write something like:

if (iNeedSomeMore) {
Script.load("myBigCodeLibrary.js"); // includes code for myFancyMethod();
myFancyMethod(); // cool, no need for callbacks!
}

There is a smart way to inject script dependencies without the need of callbacks. You simply have to pull the script via a synchronous AJAX request and eval the script on global level.

If you use Prototype the Script.load method looks like this:

var Script = {
_loadedScripts: [],
include: function(script) {
// include script only once
if (this._loadedScripts.include(script)) {
return false;
}
// request file synchronous
var code = new Ajax.Request(script, {
asynchronous: false,
method: "GET",
evalJS: false,
evalJSON: false
}).transport.responseText;
// eval code on global level
if (Prototype.Browser.IE) {
window.execScript(code);
} else if (Prototype.Browser.WebKit) {
$$("head").first().insert(Object.extend(
new Element("script", {
type: "text/javascript"
}), {
text: code
}
));
} else {
window.eval(code);
}
// remember included script
this._loadedScripts.push(script);
}
};

JSF resource (JavaScript) not rendered using addComponentResource

So, encodeBegin(FacesContext context) is not the correct location to add resources. You are too late there.

I've moved the code to the constructor of the component and now the script is added. I'm not 100% this is the best location to do so, but I've seen component libraries doing it in the constructor as well. It also works together with PrimeFaces.

See also:

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

JSF ui:include on mojarra gives One or more resources have the target of 'head', but no 'head' component has been defined within the view.

It's talking about the <h:head>. Do the same for the body, which should be <h:body>.

By the way, the generated HTML output must be syntactically valid. You usually don't put <html> in an include file, but only in the parent file or the master template.

See also:

  • How to include another XHTML in XHTML using JSF 2.0 Facelets?
  • When to use <ui:include>, tag files, composite components and/or custom components?
  • What's the difference between <h:head> and <head> in Java Facelets?
  • How to programmatically add JS and CSS resources to <h:head>?

How to load external scripts dynamically in Angular?

If you're using system.js, you can use System.import() at runtime:

export class MyAppComponent {
constructor(){
System.import('path/to/your/module').then(refToLoadedModule => {
refToLoadedModule.someFunction();
}
);
}

If you're using webpack, you can take full advantage of its robust code splitting support with require.ensure :

export class MyAppComponent {
constructor() {
require.ensure(['path/to/your/module'], require => {
let yourModule = require('path/to/your/module');
yourModule.someFunction();
});
}
}

Unable to understand h:head behaviour

In Button.xhtml where you placed

<h:commandLink value="View" action="#{printClass.printPdf}"/> 



You need to disable the ajax.So your new code should be like

<h:commandLink value="View" action="#{printClass.printPdf}">
<f:ajax disabled="true"></f:ajax>
</h:commandLink>




Related Topics



Leave a reply



Submit