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?
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");
You can add a script and style resources to a page like this:
var head = document.getElementsByTagName("head")[0];
var s = document.createElement("script");
s.type = "text/javascript";
s.src = "xxxx.js";
head.appendChild(s);
s = document.createElement("style");
s.type = "text/css"
s.src = "yyy.css";
head.appendChild(s);
Or, in function form:
function addScript(path) {
var head = document.getElementsByTagName("head")[0];
var s = document.createElement("script");
s.type = "text/javascript";
s.src = path;
head.appendChild(s);
}
function addCSSFile(path) {
var head = document.getElementsByTagName("head")[0];
var s = document.createElement("style");
s.type = "text/css";
s.src = path;
head.appendChild(s);
}
Related
I am trying to optimise my loading of CSSS files as I am loading some large CSS files on pages where they aren't used. Is there any way for me to enqueue them only if an element is present with a class on that page.
I've tried the following however, it does not work:
jQuery(document).ready(function($) {
//Script Checkers
var wowJS = $('.wow');
if (wowJS.length > 0) {
$.getScript('/wp-content/themes/gowebsites/gw-addon/js/wow.js', function() {
new WOW().init();
});
var head = document.getElementsByTagName('head')[0];
var cssNode = document.createTextNode("link");
cssNode.href = "/wp-content/themes/gowebsites/gw-addon/css/animations.css";
cssNode.rel = "stylesheet";
//console.log("CSS Node: "+cssNode); = [object Text]
head.appendChild(cssNode);
}
});
I have seen functions that work for adding css files to the head however, none of them allow the ability to make it conditional.
EDIT: I've since just used the getScripts() jQuery function however, I am still in need of knowing how to add css to the header only if required.
EDIT: For future reference for anyone, this is the final working code:
jQuery(document).ready(function($) {
//Script Checkers
var wowJS = $('.wow');
if (wowJS.length > 0) {
$.getScript('/wp-content/themes/gowebsites/gw-addon/js/wow.js', function() {
new WOW().init();
});
var head = document.getElementsByTagName('head')[0];
var cssNode = document.createElement("link");
cssNode.href = "/wp-content/themes/gowebsites/gw-addon/css/animations.css";
cssNode.rel = "stylesheet";
head.appendChild(cssNode);
}
});
Create the nodes first then append then using the appendChild() method, like :
var scriptNode = document.createElement("script");
scriptNode.src = "/wp-content/themes/gowebsites/gw-addon/js/wow.js";
var cssNode = document.createElement("link");
cssNode.href = "/wp-content/themes/gowebsites/gw-addon/css/animations.css";
cssNode.rel = "stylesheet";
head.appendChild(scriptNode);
head.appendChild(cssNode);
You should use insertAdjacentHTML
head.insertAdjacentHTML("afterend",'<script language="javascript" src="/wp-content/themes/gowebsites/gw-addon/js/wow.js"></script>');
head.insertAdjacentHTML("afterend",'<link href="/wp-content/themes/gowebsites/gw-addon/css/animations.css" rel="stylesheet">');
What i am trying is -
http://jsfiddle.net/jhrz9/1/
to remove the script generated when someone clicks the button #goBack button
Now i am able to create and append script and style tags when the user clicks the #runMyCode
But as soon as i go back to the previous screen using #goBack button the script stays on the screen, now what i want to do is to remove that script and create another one again when i click the #runMyCode button
Now i am trying this -
var newScript = document.createElement('script'); ;
var newTextNode=document.createTextNode($("#jsTextArea").val());
newScript.type = 'text/javascript';
newScript.appendChild(newTextNode);
document.body.appendChild(newScript);
$('#goBack').click(function(){
newTextNode.parentNode.removeChild(newTextNode);
});
But for some reason it is not working....
you have to give the script an id.
$("#runMyCode").click(function(){
$("#resultContainer").html($("#htmlTextArea").val());
var newScript = document.createElement('script');
newScript.id = "goback_script";
var newTextNode=document.createTextNode($("#jsTextArea").val());
newScript.type = 'text/javascript';
newScript.appendChild(newTextNode);
document.body.appendChild(newScript);
var newStyle = document.createElement('style');
var newTextNode2=document.createTextNode($("#cssTextArea").val());
newStyle.type = 'text/css';
newStyle.appendChild(newTextNode2);
document.body.appendChild(newStyle);
});
$('#goBack').click(function(){
var script = document.getElementById("goback_script");
script.parentElement.removeChild(script);
});
jsFiddle
I want to add one js file at the bottom of the page before </body> tag.
I am trying one format. But its not working properly.
My code
var url = 'sample.js';
var script = document.createElement("script");
script.type = "text/javascript";
script.src = url;
document.getElementsByTagName('body')[0].appendChild(script);
But its not working.
Now i check
var x = document.getElementsByTagName('body');
alert(x.length);
its shows 0
How can i add this js file into my bottom of the page. Please advise
See this code
var body = document.body;
alert("Body when page loading: " + body);
document.addEventListener("DOMContentLoaded", function() {
var bodyLoaded = document.body;
alert("Body when page loaded: " + bodyLoaded);
var url = "http://code.jquery.com/jquery-1.10.2.min.js";
var script = document.createElement('script');
script.type = "text/javascript";
script.src = url;
script.onload = function(){
var testP = $("<p></p>");
testP.html("JQuery worked");
$(document.body).append(testP);
}
bodyLoaded.appendChild(script);
});
If first alert you get null. But in second (when body loaded) you get HTMLBodyElement. This is your mistake if you try to append element to body in head before body loaded.
You are writing your this code in the head section and at the time this executes body element is not yet created. This is the only reason for error. Keep this code after body element is created.
Just like in the title.
I got two files: one is javascript file and one is css file. And if user-agent is an iPad I want to load those files - but only when user-agent is iPad. So below two lines are only loaded when user-agent is an iPad. how can i achieve that
<link rel="stylesheet" href="/c/dropkick.css" type="text/css"/>
<script src="/s/jquery.dropkick-1.0.0.js" type="text/javascript"></script>
if (navigator.userAgent.match(/iPad/i) != null){ // may need changing?
var js = document.createElement('script');
js.type = "text/javascript";
js.src = "/s/jquery.dropkick-1.0.0.js";
var css = document.createElement('link');
css.type = "text/css";
css.rel = "stylesheet";
css.href = "/c/dropkick.css";
var h = document.getElementsByTagName('head')[0];
h.appendChild(js);
h.appendChild(css);
}
Or whatever would be in the User-Agent header for an iPad.
References:
window.navigator.userAgent
document.createElement
node.appendChild
You can use document.createElement to create link and script elements, and then append them to the document (for instance, append them to document.getElementsByTagName('head')[0] or similar).
This answer here on SO suggests that you can dtect an iPad by just looking for the string "ipad" in the navigator.userAgent field. Of course, the user agent field can be spoofed.
So for example:
<script>
(function() {
var elm, head;
if (navigator.userAgent.indexOf("ipad") !== -1) {
head = document.getElementsByTagName('head')[0] || document.body || document.documentElement;
elm = document.createElement('link');
elm.rel = "stylesheet";
elm.href = "/c/dropkick.css";
head.appendChild(elm);
elm = document.createElement('script');
elm.src = "/s/jquery.dropkick-1.0.0.js";
head.appendChild(elm);
}
})();
</script>
...but that's off-the-cuff, untested.
(Note that there's no reason to put the type on either link or script; in the case of link, the type comes from the content-type of the response. In the case of script, the default is JavaScript.)
Ok, I've got this function:
/* jsHandler.js */
function inc(filename)
{
var body = document.getElementsByTagName('body').item(0);
script = document.createElement('script');
script.src = filename;
script.type = 'text/javascript';
body.appendChild(script)
}
What i would like is extending the script to tell js where to insert the js.file, like, say i have this in html:
<div id="mydiv"></div>
<iframe id="myiframe"></iframe>
i call
inc(this.js, mydiv)
to include the js.file in the div "mydiv",
resulting in:
<div id="mydiv"><script src="this.js" type="text/javascript"></script></div>
How do i do that?
Try this...
/* jsHandler.js */
function inc(filename,target)
{
var targetelement= document.getElementById(target); // get the target element
script = document.createElement('script');
script.src = filename;
script.type = 'text/javascript';
targetelement.appendChild(script); // add the script to the target
}
You always pick your body element
var body = document.getElementsByTagName('body').item(0);
and simply append the script tag to it:
body.appendChild(script)
What you want to do
Pick your target element and append it there.
var target = document.getElementsById(mydiv);
// ... other code lines
target.appendChild(script)