Here is the dialog code
<title><ui:insert name="title">#{msg['trip.bus.unsaved.warning']}</ui:insert></title>
<h:outputStylesheet library="css" name="theme.css" />
</h:head>
<h:body>
<ui:composition>
<h:form id="unsavedBusValidationReturnToCharterForm" width="450px">
<p:panelGrid columns="1">
<p:row>
<p:outputLabel value="#{msg['trip.bus.unsaved.validation.string1']}" style="color:red; font-weight:bold; font-size:12px;"/>
</p:row>
<p:row>
<p:outputLabel value="#{msg['trip.bus.unsaved.validation.string2']}" style="color:red; font-weight:bold; font-size:12px"/>
</p:row>
<p:row>
<p:outputLabel value="#{msg['trip.bus.unsaved.validation.string3']}" style="color:red; font-weight:bold; font-size:12px"/> </p:row>
</p:panelGrid>
<p:commandButton value="#{msg['trip.bus.cancellation.button.ok']}" style="width:140px;" type="submit" onclick="PF('unsavedBusValidReturnToChartDialog').hide();"
action="#{tripInformationController.returnToTripInfo}" update="busPg">
<!-- <f:ajax listener="PF('unsavedBusValidReturnToChartDialog').hide();" /> -->
</p:commandButton>
<p:spacer width="4px"></p:spacer>
<p:commandButton value="#{msg['trip.bus.cancellation.button.cancel']}" style="width:140px;"
onclick="PF('unsavedBusValidReturnToChartDialog').hide();"></p:commandButton>
</h:form>
</ui:composition>
</h:body>
</html>
This is the dialog that includes that code
<p:dialog widgetVar="unsavedBusValidReturnToChartDialog" showHeader="true" showEffect="clip" hideEffect="clip" appendToBody="true" width="auto"
height="auto" resizable="true" draggable="true" modal="true"
styleClass="customDialog dialogTitleNone">
<ui:include src="/charter/unsaved_bus_validation_return_to_charter.xhtml" />
</p:dialog>
Then this method runs when I click on ok to navigate back one page.
public String returnToTripInfo() {
logger.info("returnToTripInfo() entry");
doRemoveUnsavedBus();
if (getBusInfoListVo().size() > 0) {
busbutton = "Edit Buses";
List<FinancialDetailVo> tempFinancialDetails = busInfoSer.getFinancialDetails(tripInfoVo.getCharterId());
if (tempFinancialDetails != null && tempFinancialDetails.size()>0 ) {
tripInfoVo.setFinancialDetailVoSet(tempFinancialDetails);
calculateFinancialtotalAmount();
}
else
{
tripInfoVo.setFinancialDetailVoSet(null);
tripInfoVo.setFinancialTotalAmount(null);
calculateFinancialtotalAmount();
}
if(getBusInfoVo().getSelectStatus()==4)
{
setDisableBus(false);
setDisableCharges(false);
setDisableBusStatus(false);
setDisableBusSave(false);
}
}
logger.info("returnToTripInfo() exit");
return "Charter_information_tab.xhtml";
}
When the dialog closes and navigates back one screen, the input field on that screen are acting as if they are disabled. I tried the appendToBody="true" and appendTo="#(body)". I am running primefaces version 6.
I just need the inputs on the navigated to screen to be editable after the dialog navigates and closes.
The page was navigating before the hideEffect was able to finalize, so the dialog could not close before the page navigated. I took the hideEffect out, and the dialog was able to fully close before navigating.
<p:dialog widgetVar="unsavedBusValidReturnToChartDialog" showHeader="true" showEffect="clip" appendToBody="true" width="auto"
height="auto" resizable="true" draggable="true" modal="true"
styleClass="customDialog dialogTitleNone">
<ui:include src="/charter/unsaved_bus_validation_return_to_charter.xhtml" />
</p:dialog>
Related
I use primefaces version 6.2 in combination with jsf and trinidaad.
In the project I have a table with each row containing a button to redirect this page to another page based on selected row.
jsf and trindad commandLink and commandButton does the job but primefaces commandLink and command button doesn't.
What I have already done:
Changed the type of button to type="button"
Added immediate="true"
I used actionListener="#{coolingBean.view(row)}" instead of action="#{coolingBean.view}".
Anyone know why and what should I change?
<p:column id="viewButtonColumn" exportable="false" style="text-align: center" >
<tr:commandLink textAndAccessKey="&view " id="viewButton" action="#{coolingBean.view}" styleClass="commandLinkMediumSmallFont" onclick="PF('bui').show()">
<tr:image source="/imgs/view.png" styleClass="commandLinkImageWithText"/>
<f:setPropertyActionListener value="#{row.number}" target="#{coolingBean.criteria.number}"/>
<f:setPropertyActionListener value="#{row.id}" target="#{searchBean.selectedId}"/>
</tr:commandLink>
</p:column>
<p:column id="viewButtonColumn1" exportable="false" style="text-align: center" >
<h:commandLink textAndAccessKey="&view " id="viewButton1" action="#{coolingBean.view}" styleClass="ui-priority-primary" onclick="PF('bui').show()">
<i class="fa fa-search" ></i>
<f:setPropertyActionListener value="#{row.number}" target="#{coolingBean.criteria.number}"/>
<f:setPropertyActionListener value="#{row.id}" target="#{searchBean.selectedId}"/>
</h:commandLink>
</p:column>
<p:column id="viewButtonColumn2" exportable="false" style="text-align: center" >
<p:commandLink value="View" id="commandLinkView" action="#{coolingBean.view}" styleClass="ui-priority-primary" onclick="PF('bui').show()">
<i class="fa fa-search" ></i>
<f:setPropertyActionListener value="#{row.number}" target="#{coolingBean.criteria.number}"/>
<f:setPropertyActionListener value="#{row.id}" target="#{searchBean.selectedId}"/>
</p:commandLink>
</p:column>
<p:column id="viewButtonColumn3" exportable="false" style="text-align: center" >
<p:commandButton id="viewButton2" value="View" action="#{coolingBean.view}" icon="fa fa-search" immediate="true" type="button" onclick="PF('bui').show()">
<f:setPropertyActionListener value="#{row.number}" target="#{coolingBean.criteria.number}"/>
<f:setPropertyActionListener value="#{row.id}" target="#{searchBean.selectedId}"/>
</p:commandButton>
</p:column>
Inside managed Bean
public String view(Row selectedRow) {
if(criteria == null)
criteria = new criteriaBean();
criteria.setNummer(selectedRow.getNummber());
searchBean.selectedId = selectedRow.getId();
//FacesContext.getCurrentInstance().getExternalContext().dispatch("view.jsp");
return view();
}
public String view(){
return"view';
}
This one actually helped me.
Basically adding one of the following did the trick for me:
Adding ajax="false" into the commandButton
Appending ?faces-redirect=true to the url ( e.g. return "view?faces-redirect=true';)
I'm new in this community, but I really need help!
I'm programming a application which gonna run in Desktop, with Java, and online, with Java Web, using Hibernate 4.3, without JPA, and Primefaces 8.2.
My issue is, I have a page with a dataTable, this dataTable contains a button on each register to open a dialog with more information of this register.
Inside this dialog i have another dataTable with another button inside each register.
Here I have two issues.
First, when user clicks on the button in the first dialog, the second dialog appears but, it just ignore the ActionListener.
Second, on the first dialog, when user clicks to go to other page of dataTable, or just increase the number of rows, the data disappear! If you close and reopen the dialog, it open in the page you clicked before and the data will be there.
I'll post the principal code of the problem, the github link and a video to make it easy to figure out the problem.
Bean.java
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.event.ActionEvent;
import org.primefaces.model.LazyDataModel;
import com.sysnutriweb.dao.AlimentoXDietaDAO;
import com.sysnutriweb.dao.DietaDAO;
import com.sysnutriweb.dataModel.AlimentoDataModel;
import com.sysnutriweb.domain.Alimento;
import com.sysnutriweb.domain.AlimentoXDieta;
import com.sysnutriweb.domain.Dieta;
#ManagedBean(name = "MBDiet")
#SessionScoped
public class DietaBean implements Serializable {
private static final long serialVersionUID = 1L;
private List<Dieta> listDiets;
private Dieta diet = new Dieta();
private DietaDAO dDao;
private LazyDataModel<AlimentoXDieta> foods;
private Alimento food = new Alimento();
#PostConstruct
public void begin() {
dDao = new DietaDAO();
listDiets = dDao.loadAll();
}
public void getDietSelected(ActionEvent e) {
diet = (Dieta) e.getComponent().getAttributes().get("selectedDiet");
List<AlimentoXDieta> foods = new ArrayList<>();
List<AlimentoXDieta> axd = new AlimentoXDietaDAO().loadAll();
for (int i = 0; i < axd.size(); i++) {
if (axd.get(i).getDietId().getId() == diet.getId())
foods.add(axd.get(i));
}
this.foods = new AlimentoDataModel(foods);
}
public void getFoodSelected(ActionEvent e) {
food = (Alimento) e.getComponent().getAttributes().get("selectedFood");
}
// Getters and Setters
Index.xhtml
<f:metadata>
<f:param name="selectedDiet" value="#{MBDiet.diet}" />
</f:metadata>
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Menu de dietas SysNutri</title>
</h:head>
<h:body>
<p:layout fullPage="true">
<p:layoutUnit position="north" size="100" resizable="false"
closable="false" collapsible="false">
<center>
<h:outputText value="Sistema de Nutrição SYSNUTRIWEB" />
</center>
</p:layoutUnit>
<p:layoutUnit position="center">
<h:form id="formTable">
<p:dataTable emptyMessage="Nenhum dado cadastrado!"
paginator="false" id="tbAllDiets" value="#{MBDiet.listDiets}"
var="diet">
<p:column headerText="Nome" id="nome">
<p:outputLabel value="#{diet.nomeDieta}" />
</p:column>
<p:column headerText="Descrição da dieta" id="descricao">
<p:outputLabel value="#{diet.descricaoDieta}" />
</p:column>
<p:column headerText="Ações" id="acoes" width="10%">
<center>
<p:commandButton immediate="false" icon="ui-icon-info"
id="btnInfo" update=":formInfoTable"
actionListener="#{MBDiet.getDietSelected}"
oncomplete="PF('dlgFoods').show()">
<f:attribute name="selectedDiet" value="#{diet}" />
</p:commandButton>
<p:tooltip id="toolTipBtnInfo" for="btnInfo"
value="Clique para ver os alimentos presentes nesta dieta"
position="top" />
</center>
</p:column>
</p:dataTable>
</h:form>
</p:layoutUnit>
</p:layout>
<!-- Dialogs -->
<!-- Diet info -->
<p:dialog header="Alimentos da dieta selecionada" widgetVar="dlgFoods"
closable="true" modal="true" showEffect="explode" id="dialogFoods"
resizable="false" draggable="false" appendTo="#(body)">
<h:form id="formInfoTable">
<center>
<p:outputLabel id="diet" value="Dieta #{MBDiet.diet.nomeDieta}"
style="font-weight: bold;" />
</center>
<p:dataTable emptyMessage="Nenhum dado cadastrado!" paginator="true"
id="tbFoodsDiet" value="#{MBDiet.foods}" var="food" rows="4"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="4,5,6,7,8,9,10" lazy="true">
<p:column headerText="Nome" id="nome" width="10px">
<p:outputLabel value="#{food.foodId.nome}" />
</p:column>
<p:column headerText="Hora para consumir" id="descricao" width="40%">
<p:outputLabel value="#{food.hora}" />
</p:column>
<p:column headerText="Ações" id="acoes" width="10%">
<center>
<p:commandButton immediate="false" icon="ui-icon-info"
id="btnInfo" update=":formInfo"
actionListener="#{MBDiet.getFoodSelected}"
oncomplete="PF('dlgFoodInfo').show()">
<f:attribute name="selectedFood" value="#{food}" />
</p:commandButton>
<p:tooltip id="toolTipBtnInfo" for="btnInfo"
value="Clique para ver os alimentos presentes nesta dieta"
position="top" />
</center>
</p:column>
</p:dataTable>
</h:form>
</p:dialog>
<!-- Second Dialog -->
Github: https://github.com/SakamotoLfe/SysNutriWebV0
Vdieo: Coming soon.
I have problem with "" component in my application. I have a datatable with 2 fields editable first is an inputtext and second field is a dateInput.
Inside fields I put to update value in list but when submit it to bean not updated the values.
Below is my page.xhtml and bean.
<p:dialog id="modalNovosParametrosRecesso" header="Salvar Novos Parâmetros de Estagiário"
widgetVar="widgetvarNovoParametro"
draggable="true" resizable="false"
closable="false" modal="true" width="630">
<h:outputText styleClass="modalRecessoAuto" value="#{msg.MN064}" escape="false" />
<br />
<h:panelGroup>
<br />
<p:dataTable id="tableRegRecessoAuto" var="recessoAuto"
value="#{parametroEstagiarioMB.visao.listaOcorrenciaRegistroRecesso}"
styleClass="hide-column-names" rowIndexVar="rowIndex" >
<p:column style="width:98px;">
<h:outputLabel value="#{rowIndex+1}º Recesso de " style="color: #0039BA" />
<p:inputText value="#{recessoAuto.diasRecesso}" size="2">
<p:ajax event="blur" update=":frmFiltro:tableRegRecessoAuto" ignoreAutoUpdate="true" global="false" />
</p:inputText>
<h:outputLabel value="dia(s) começando em " style="color: #0039BA" />
<p:inputMask value="#{recessoAuto.dtInicioOcorrencia}" mask="99/99/9999" size="10">
<f:convertDateTime pattern="dd/MM/yyyy" locale="pt_BR" />
<p:ajax event="blur" update=":frmFiltro:tableRegRecessoAuto" ignoreAutoUpdate="true" global="false"/>
</p:inputMask>
<h:outputLabel value=" e finalizando em " style="color: #0039BA; margin-left: 5px;"/>
<h:outputLabel id="dtLbl1" value="#{recessoAuto.dtFimOcorrencia}" style="color: #0039BA; margin-left: 5px;" >
<f:convertDateTime for="dtLbl1" pattern="dd/MM/yyyy" locale="pt_BR"/>
</h:outputLabel>
</p:column>
-->
<div style="padding-left: 170px;">
<p:commandLink styleClass="btnLaranja marginTop"
ignoreAutoUpdate="true" global="false" ajax="false" action="#{parametroEstagiarioMB.salvarRecessoPrimeiraParametrizacao()}"
update=":frmFiltro:tableRegRecessoAuto">
<span>Confirmar</span>
</p:commandLink>
<p:commandLink styleClass="btnLaranja marginTop"
id="btnCancelarRecessoAuto"
oncomplete="PF('widgetvarNovoParametro').hide();"
ignoreAutoUpdate="true" global="false" actionListener="#{parametroEstagiarioMB.cancelar}">
<f:setPropertyActionListener
target="#{parametroEstagiarioMB.visao.exibirModal}"
value="#{false}" />
<span>Cancelar</span>
</p:commandLink>
<p:commandLink styleClass="btnLaranja marginTop"
id="btnVerRegrasAuto"
oncomplete="PF('widgetvarModalRegras').show();"
ignoreAutoUpdate="true" global="false">
<span>Regras</span>
</p:commandLink>
</div>
</p:dialog>
My Bean:
public void salvarRecessoPrimeiraParametrizacao(){
int count = 0;
final DataTable dataTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot()
.findComponent(":frmFiltro:tableRegRecessoAuto");
List<OcorrenciaPonto> teste = new ArrayList<OcorrenciaPonto>();
for(OcorrenciaPonto c : (List<OcorrenciaPonto>) dataTable.getValue()){
teste.add(c);
count+=1;
}}
datatable.getValues() not get new values and yes old values that displayed in screen.
Are you using getters and setters correctly?
Have you tried to use immediate="true" on input fields?
I saw you are using <p:ajax> . I had some troubles with this. Maybe, if you change to **<f:ajax>** this must works so well.
I need help in implementing file download in JSF page. So far I managed to create this:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<ui:insert name="header">
<ui:include src="header.xhtml"/>
</ui:insert>
</h:head>
<h:body>
<h1><img src="resources/css/images/icon.png" alt="DX-57" /> Settings Center</h1>
<!-- layer for black background of the buttons -->
<div id="toolbar" style="margin: 0 auto; width:100%; height:30px; position:relative; background-color:black">
<!-- Include page Navigation -->
<ui:insert name="Navigation">
<ui:include src="Navigation.xhtml"/>
</ui:insert>
</div>
<div id="logodiv" style="position:relative; top:35px; left:0px;">
<h:graphicImage alt="Glassfish" style="position:relative" value="resources/images/logo_glassfish_settings.png" />
</div>
<div id="main" style="margin: 0 auto; width:1190px; height:700px; position:absolute; background-color:transparent; top:105px">
<div id="mainpage" style="margin: 0 auto; width:1190px; height:500px; position:absolute; background-color:transparent; top:80px">
<div id="settingsdiv" style="width:350px; height:400px; position:absolute; background-color:r; top:20px; left:1px">
<div id="settingsHashMap" style="width:1050px; height:400px; position:absolute; background-color:r; top:20px; left:1px">
<h:form id="form" >
<p:growl id="growl" showDetail="true" sticky="true" />
<!-- The sortable data table -->
<h:dataTable onmouseover="addOnclickToDatatableRows();" id="dataTable" headerClass="columnHeader" value="#{GlassfishController.dataList}" binding="#{table}" var="item">
<!-- Check box -->
<h:column>
<f:facet name="header">
<h:selectBooleanCheckbox style="margin-left: 0px;" value="#{GlassfishController.mainSelectAll}" class="checkall" >
<f:ajax listener="#{GlassfishController.selectAll}" render="#form" />
</h:selectBooleanCheckbox>
</f:facet>
<h:selectBooleanCheckbox onclick="highlight(this)" value="#{GlassfishController.selectedIds[item.filename]}" >
<!-- if the user deselects one row deselect the main checkbox -->
<f:ajax listener="#{GlassfishController.deselectMain}" render="#form" />
</h:selectBooleanCheckbox>
<!-- Click on table code -->
<h:outputLink id="lnkHidden" onclick="document.getElementById('form:btnHello').click(); return false;" style="text-decoration:none; color:white; background-color:black">
</h:outputLink>
</h:column>
<!-- Row number -->
<h:column>
<f:facet name="header">
<h:outputText value="№" />
</f:facet>
<h:outputText value="#{table.rowIndex + GlassfishController.firstRow + 1}" />
</h:column>
<h:column>
<f:facet name="header">
<h:commandLink value="File Name" actionListener="#{GlassfishController.sort}" style="text-decoration:none; color:white; background-color:black">
<f:attribute name="sortField" value="filename" />
<f:ajax render="#form" />
</h:commandLink>
</f:facet>
<h:outputText value="#{item.filename}" />
</h:column>
<h:column>
<f:facet name="header">
<h:commandLink value="Size" actionListener="#{GlassfishController.sort}" style="text-decoration:none; color:white; background-color:black">
<f:attribute name="sortField" value="size" />
<f:ajax render="#form" />
</h:commandLink>
</f:facet>
<h:outputText value="#{item.size} bytes" />
</h:column>
</h:dataTable>
<!-- The paging buttons -->
<h:commandButton value="first" action="#{GlassfishController.pageFirst}"
disabled="#{GlassfishController.firstRow == 0}" >
<f:ajax render="#form" execute="#form"></f:ajax>
</h:commandButton>
<h:commandButton value="prev" action="#{GlassfishController.pagePrevious}"
disabled="#{GlassfishController.firstRow == 0}" >
<f:ajax render="#form" execute="#form"></f:ajax>
</h:commandButton>
<h:commandButton value="next" action="#{GlassfishController.pageNext}"
disabled="#{GlassfishController.firstRow + GlassfishController.rowsPerPage >= GlassfishController.totalRows}" >
<f:ajax render="#form" execute="#form"></f:ajax>
</h:commandButton>
<h:commandButton value="last" action="#{GlassfishController.pageLast}"
disabled="#{GlassfishController.firstRow + GlassfishController.rowsPerPage >= GlassfishController.totalRows}" >
<f:ajax render="#form" execute="#form"></f:ajax>
</h:commandButton>
<h:outputText value="Page #{GlassfishController.currentPage} / #{GlassfishController.totalPages}" />
<br />
<!-- The paging links -->
<ui:repeat value="#{GlassfishController.pages}" var="page">
<h:commandLink value="#{page}" actionListener="#{GlassfishController.page}"
rendered="#{page != GlassfishController.currentPage}" style="text-decoration:none;color:white;">
<f:ajax render="#form" execute="#form"></f:ajax>
</h:commandLink>
<h:outputText value="#{page}" escape="false"
rendered="#{page == GlassfishController.currentPage}" style="text-decoration:none;color:gray;"/>
</ui:repeat>
<br />
<!-- Set rows per page -->
<h:outputLabel for="rowsPerPage" value="Rows per page" />
<h:inputText id="rowsPerPage" value="#{GlassfishController.rowsPerPage}" size="3" maxlength="3" />
<h:commandButton value="Set" action="#{GlassfishController.pageFirst}" >
<f:ajax render="#form" execute="#form"></f:ajax>
</h:commandButton>
<h:message for="rowsPerPage" errorStyle="color: red;" />
<!-- hidden button -->
<h:commandButton id="deleterow" value="HiddenDelete" action="#{GlassfishController.deleteSelectedIDs}" style="display:none">
<f:ajax render="#form"></f:ajax>
</h:commandButton>
<!-- the delete button -->
<h:button value="Delete" onclick="deletedialog(this, 'Do you want to delete the selected rows?'); return false;" />
<script type="text/javascript" src="resources/js/tabs.js"></script>
<h:commandLink id="btnHello" value="Download Files"
action="#{GlassfishController.downloadFile}">
</h:commandLink>
</h:form>
</div>
</div>
</div>
</div>
</h:body>
</html>
// Execute the download procedure
public void executeDownload(String filename) throws IOException{
int DEFAULT_BUFFER_SIZE = 10240;
String filePath = "/opt/glassfish3/glassfish/domains/domain1/logs/" + filename;
FacesContext context = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
File file = new File(filePath);
if (!file.exists())
{
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setContentType("text");
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "attachment;filename=\""
+ file.getName() + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try
{
input = new BufferedInputStream(new FileInputStream(file),
DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(),
DEFAULT_BUFFER_SIZE);
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0)
{
output.write(buffer, 0, length);
}
}
finally
{
input.close();
output.close();
}
context.responseComplete();
}
There is a problem that I cannot solve and I need help. When I click on the download button I successfully can download the log file.
I want to download a file into the JSF table when I click on it. Can you please help me to implement it? Or can you give me some advice how to do it?
Best wishes
Based in your comments, you can use a commandLink/commandButton to call another commandLink/commandButton in the same page. Remember that these components will behave like normal HTML components. Posting a sample of this behavior
<h:form id="frmTest">
<h:commandLink value="I will call the commandButton below me"
onclick="document.getElementById('frmTest:btnHello').click(); return false;" />
<br />
<h:commandButton id="btnHello" value="I'm the commandButton below the commandLink"
action="#{bean.someAction}" />
</h:form>
EDIT: Based on your comment on the question, you have several ways to pass the parameter to your commandButton action. I'll show you one that uses JavaScript. The logic is simple:
Use an <h:inputHidden> tag component which value will be the name of the file you want to download.
Before sending the onclick event, fill this hidden component with the value you need.
Let the HTML request continue with its work.
<h:form id="frmTest">
<h:commandLink id="hidFileName" value="#{bean.fileToDownload}" />
<h:commandLink value="I will call the commandButton below me"
onclick="document.getElementById('frmTest:hidFileName').value='#{bean.fileName}'; document.getElementById('frmTest:btnHello').click(); return false;" />
<br />
<h:commandButton id="btnHello" value="I'm the commandButton below the commandLink"
action="#{bean.someAction}" />
</h:form>
I have two selectOneMenu. I need following:
On first menu change I need to populate second one and some form's fields with AJAX
On second menu change I need to populate only some form's fields wit AJAX.
Populating second menu and form's fields on step 1 is perfect and right after first menu change, but there is a problem with populating form on step 2.
Nothing happens when I change second menu's value. But when I returned second menu value to NoSelectionOption ajax listener invoked. It seems that AJAX listener ignores values that was added with AJAX.
Here's my code fragments:
JSF:
<h:panelGrid>
<h:panelGrid columns="1">
<h:panelGrid columns="1">
<h:panelGrid columns="2">
<h:outputText value="Получатель:" />
<h:selectOneMenu value="#{paymentOrder.curContractor}">
<f:selectItem itemLabel="Выберите контрагента .." noSelectionOption="true" />
<f:selectItems value="#{paymentOrder.userContractors}" var="contr"
itemValue="#{contr.idcontractor}"
itemLabel="#{contr.pnamecontractor}"/>
<a4j:ajax event="valueChange" listener="#{paymentOrder.valueContractorChanged}" render="idINNContractor, idKPPContractor, idNameContractor, idContractorAccounts" execute="#this"/>
</h:selectOneMenu>
</h:panelGrid>
<h:panelGrid columns="1">
<h:panelGrid columns="4">
<h:outputText value="ИНН"/>
<h:inputText id="idINNContractor" value="#{paymentOrder.chosenContractor.inncontractor}"/>
<h:outputText value="КПП"/>
<h:inputText id="idKPPContractor" value="#{paymentOrder.chosenContractor.kppcontractor}"/>
</h:panelGrid>
<h:panelGrid columns="2">
<h:outputText value="Получатель"/>
<h:inputTextarea id="idNameContractor" value="#{paymentOrder.chosenContractor.pnamecontractor}"/>
</h:panelGrid>
</h:panelGrid>
<h:panelGrid columns="1">
<h:panelGrid columns="2">
<h:outputText value="Счёт получателя:"/>
<h:selectOneMenu id="idContractorAccounts" value="#{paymentOrder.curContractorAccount}">
<f:selectItem itemLabel="Выберите счёт .." noSelectionOption="true" />
<f:selectItems value="#{paymentOrder.contractorAccounts}" var="acc"
itemValue="#{acc.naccountcontractor}"
itemLabel="#{acc.advName}"/>
<a4j:ajax event="valueChange" listener="#{paymentOrder.valueAccountChanged}" render="idContrAcc, idNameContrBank, idBikContrBank, idAccContrBank" execute="#this"/>
</h:selectOneMenu>
</h:panelGrid>
<h:panelGrid columns="2">
<h:outputText value="Сч.№"/>
<h:inputText id="idContrAcc" value="#{paymentOrder.curContractorAccount}"/>
</h:panelGrid>
</h:panelGrid>
</h:panelGrid>
</h:panelGrid>
<h:panelGrid columns="1">
<h:panelGrid columns="4">
<h:panelGrid columns="2">
<h:outputText value="Банк получателя"/>
<h:inputTextarea id="idNameContrBank" value="#{paymentOrder.chosenBank.namebank}" />
</h:panelGrid>
<h:panelGrid columns="2">
<h:outputText value="БИК"/>
<h:inputText id="idBikContrBank" value="#{paymentOrder.chosenBank.bikbank}"/>
<h:outputText value="Сч.№"/>
<h:inputText id="idAccContrBank" value="#{paymentOrder.chosenBank.bankkorshet}"/>
</h:panelGrid>
</h:panelGrid>
</h:panelGrid>
</h:panelGrid>
And my back bean fragment:
public class PaymentOrder {
#EJB(lookup="JpaBankBean/local")
private JpaBankBeanLocal jpaBean;
private Paymentdocument pDocument;
private Paymentorder pOrder;
private Klbankrf chosenBank;
private String curContractorAccount;
private String curContractorBank;
private String curContractor;
private String err;
private String chosenAccount;
private Contractor chosenContractor;
#SuppressWarnings("rawtypes")
private Set contractorAccounts;
#SuppressWarnings("rawtypes")
private List contractorBanks;
private String userName;
private Date nowDate;
public PaymentOrder() {
this.nowDate = Calendar.getInstance().getTime();
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
setUserName(((UserDetails)principal).getUsername());
} else {
setUserName(principal.toString());
}
pDocument = new Paymentdocument();
pOrder = new Paymentorder();
chosenContractor = new Contractor();
chosenBank = new Klbankrf();
}
public void valueContractorChanged()
{
chosenContractor = jpaBean.getContractor(Integer.valueOf(getCurContractor()));
setContractorAccounts(jpaBean.getContractorAccounts(Integer.valueOf(getCurContractor())));
pDocument.setReceiver(chosenContractor.getPnamecontractor());
}
public List getUserContractors()
{
return jpaBean.getUserContractors(userName);
}
public void valueAccountChanged()
{
chosenBank.setNamebank("SBER");
//TODO chosenBank = jpaBean.getContractorBank(getCurContractorAccount());
//TODO setChosenAccount("012345678901234567890");
}
}
So, "SBER" appear in idNameContrBank field only if I change second menu value to somethig and then change back to NoSelectOption. It is strange to me.
I use RichFaces 4, JBoss AS 6.
I've found some information at this forum, but there is no solution.
How to make second menu to change something? Or is there my mistake? Any ideas?
Thanks in advance!
I've made some experiments.
When I change second menu to some value populated with AJAX, page gets response like that:
<?xml version='1.0' encoding='UTF-8'?>
<partial-response>
<changes>
<update id="docForm:idContrAcc">
<![CDATA[<input id="docForm:idContrAcc" type="text" name="docForm:idContrAcc" style=" width : 100%;" />]]>
</update>
<update id="docForm:idNameContrBank">
<![CDATA[<textarea id="docForm:idNameContrBank" name="docForm:idNameContrBank" style=" width : 130px;"></textarea>]]>
</update>
<update id="docForm:idBikContrBank">
<![CDATA[<input id="docForm:idBikContrBank" type="text" name="docForm:idBikContrBank" style=" width : 140px;" />]]>
</update>
<update id="docForm:idAccContrBank">
<![CDATA[<input id="docForm:idAccContrBank" type="text" name="docForm:idAccContrBank" style=" width : 140px;" />]]>
</update>
<update id="javax.faces.ViewState"><![CDATA[3312710224811729695:3995303008700914422]]>
</update>
</changes>
</partial-response>
There are no values, but right IDs! How it can be? Why?
But if I return NoSelectionOption active then page gets response
<?xml version='1.0' encoding='UTF-8'?>
<partial-response>
<changes>
<update id="docForm:idContrAcc">
<![CDATA[<input id="docForm:idContrAcc" type="text" name="docForm:idContrAcc" value="" style=" width : 100%;" />]]>
</update>
<update id="docForm:idNameContrBank">
<![CDATA[<textarea id="docForm:idNameContrBank" name="docForm:idNameContrBank" style=" width : 130px;">SBER</textarea>]]>
</update>
<update id="docForm:idBikContrBank">
<![CDATA[<input id="docForm:idBikContrBank" type="text" name="docForm:idBikContrBank" style=" width : 140px;" />]]>
</update>
<update id="docForm:idAccContrBank">
<![CDATA[<input id="docForm:idAccContrBank" type="text" name="docForm:idAccContrBank" style=" width : 140px;" />]]>
</update>
<update id="javax.faces.ViewState">
<![CDATA[3312710224811729695:3995303008700914422]]>
</update>
</changes>
</partial-response>
It's seems OK - values are presented! But why does it happen when NoSelectionOption is active?!
I suspect JSF might be overwriting your attempts since it usually calls all the setters for all the properties exposed on the page and it normally does this after the valueChangeListeners are executed. I've never seen the <a4j:ajax /> tag but you could try the <a4j:support /> tag. Instead of this:
<a4j:ajax event="valueChange" listener="#{paymentOrder.valueContractorChanged}" render="idINNContractor, idKPPContractor, idNameContractor, idContractorAccounts" execute="#this"/>
Try this:
<a4j:support event="onchange" ajaxSingle="true" reRender="idINNContractor, idKPPContractor, idNameContractor, idContractorAccounts"/>
Since ajaxSingle="true" is included in the tag it means that only the setter for curContractor will be called (and not all the rest on the page like JSF normally does). Then you can call valueContractorChanged from the setter (or even just make it part of the setter).
If you replace all of the <a4j:ajax /> tags in this way you should get the desired result. Check out more info about the tag via the link above.