I'm using WildFly 8.0.2 along with primefaces 5.2, i have a p:datatable, with a column that have a p:inputSwitch, the value on this p:inputSwitch is a method (that return either true or false), so it does not have a setter method, i have attached a p:ajax to handle the switching event (on/off), but when i change the value it always raise an javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation exception (cause the value is a method ... and has no setter).
here is my code:
<p:column styleClass="status #{employee.haveSkill(skill) == true ? 'have' : 'dosntHave'}">
<div style="text-align: center;">
<p:inputSwitch value="#{employee.haveSkill(skill)}" onLabel="#{msgs.yes}" offLabel="#{msgs.no}">
<p:ajax listener="#{skillsController.addSkill(employee, skill)}" />
</p:inputSwitch>
</div>
</p:column>
i have tried with a c:set, that stores the result of the method in a variable and then assign it to the p:inputSwitch component, but that didnt work for me, and the p:inputSwitch is always set to false (although the EL expression for the style class of the cell is working fine), here is the code that i have tried:
<p:column styleClass="status #{employee.haveSkill(skill) == true ? 'have' : 'dosntHave'}">
<div style="text-align: center;">
<c:set var="have" value="#{employee.haveSkill(skill)}" scope="request" />
<p:inputSwitch value="#{have}" onLabel="#{msgs.yes}" offLabel="#{msgs.no}">
<p:ajax listener="#{skillsController.addSkill(employee, skill)}" >
</p:ajax>
</p:inputSwitch>
</div>
</p:column>
So is there like a way to tell jsf or el not to fire the "set" method for that component? and just execute that listener on the ajax??
UPDATE:
I have also tried with the ui:param, but it also raises the javax.el.PropertyNotWritableException :
<p:column styleClass="status #{employee.haveSkill(skill) == true ? 'have' : 'dosntHave'}">
<div style="text-align: center;">
<ui:param name="have" value="#{employee.haveSkill(skill)}" />
<p:inputSwitch value="#{have}" onLabel="#{msgs.yes}" offLabel="#{msgs.no}">
<p:ajax listener="#{skillsController.addSkill(employee, skill)}" >
</p:ajax>
</p:inputSwitch>
</div>
</p:column>
Related
I have a datatable created in PrimeFaces which receives and render a list of objects. At the end of the row I have a commandButton element and when it is used it do some stuff on the managedBean on the server.
All the data about the current row is retrieved using an object id placed in the command button in the param attribute.
The problem is that I have a selectOneMenu element and it is not related to the object. I select one value that affects the logic behind.
Here is the table:
<h:panelGrid id="panel" columns="2" bgcolor="#cce4ff"
cellpadding="10" cellspacing="1" rendered="#{indexBean.showChannelList}"
style="margin-top: 10px; margin-left: 100px;">
<p:dataTable var="program" value="#{indexBean.programList}" style="width:1000px;"
paginator="True" rows="10" rowIndexVar="row" sortBy="#{program.id}"
paginatorPosition="bottom" widgetVar="programDT" id="programDT">
... That the select
<p:column headerText="text" width="15%">
<h:selectOneMenu id="select-valability" value="#{indexBean.valabilitySelected}" disabled="#{indexBean.disabled}" style="font-size: small;">
<f:selectItems value="#{indexBean.listValabilities}" />
<f:param value="#{program.id}" />
<f:ajax resetValues="true" />
</h:selectOneMenu>
</p:column>
... and there is the command button
<p:column headerText="text" width="20%" style="text-align: center;">
<h:commandButton id="cmd-button-id" value="gen JSON" action="#{indexBean.action}"
style="width: 200px; height: 30px;"
class="ui-button ui-widget ui-state-default ui-corner-all"
>
<f:param name="programId" value="#{program.id}" />
</h:commandButton>
</p:column>
I want to be able to get the value of the select element from that specific row from which the action was triggered.
I've try with context.findComponent() but it gives me null even if I put the absolute path to the element with the index generated by JSF table as form:table:index:staticIdOfSelect.
I don't know how to get the sibling element. That was another though.
From the bean class:
#ManagedBean
#SessionScoped
public class IndexBean
I'm really stuck here.
Thanks in advance!
Use some element on the row to set an ajax listener in the bean to store the data and then update="the element" you want to get the information from.
I want to change a div's class dynamically based on if an input value is true or false. Thought the function that validates the input is called the class is never changed. Here's the xhmtl:
<td>
<div class="#{regBean.nameclass}">
<h:inputText class="form-control input-sm" value="#{regBean.name}">
<f:ajax event="blur" listener="#{regBean.validateName}" render="namemsg" />
</h:inputText>
</div>
</td>
<td class="error">
<h:outputText class="error-msg" id="namemsg" value="#{regBean.nameMsg}"></h:outputText>
</td>
and here's the function from the according bean:
private static final String SUCCESS="form-group has-success";
private static final String ERROR="form-group has-error";
public void validateName(){
if(ValidatorUtilities.empty(name)){
nameMsg="Παρακαλώ εισάγετε όνομα!";
}
nameMsg=ValidatorUtilities.validateName(name);
if(nameMsg.equals("")){
nameclass=SUCCESS;
validations.put("name",true);
}
else{
nameclass=ERROR;
validations.put("name",false);
}
}
thought the message at element with id="namemsg" is correctly shown the class remains the same. Is there anything wrong or am I going for the wrong implementation and should do this client side by jquery?
Note:I've set the getter-setter for the string nameclass
Your code is not re-rendering the <div>. Your code is only re-rendering the <h:outputText>. I'm not sure why and how exactly you expected that the <div> is also covered by the re-rendering. All you need to so is to specify its client ID in the render attribute as well. You only need to replace <div> by <h:panelGroup layout="block">, because rendering can only target true JSF components.
<td>
<h:panelGroup id="field" layout="block" styleClass="#{regBean.nameclass}">
<h:inputText ...>
<f:ajax ... render="field namemsg" />
</h:inputText>
</h:panelGroup>
</td>
<td class="error">
<h:outputText id="namemsg" ... />
</td>
Unrelated to the concrete problem, your whole validation approach is utterly broken. You're supposed to use a true Validator and a <h:message>, exactly like as shown in every decent JSF book. This is also a strong hint that you still don't have one. I warmly recommend to work on that first.
See also:
How to create JSF form with AJAX data validation
How to perform validation in JSF, how to create a custom validator in JSF
Based on this subject, I would like to update a <p:overlayPanel> from a datatable to a composite component
View
<h:form id="myForm">
<p:dataTable id="myTable" ...>
<p:column headerText="1">
<p:commandLink id="link"
actionListener="#{bean.update}"
update=":toto" value="Val" />
<p:overlayPanel id="panel" for="link">
<my:view id="toto">
</p:overlayPanel>
</p:column>
</p:dataTable>
</h:form>
Composite
<composite:implementation>
<span id="#{cc.clientId}">
<p:dataTable id="toto" ...>
</p:dataTable>
</span>
</composite:implementation>
However I always get an error message saying that :toto component id can not be reached.
So, how can I access the dataTable placed in the composite ?
EDIT : Actually I changed my mind concerning the utilisation of p:overlayPanel for a p:datatable because of the creation of dynamic ids. I replaced this by a p:dialog and it works great.
I have been looking at Primefaces 3.4.2 since IceFaces 3.2.0 has too many issues. I have a dataGrid of vehicles which are contained in a panel. I have an add button and each vehicle panel contains a remove button.
The add works fine; it adds a new vehicle panel each time. The issue is when I delete a vehicle, the panel is removed, but the value(s) remain. For instance, if I have 3 vehicles with the year as 2008, 2010, 2012, and then I delete the first vehicle, you'd think you would see 2 panels remaining with the year as 2010, and 2012. Instead, I see 2008 and 2012. The backing bean is doing it correctly and I do see the correct values if I manually refresh the screen. Now that I have presented my case here's the code:
<p:dataGrid id="vehicleGrid" var="currentVehicle" value="#{vehicleInfoBean.getVehicleList()}" columns="#{vehicleInfoBean.getVehicleList().size()}" styleClass="vehicleInfoPanel" rowIndexVar="rowIdx">
<p:panel header="VEHICLE ##{rowIdx+1}:" style="width:100%" styleClass="textEntryInputTable">
<h:panelGrid columns="1" style="width:100%" styleClass="vehicleInfoPanel">
<ui:include src="../components/vehicleinfo/vehiclecomponents.xhtml">
<ui:param name="currentVehicle" value="#{currentVehicle}" />
<ui:param name="labelOnly" value="false" />
</ui:include>
<div class="deleteButton">
<p:commandButton value="Remove" label="Delete Vehicle" action="#{vehicleInfoBean.deleteVehicle}" update=":vehicleInfoForm:vehicleGrid" process="#this">
<f:setPropertyActionListener value="#{currentVehicle}" target="#{vehicleInfoBean.currentVehicle}" />
</p:commandButton>
</div>
</h:panelGrid>
</p:panel>
</p:dataGrid>
Any ideas? I have tried all sorts of update values including #form, but it's all the same. I haven't used a dataGrid before but I need the iterative capabilities that ice:panelSeries has.
UPDATE: Here's the code in the include:
<h:panelGrid columns="2">
<p:inputText id="vinInput" styleClass="stdFieldControl" value="#{currentVehicle.vin}" label=""
required="true" requiredMessage="VIN is required" >
<p:ajax update="#this vinMsg"/>
</p:inputText>
<p:message id="vinMsg" for="vinInput" errorClass="ui-state-error-text"/>
<p:outputLabel value="-----OR-----"/>
</h:panelGrid>
1/14/2013 - Updated code
<p:dataGrid id="vehicleGrid" var="currentVehicle" value="#{vehicleInfoBean.getVehicleList()}" columns="#{vehicleInfoBean.getVehicleList().size()}" styleClass="vehicleInfoPanel" rowIndexVar="rowIdx">
<p:panel header="VEHICLE ##{rowIdx+1}:" style="width:100%" styleClass="textEntryInputTable">
<h:panelGrid columns="1" style="width:100%" styleClass="vehicleInfoPanel">
<p:inputText id="vinInput" styleClass="stdFieldControl" value="#{currentVehicle.vin}" label="" required="#{empty param['vehicleGrid:0:btnDelete'] and empty param['btnAdd']}" requiredMessage="VIN is required" >
</p:inputText>
<p:message id="vinMsg" for="vinInput" errorClass="ui-state-error-text"/>
<p:outputLabel value="-----OR-----"/>
<h:inputText id="yearInput" styleClass="stdFieldControl" value="#{currentVehicle.year}" label=""
required="#{empty param['vehicleGrid:0:btnDelete']}" requiredMessage="Year is required">
</h:inputText>
<p:message id="yearMsg" for="yearInput"
errorClass="ui-state-error-text"/>
<div class="deleteButton">
<p:commandButton id="btnDelete" value="Remove" label="Delete Vehicle" action="#{vehicleInfoBean.deleteVehicle}" update="#form">
<f:setPropertyActionListener value="#{currentVehicle}" target="#{vehicleInfoBean.currentVehicle}" />
</p:commandButton>
</div>
</h:panelGrid>
</p:panel>
</p:dataGrid>
The add code looks like this:
<div class="addButton" style="padding-left: 2.17%; float: left; clear: both">
<p:commandButton id="btnAdd" value="AddVehicle" label="Add Vehicle" actionListener="#{vehicleInfoBean.addVehicle}" update="vehicleGrid"/>
</div>
Instead of putting the check on the buttons, I decided to set the required attribute of the components referring to the buttons. This code works if I hardcode the iterator index. For example, required="#{empty param['vehicleGrid:0:btnDelete']}". This code points to the first delete button in the panelGrid. What I need is to dynamically derive the index to this - required="#{empty param['vehicleGrid:#{rowIdx}:btnDelete']}". The add button was easy since it doesn't reside in an iterator. How do I code the param in a way that I can dynically refer to the rowId of the panelGrid? The RowId looks confusing but this is coded in a way that each Vehicle Panel is displayed next to the previous panel. The row in this case can be thought of as a column. Anyone have any ideas?
Presently I am conditionaly rendering the Checkbox inside outputPanel,but when i am selecting it,its value is not getting updated in the backing bean.Please help how can I fix this.
Please find the code below:
<p:outputPanel rendered="#{dataBean.dataCleanModel.checkThresholdValueForStdDev(o)}">
<td><h:selectBooleanCheckbox value="#{o.checkBoxToAcceptTheRow}"/></td>
</p:outputPanel>
<p:outputPanel rendered="#{!dataBean.dataCleanModel.checkThresholdValueForStdDev(o)}">
<td><h:selectBooleanCheckbox value="#{o.checkBoxToAcceptTheRow}" /></td>
</p:outputPanel>
As shown changing the checkbox value corresponding setter method is not getting invoked/changed value is not getting set in the bean
use <f:ajax/> if you want the check box to immediately set the value to the server
<h:form>
<p:outputPanel rendered="#{dataBean.dataCleanModel.checkThresholdValueForStdDev(o)}">
<td>
<h:selectBooleanCheckbox value="#{o.checkBoxToAcceptTheRow}">
<f:ajax/>
</h:selectBooleanCheckbox>
</td>
</p:outputPanel>
<p:outputPanel rendered="#{!dataBean.dataCleanModel.checkThresholdValueForStdDev(o)}">
<td>
<h:selectBooleanCheckbox value="#{o.checkBoxToAcceptTheRow}">
<f:ajax/>
</h:selectBooleanCheckbox>
</td>
</p:outputPanel>
</h:form>