Is it possible to display the current date (today's) in JSF without using a backing bean?
I have the following code snippet , but it didn't work out.
<div class="leftSide">Today's date #{currentDate}</div>
or
<f:facet name="header">
<h:outputText value="Today's date" />
</f:facet>
<h:outputText value="#currentDate">
<f:convertDateTime pattern="MM/dd/yyyy" type="date" />
</h:outputText>
You could register an instance of java.util.Date as a request scoped bean in faces-config.xml.
<managed-bean>
<managed-bean-name>currentDate</managed-bean-name>
<managed-bean-class>java.util.Date</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
This way it's available as #{currentDate} without the need for a custom backing bean class.
Update: the JSF utility library OmniFaces has such a bean already registered as #{now}. So if you happen to use OmniFaces already, you can just make use of it directly.
<h:outputText value="#{now}">
<f:convertDateTime pattern="MM/dd/yyyy" type="date" />
</h:outputText>
In JSF you could use the implicit EL object session that provides access to the current HttpSession. The HttpSession#getLastAccessedTime time ...
... returns the last time the client sent a request associated with this
session, as the number of milliseconds since midnight January 1, 1970
GMT, and marked by the time the container received the request.
So you could use the following code snippet in your facelet:
<h:outputText value="#{session.lastAccessedTime}">
<f:convertDateTime pattern="MM/dd/yyyy" type="date" />
</h:outputText>
This will be server time and may differ from client time with respect to different time zones.
But you could also use a javascript solution, as discussed here:
How do I get the current date in JavaScript?
Or you could do it using Omnifaces. I'm surprised BalusC hasn't told you about this solution (I think he's a great Omnifaces contributor). Maybe it's because using Omnifaces just to display a simple date in a page might be an overkill to some.
Anyway, if your project already uses Omnifaces, there are 2 managed beans exposed by default and one in particular that you may find handy. As per the tag documentation specifies, once Omnifaces is added to your project, you can use the #{now} managed bean.
For instance, to set a Primefaces calendar's max date, I just wrote the following :
<p:calendar id="myCalendar" pattern="dd/MM/yyyy"
value="#{mybean.myDate}" maxdate="#{now}"/>
I guess the #{now} managed bean can be used in many more situations, and probably yours as well.
If your project does not use Omnifaces yet, I suggest you look at their spec and see how helpful it could be for you.
For instance, I'm using their validateOrder tag to make sure two dates are properly ordered.
You can use the tag which PrimeFaces provide.
<p:clock pattern="HH:mm:ss dd-MM-yyyy"/>
Related
In JSF2 I have an XHTML like this:
<h:form id="myForm">
...
<c:forEach items="#{myController.header}" var="hd" varStatus="count">
#{hd}
<h:selectOneMenu value="#{myController.type[count.index]}" id="formtype" >
<f:selectItem itemValue="Nop" itemLabel="Nop" />
<f:selectItem itemValue="Yep" itemLabel="Yep" />
<f:ajax render="#form" />
</h:selectOneMenu>
#{myController.type[count.index]}
<h:selectBooleanCheckbox value="#myController.valid[count.index]}" id="valid">
<f:ajax render="#form"/>
</h:selectBooleanCheckbox>
#{myController.valid[count.index]}
</c:forEach>
...
</h:form>
And my managed bean has:
private String[] type;
private boolean[] valid;
which I initialise (type = new String[...]; and assign a value to each position) when the named bean is 1st loaded.
If I modify the combo or the check box, it works, the value is changed in the managed bean and the new value gets printed (rendered) in the JSF page. But only the 1st time. Next changes do not modify anything at all. It is strange because I have similar code in other apps and works fine, so I am doing something incorrectly but cannot find it. My template has a h:header and I cannot see any logs in the JS console or in TomEE (I only see .INFO - The start() method was called on component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/myApp]] after start() had already been called. The second call will be ignored but I think it is unrelated). I have tried to add execute="#this"/execute="#form" and others unsuccessfully, and check all points of this post but nothing seems to apply to me.
What is the mistake I am not seeing?
EDIT
#Named(value = "myController")
#ViewScoped
public class MyController implements Serializable {
...
I also have a <h:messages globalOnly="true" showDetail="true" showSummary="true" /> in my template.
I think I got it, finally!
Thanks to two things:
Point 3 in BalusC answer. I added an id to my message in the template <h:messages id="msg" and then use <f:ajax render="#form msg"..... This made an error j_idt1: Validation Error: Value is required to appear.
Then I could find the solution in this post: to change the required parameter from true to <f:viewParam required="#{!facesContext.postback}". This was not required in my other apps because required was "false", since it could be called with parameter or without it. When it was called with a parameter, it worked because by serendipity the page could be called without it.
Ran into the exact same problem, my <f:ajax> tag would work the first time and then nothing... no error or anything on the page. After a few hours and countless googling nothing was turning up. (Most of the questions on StackOverflow were actually having the opposite problem, the Ajax wouldn't fire the first time but then it would work fine). I finally stumbled on this question which described exactly what I was seeing.
I was previously trying to re-render only a section of the page, but I noticed that once I changed the render attribute to "#all", I got the same error message describe above:
j_idt1: Validation Error: Value is required
I scrolled up and noticed I had a <f:viewParam> with required set to "true". I made the change described by user1156544 and that did the trick.
I had a bad time trying to solve p:selectBooleanButton doesn't render preselected value, a lot of hours just to fix it changing ui:repeat to h:datatable.
Here is both pieces of code.
<ui:repeat value="#{presupuestoBean.getItemsPresupuestBySeccion('Parte Delantera')}" var="itemPresupuesto">
<tr>
<td><h:outputText value="#{itemPresupuesto.descripcion}"/></td>
<td>
<p:selectBooleanButton value="#{presupuestoBean.itemsPresupuestoAsignadoCambiar[itemPresupuesto.id]}" onLabel="Yes" offLabel="No" onIcon="ui-icon-check" offIcon="ui-icon-close"/>
<h:outputText value="#{presupuestoBean.itemsPresupuestoAsignadoCambiar[itemPresupuesto.id]}" />
</td>
</tr>
</ui:repeat>
(Notice that the button is showing 'FALSE (or NO)' value although the property value is 'TRUE' as displayed by outputText)
On the other hand, the exactly same code with h:datatable.
<h:dataTable value="#{presupuestoBean.getItemsPresupuestBySeccion('Parte Delantera')}" var="itemPresupuesto2">
<h:column>
<h:outputText value="#{itemPresupuesto2.descripcion}"/>
</h:column>
<h:column>
<p:selectBooleanButton value="#{presupuestoBean.itemsPresupuestoAsignadoCambiar[itemPresupuesto2.id]}" onLabel="Si" offLabel="No" onIcon="ui-icon-check" offIcon="ui-icon-close"/>
<h:outputText value="#{presupuestoBean.itemsPresupuestoAsignadoCambiar[itemPresupuesto2.id]}" />
</h:column>
</h:dataTable>
Anyone know why is this happening ??. As far as I know, this two tags could be exchangeable. (at least according the example that I saw e.g JSF 2 Repeat Tag Example)
I'm using com.sun.faces jsf-api and jsf-impl 2.2.4
Also Primefaces 4.0
You confuse view build time with view render time! BalusC posted an explanation here:
JSTL in JSF2 Facelets... makes sense?
I had the same behavior, and was not able to make work the ui:repeat properly with map and default value.
As you are using primefaces, you might also found p:dataGrid as an alternative to h:dataTable.
This example is from a book on JSF. The excercise is to refactor the following Facelets code while eliminating <c:if> and fn:toUpperCase(). Usage of <c:forEach> is allowed.
#{myBean.numbers} returns String["one","two","three"]
As the book is on JSF and not on Java, I suppose the existing Java-code is not to be touched. But I can't think of another way to do this solely in Facelets.
<c:forEach var="item" items="#{myBean.numbers}">
<c:if test="#{not fn:endsWith(item,'o')}">
#{item}
</c:if>
<c:if test="#{fn:endsWith(item,'o')}">
#{fn:toUpperCase(item)}
</c:if>
</c:forEach>
Only thing I can think of is using a converter that conditionally uses String#toUpperCase() and then I still do not understand why use of <c:forEach> should still be allowed:
<ui:repeat var="item" value="#{myBean.numbers}">
<h:outputText value="#{item}" converter="conditionalConverter"/>
</ui:repeat>
Is there a more "Facelets way" to do this (and still a need to use <c:forEach>)?
UPDATE:
Instead of <c:if> one could still use e.g. <h:outputPanel> and it's rendered-attribute, but there is still no Java-less replacement for fn:toUpperCase().
I am asking for learning purposes only. I suppose the <ui:repeat>-solution with a converter is the cleanest and represents most how JSF is supposed to be used. Do you think so, too?
As to <c:if>, the JSF alternative to JSTL <c:if> is the rendered attribute on any component. For example, <h:panelGroup> or <h:outputText>. Those components doesn't generate additional markup if there are no attribtues specified which should end up in HTML, like id or styleClass, otherwise they generate a <span>.
Here's an example of both:
<h:panelGroup rendered="#{not fn:endsWith(item,'o')}">
#{item}
</h:panelGroup>
<h:outputText value="#{fn:toUpperCase(item)}" rendered="#{fn:endsWith(item,'o')}" />
As to fn:toUpperCase(), JSF has no alternative. I'm not sure why you would need a JSF alternative as it's essentially not a tag, but a simple EL function which is perfectly usable in both JSTL and JSF tags. In any case, you could if necessary throw in CSS text-transform: uppercase. As this takes place entirely client side, your only problem may be the browser support.
<h:outputText value="#{item}" style="text-transform: uppercase" />
(note: this is just an example, the normal practice is to put styles in its own .css file which you load by <h:outputStylesheet>)
<h:outputText value="#{item}" styleClass="uppercased" />
I suppose the -solution with a converter is the cleanest and represents most how JSF is supposed to be used. Do you think so, too?
I'm a big fan of "Use the right tool for the job". Use JSTL tags to conditionally build the JSF component tree. Use JSF components to generate HTML. That's it. See also JSTL in JSF2 Facelets... makes sense?
We have to display the year field on the Facelets page.
<h:outputText value="#{dateTOloginDate.get(Calendar.YEAR)}"/>
This always returns a 1 and not the year value. How can I achieve it?
The Calendar.YEAR is a constant field value. Constant field values are by default not available in EL scope at all. Hardcoded constant values do however work, as you encountered yourself.
There are several ways to achieve this in a more clean manner:
Use <f:convertDateTime> instead. You'll only need to get the java.util.Date instance by Calendar#getTime().
<h:outputText value="#{dateTOloginDate.time}">
<f:convertDateTime pattern="yyyy" />
</h:outputText>
Use OmniFaces <o:importConstants>. It allows you to import the constant field values of a given type into the EL scope. This way you'll be able to use exactly the intented syntax.
<o:importConstants type="java.util.Calendar" />
...
<h:outputText value="#{dateTOloginDate.get(Calendar.YEAR)}" />
Only, this is IMO an extreme use case. I'd personally prefer the <f:convertDateTime> way. It would also be more ideal if you just use java.util.Date instead of the clumsy java.util.Calendar. I don't see how it's beneficial to have a java.util.Calendar as model value type.
Is there a way to update UI elements asynchronously in JSF 2?
For example a person is looking on the screen and some pieces on the screen get updated, when say a batch job changes some value.
There are a couple of solutions. One is e.g. a4j:push, which is further described here.
IceFaces is also known for this. Note that some of the components essentially do polling via AJAX, while others actually use reverse ajax/comet.
You can also use the <p:poll> provided by PrimeFaces.
Here is a working example:
<h:form>
<h:outputText id="txt_count" value="#{counterView.number}" />
<p:poll interval="3" listener="#{counterView.increment}" update="txt_count" />
</h:form>