Include JS files based on current page - jsf

I have the following on my main jsf wrapper page:
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8"/>
<title>
<ui:insert name="pageTitle" />
</title>
<a4j:loadScript src="resource://jquery.js" />
<a4j:loadScript src="resource:///bla/html/js/base.js" />
<a4j:loadScript src="resource:///bla/html/js/common.js" />
<a4j:loadScript src="resource:///bla/html/js/inactivity.js" />
</head>
Now I have a new page on the site and it requires some js functions. So i have created a new js file, myNewJSFile.js
I only want it loaded if a user lands on this page so obviosuly I dont want to add it to my above list of files in the head. Additionally I'd rather not include it at the top of my new page.
What I want is one place where I can define what files to load based on the current page.
So somthing like this (Pseudo code):
main jsf wrapper:
<head>
<jsIncludes>
</head>
jsIncludes file:
<a4j:loadScript src="resource://jquery.js" />
<a4j:loadScript src="resource:///bla/html/js/base.js" />
<a4j:loadScript src="resource:///bla/html/js/common.js" />
<a4j:loadScript src="resource:///bla/html/js/inactivity.js" />
<if page == "myNewPage>
<a4j:loadScript src="resource:///bla/html/js/myNewJsFile.js" />
<elfeif ...>
...
</if>
Is there a simple way of doing this?
Thanks

a4j:loadScript always places the javascript in the <head>, no matter where you use it, you have to do nothing. (the doc doesn't mention this for some strange reason)
So to answer your question: if you use <a4j:loadScript src="resource:///bla/html/js/myNewJsFile.js" /> in the page where you need it, the <script style="text/javascript" src="..." /> will appear in the <head>.

I'd rather add another <ui:insert> to the <head> of the main template.
<head>
...
<ui:insert name="headContent" />
</head>
Then in the page template, just define the additional script to be inserted there.
<ui:composition template="main.xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://??? can't tell from top of head :)"
>
<ui:define name="headContent">
<a4j:loadScript src="resource:///bla/html/js/myNewJsFile.js" />
</ui:define>
...
</ui:composition>

Related

Using #local_variable in CSHTML code in asp-page

I develop ASP.Net Core 2.1 RazorPages web application. I want parametrize the the value of asp-page tag helper.
So I use following code in cshtml file. There is a del_link local variable defined in begining of file. This variable is late used as parameter for second asp-page tag helper.
#page
#{
string del_link = "/UnloadDelete";
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div>
<a asp-page="/UnloadEdit">Details</a>
<a asp-page=#del_link>Delete</a>
</div>
</body>
</html>
ASP.Net Razor generate following HTML code.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div>
Details
Delete
</div>
</body>
</html>
As you can see in HTML code, asp-page="/UnloadEdit" is properly rendered to HTML code, but asp-page=#del not, it is rendered to <a href="">. How I can use local variable for asp-page tag helper in Razor Pages?
Thanks in advance.
You must pass a page name to the asp-page attribute. So what you are trying to do is not supported. If #del_link renders a relative URL, you can pass that to the href attribute instead. There may be other suitable solutions, depending on why you feel the need to use #del_link at all.

Getting Javascript with .xhtml extension in browser

I have loaded javascript from Java call in xhtml file. When I opened the browser in debug mode( both IE and chrome) , javascripts are loading with .xhtml extensions.
Below is the code I am using
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title><ice:outputText nospan="true" value="#{msgs.loginTitle}" /></title>
<link href="../css/style.css" type="text/css" rel="stylesheet" />
<ice:outputText value="#{MyAction.javaScripts}" visible="false" />
</h:head>
Here JavaScripts is the methods and it returns String.
value="#{MyAction.javaScripts}" Return the below string
<script src="../js/myJs.js" type="text/javascript"></script>
But when I open the browser in debug mode my javascript is like abc.js.xhtml?xxx and some of the functions are not working. My questions are
1) Will java script work perfectly even if it is showing like this?
2) Is the Browser changing the extension or it is configuration issue?
Please help me
Javascript files should be included in your JSF .xhtml file by using either <h:outputScript> or <script>:
(referencing a script file named 'help.js' in the /js folder)
<h:outputScript library="js" name="help.js" />
or
(embedded script directly within the page)
<script type="text/javascript">
function sayHello(){
alert('Hello');
}
</script>

