JBoss/RichFaces: Action not called if first selectOneMenu in DataTable is empty - jboss

I have a problem with richfaces page on JBoss. The page contains (among other things) a list of projects that are to be closed. Before the project can be closed a reason has to be selected. Not all projects need to be filled out. The ones that are left blank are not closed and remain in the table.
Now the problem: If the first row is left blank (no matter which other rows are filled out), the page reloads but the function specified as action on the command button (adminInformationBean.startClosingProjects()) is never called. If a reason is selected at least for the first row, everything is working fine.
This is the xhtml file:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.org/schema/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
template="/layout/template.xhtml"
xmlns:a4j="http://richfaces.org/a4j">
<ui:define name="body">
<div id="cku1405090004">
<h:form id="uma1407080001">
<div>
<rich:panel styleClass="PanelHeader">
<f:facet name="header">
#{messages.adminInfo_table_header}
</f:facet>
<rich:tabPanel id="myTabPanelAdminInfo" styleClass="PanelHeader">
[...]
<!-- closed Projects -->
<rich:tab id="closedProjects">
<f:facet name="header">#{messages.adminInfo_table_type_close}
<h:outputText value="#{adminInformationBean.closedProjectsSize}"/>
</f:facet>
<div class="actionButtons">
<div class="ViewButtonLeft" />
<h:commandButton id="cku1405090011" styleClass="ViewSubmitButtonBody" value="#{messages['adminInfo_table_button_check']}" action="#{adminInformationBean.startClosingProjects()}" onclick="doPostBack();"/>
<div class="ViewButtonRight" />
</div>
<rich:dataTable id="closedProjectsTableId" styleClass="rich-datatable" value="#{adminInformationBean.infoListClosedProjects}" var="adminInfo" iterationStatusVar="iterator" rows="#{adminInformationBean.selectedItem}" rowKeyVar="row" rowClasses="ViewOddLine, ViewEvenLine">
<f:facet name="noData">#{messages.team_table_filter_message}</f:facet>
<f:facet name="header">
<rich:columnGroup>
<rich:column>
<span>
<h:outputText value="#{messages.adminInfo_table_header_projectName} " />
</span>
</rich:column>
<rich:column>
<span>
<h:outputText value="#{messages.adminInfo_table_header_reason}" />
</span>
</rich:column>
</rich:columnGroup>
</f:facet>
<rich:column filterValue="#{filterBean.projectNameFilter}" filterExpression="#{fn:containsIgnoreCase(adminInfo.projectName, filterBean.projectNameFilter)}">
<f:facet name="header">
<h:panelGroup>
<h:inputText id="projectNameClose" value="#{filterBean.projectNameFilter}">
<a4j:ajax render="closedProjectsTableId#body, tgrid2Id4#body" execute="#this" event="keyup" />
</h:inputText>
</h:panelGroup>
</f:facet>
<span>
<h:outputText value="#{adminInfo.projectName}" rendered="#{adminInfo.projectName != null}"/>
</span>
</rich:column>
<rich:column>
<div align="center">
<h:selectOneMenu class="selectReason" value="#{adminInfo.reason}">
<s:selectItems value="#{adminInformationBean.possibleReasons}" var="reason" label="#{reason.name}" itemValue="#{reason.id}" noSelectionLabel="" />
</h:selectOneMenu>
</div>
</rich:column>
</rich:dataTable>
<h:panelGrid id="tgrid2Id4" columns="3">
#{messages.team_table_rows_selectonemenu}
<h:selectOneMenu value="#{adminInformationBean.selectedItem}" onchange="submit()" valueChangeListener="#{adminInformationBean.pageSizeValueChanged}">
<f:selectItems value="#{adminInformationBean.selectItemsMap}"/>
</h:selectOneMenu>
<rich:dataScroller for="closedProjectsTableId" page="#{adminInformationBean.page}" maxPages="" fastControls="hide">
<f:facet name="first">
<h:outputText value="<<"/>
</f:facet>
<f:facet name="previous">
<h:outputText value="<"/>
</f:facet>
<f:facet name="next">
<h:outputText value=">"/>
</f:facet>
<f:facet name="last">
<h:outputText value=">>"/>
</f:facet>
</rich:dataScroller>
</h:panelGrid>
<div class="actionButtons" style="padding-bottom: 20px">
<div>
<div class="ViewButtonLeft" />
<h:commandButton id="cku1405090012" styleClass="ViewSubmitButtonBody" value="#{messages['adminInfo_table_button_check']}" action="#{adminInformationBean.startClosingProjects()}" onclick="doPostBack();"/>
<div class="ViewButtonRight" />
</div>
</div>
</rich:tab>
[...]
</rich:tabPanel>
</rich:panel>
</div>
</h:form>
</div>
</ui:define>
</ui:composition>

