JSF Conditionally render errors in a row - jsf

I would like to render the errors in a separate row of this table. However, the binding doesn't work when I use the ui:repeat as it sets all rows to the same value.
<ui:repeat id="quest" value="#{questions}" var="question">
<tr>
<td class="col-md-2">
<p:selectOneRadio id="questionId" value="#{question.response}" binding="#{questionBinding}" validator="#{question.validate}" required="true" requiredMessage="You must answer the question to continue">
<f:selectItem itemLabel="Yes" itemValue="Yes" />
<f:selectItem itemLabel="No" itemValue="No" />
<p:ajax update="error-row" />
</p:selectOneRadio>
</td>
</tr>
<h:panelGroup id="error-row">
<ui:fragment rendered="#{not empty facesContext.getMessageList(questionBinding.clientId)}">
<tr>
<td colspan="2"><p:message for="questionId" id="msgQuestion" /></td>
</tr>
</ui:fragment>
</h:panelGroup>
</ui:repeat>

Call javascript on ajax update:
....
<p:ajax update="msgQuestion" oncomplete="clearEmptyRows()" />
....
Using javascript function:
<script>
function clearEmptyRows() {
$(".error-row").each(function(index) {
if ($(this).text().trim() == '') {
$(this).css("display", "none");
} else {
$(this).css("display", "table-row");
}
});
}
$(document).ready(function() {
clearEmptyRows();
});
</script>

Related

How to pass a parameter to get values for f:selectItem inside p:selectOneMenu

I want to pass a parameter to get values for f:selectItem inside p:selectOneMenu. (I used this p:selectOneMenu inside a ui:repeat)
The values that will populate the select one menu needs to be changed depending on the parameter passed to the bean.
I tried as follows, but erros comes as "The class does not have the property
'proceduresPerformedInAProcedureRoom'.
How can I achieve that ?
JSF File
<table >
<tr>
<td>
<p:outputLabel value="Room" ></p:outputLabel>
</td>
<td>
<p:selectOneMenu value="#{ii.ci.institutionValue}" >
<f:selectItem itemLabel="Please select" ></f:selectItem>
<f:selectItems value="#{webUserController.loggableProcedureRooms}"
var="ipr"
itemLabel="#{ipr.name}"
itemValue="#{ipr}">
</f:selectItems>
<f:ajax event="change" execute="#this" render="prM lblPrM" ></f:ajax>
</p:selectOneMenu>
</td>
</tr>
<tr>
<td>
<p:outputLabel id="lblPrM" value="Procedures for #{ii.ci.institutionValue}" ></p:outputLabel>
</td>
<td>
<p:selectOneMenu id="prM" value="#{ii.addingItem.ci.itemValue}" >
<f:selectItem itemLabel="Please select" ></f:selectItem>
<f:selectItems value="#{relationshipController.proceduresPerformedInAProcedureRoom}"
var="li"
itemLabel="#{li.displayName}"
itemValue="#{li}">
<f:param name = "procedureRoom" value = "#{ii.ci.institutionValue}" />
</f:selectItems>
</p:selectOneMenu>
</td>
</tr>
</table>
Controller
public List<Item> proceduresPerformedInAProcedureRoom(Institution procedureRoom){
List<Relationship> rs = findRelationships(institution, RelationshipType.Procedure_for_institution);
List<Item> ps = new ArrayList();
for(Relationship r:rs){
ps.add(r.getItem());
}
return ps;
}

Primefaces custom selectOneRadio, doesn't propagate to backing bean

I'm currently having a problem with the <p:radioButton> and <p:selectOneRadio>. I'm trying to make a form with three radio buttons with some boxes next to them, this works and the "radio-mechanism" in the buttons work so that only one can be selected at once. However the selected radio button is not propagated to the backend. I've tried putting a <p:ajax> in the <p:selectOneRadio> to make it trigger some sort of call to the backing bean but with no success. I have looked at the following primefaces example: http://www.primefaces.org/showcase/ui/selectOneRadio.jsf
Can someone point me in the right direction to solve this problem?
<p:selectOneRadio id="customRadio" layout="custom" value="advancedSettingsBean.radioValue">
<f:selectItem itemValue="1" />
<f:selectItem itemValue="2" />
<f:selectItem itemValue="3" />
<p:ajax />
</p:selectOneRadio>
<tr>
<td valign="top">
<p:radioButton id="CheckboxValidTimeCurrent" for="customRadio" itemIndex="0">
</p:radioButton>
</td>
<td colspan="2">
<h:outputText value="#{messages.search_advanced_validtimecurren}" />
<br />
</td>
</tr>
<tr>
<td valign="top">
<p:radioButton id="CheckboxvValidTimeDate" for="customRadio" itemIndex="1">
</p:radioButton>
</td>
<td colspan="2">
<h:outputText value="#{messages.search_advanced_validtimedate}" />
<br />
<p:calendar id="singledate" value="#{advancedSettingsBean.singleSearchDate}"
datePattern="yyyy-MM-dd" direction="smart" jointPoint="auto"
inputStyle="width:80px" style="width: 200px">
<f:convertDateTime pattern="yyyy-MM-dd" timeZone="UTC" />
</p:calendar> Z
<br />
<p:message showSummary="true" showDetail="false"
id="singledateError" for="singledate" />
<br />
</td>
</tr>
<tr>
<td valign="top">
<p:radioButton id="CheckboxvValidTimeSpan" for="customRadio" itemIndex="2">
</p:radioButton>
</td>
...
You should put the value of selectoneradio in a el expression:
value="#{advancedSettingsBean.radioValue}"

