I use composite component which has InputNumber from Primefaces extensions in its basis. I've set required attribute to true and message is not shown. Also I don't have * mark which indicates that the field is required.
Here is the code:
<p:outputLabel for="maxvrednost" value="#{resources['skale.maxvrednost']}" />
<asw:inputDecimal id="maxvrednost" bean="#{attrsBean}" column="maxvrednost" required="true" disabled="#{tip == 'brisanje'}" value="#{dto.maxvrednost}"/>
<p:message for="maxvrednost" display="icon" />
Code for composite component is:
<cc:interface>
<cc:attribute name="bean" required="true" type="asw.iis.common.ui.beans.CommonListBackingBean" />
<cc:attribute name="column" required="true" type="java.lang.String" />
<cc:attribute name="value" required="true" type="java.lang.Object" />
<cc:attribute name="disabled" default="false" required="false" type="java.lang.Boolean" />
<cc:attribute name="title" required="false" type="java.lang.String" default=""/>
</cc:interface>
<cc:implementation>
<pe:inputNumber emptyValue="" style="text-align: right;" value="#{cc.attrs.value}" required="#{cc.attrs.required}"
decimalSeparator="#{applicationPropertiesBean.decimalSeparator}" disabled="#{cc.attrs.disabled}"
decimalPlaces="#{cc.attrs.bean.findNumberOfDecimalPlaces(cc.attrs.column)}" title="#{cc.attrs.title}"
thousandSeparator="#{applicationPropertiesBean.groupSeparator}">
</pe:inputNumber>
</cc:implementation>
Not a 100% proper solution but it works for me:
<composite:interface >
<composite:attribute name="value" required="false" type="java.lang.String" default=""></composite:attribute>
<composite:attribute name="update" required="false" type="java.lang.String" default=""></composite:attribute>
<composite:attribute name="process" required="false" type="java.lang.String" default=""></composite:attribute>
<composite:attribute name="requiredMessage" required="false" type="java.lang.String" default=""></composite:attribute>
<composite:attribute name="decimalPlaces" required="false" type="java.lang.Integer" default="0"></composite:attribute>
<composite:editableValueHolder name="value" targets="num"></composite:editableValueHolder>
<composite:
</composite:interface>
<composite:implementation>
<div id="#{cc.clientId}">
<pe:inputNumber id="num" roundMethod="S" decimalPlaces="#{cc.attrs.decimalPlaces}" symbol="#{applicationBean.currentCurrencySymbol}"
minValue="0" required="true" requiredMessage="#{cc.attrs.requiredMessage}"
value="#{cc.attrs.value}"></pe:inputNumber>
</div>
</composite:implementation>
Use as follows:
<p:outputLabel value="Enter Amount" for="amt:num"></p:outputLabel>
<p:message for="amt:num"></p:message>
<comp:InputCurrency id="amt" roundMethod="S" decimalPlaces="0" symbol="#{applicationBean.currentCurrencySymbol}"
minValue="1" requiredMessage="#{loc._('Please enter amount to withdraw!')}"
value="#{myBean.amount}"></comp:InputCurrency>
Note that 'required' attribute is hardcoded to 'true'. If I define composite component attribute 'required' and copy the value to inputNumber 'required' property it behaves as required, but does not render the '*' mark on the label. This happens because inputNumber's 'required' attribute has not been set at render time, comes back as 'false' - not sure why, didnt have time to dig into this.
Related
Please help to find out the problem.
I have two composite components:
ajaxCommandButton:
<cc:interface>
<cc:actionSource name="ajaxAction" targets="ajaxCmd" />
<cc:attribute name="action" targets="ajaxCmd" method-signature="void action()" />
<cc:attribute name="value" />
<cc:attribute name="title" />
</cc:interface>
<cc:implementation>
<h:commandButton value="#{cc.attrs.value}" id="ajaxCmd"
title="#{cc.attrs.title}" >
<f:ajax />
</h:commandButton>
</cc:implementation>
and treeItem:
<cc:interface>
<cc:actionSource name="itemAction" targets="ajaxAction" />
</cc:interface>
<cc:implementation>
<ccb:ajaxCommandButton value="test" action="#{action()}" id="ajaxAction">
<f:setPropertyActionListener for="ajaxAction" value="#{value}" target="#{beanProperty}" />
</ccb:ajaxCommandButton>
</cc:implementation>
and usage from ui:composition
<ccb:treeItem>
<f:setPropertyActionListener for="ajaxAction" value="#{value}" target="#{beanProperty}" />
</ccb:treeItem>
What right way to set actionSource from ui:composition to ccb:ajaxCommandButton ?
Thanks in advance!
I'm facing a problem using OmniFaces 2.1 o:validateBean with method="validateCopy" when my inputs are composite components. With method="validateActual", it validates as expected.
JSF implementation: Mojarra 2.2.8-jbossorg-1.
My composite component source:
<composite:interface>
<composite:attribute name="target" />
<composite:attribute name="label"/>
<composite:attribute name="value" />
<composite:attribute name="required" />
<composite:attribute name="size" />
<composite:attribute name="disabled" />
<composite:attribute name="styleInput" required="false" />
<composite:editableValueHolder name="input" targets="input" />
<composite:clientBehavior name="change" event="change" targets="input" />
<composite:clientBehavior name="keypress" event="keypress" targets="input" />
</composite:interface>
<composite:implementation>
<p:outputLabel id="label" for="input" value="#{cc.attrs.label}" />
<h:panelGrid columns="3">
<p:inputText id="input" value="#{cc.attrs.value}"
style="#{cc.attrs.styleInput}" size="#{cc.attrs.size}"
disabled="#{cc.attrs.disabled}" required="#{cc.attrs.required}">
</p:inputText>
<p:message for="input" display="icon">
<p:effect type="pulsate" event="load" delay="500" />
</p:message>
</h:panelGrid>
</composite:implementation>
I tracked down to the omnifaces source and got to the source point below, in the o:validateBean:
ValueReference valueReference = getValueReference(context.getELContext(), valueExpression);
if (valueReference.getBase().equals(base)) {
operation.run((EditableValueHolder) component, valueReference);
}
In a case where I use a simple input text, the valueReference().getBase() returns my to be validated bean. In a case where I use a composite component, the valueReference().getBase() returns a reference to CompositeComponentAttributesELResolver.ExpressionEvalMap.
Is threre a way to change my composite component so that it works with o:validateBean?
I working on custom JSF 2.2 components with corporate design.
I have a problem with input text.
The problem is that if I use my component and want to specify <h:message for="id_of_component"/> its not work. Because the id of component is different.
<h:message for="input"/>
<custom:input id="input" required="true"/>
If i specify it inside component it works but it's not what I want. It should be flexible in case anyone want to use message on diferent place than I specify in component.
Component definition (with message):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:cc="http://xmlns.jcp.org/jsf/composite"
xmlns:p="http://xmlns.jcp.org/jsf/passthrough">
<!-- INTERFACE -->
<cc:interface name="input" expert="true">
<cc:attribute name="id" required="false"/>
<cc:attribute name="label" />
<cc:attribute name="value" />
<cc:attribute name="title" />
<cc:attribute name="readonly" default="false" type="java.lang.Boolean" />
<cc:attribute name="required" default="false" type="java.lang.Boolean" />
<cc:attribute name="rendered" default="true" type="java.lang.Boolean" />
<cc:attribute name="placeholder" type="java.lang.String"/>
<cc:clientBehavior name="click" targets=":#{cc.id}" event="click" default="true"/>
<cc:clientBehavior name="change" targets=":#{cc.id}" event="change" default="true"/>
<cc:clientBehavior name="blur" targets=":#{cc.id}" event="blur" default="true"/>
<cc:clientBehavior name="keyup" targets=":#{cc.id}" event="keyup" default="true"/>
</cc:interface>
<cc:implementation>
<h:panelGrid rendered="#{cc.attrs.rendered}" columns="2" id="panel" styleClass="customInputWrapper">
<h:outputLabel title="#{cc.attrs.title}"
value="#{cc.attrs.label}#{cc.attrs.required ? ' *' : ''}" for="#{cc.attrs.id}" />
<h:inputText id="#{cc.attrs.id}" styleClass="customInput" value="#{cc.attrs.value}" p:placeholder="#{cc.attrs.placeholder}" readonly="#{cc.attrs.readonly}" title="#{cc.attrs.title}" required="#{cc.attrs.required}"/>
<h:message for="#{cc.attrs.id}" />
<h:outputStylesheet library="custom" name="customComponentsStyle.css"/>
</h:panelGrid>
</cc:implementation>
</html>
Do you have any solution how to solve this problem?
I have the following JSF composite component:
<composite:interface componentType="myComp">
<composite:attribute name="input" type="java.lang.Integer" />
<composite:attribute name="output" type="java.lang.Integer" />
<composite:attribute name="action" method-signature="java.lang.String action()"/>
</composite:interface>
<composite:implementation>
<h:inputText id="input" value="#{cc.attrs.input}" />
</composite:implementation>
Assuming the composite is invoked as
<h:form id="form">
<cc:myComposite id="cc" input="#{bean.input}"
output="#{bean.output}" action="#{bean.action}" />
</h:form>
Once bean.action is invoked it sets a value in bean.output. I need to access this value in my javascript, something like this
document.getElementById('form:cc:output').value
From myComp I can set the attribute with
getAttributes().put("output", output);
But the data resides in the backing bean. Any ideas?
You need a component to submit the 'output' value to the backing bean. Use inputHidden to accomplish this:
<composite:interface componentType="myComp">
<composite:attribute name="input" type="java.lang.Integer" />
<composite:attribute name="output" type="java.lang.Integer" />
<composite:attribute name="action" method-signature="java.lang.String action()"/>
</composite:interface>
<composite:implementation>
<h:inputText id="input" value="#{cc.attrs.input}" />
<h:inputHidden id="output" value="#{cc.attrs.output}" />
</composite:implementation>
Then you'll be able to set the 'output' value using its hidden input element via javascript.
I have the following problem with nested composite components and passing validators to a inputtext in a nested component:
The wrapper custom component (wrapper.xhtml):
<cc:interface>
<cc:attribute name="value" required="false" />
</cc:interface>
<cc:implementation>
<h:panelGroup>
<h:outputLabel value="TEST:"/>
<temptest:input value="#{cc.attrs.value}">
<cc:insertChildren/>
</temptest:input>
</h:panelGroup>
</cc:implementation>
The nested custom component (input.xhtml):
<cc:interface>
<cc:attribute name="value" required="false" />
<cc:editableValueHolder name="input" targets="input" />
</cc:interface>
<cc:implementation>
<h:inputText value="#{cc.attrs.value}" id="input" >
<cc:insertChildren/>
</h:inputText>
</cc:implementation>
The trial to pass a validator to the nested custom component (pageXYZ.xhtml):
<h:form>
...
<temptest:wrapper value="#{bean.value}">
<f:validateRequired for="input"/>
</temptest:wrapper>
<!-- this works:
<temptest:input value="#{bean.value}">
<f:validateRequired for="input"/>
</temptest:input> -->
<h:message for="input"/>
...
</h:form>
Is there a way to pass (one or more) validators to a nested custom component?