Related

update a form from a component of another page jsf

i have a xhtml page which sets the values of my datatable which is in another page and i want to update the datatable when i set a new object which occurs when i click in a commandbutton.
heres my page that sets value: fichas_horas.xhtml
<h:body>
<f:view>
<h:form id = "formulario">
<h1>Medicos</h1>
<p:messages id="messages" showDetail="true" autoUpdate="true" closable="true" />
<p:dataTable id= "tabla" value="#{fichaBean.horas}" var="Grupo_horario" border="1" >
<p:column>
<f:facet name="header">
Hora
</f:facet>
#{fichaBean.Nombrehora(Grupo_horario)}
</p:column>
<p:column>
<f:facet name="header">
Disponibles
</f:facet>
#{fichaBean.disponibles(Grupo_horario.codigo)}
</p:column>
<p:column>
<f:facet name="header">Seleccionar</f:facet>
<p:commandButton id="bespecialidad" action="tipo_ficha" disabled="#{(fichaBean.bloquear(fichaBean.disponibles(Grupo_horario.codigo)))}" value ="seleccionar" >
<f:actionListener binding="#{fichaBean.guardar_ficha(Grupo_horario.codigo)}" />
<f:actionListener binding="#{fichaBean.cargarcolacaja()}" update=":formcolacajas" />
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
</f:view>
</h:body>
and this one is the datatable that i want to update: lista_espera_caja.xhtml
<h:body>
<f:view>
<h:form id = "formcolacajas">
<h1>Lista de espera a caja</h1>
<p:messages id="messages" showDetail="true" autoUpdate="true" closable="true" />
#{fichaBean.cargarcolacaja()}
<p:dataTable id= "tabla" value="#{fichaBean.colacaja}" var="Ficha" border="1">
<p:column>
<f:facet name="header">
Turno
</f:facet>
#{fichaBean.nombreturno(Ficha)}
</p:column>
</p:dataTable>
</h:form>
</f:view>
</h:body>
i tried to put an update=":formcolacajas" in my button but it does nothing.

JSF Updating forms

I am trying to submit some data in JSF. The problem is that I have two forms and the button which I want to trigger the update is outside of the forms, here I place my code so that you can understand better what I mean. Because of that I cannot submit any data to the server.
<ui:define name="mainArea">
<h:form id="form">
<div class="row">
<div class="col-md-5">
<p:outputLabel for="rfqName" value="Name" />
<br></br>
<p:inputText id="rfqName" required="true" style="width:100%;"
value="#{data.data.rfqName}" maxlength="100">
<p:ajax event="change" update="#form"/>
</p:inputText>
</div>
</div>
<div class="row">
<div class="col-md-3">
<p:outputLabel for="rfqVersion" value="Version" />
<br></br>
<p:inputText id="rfqVersion" required="true" style="width:60%;"
value="#{data.data.rfqVersion}" maxlength="20"></p:inputText>
</div>
</div>
</h:form>
</ui:define>
<ui:define name="actionSection">
<p:commandButton actionListener="#{logic.close}" value="Proceed" update=":form"
styleClass="pull-right">
</p:commandButton>
<p:commandButton value="Save" styleClass="pull-right" />
</ui:define>
You can use the primefaces RemoteCommand. This allows you to click the button on the form from the outside.
<ui:define name="mainArea">
<h:form id="form">
<div class="row">
<div class="col-md-5">
<p:outputLabel for="rfqName" value="Name" />
<br></br>
<p:inputText id="rfqName" required="true" style="width:100%;"
value="#{data.data.rfqName}" maxlength="100">
<p:ajax event="change" update="#form" />
</p:inputText>
</div>
</div>
<div class="row">
<div class="col-md-3">
<p:outputLabel for="rfqVersion" value="Version" />
<br></br>
<p:inputText id="rfqVersion" required="true" style="width:60%;"
value="#{data.data.rfqVersion}" maxlength="20"></p:inputText>
</div>
</div>
<p:remoteCommand name="remoteClose" actionListener="#{logic.close}"
update=":form" styleClass="pull-right" />
<p:remoteCommand name="remoteSave" value="Save"
styleClass="pull-right" />
</h:form>
</ui:define>
<ui:define name="actionSection">
<p:commandButton type="button" onclick="remoteClose()" value="Proceed" />
<p:commandButton type="button" onclick="remoteSave()" value="Save"
styleClass="pull-right" />
</ui:define>