selectBooleanCheckBox does not work seperatly in p:dialog

I have button that when I click on it, the dialog appear and in that dialog , I have p:selectBooleanCheckBox and h:outputlable.
The first problem is when p:dialog appear I can not choose p:selectBooleanCheckBox separately. It means that when I click on one of them, all of p:selectBooleanCheckBox choose.
The second problem is when I click on p:commandButton in dialog , the actionListener work but it dos not disappaer and it shows permanently. I think the problem cause by Ajax. could you please tell me how can I fix this problem?
<h:panelGrid>
<p:dialog appendToBody="true" header="Selected Values" modal="false" showEffect="fade" hideEffect="fade" widgetVar="dlg">
<h:panelGrid columns="1" id="display">
<p:dataGrid id="AcceptDataGrid" var="tBusinessPartnerRequestInfo" value="#{inviteRequestManagedBean.filterBusinessRequest()}"
columns="1" >
<tr>
<td>
<p:selectBooleanCheckbox/>
</td>
<td>
<h:outputLabel value="test"/>
</td>
</tr>
</p:dataGrid>
<p:commandButton id="acceptCommonButton" value="#{inviteRequest_msg.accept}"
actionListener="#{inviteRequestManagedBean.acceptRequest(tBusinessPartnerRequestInfo.id)}"
update="display" />
</h:panelGrid>
</p:dialog>
</h:panelGrid>
<table style="width: 100%" id="tabell">
<p:selectOneButton value="#{inviteRequestManagedBean.filterType}">
<f:selectItem itemLabel="#{inviteRequest_msg.request}" itemValue="request" />
<f:selectItem itemLabel="#{inviteRequest_msg.archive}" itemValue="archive" />
<f:ajax event="change" execute="#form" render="#form" />
<tr>
<td>
<p:panel></p:panel>
<p:dataGrid id="requestDataGrid" var="tBusinessPartnerRequestInfo"
value="#{inviteRequestManagedBean.filterBusinessRequest()}" columns="1" >
<p:column>
<div>
<table border="0" width="100%">
<tr>
<td>
<p:graphicImage value="#{tBusinessPartnerRequestInfo.partySender_imageUrl}"/>
</td>
<td>
<div>
<table border="0" width="100%">
<tr>
<td>
<h:outputLabel value="#{tBusinessPartnerRequestInfo.requestDate}"/>
</td>
</tr>
<tr>
<td>
<h:outputLabel value="#{tBusinessPartnerRequestInfo.partySender_fullName}"/>
</td>
</tr>
</table>
</div>
</td>
here is where p:dialog call
<td>
<p:commandButton id="acceptCommonButton" value="#{inviteRequest_msg.accept}"
onclick="dlg.show()" />
</td>
<td>
<p:commandButton id="noNowCommonButton" value="#{inviteRequest_msg.notnow}"
actionListener="#{inviteRequestManagedBean.notNowRequest(tBusinessPartnerRequestInfo.id)}"
update="#form" />
</td>
<p:blockUI block="acceptCommonButton" trigger="acceptCommonButton"/>
<p:blockUI block="noNowCommonButton" trigger="acceptCommonButton"/>
<p:blockUI block="acceptCommonButton" trigger="noNowCommonButton"/>
<p:blockUI block="noNowCommonButton" trigger="noNowCommonButton"/>
<td>
<p:panel>
<p:ajaxStatus>
<f:facet name="start">
<p:graphicImage value="../resources/img/loading.gif"/>
</f:facet>
<f:facet name="complete">
<h:outputLabel value=""/>
</f:facet>
</p:ajaxStatus>
</p:panel>
</td>
</tr>
</table>
</div>
<hr/>
</p:column>
</p:dataGrid>
</td>
</tr>
</p:selectOneButton>
</table>
</h:panelGrid>
<h:panelGrid>
<p:dialog appendToBody="true" header="Selected Values" modal="false" showEffect="fade" hideEffect="fade" widgetVar="dlg">
<h:panelGrid columns="1" id="display">
<p:dataGrid id="AcceptDataGrid" var="tBusinessPartnerRequestInfo" value="#{inviteRequestManagedBean.loadPartyRelationShipType()}"
columns="1" >
<tr>
<td>
<p:selectBooleanCheckbox/>
</td>
<td>
<h:outputLabel value="test"/>
</td>
</tr>
</p:dataGrid>
<p:commandButton id="acceptCommonButton" value="#{inviteRequest_msg.accept}"
actionListener="#{inviteRequestManagedBean.acceptRequest(tBusinessPartnerRequestInfo.id)}"
update="display" oncomplete="dlg.hide()" />
</h:panelGrid>
</p:dialog>
</h:panelGrid>
</ui:composition>
Your markup is a bit scary, I don't get why you've got so much thing in your <p:selectOneButton (all the <tr>'s) so instead of trying to correct everything as I start to understand what you try to achieve I'll give you a working example.
Sample.java
public class Sample implements Serializable {
private String name;
private boolean checked;
public Sample() {
}
public Sample(String name, boolean checked) {
this.name = name;
this.checked = checked;
}
// Getter and Setter for name and checked omitted
}
SampleBean.java
#ManagedBean
#ViewScoped
public class SampleBean implements Serializable {
private List<Sample> samples;
private Sample currentSample;
public void prepareEdit(Sample sample) {
this.currentSample = sample;
}
public void edit() {
// Do what you need to do with sample
// You can get it with : this.currentSample
RequestContext.getCurrentInstance().execute("dlg.hide()");
}
public List<Sample> getSamples() {
if (this.samples == null) {
this.samples = new ArrayList<Sample>();
for (int i = 1; i <= 10; ++i) {
this.samples.add(new Sample("Sample n°" + i, (i % 3 == 0)));
}
}
return samples;
}
public void setSamples(List<Sample> samples) {
this.samples = samples;
}
public Sample getCurrentSample() {
return currentSample;
}
public void setCurrentSample(Sample currentSample) {
this.currentSample = currentSample;
}
}
view.xhtml :
<h:form id="myForm">
<p:dataTable value="#{sampleBean.samples}" var="sample">
<p:column headerText="Name">
<h:outputText value="#{sample.name}" />
</p:column>
<p:column headerText="Checked?">
<h:outputText value="#{sample.checked}" />
</p:column>
<p:column style="width: 1px; text-align: center;">
<p:commandButton value="edit"
actionListener="#{sampleBean.prepareEdit(sample)}"
update=":dialog"
oncomplete="dlg.show()" />
</p:column>
</p:dataTable>
</h:form>
<p:dialog id="dialog" widgetVar="dlg" header="Editing">
<h:form rendered="#{!empty sampleBean.currentSample}">
<h:outputText value="Current sample is #{sampleBean.currentSample.name}" />
<br />
<p:selectBooleanCheckbox value="#{sampleBean.currentSample.checked}" />
<br />
<p style="width: 100%; text-align: center;">
<p:commandButton actionListener="#{sampleBean.edit()}"
value="Edit"
update="#form :myForm" />
</p>
</h:form>
</p:dialog>
As you can see I'm storing a currentSample (sampleBean must be #ViewScoped) which helps me to render a custom dialog with the correct current information.
My last comment from your question about the binding of the <p:selectBooleanCheckbox is important because you can get a custom checkbox value only if it's bound to a different endpoint based on the context (here currentSample).
Don't hesitate to comment if something is unclear for you!

How to display input field on mouseover

I have this JSF table which I use to display data and to edit data:
<table>
<ui:repeat var="ud" value="#{DCProfileTabGeneralController.dcData}">
<tr>
<td>Datacenter Type</td>
<td>
<h:outputText value="#{ud.type}"
rendered="#{not DCProfileTabGeneralController.editable}" />
<h:inputText value="#{ud.type}" rendered="#{DCProfileTabGeneralController.editable}" />
</td>
</tr>
<tr>
<td>Date Added</td>
<td>
<h:outputText value="#{ud.dateAdded}"
rendered="#{not DCProfileTabGeneralController.editable}" />
<h:inputText styleClass="datepicker" value="#{ud.dateAdded}" rendered="#{DCProfileTabGeneralController.editable}" />
</td>
</tr>
<tr>
<td>Hour Added</td>
<td>
<h:outputText value="#{ud.hourAdded}"
rendered="#{not DCProfileTabGeneralController.editable}" />
<h:inputText value="#{ud.hourAdded}" rendered="#{DCProfileTabGeneralController.editable}" />
</td>
</tr>
<tr>
<td>Date Deployed</td>
<td>
<h:outputText value="#{ud.dateDeployed}"
rendered="#{not DCProfileTabGeneralController.editable}" />
<h:inputText styleClass="datepicker" value="#{ud.dateDeployed}" rendered="#{DCProfileTabGeneralController.editable}" />
</td>
</tr>
<tr>
<td>Hour Deployed</td>
<td>
<h:outputText value="#{ud.hourDeployed}"
rendered="#{not DCProfileTabGeneralController.editable}" />
<h:inputText value="#{ud.hourDeployed}" rendered="#{DCProfileTabGeneralController.editable}" />
</td>
</tr>
</ui:repeat>
</table>
This solution works fine but I want to extend it this way: I want to click on button which sets the edit flag to true. When I move the mouse over the value of the table the outputText to change to inputText.
And one more simple question. How I can add bottom padding to all fields globally?
I suggest you to use Richfaces library and use <rich:inplaceInput> component as below.
<rich:inplaceInput value="hhhh" editEvent="onmouseover"/>
However if you still like to stick to javascript this is a concept.
<h:form id="myForm">
<h:outputText value="aaa" id="outText"/><br/>
<h:inputText value="aaa" style="display:none;" id="inText" />
</h:form>
This is the javascript code
<script>
window.onload = function() {
var outputText = document.getElementById("myForm:outText");
var inputText = document.getElementById("myForm:inText");
outputText.onmouseover = function() {
outputText.style.display = 'none';
inputText.style.display = '';
}
inputText.onblur = function() {
outputText.style.display = '';
inputText.style.display = 'none';
}
};
</script>
Since you are using a ui:repeat, you should change the javascript code accordingly.

JSF component closing-off table cell

I'm trying to nest a table inside a h:panelGrid component, and h:selectOneMenu is screwing-up the formatting by closing off the cell it appears within and creating a new (and unwanted) row.
My code looks something like this:
<h:panelGrid columns="2">
[Other rows that work just fine]
<h:outputText value="Match [Stuff] to [More Stuff]:" />
<table>
<tr>
<th>[Stuff]</th>
<th>[More Stuff]</th>
</tr>
<tr>
<td>
<h:outputText value="Manually Created First Element of Stuff" />
</td>
<td>
<h:selectOneMenu value="#{bean.moreStuffSetting}">
<f:selectItem itemLabel="--None--" itemValue="" />
<f:selectItem itemLabel="Manual First Choice" itemValue="manual" />
<f:selectItems
value="#{bean.listOfMoreStuff}"
var="moreStuff"
itemLabel="#{moreStuff.name}"
itemValue="#{moreStuff.value}" />
</h:selectOneMenu>
</td>
</tr>
<ui:repeat value="#{bean.listOfStuff}" var="stuff">
<tr>
<td>
<h:outputText value="#{stuff.name}" />
</td>
<td>
<h:selectOneMenu value="#{bean.moreStuffSetting}">
<f:selectItem itemLabel="--None--" itemValue="" />
<f:selectItem itemLabel="Manual First Choice" itemValue="manual" />
<f:selectItems
value="#{bean.listOfMoreStuff}"
var="moreStuff"
itemLabel="#{moreStuff.name}"
itemValue="#{moreStuff.value}" />
</h:selectOneMenu>
</td>
</tr>
</ui:repeat>
</table>
</h:panelGrid>
The problem occurs with that first h:selectOneMenu element. (The h:selectOneMenu element inside ui:repeat is doing exactly what I expect it to, however.) I'm expecting "Manually Created First Element of Stuff" and that drop-down to appear as two cells in the same row. However, this is what's showing up in the generated HTML:
<tr>
<td>Manually Created First Element of Stuff</td>
<td>
</td>
<td></td>
</tr>
<tr>
<td><select...
Two rows. However, in the nested one below, I get this:
<tr>
<td>[Label I'm expecting]
</td>
<td><select...
... which is exactly how I expected it to behave.
What am I doing wrong? Am I misusing JSF somehow? Is there some face-palm-worthy typo in there I'm not seeing?
The <h:panelGrid> picks the first sibling in the JSF component tree to start a new table cell. The plain HTML <table> element which you've there isn't a JSF component.
Wrap it in a <h:panelGroup>.
<h:panelGrid columns="2">
<h:outputText value="Match [Stuff] to [More Stuff]:" />
<h:panelGroup>
<table>
...
</table>
</h:panelGroup>
</h:panelGrid>
An alternative is to just use <h:dataTable> instead.

Resources