JSF InputText conditional attribute render - jsf

I have a composite component (CC) that renders a inputText. I have a attribute called "autoFocus" in CC that should be rendered in inputText only when it values is true, see the code:
<composite:attribute name="myAutoFocus" default="false" type="java.lang.Boolean"/>
So, inside composite:implementation i have the following:
<h:inputText pt:autofocus="#{cc.attrs.myAutoFocus}" />
In this way my autoFocus is always enable, because "autofocus=false" and "autofocus=true" is both TRUE. So i need a way to render the autoFocus looking for my CC attribute value.

I used c:if to conditionally render the autofocus attribute via the f:passThroughAttribute from JSF 2.2 to solve my problem:
<h:inputText>
<c:if test="#{cc.attrs.myAutoFocus}">
<f:passThroughAttribute name="autofocus" value="autofocus"/>
</c:if>
</h:inputText>

Related

Automatically set h:inputText maxlength based on Bean Validation #Size

I use JSF 2 and Hibernate Validator 5.1 in a web application.
I use the annotations like #Size or #NotNull in my beans to validate automatically my HTML forms.
It works perfectly but I would like to know if there is a way to automatically limit the number of characters typed in an input text (ie set the attribute maxlength in HTML) based on the #Size annotation.
Use maxlength attribute of <h:inputText>
You can also use f:validate -
<h:inputText id="Username" value="#{model.username}"
required="true"
label="UserName" >
<f:validateLength minimum="5" maximum="10" />
</h:inputText>
HTML5 + JSF 2.2+
If you're using HTML5 and JSF 2.2+, specify it as a passthrough attribute.
<html ... xmlns:a="http://xmlns.jcp.org/jsf/passthrough">
<h:inputTextarea value="#{bean.text}" a:maxlength="2000" />

Manipulate component tree in restore view phase

For a web application (myfaces 2.2), I need to reduce the component tree to speed up the application. How can I do this?
given:
a composite component that renders input elements due to a backing bean value
<h:dataTable value="#{myList}" var="myBean">
<h:column>
<h:inputText ... rendered="#{myBean.myValue == 1}" />
<h:selectOneMenu ... rendered="#{myBean.myValue == 2}">...</...>
<h:inputTextarea ... rendered="#{myBean.myValue == 3}" />
</h:column>
</h:dataTable>
problem:
all components appear in component tree, even when their rendered attribute is false
inputtext
selectOneMenu
inputTextarea
Is it possible to forbid JSF to build up the component tree with all three components? The restore view phase doesn't know about content of the apply request values phase, but it would be important to be able to interpret it still before.
If you want to achieve this behavior, try to use <c:if> tag instead of rendered atribute on JSF component
<c:if test="#{ myBean.myValue == 1 }">
<h:inputText .../>
</c:if>
don't forget to add namespace definition
xmlns:c="http://java.sun.com/jstl/core"

How to create a composite component which switches between inputText and inputSecret?

I'm writing a Facelets composite component that switches between using inputText and inputSecret based on a parameter:
<composite:interface>
<composite:attribute name="myId" required="true"/>
<composite:attribute name="secret" required="false" default="false" />
</composite:interface>
<composite:implementation>
<h:inputSecret rendered="#{cc.attrs.secret}" id="#{cc.attrs.myId}" />
<h:inputText rendered="#{!cc.attrs.secret}" id="#{cc.attrs.myId}" />
</composite:implementation>
The problem is that I get the following error:
Component ID [JSF mangled id] has already been found in the view.
Use a view build time tag like JSTL <c:if> or <c:choose> instead of the JSF component's rendered attribute. View build time tags are evaluated during constructing the JSF component tree, while the rendered attribute is only evaluated during generating HTML based on the JSF component tree (and thus you still end up with both components with the same ID in the JSF component tree!).
E.g.
<c:if test="#{not cc.attrs.secret}">
<h:inputText id="input" />
</c:if>
<c:if test="#{cc.attrs.secret}">
<h:inputSecret id="input" />
</c:if>
See also:
JSTL in JSF2 Facelets... makes sense?
Unrelated to the concrete problem, the myId doesn't make sense. Just give those a fixed ID. In case the reason was the inability to reference them from outside by ajax, head to Referring composite component ID in f:ajax render.
Whether or not the component is actually rendered doesn't matter.Both components will still exist in the view's internal component tree and will require a unique id. We ran into this problem as well.
We suffixed the id with a _1 and _2 and if we need to get a hold of the id inside javaScript, we use JQuery's partial matchers.
In your case, can you not make your bean's getMyId() method return a different id based on the value of the secret property?

Issue in attribute for on h:outputLabel inside ui:repeat

I have following piece of code, i want to render radioButtons and labels for them. Due to the layout renderized by selectOneRadio and selectItem i decided to use plain HTML for the input radioButtons.
<h:panelGrid columns="6">
<ui:repeat value="#{myBean.list}" var="item">
<input id="#{item.innerList[0].id}" type="radio" name="radioItem" value="#{item.innerList[0].id}" />
<h:outputLabel for="#{item.innerList[0].id}" value="#{item.label}" />
</ui:repeat>
</h:panelGrid>
When trying to assign a label for them using outputLabel it renders the attribute for in HTML something like:
j_idt94:0:theidiassigned
The prependId flag in the tag form containing this code is set to false and in the documentation there is no such flag in the attributes of the other containing tags of the outputLabel.
The ui:repeat component is a NamingContainer. It controls the client identifier of its children.
The for attribute on a h:outputLabel will generally look for a component with a matching component identifier or client identifier.
So, for this markup:
<foo:someNamingContainer id="x">
<h:inputText id="foo" />
<h:outputLabel for="foo" />
</foo:someNamingContainer>
...the label would emit the matching, namespaced identifier <label for="...:x:foo".
There is no matching JSF component with a matching id since you are using a straight XHTML <input> element.
Consider just using a XHTML <label> element instead.

a4j:support after h:inputText value change doesn't work

can anyone figure out why the h:outputText doesn't get refreshed after inputText value change?
I've tried both onkeyup and onchange and both don't affect..
When I do some other thing that makes the page refresh, the h:outputText is rendered correctly so it's only a matter of getting the ajax to actually rerender the component.
<h:inputText autocomplete="off" styleClass="propertyInput"
value="#{activesyncDM.userNameDomain}" validator="#{activesyncDM.validate}"
id="userNameDomain" dir="ltr">
<a4j:support event="onkeyup" reRender="domainNameSlash"/>
</h:inputText>
<h:outputText id="domainNameSlash" value="\\" rendered="#{!empty activesyncDM.userNameDomain}"/>
Thanks!!
besides putting ajaxSingle="true" for a4j:support which is mentioned by Cristian , the id attribute in HTML code rendered by the JSF may not be the same as the ID value you set in <h:outputText> . Richfaces provides a function rich:clientId('id') to get these dynamic ID generated by JSF . This function is invoked via the EL expression.
So , you can try :
<a4j:support event="onkeyup" ajaxSingle="true" reRender="#{rich:clientId('domainNameSlash')}"/>
You have to send the value of inputText to the backing bean in order the outputText to reflect the changes so you should put: ajaxSingle="true" for a4j:support
<a4j:support event="onkeyup" ajaxSingle="true" reRender="domainNameSlash"/>

Resources