checkbox selection datatable jsf2 primefaces

I use the datatable with checkbox selection feature, but when I click on footer button after selecting some rows, thoses rows don't be affected to my object selectedCommandes[], and the proof is that I added a row in the method that show me the lenght of selectedCommandes[] but it return 0, I don't know why,
I think all my codes are good
here is the datatable :
<p:dataTable id="cars" var="car" value="#{commandesUserController.mediumCommandesModel}" selection="#{commandesUserController.selectedCommandes}" tableStyle="width:auto">
<f:facet name="header">
Checkbox Based Selection
</f:facet>
<p:column selectionMode="multiple" style="width:18px" />
<p:column headerText="Model" style="width:100px">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Year" style="width:100px">
<h:outputText value="#{car.dateEnvoi}" />
</p:column>
<p:column headerText="Manufacturer" style="width:100px">
<h:outputText value="#{car.dateLivraisonRecommande}" />
</p:column>
<p:column>
<p:commandLink ajax="false" value="Editer" action="updateUser_v1" >
<f:setPropertyActionListener value="#{car}" target="#{editUserController.u1}" />
</p:commandLink>
</p:column>
<p:column>
<p:commandLink value="Supprimer" oncomplete="confirmation.show()" >
<f:setPropertyActionListener value="#{car}" target="#{commandesUserController.selectedCommande}" />
</p:commandLink>
</p:column>
<p:column style="width:40px">
<p:commandButton id="selectButton" update=":myform:carDlg" oncomplete="carDialog.show()" icon="ui-icon-search" title="View">
<f:setPropertyActionListener value="#{car}" target="#{commandesUserController.selectedCommande}" />
</p:commandButton>
</p:column>
<f:facet name="footer">
<p:commandButton id="supprion" value="supprimer selection" oncomplete="confirmation2.show()" />
</f:facet>
</p:dataTable>
and here is the button where there is the problem :
<f:facet name="footer">
<p:commandButton id="supprion" value="supprimer selection" oncomplete="confirmation2.show()" />
</f:facet>
and here is the dialog that appears when I click in the button above :
<p:confirmDialog id="confirmDialog2" message="etes vous sur de vouloir supprimer ces commande avec tous les données et fichiers correspondants !"
header="confirmation de suppression" severity="alert" widgetVar="confirmation2">
<p:commandButton id="confirm2" value="oui" update="cars" oncomplete="confirmation2.hide()"
action="#{commandesUserController.deleteCommandes()}" />
<p:commandButton id="decline2" value="non" onclick="confirmation2.hide()" type="button" />
</p:confirmDialog>
and here is the method in the managedBean :
public String deleteCommandes(){
System.out.println("je suis dans delete l ensemble avec tous = "+selectedCommandes.length);
for(int j = 0;j<selectedCommandes.length;j++){
selectedCommandes[j].setListFichiers(uh.getFichiersById(this.selectedCommandes[j].getId()));
for(int i = 0; i<selectedCommandes[j].getListFichiers().size();i++){
//System.out.println("alors "+selectedCommande.getListFichiers().get(i).getId());
uh.deleteFichier(selectedCommandes[j].getListFichiers().get(i));
}
uh.deleteCommande(selectedCommandes[j]);
}
return "commandesUser";
}
this line : System.out.println("je suis dans delete l ensemble avec tous = "+selectedCommandes.length); always return 0
I already created the class that implement SelectableDataModel
I hope I explained the problem
do you have any idea
thank you
Is there a h:form placed around the p:dataTable? If this is not the case this is probably the cause of your problem.
On PrimeFaces' showcase page the structure looks like this:
<h:form>
<p:dataTable>
<!-- content of data table -->
</p:dataTable>
<p:confirmDialog>
<!-- content of dialog -->
</p:confirmDialog>
</h:form>
Putting the p:dataTable and the p:confirmDialog in a separate form should work too I guess:
<h:form>
<p:dataTable>
<!-- content of data table -->
</p:dataTable>
</h:form>
<h:form>
<p:confirmDialog>
<!-- content of dialog -->
</p:confirmDialog>
</h:form>
You can set a breakpoint on the setter of selectedCommandes to check is this is called. (Don't worry is the setter is called multiple times, this is normal.)
as you told me, I tested with two form and in a separate page:
here is the new xhtml page :
<?xml version='1.0' encoding='UTF-8' ?>
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<body>
<ui:composition template="./template_utilisateur.xhtml">
<ui:define name="tohead">
</ui:define>
<ui:define name="content">
Bienvenue #{userController.u1.nom} #{userController.u1.prenom}
<br></br><br></br><br></br>
<h:form id="form">
<p:dataTable id="cars" var="car" value="#{acceuilUserController.lc_maj}" tableStyle="width:auto" rowStyleClass="#{(car.lu == false) ? 'red' : null}" >
<p:column headerText="Commande N° : " style="width:100px">
<h:outputText value="#{car.commande.id}" />
</p:column>
<p:column headerText="Date de mise à jour : " style="width:100px">
<h:outputText value="#{car.dateMaj}" />
</p:column>
<p:column headerText="Decision : " style="width:100px">
<h:outputText value="#{car.decison}" />
</p:column>
<p:column headerText="Etat : " style="width:100px">
<h:outputText value="#{car.etat}" />
</p:column>
<p:column style="width:40px">
<p:commandButton id="selectButton" update=":form:carDlg" oncomplete="carDialog.show()" icon="ui-icon-search" title="plus de détails">
<f:setPropertyActionListener value="#{car}" target="#{acceuilUserController.selectedMajCommande}" />
</p:commandButton>
</p:column>
</p:dataTable>
<p:dialog header="Commande editée le #{acceuilUserController.selectedMajCommande.dateMaj} par l'#{acceuilUserController.selectedMajCommande.utilisateur.type} #{acceuilUserController.selectedMajCommande.utilisateur.nom} #{acceuilUserController.selectedMajCommande.utilisateur.prenom}" widgetVar="carDialog" resizable="false" id="carDlg"
showEffect="fade" hideEffect="explode" modal="true">
<f:ajax event="close" execute="#this" render="cars" listener="#{acceuilUserController.refreshDatatable()}"/>
<table id="gradient-style" >
<tr style="border: hidden;">
<th>
<h:outputLabel value="Model:" />
</th>
<td>
<h:outputLabel style="font-weight: bold;" value="#{acceuilUserController.selectedMajCommande.commande.id}" />
</td>
</tr>
<tr style="border: hidden;">
<th>
<h:outputLabel value="Year:" />
</th>
<td>
<h:outputLabel style="font-weight: bold;" value="#{acceuilUserController.selectedMajCommande.commande.etat}" />
</td>
</tr>
<tr style="border: hidden;">
<th>
<h:outputLabel value="Manufacturer:" />
</th>
<td>
<h:outputLabel style="font-weight: bold;" value="#{acceuilUserController.selectedMajCommande.commande.dateEnvoi}" />
</td>
</tr>
<tr style="border: hidden;">
<th>
<h:outputLabel value="Color:" />
</th>
<td>
<h:outputLabel style="font-weight: bold;" value="#{acceuilUserController.selectedMajCommande.commande.dateLivraisonRecommande}" />
</td>
</tr>
</table>
<table id="gradient-style" >
<th>Nom Fichier</th><th>Taille</th><th>Télécharger</th>
<ui:repeat value="#{acceuilUserController.selectedMajCommande.commande.listFichiers}" var="jjjjj">
<tr>
<td>
<h:outputLabel style="font-weight: bold;" value="#{jjjjj.nom}" />
</td>
<td>
<h:outputLabel style="font-weight: bold;" value="#{jjjjj.taille}" />
</td>
<td>
<h:commandLink value="Télécharger">
<p:fileDownload value="#{jjjjj.convertFichier}" />
</h:commandLink>
</td>
</tr>
</ui:repeat>
</table>
</p:dialog>
</h:form>
</ui:define>
</ui:composition>
</body>
</html>
and here is the set method from selectedCommandes :
public void setSelectedCommandes(Commande[] selectedCommandes) {
System.out.println("je suis la dans son set tous : :"+selectedCommandes.length);
this.selectedCommandes = selectedCommandes;
}
I noticed that when I check one line the method above doesn't be run, it run only once when I click on :
<f:facet name="footer">
<p:commandButton id="supprion" value="supprimer selection" update=":form2:displayMulti" oncomplete="confirmation2.show()" />
</f:facet>
in footer to datatable, and it is written :
Infos: je suis la dans son set tous : :0
do you have any idea, thanks
add
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":form:messages" />
under
<p:datatTable>

render a form from another form in a layoutUnit, not work, primefaces

I'm using primefaces 3.2, Mojarra JSF 2.1.3-FCS
Perform a basic example to prove that you can render a form from another form
<h:form id="one" rendered="#{test.enable}">
<p:panelGrid id="panelGrid" style="margin-top:10px">
<f:facet name="header">
<p:row>
<p:column colspan="2" style="font-size: 12px !important;
font-weight: bold;">data</p:column>
</p:row>
</f:facet>
</p:panelGrid>
</h:form>
<h:form id="two">
<p:commandButton value="change" update=":one" actionListener="#{test.see}"></p:commandButton>
</h:form>
After basic example, I try to do with primefaces, using the same idea in p: layoutUnit
<p:layout fullPage="true">
<p:layoutUnit position="north" size="100" id="top">
</p:layoutUnit>
<p:layoutUnit position="west" size="200" id="left">
<h:form id="nom">
<h:outputLabel id="nombre2" value="#{home.num}">
</h:outputLabel>
</h:form>
<h:form>
<p:commandButton value="cambia" update=":nom"
actionListener="#{home.ver}"></p:commandButton>
</h:form>
</p:layoutUnit>
<p:layoutUnit position="center">
</p:layoutUnit>
<p:layoutUnit size="50" position="south" id="bottom">
</p:layoutUnit>
</p:layout>
But not work... Any Idea

How to define form action in JSF?

In order to replace the default Spring security login form I came up with this solution:
<form name="f" action="../j_spring_security_check" method="POST" >
<h:panelGrid columns="2">
<h:outputText value="Username" />
<h:inputText id="j_username" />
<h:outputText value="Password" />
<h:inputText id="j_password" />
</h:panelGrid>
<h:commandButton value="Login" />
</form>
But instead of plain <form> tag I would like to use <h:form> since Primefaces components only work within <h:form>. Using <h:form> the form action will be set automatically by JSF to the current page, not to the value set by me in the example above. Where to I have to code the action "../j_spring_security_check" now? I tried putting it into the <h:commandButton> as follows but that doesn't work:
<h:form name="f">
<h:panelGrid columns="2">
<h:outputText value="Username" />
<h:inputText id="j_username" />
<h:outputText value="Password" />
<h:inputText id="j_password" />
</h:panelGrid>
<h:commandButton value="Click here" action="../j_spring_security_check" />
</form>
It leads to the error message Unable to find matching navigation case with from-view-id '/login.xhtml' for action '../j_spring_security_check' with outcome '../j_spring_security_check'.
Is it the only way to define a navigation case in faces-config.xml? I want to avoid using a bean for this simple use case.
The best solution for me is to use the default <button> tag instead. Since typical button styling is not being applied (in my case I am using Primefaces), I set it manually. Here's the whole result:
<h:outputStylesheet library="primefaces" name="jquery/ui/jquery-ui.css" />
<h:outputStylesheet library="css" name="login.css" />
<div class="message">
<c:if test="#{param.error == 1 and SPRING_SECURITY_LAST_EXCEPTION != null}">
<span class="error">#{SPRING_SECURITY_LAST_EXCEPTION.message}</span>
</c:if>
</div>
<div class="login">
<form action="../j_spring_security_check" method="post">
<h:panelGrid columns="2">
<h:outputText value="Username" />
<h:inputText id="j_username" />
<h:outputText value="Password" />
<h:inputSecret id="j_password" />
</h:panelGrid>
<div class="submit">
<button type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
<span class="ui-button-text">Login</span>
</button>
</div>
</form>
</div>
<h:form id="login" prependId="false" onsubmit="document.getElementById('login').action='j_security_check';">
Your action attribute should be an EL expression like follows:
action="#{managedBean.method}"
Your best chance is to use the onclick property of the button. This is an example with a primefaces commandButton, but it will also work for jsf components because it uses the (native) javascript onclick function.
<h:form>
<p:commandButton value="Submit" onclick="alert('JS!')" actionListener="#{tweetBean.addTweet()}" update=":tabView,:trends,:tweetsnr" />
</h:form>