SVG images in AMP article Microdata?

When attempting to validate a schema.org/Article against Google's Structured Data Testing Tool, I noticed that it gives an error if you specify an SVG image:
The value provided for logo must be a valid URL.
Required by:
AMP Articles (what's this?)
When the URL is changed to have a .png (or .jpg, .bmp, .webp, etc.) extension, rather than .svg, it passes validation.
Here is the example I'm working with:
<div itemscope itemtype="http://schema.org/Article">
<div itemprop="publisher" itemscope itemtype="https://schema.org/Organization">
<meta itemprop="name" content="Example" />
<meta itemprop="url" content="http://example.com" />
<div itemprop="logo" itemscope itemtype="https://schema.org/ImageObject">
<meta itemprop="url" content="http://example.com/logo.svg" />
<meta itemprop="width" content="600" />
<meta itemprop="height" content="60" />
</div>
</div>
<meta itemprop="dateModified" content="2016-01-05T12:43" />
<meta itemprop="datePublished" content="2016-01-05T12:43" />
<meta itemprop="headline" content="Example" />
<meta itemprop="name" content="Example" />
<meta itemprop="author" content="Example" />
<link itemprop="mainEntityOfPage" href="http://example.com/article" />
<div itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
<meta itemprop="url" content="http://example.com/article.jpg" />
<meta itemprop="width" content="1200" />
<meta itemprop="height" content="800" />
</div>
</div>
Changing the other image's URL's extension will also produce the error.
I was unable to find any information on why it rejects SVGs in the Rich Snippets documentation or the AMP HTML spec. Does anyone have an explanation for this behavior?
Google has updated the documentation and specifically mentioned svg.
Logo image files should be raster (for example, .jpg, .png, .gif), not vector (for example, .svg), with no animation.
From one of the links you gave: https://developers.google.com/structured-data/rich-snippets/articles
Images should be in .jpg, .png, or. gif format.
Why? Who knows. Perhaps because SVGs still have some support issues in some browsers (particularly older ones).
Update: 2022 - after reading the google documentation, it seems they do now accept svgs. https://developers.google.com/search/docs/appearance/structured-data/logo#structured-data-type-definitions

OmniFaces conditionalComment not written to HTML output

I'm using OmniFaces conditionalComment to load a javascript file for IE 6 browsers. On the webiste it says the script should be included in the page as:
<script type="text/javascript" src="[JS library]"></script>
<!--[if (gte IE 6)&(lte IE 8)]>
<script type="text/javascript" src="selectivizr.js"></script>
<noscript><link rel="stylesheet" href="[fallback css]" /></noscript>
<![endif]-->
This is not valid xml, so can't be used in the JSF xhtml files. Instead I use this:
<h:body>
<f:facet name="last">
<o:conditionalComment if="if (gte IE 6)&(lte IE 8)">
<h:outputScript library="js" name="selectivizr-min.js" target="head"/>
</o:conditionalComment>
</f:facet>
...
</h:body>
I include the script in the body part of the xhtml and put it in the facet name="last", so it is included after JQuery (I use PirmeFaces and read that's the safest way to do that). target="head" ensures that it is written to the head section of the resulting html file. The link to the script is included in the correct part of the document (after the PrimeFaces imports), but it is not surrounded by the conditional comments.
Here is the relevant part of the html (reformatted for easier reading):
<head>
<link type="text/css" rel="stylesheet" href="/javax.faces.resource/theme.css.xhtml?ln=primefaces-aristo" />
<link type="text/css" rel="stylesheet" href="/javax.faces.resource/primefaces.css.xhtml?ln=primefaces&v=5.1" />
<script type="text/javascript" src="/javax.faces.resource/jquery/jquery.js.xhtml?ln=primefaces&v=5.1"></script>
<script type="text/javascript" src="/javax.faces.resource/primefaces.js.xhtml?ln=primefaces&v=5.1"></script>
<script type="text/javascript" src="/javax.faces.resource/jquery/jquery-plugins.js.xhtml?ln=primefaces&v=5.1"></script>
<script type="text/javascript" src="/javax.faces.resource/omnifaces.js.xhtml?ln=omnifaces"></script>
<link type="text/css" rel="stylesheet" href="/javax.faces.resource/styles.css.xhtml?ln=css" />
<script type="text/javascript" src="/javax.faces.resource/selectivizr-min.js.xhtml?ln=js"></script>
The last line is missing the comments (!--[if (gte IE 6)&(lte IE 8)]> ...).
What am I doing wrong? Any suggestions?
Cheers,
Dominik
This problem is two-fold:
The <f:facet name="last"> makes no sense in this context. Get rid of it. It would be ignored including any of its children. It's only valid inside <h:head> (and even then only if you're using PrimeFaces; who actually overlooked the native JSF possibility to order head resources as last).
You can't use <h:outputScript> (nor <h:outputStylesheet> inside <o:conditionalComment>, because JSF will implicitly auto-relocate it to the <head>. This is also hinted in the documentation and showcase.
Just use plain vanilla <script> (or <link rel="stylesheet">).
<o:conditionalComment if="(gte IE 6)&(lte IE 8)">
<script src="#{resource['js/selectivizr-min.js']}" />
</o:conditionalComment>
Note that I fixed the invalid if attribute value by removing the duplicated if.
Unrelated to the concrete problem: The library="js" indicates a misunderstanding of the library attribute. Carefully read What is the JSF resource library for and how should it be used? The #{resource} resolver in above answer has already been altered to use js as regular folder instead of as library.

On submit of a4j:commandlink i get random html of that action rather than html in JSF

I am working with SEAM - JSF framework
I have following a4j commandlink on my xhtml page.
<a4j:commandLink id="rateImage" action="#{ratingSessionAction.rateImage}" oncomplete="getNewImageForSlider();"/>
When i click on this link first time after clearing my browser history, i get following html
<?xml version="1.0"?>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link class="component"
href="/abc/a4j/s/3_3_3.Finalorg/richfaces/renderkit/html/css/basic_classes.xcss/DATB/eAELXT5DOhSIAQ!sA18_"
rel="stylesheet" type="text/css" />
<link class="component"
href="/abc/a4j/s/3_3_3.Finalorg/richfaces/renderkit/html/css/extended_classes.xcss/DATB/eAELXT5DOhSIAQ!sA18_"
media="rich-extended-skinning" rel="stylesheet" type="text/css" />
<script
src="/abc/a4j/g/3_3_3.Finalorg.ajax4jsf.javascript.AjaxScript"
type="text/javascript">
</script>
<script
src="/abc/a4j/g/3_3_3.Finalorg/ajax4jsf/javascript/scripts/form.js"
type="text/javascript">
</script>
<script
src="/abc/a4j/g/3_3_3.Finalorg/richfaces/renderkit/html/scripts/skinning.js"
type="text/javascript">
</script>
</head>
<body>
<meta name="Ajax-Update-Ids" content="" />
<span id="ajax-view-state"><input type="hidden"
name="javax.faces.ViewState" id="javax.faces.ViewState"
value="" />
</span>
<meta id="Ajax-Response" name="Ajax-Response" content="true" />
<span id="org.ajax4jsf.oncomplete">getNewImageForSlider();</span>
</body>
</html>
I removed value from viewstate hidden field purposely to reduce the
length of post.
Can anybody explain me why this is happening, and how can overcome it.
Thanks in advance
Richfaces (a4j) is always returning you a complete html response. After the return it will use the ajax-update-id to split the response into parts and place them where you have the defined ids of your rerender attribute.
You are not specifing anything to rerender and because of that only your js should be executed oncomplete.
Either you can fetch a new image during the a4j request directly and use rerender (your page needs to be prepared for that with an img tag and a random src i suppose) or you gave to do this in your oncomplete callback and create a new img tag and place it yourself.
The second approach can be tricky because the server state will not be aligned in a next request assuming you are using conversations in seam for example

Resources