Does jsf support ES6 modules? - jsf

I tried to include some simple javascript code in my JSF page.
Works ok but problems begin including javascript code with modules functionalities.
in file myLib.js:
import { tag } from '/primefaces-crud-1.1/resources/js/html.js';
in file button.xhtml:
<h:outputScript library="js" name="myLib.js" />
console error:
Uncaught SyntaxError: Unexpected token {
main.js:42 in Startnull

​

Related

h:body not rerendered when using FullAjaxExceptionHandler

I'm using the OmniFaces FullAjaxExceptionHandler to display error pages. The error pages are shown correctly, but I'm having issues with the styling of those pages.
My application is using a template which has CSS classes defined on the body element. These classes are different for normal and error pages:
Normal page:
<h:body styleClass="main-body layout-compact">
Error page:
<h:body styleClass="exception-body error-page">
When the FullAjaxExceptionHandler processes an exception, a forward to the error page is performed (based on the <error-page> mechanism in web.xml). Apparently this does not rerender the <h:body> tag, because when checking the HTML output, I can see that the <body> tag still contains the CSS classes from the normal page (instead of the classes of the error page).
It seems that the content of the original <h:body> is replaced with the content of the error page <h:body> instead of just replacing the full <h:body>. I don't know if this is default JSF / FullAjaxExceptionHandler behaviour.
Is there any way to have the <h:body> rendered with the correct CSS classes? Moving the CSS classes away from <h:body> is not an option.
This is unfortunately "by design". JSF doesn't replace the entire document when performing ajax navigation, but it only replaces the children of individual <head> and <body> elements, leaving the parents untouched. This is done so for historical reasons; older Internet Explorer versions namely doesn't support replacing them altogether.
What I have done myself is to simply put the style into the <main> element instead. The <header> and <footer> are usually identical anyway in the final HTML output. Basically:
<html>
<head>
<title>...</title>
</head>
<body>
<header>...</header>
<main class="#{page.type}">...</main>
<footer>...</footer>
</body>
</html>
If you really need to have the <body class> modified, then your best bet is to do so via JavaScript embedded in the error page template.
<h:outputScript rendered="#{faces.ajaxRequest}">
document.body.className = "exception-body error-page";
</h:outputScript>
Note: #{faces} is only available since OmniFaces 2.5, if you're using an older version, use instead #{facesContext.partialViewContext.ajaxRequest}).

template and <h:outputScript> [duplicate]

This question already has an answer here:
How to include JavaScript files by h:outputScript? [duplicate]
1 answer
I have a JavaScript file stored in the web root like,
SocialNetworking/web/resources/js/decimal_number_text_field.js
I'm trying to import this js file in an XHTML page like,
<h:body>
<ui:composition template="template/Template.xhtml">
<ui:define name="content">
<h:outputScript name="../resources/js/decimal_number_text_field.js"/>
</ui:define>
</ui:composition>
</h:body>
The path is correct but it doesn't work.
The generated JavaScript tag looks like the following.
<script type="text/javascript" src="/SocialNetworking/javax.faces.resource/../resources/js/decimal_number_text_field.js.jsf">
</script>
So, the src attribute contains a wrong URL. If this script is added to the template within the <h:head> tag like so,
<h:outputScript name="js/decimal_number_text_field.js"/>
then it works fine.
Why does it take a wrong URL when this tag is placed in an XHTML page which covers the template?
Try to use : #{request.contextPath} as below. Based one your file path, resources package must be under web application root directory.
or
<script type="text/javascript" src="#{request.contextPath}/resources/js/decimal_number_text_field.js.jsf">
</script>
directory structure :
applicaiton.war
- resources
- js
- decimal_number_text_field.js.jsf

How to force browser to reload h:outputScript resource?

The JS file extra.js is included as follows:
<h:outputScript library="js" name="extra.js" />
I am facing issue of browser caching. Many times, I will not get the updated copy.
In plain HTML, we used to append version number or random number with JS URL like:
<script type="text/javascript" src="http://yyy.zzzz.net/js/tryjs?v=1234"></script>
where v is the version number.
Is there any way to add some version number to the generated resource URL in h:outputScript?
You can do one of the following
Manage the version number in one of you beans #{myBean.myVersion} and append it to you js file in h:outputScript
Like this:
<h:outputScript library="js" name="extra.js?#{myBean.myVersion}/>
or rename your js file to include the #{myBean.myVersion} as a part of its name like this
<h:outputScript library="js" name="extra.#{myBean.myVersion}.js/>
Also you can take a look at this : Resources (Library) In JSF 2.0

JSF outputScript and JavaScripts not parsed by EL? [duplicate]

**Possible Duplicate: The solution to this post is not feasible in this case, re-open this post please! **
JSF bean property not evaluated in external JavaScript file
The EL parser do not translate files including with the <outputScript> tag (JavaScript files). When trying to access the resource bundle.
<h:outputScript library="js" name="myScripts.js" target="head"/>;
myScripts.js file:
alert("#{msg.browser_not_html5_compatible}");
The result is that I get the same string back when the alert window renders.
If I have this line of JavaScript in a <script> tag in my XHTML file, the EL parser will replace it with the correct resource string from the bundle;
<script>
alert("#{msg.browser_not_html5_compatible}");
</script>
Can I make the EL parser translate my included (<h:outputScript>) JavaScript file to access the resource bundle?
Servlet
One option could be creating a servlet which loads your message bundle and creates a Javascript file containing a JSON object containing the message keys and values. It might look like:
var messages = {
"browser_not_html5_compatible": "You browser..."
, "other_key": "Other value"
};
If you have a large resource bundle and you don't want to expose all messages to Javascript you could prefix specific Javascript messages with something like js_. That way you can easily iterate over the resource bundle's keySet and only use the Javascript keys:
for (String key : resourceBundle.keySet()){
if (key.startsWith("js_")){
// Do something with resourceBundle.getString(key);
}
}
On your JSF page you have to add the generated Javascript. If you need it, you can pass your view's locale to your servlet using #{view.locale}:
<h:outputScript library="js" name="/path-to-servlet/#{view.locale}" target="head"/>
<h:outputScript library="js" name="myScripts.js" target="head"/>
And in myScripts.js you can use:
alert(messages.browser_not_html5_compatible);
JSP
A variation on the servlet option is using JSP to create the Javascript containing JSON. You can by setting the content type to application/javascript:
<%# page contentType="application/javascript; charset=UTF-8" %>
You need EL 2.2 to iterate over the resource bundle's keySet though (since there is no getter to access it).

JSF button is not shown

I have the following code and whatever I do my web browser does not render any submit button.
I am using eclipse with Glassfish.
The problem is also that somehow when I try my examples fast , the server sometimes hangs around and browser is in the waiting mode for minutes without any error or anything.
Sometimes it does give the page away and it works perfect.
Why is the button not shown and my server is so unstable?
<h:head><title>JSF 2: Using #ManagedBean</title>
<link href="./css/styles.css"
rel="stylesheet" type="text/css"/>
</h:head>
<h:body>
<div align="center">
<table class="title">
<tr><th>JSF 2: Using #ManagedBean</th></tr>
</table>
<p/>
<fieldset>
<legend>Random Results Page</legend>
<h:form>
Press button to get one of three possible results pages.
<br/>
<h:commandButton value="Go to Random Page" action="#{navigator.choosePage}" />
</h:form>
</fieldset>
</div>
package coreservlets;
import javax.faces.bean.*;
#ManagedBean
#ApplicationScoped
public class Navigator {
private String[] resultPages =
{ "page1", "page2", "page3" };
public String choosePage() {
return(RandomUtils.randomElement(resultPages));
}
}
That can happen if you either forgot to declare the h: XML namespace, causing the <h:xxx> tags being unrecognized. This can be confirmed by just looking at the JSF source code and the generated HTML output (rightclick - View Source in browser).
<html ... xmlns:h="http://java.sun.com/jsf/html">
Or the request URL as you see in browser's address bar didn't match the <url-pattern> of the FacesServlet as mapped in web.xml, causing the <h:xxx> tags being unparsed. This can be confirmed by just looking at the request URL, the web.xml and the generated HTML output.
<url-pattern>*.xhtml</url-pattern>
Or the CSS in styles.css has hidden it in some way. This can be confirmed by checking the CSS file, and/or using the browser's developer toolset and/or checking the generated HTML output.
input[type=submit] {
display: none;
}
See also:
Our JSF wiki page - contains a Hello World example and several tutorial links
Unrelated to the concrete problem, using an application scoped bean for the particular use case is quite strange. It's been shared among all users in all sessions. So if the action is invoked by webapp user X elsewhere in the world, all other webapp users over the world would see it being reflected. Wouldn't you rather use a request or view scoped bean?
See also:
How to choose the right bean scope?

Resources