I'm using primefaces 3.5 JBoss 7.1.1. I'm migrating my app to Wildfly 9.0.2.
The following code used to work with JBoss but no longer with WildFly.
<p:tabView id="tabView" dynamic="true" cache="false" style="width:1120px">
<f:event listener="#{ucoController.loadUcoConfiguration}" type="preRenderView" />
<p:tab id="Activation" title="SOMF Activation">
<h:panelGrid id="ActivationPG" columns="1" cellpadding="10" border="0">
<h:form id="user" class="sgdsForm clear">
<script type="text/javascript">
function startAjaxStatus(){
document.getElementById("tabView:user:image").style.display='block';
document.getElementById("tabView:user:shutDown").style.display='block';
}
</script>
<ol>
<li>
<label for="activate" class="label">SOMF Activation</label>
<p:selectBooleanCheckbox value="#{configurationBean.SOMFActivated}" />
</li>
<li>
<br/>
<h:outputText value="#{configurationBean.SOMFActivationMessage}" style="float:left; text-align:left;margin-leftt:7px;color:#0F5795;font-weight:bold;font-size:0.9em;line-height:23px;"/>
</li>
<li>
<br/>
<p:commandButton ajax="false" global="#{configurationBean.SOMFActivated}" onclick="startAjaxStatus()" value="Update" actionListener="#{ucoController.updateUco}" id="updateActivation" icon="ui-icon-disk" update=":tabView:user,:tabView:ScreeningForm>
</p:commandButton>
</li>
</ol>
<h:panelGrid columns="2" border="0" >
<h:outputText value="Update in progress..." id="shutDown" style="color:#0F5795;font-weight:bold;font-size:0.9em;line-height:23px;display:none;"/>
<p:graphicImage value="resources/img/load.gif" id="image" style="display:none;"/>
</h:panelGrid>
</h:form>
</h:panelGrid>
</p:tab>
<p:tab id="Screening" title="Screening" rendered="#{ucoController.disableConfiguration}">
<h:panelGrid id="ScreeningPG" columns="1" cellpadding="10" border="0">
<h:form id="ScreeningForm" class="sgdsForm clear" >
<ol>
<li>
<label for="analysis" class="label required">Think Time (ms)</label>
<h:inputText id="thinkTime" value="#{configurationBean.screeningThinktime}" maxlength="5" readonly="#{configurationBean.SOMFActivated}">
<f:validator validatorId="screeningTimeValidator" />
<f:attribute name="autoScreening" value="#{configurationBean.automaticScreening}" />
</h:inputText>
</li>
<li>
<label for="activate" class="label">Automatic Screening</label>
<p:selectBooleanCheckbox value="#{configurationBean.automaticScreening}" readonly="#{configurationBean.SOMFActivated}" disabled="#{configurationBean.SOMFActivated}"/>
</li>
<li>
<br/>
<p:commandButton disabled="#{configurationBean.SOMFActivated}" oncomplete="handleComplete(xhr, status, args)" value="Update" actionListener="#{ucoController.updateUco}" id="updateScreening" icon="ui-icon-disk" process="#this,ScreeningForm" update=":tabView:ScreeningPG"/>
</li>
</ol>
</h:form>
</h:panelGrid>
</p:tab>
</p:tabView>
And my backing bean :
#ManagedBean(name = "ucoController", eager = true)
#SessionScoped
public class UcoController implements Serializable {
public final ConfigurationBean loadConfiguration() {
// load configuration
}
public final void updateUco(ActionEvent event) {
// update configuration
}
}
I wonder why the updateUco method is not fired when submiting the form. In consequence my form seems to not be submitted! The model doesn't change.
Is there anything wrong with mojarra version or primefaces?
I went through this exhaustive answer for what to appear the same problem. But none of the point described fit for my case !
Please upgrade primefaces to version 4.0 in order to support JSF version 2.2 which is supported in Wildfly 9.0.2.
Related
I have a problem with the rendering of a datatable.
In my application I have this navigation bar:
<h:form>
<ul class="nav nav-tabs">
<li class="active" role="presentation">
<h:commandLink value="Veranstaltungen" action="#{eventController.redirect('veranstaltung.xhtml')}"/>
</li>
<li role="presentation">
<h:commandLink value="Beacons" action="#{beaconcontroller.redirect('beacon.xhtml')}"/>
</li>
[...]
</ul>
</h:form>
Redirect (beaconcontroller):
public String redirect(String link) {
beacons = database.getAllBeacons();
return "./" + link;
}
The navigation works perfectly, but when I submit the form beaconData in the beacon.xhtml my datatable won't be rendered.
<h:form id="beaconsTable">
<p:dataTable value="#{beaconcontroller.beacons}" var="b"
tableStyleClass="table table-striped"
emptyMessage="Keine Beacons verfügbar"
style="font-size:14px"
rowIndexVar="rowIndex"
rowStyleClass="#{(rowIndex mod 2) eq 0 ? 'first-row' : 'second-row'}"
>
<p:column style="float:left;border:none;">
<f:facet name="header">
<h:commandLink actionListener="#{beaconcontroller.sortBeacons}">
<f:ajax execute="#this" render="beaconsTable"/>
Beacons
</h:commandLink>
</f:facet>
<h:commandLink>
<f:ajax listener="#{beaconcontroller.fillFields(b)}" execute="#this" render=":beaconData beaconsTable :delete"/>
<h:outputText value="#{beaconcontroller.getCompleteString(b)}" style="#{beaconcontroller.currentBeacon == b ? 'color:#337AB7' : 'color:#555555'}"></h:outputText>
</h:commandLink>
</p:column>
</p:dataTable>
</h:form>
</div>
<div class="col-lg-6">
<h:form role="form" id="beaconData" enctype="multipart/form-data">
<div class="form-group">
<label>UUID*</label>
<h:inputText id="id_uuid" binding="#{uuidAttribute}" class="form-control" value="#{beaconcontroller.uuid}" p:placeholder="Unternehmen" required="true" requiredMessage="Bitte UUID angeben" validatorMessage="Bitte nur Zahlen und Buchstaben angeben">
<f:validateRegex pattern="[0-9a-zA-Z]+"/>
</h:inputText>
<h:message styleClass="errMessage" for="id_uuid" style="color: red"/>
</div>
[...]
<h:commandButton type="submit" value="Speichern" actionListener="#{beaconcontroller.saveData}" class="btn btn-primary" disabled="#{beaconcontroller.currentBeacon == null}">
<f:ajax render="beaconData :beaconsTable" execute="#form"/>
</h:commandButton>
</h:form>
</div>
Clicking on an other entry in the datatable, solves the problem. Then the table will be rendered on submit. But why dosen't it work on the first time?
When I now change action="#{beaconcontroller.redirect('beacon.xhtml')}" in the navigation bar to action="beacon.xhtml" it works all correct. I thought these expressions are meaning the same?
I have the next jsf form with 2 parts
1) Header Form
2) Datatable Fields
I want add validation to 2 parts, but when i will do post the header form the validation of datatable is not necessary, and when i do update row datatable the validation of the header form is not necessary. My Problem is that when i do post the update row datatable, the jsf wants validate the header form..
My question is..
Using only JSF 2 Implementation without rich faces or another library, how to i do to jsf to validate a partial form? what is the best way to manage subforms?
Thanks,
This is my example Code
<h:form styleClass="horizontal-form" id="form">
<h:messages></h:messages>
<h3>
<h:outputText value="#{msgs.title}"></h:outputText>
</h3>
<table>
<tr>
<td><h:outputLabel for="userName" id="nameLbl">Name</h:outputLabel></td>
<td><h:inputText id="userName" value="#{actionBean.name}"
styleClass="form-control" required="true" /> <h:message
for="userName"></h:message></td>
</tr>
<tr>
<td>Monto:</td>
<td><h:inputText id="userAmount" value="#{actionBean.amount}"
label="Edad" /> <h:message for="userAmount"></h:message></td>
</tr>
</table>
<div>
Datatable
<h:dataTable value="#{actionBean.items}" var="item" id="datatable">
<h:column>
<f:facet name="header">
<h:outputText value="Nombre"></h:outputText>
</f:facet>
<h:outputText value="#{item.data.name}" rendered="#{!item.edit}"></h:outputText>
<h:inputText id="inputName" value="#{item.editData.name}" required="true"
rendered="#{item.edit}"></h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Actions"></h:outputText>
</f:facet>
<h:commandButton value="Edit"
action="#{actionBean.edit(item)}" rendered="#{!item.edit}"
immediate="true" styleClass="btn btn-sm btn-primary">
<f:ajax execute="form" render="form" />
</h:commandButton>
<h:commandButton value="Update"
action="#{actionBean.update(item)}" rendered="#{item.edit}"
styleClass="btn btn-sm btn-primary ">
<f:ajax execute="datatable" render="form" />
</h:commandButton>
</h:column>
</h:dataTable>
</div>
<p>
<h:commandButton value="Login" action="#{actionBean.count}"
styleClass="btn btn-sm btn-primary">
<f:ajax execute="form" render="form datatable_form" />
</h:commandButton>
<h:commandButton value="Begin" action="index" immediate="true"
styleClass="btn btn-sm btn-primary" />
</p>
</h:form>
It's probably happening because you are trying to update the whole form instead of just the datatable.
Example:
<h:commandButton value="Edit"
action="#{actionBean.edit(item)}" rendered="#{!item.edit}"
immediate="true" styleClass="btn btn-sm btn-primary">
<f:ajax execute="form" render="form" />
</h:commandButton>
In this case you should try to execute/render just the datable you want do validate, just like this:
<h:commandButton value="Edit"
action="#{actionBean.edit(item)}" rendered="#{!item.edit}"
immediate="true" styleClass="btn btn-sm btn-primary">
<f:ajax execute="datatable" render="datatable" />
</h:commandButton>
I have a command Button that calls a method from the Session Scoped Bean if the inputs are valid.
<h:form id="mainform">
<p:panel id="panelform" header="Email Extractor" >
<h:panelGrid id="formulaire" columns="2">
<h:panelGroup id="formblock" layout="block" >
<p:panelGrid columns="2">
<p:outputLabel for="Keyword" value="Keyword: " />
<p:inputText id="Keyword" type="search" requiredMessage="Keyword is required"
value="#{mailMB.keyword}" required="true" label="Keyword">
</p:inputText>
<p:outputLabel for="Emailsnbr" value="Enter the emails'number:" />
<p:inputText id="Emailsnbr" type="number" requiredMessage="Emails number is required" validatorMessage="Enter a number"
value="#{mailMB.number}" required="true" label="Emailsnbr">
<f:validateDoubleRange minimum="1" maximum="53500" />
</p:inputText>
</p:panelGrid>
</h:panelGroup>
</h:panelGrid>
<p:commandButton value="Extract" style="width: 12%;height: 100%" update="tableemails, :confirmPurchaseTest, :mainform" id="extractbutton" ajax="true" widgetVar="ButtonExtract"
actionListener="#{mailMB.searchEmails()}" onstart="blockUIWidget1.show();" oncomplete=" blockUIWidget1.hide(); if (args && !args.validationFailed) confirmDialog.show();" />
<p:dialog widgetVar="blockUIWidget1" modal="true" closable="false" resizable="false" >
<h:panelGrid columns="2">
<div>
<p:graphicImage url="pictures/loading81.gif" width="200" height="200" alt="animated-loading-bar"/>
<h:outputLabel value="Please wait..."/>
</div>
<div>
<p:button outcome="home" icon="ui-icon-arrowthick-1-w" title="Back To Home" style="margin-right: 5px;white-space: nowrap" />
</div>
</h:panelGrid>
</p:dialog>
</p:panel>
<p:dataTable rowIndexVar="rowIndex" id="tableemails" value="#{mailMB.mails}" var="item" rowsPerPageTemplate="5,10,15" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
paginator="true" rows="5" styleClass="case-table" emptyMessage="No records found with given criteria" paginatorPosition="bottom"
filteredValue="#{mailMB.filteredMails}" rowKey="#{item.id}"
selection="#{mailMB.selectedMail}" selectionMode="single" >
<p:ajax event="rowSelect" update=":mainform"/>
<p:column styleClass="blockable">
<f:facet name="header">
<h:outputText value="Email"/>
</f:facet>
<h:outputText value="#{item.email}"/>
</p:column>
</p:dataTable>
</h:form>
<p:confirmDialog closable="false" style="position: absolute; width: 50px; border-color: blue" id="confirmPurchaseTest" message="Your Database was successfully created. It contains #{mailMB.number} Emails "
appendToBody="true"
header="Get Emails List" severity="info" widgetVar="confirmDialog">
<h:form>
<p:commandButton id="getEmails" style="width: 35%;height: 100%" value="Get Emails" oncomplete="window.location.href = '/Hitonclick/emailsList.xhtml'" >
<f:event type="preRenderView" listener="#{mailMB.preRender}"/>
</p:commandButton>
<p:commandButton id="declineTest" style="width: 35%;height: 100%" value="Decline" onclick="deleteDialog.show();" />
</h:form>
</p:confirmDialog>
My SessionScoped Bean is
#ManagedBean(name = "mailMB")
#SessionScoped
public class MailManagedBean implements Serializable {
#Inject
private MailBusinessLocal mailmanagerLocal;
#Inject
private DataBusinessLocal dataBusinessLocal;
#Inject
private CustomerBusinessLocal customerBusinessLocal;
.....
#PostConstruct
public void init() {
mails = new ArrayList<>();
}
public void searchEmails() throws Exception {
idCustomer = (String) session.getAttribute("idCustomer");
System.out.println(idCustomer + " this is it");
Customer customer = customerBusinessLocal.findById(idCustomer);
data = dataBusinessLocal.createData(new Date(), number, keyword, moteur, customer, State.REJECTED);
mails = mailBusinessLocal.createEmails(keyword, number, moteur, data);
System.out.println("Method was invoked");
}
}
if i enter 0 in the emails's number input for exemple and submit with Extract command Button for the first time i get the validatorMessage So i enter a valid number and submit again. And here comes the problem, the dialog in the oncomplete is shown without invoking the method in the actionListener. I mean i get the confirm dialog of persisted object without invoking the method that persists the object. Am i missing something??
How could i fix that?
I have a page in which through AJAX I include other pages conditionally. On one included page I would like to do another ajax call.
My initial page:
<ui:composition template="../../templates/template.xhtml">
<ui:define name="title">
Pay
</ui:define>
<ui:define name="content">
<h:form>
<div id="loginDiv">
<div class="homeDiv" style="text-align: left;">
<h:form>
<h:outputText value="#{strings.paymentMainSpeech} " />
<ul id="grileList">
<li>#{strings.payThroughSMS}</li>
<li>#{strings.payThroughCard}</li>
<li>#{strings.payThroughPayPal}</li>
</ul>
<h:outputText value="#{strings.bellowYouHavePaymentOptions}" />
</h:form>
</div>
<h:selectOneRadio value="#{payment.option}" immediate="true">
<f:selectItem itemValue="#{strings.payThroughSMS}"
itemLabel="#{strings.payThroughSMS}" />
<f:selectItem itemValue="#{strings.payThroughCard}"
itemLabel="#{strings.payThroughCard}" />
<f:selectItem itemValue="#{strings.payThroughPayPal}"
itemLabel="#{strings.payThroughPayPal}" />
<f:ajax event="change" listener="#{payment.changeListener()}"
render="payment" />
</h:selectOneRadio>
</div>
<h:panelGroup id="payment">
<!-- PayPal -->
<h:panelGroup rendered="#{payment.option == 'PayPal'}">
<ui:include src="../payments/paypal/paypal.xhtml" />
</h:panelGroup>
<!-- CARD -->
<h:panelGroup rendered="#{payment.option == 'Card'}">
<ui:include src="../payments/card/mobilPay.xhtml" />
</h:panelGroup>
</h:panelGroup>
</h:form>
</ui:define>
I select from the radio buttons the pages which I want to include through an ajax listener. That works well.
On one included page (on mobilPay.xhtml)
<ui:composition>
<ui:define name="title">
Pay Card Mobil Pay
</ui:define>
<div id="loginDiv">
<h:panelGroup id="next">
<h:panelGroup rendered="#{not mobilPayInitBean.forward}">
<h:outputText value="#{strings.paymentSpeech} " />
<h:outputText value="#{strings.paymentSpeech} " />
<h:outputText value=" #{strings.paymentSpeech2}" />
<br />
<br />
<h:form>
<h:selectOneMenu value="#{mobilPayInitBean.options}">
<f:selectItem itemValue="five" itemLabel="#{strings.fiveEuro}" />
<f:selectItem itemValue="seven" itemLabel="#{strings.sevenEuro}" />
<f:selectItem itemValue="ten" itemLabel="#{strings.tenEuro}" />
</h:selectOneMenu>
<br />
<br />
<f:ajax render="next">
<h:commandButton value="#{strings.nextStep}"
action="#{mobilPayInitBean.nextStep()}"
rendered="#{not mobilPayInitBean.forward}" />
</f:ajax>
</h:form>
</h:panelGroup>
<h:panelGroup rendered="#{mobilPayInitBean.forward}">
<div id="loginDiv">
<form name="frmPaymentRedirect" method="post"
action="#{mobilPayInitBean.paymentURL}">
<input type="hidden" name="env_key"
value="#{mobilPayInitBean.paymentURL}" /> <input type="hidden"
name="data" value="#{mobilPayInitBean.paymentURL}" />
<p>
If not reditect in 5 seconds <input type="image"
src="images/12792_mobilpay-96x30.gif" />
</p>
</form>
</div>
<script type="text/javascript" language="javascript">
window.setTimeout(document.frmPaymentRedirect.submit(), 3000);
</script>
</h:panelGroup>
</h:panelGroup>
</div>
I want to select from the select one menu an item and click on the command button and I want the whole selectonemenu and the command button to disaper and the last form (name="frmPaymentRedirect")to appear.
Now the problem:
I include the mobilPay.xhtml page and the whole page with the radiobuttons and the mobilPay.xhtml page appears, BUT when I click on the command button the hole mobilPay.xhtml disappears and so does the selection in the radio button.
Thank you for your time.
It was the nested forms!!!
I used a master template -> child template -> included page.
In the child template a had a form and inside the form I inserted the pages and in the one inserted page I had another set of form.
Thank you for pointing that obvious thing out!!!
I have a problem that my AJAX requests are not firing in JSF, for unknown reasons.
admin.xhtml Snippet:
<h:form id="adminPanel">
...
<f:subview id="editCustomer#{customer.id}">
<p class="#{adminService.getEditCustomerClass(customer.id)}">
<h:inputText id="email#{customer.id}" value="#{adminService.customerEmail}"/><br/>
<h:inputText id="firstName#{customer.id}" value="#{adminService.customerFirstName}"/>
<h:inputText id="lastName#{customer.id}" value="#{adminService.customerLastName}"/><br/>
<h:commandButton id="saveEdit#{customer.id}" type="button" value="Save">
<f:ajax render="#form" event="click" listener="#{adminService.saveCustomer()}"/>
</h:commandButton>
<h:commandButton id="cancelEdit#{customer.id}" type="button" value="Cancel">
<f:ajax render="#form" event="click" listener="#{adminService.cancelEdit()}"/>
</h:commandButton>
</p>
</f:subview>
...
</h:form>
AdminService.java Snippet:
#Named
#Stateless
#LocalBean
public class AdminService {
public String getEditCustomerClass(int id) {
return id != customerId ? "hidden" : "";
}
public void saveCustomer() {
cancelEdit();
}
public void cancelEdit() {
movieId = -1;
customerId = -1;
orderId = -1;
actorId = -1;
employeeId = -1; //if none of the id's match, p should return 'hidden' class and not be seen.
}
}
Originally I had problems because instead of hiding and showing with CSS, I was using the "rendered=" attribute. However, I heard that partial rendering of views can break AJAX, so I phased it out, hoping that not partially rendering the view (only hiding and showing it) would fix the problem.
However this ajax is still not calling the method I specified in the listener attribute (the entire page is a lot bigger and uses a lot more AJAX, though the rest of it works until these buttons are pressed, then other ajax buttons stop responding.)
If I change the button type to submit, it will actually perform the listener method if I press the button twice, but then the other ajax links don't call their respective listener methods.
How can I get this to work?
Update:
Here is the information from POST request that JSF fires on click:
Request Headers:
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:2186
Content-type:application/x-www-form-urlencoded;charset=UTF-8
Cookie:JSESSIONID=7342e0de92edc023eecbf706dae3
Faces-Request:partial/ajax
Host:www.minimalcomputers.com:8181
Origin:https://www.minimalcomputers.com:8181
Referer:https://www.minimalcomputers.com:8181/MovieProject/Admin/admin.xhtml
User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
Form Data:
adminPanel:adminPanel
adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:email1:phroph#yahoo.com
adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:firstName1:
adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:lastName1:
adminPanel:representativeActionPane:customerPane:customersList:1:editCustomer1:email1:phroph#yahoo.com
adminPanel:representativeActionPane:customerPane:customersList:1:editCustomer1:firstName1:
adminPanel:representativeActionPane:customerPane:customersList:1:editCustomer1:lastName1:
adminPanel:representativeActionPane:customerPane:customersList:2:editCustomer1:email1:phroph#yahoo.com
adminPanel:representativeActionPane:customerPane:customersList:2:editCustomer1:firstName1:
adminPanel:representativeActionPane:customerPane:customersList:2:editCustomer1:lastName1:
adminPanel:representativeActionPane:customerPane:customersList:3:editCustomer1:email1:phroph#yahoo.com
adminPanel:representativeActionPane:customerPane:customersList:3:editCustomer1:firstName1:
adminPanel:representativeActionPane:customerPane:customersList:3:editCustomer1:lastName1:
adminPanel:representativeActionPane:customerPane:customersList:4:editCustomer1:email1:phroph#yahoo.com
adminPanel:representativeActionPane:customerPane:customersList:4:editCustomer1:firstName1:
adminPanel:representativeActionPane:customerPane:customersList:4:editCustomer1:lastName1:
javax.faces.ViewState:1088200739038195170:4402027985833798256
javax.faces.source:adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:cancelEdit1
javax.faces.partial.event:click
javax.faces.partial.execute:adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:cancelEdit1 adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:cancelEdit1
javax.faces.partial.render:adminPanel
javax.faces.behavior.event:click
javax.faces.partial.ajax:true
Response Header
Cache-Control:no-cache
Content-Type:text/xml;charset=UTF-8
Date:Thu, 02 May 2013 21:45:05 GMT
Server:GlassFish Server Open Source Edition 3.1.2.2
Transfer-Encoding:chunked
X-Powered-By:Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 3.1.2.2 Java/Sun Microsystems Inc./1.6)
X-Powered-By:JSF/2.0
Update 2:
When I switch to commandButtons of type "submit" without AJAX, it works as expected (except some of the buttons requires two clicks to activate). So the problem is localized to the f:ajax tags.
Update 3:
The entire base of code for admin.xhtml. IT's a bit unclean because it's in the process of being debugged and trying things to make it work.
<?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:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"/>
<h:outputStylesheet name="header.css" library="css"/>
<link href='http://fonts.googleapis.com/css?family=Noto+Sans' rel='stylesheet' type='text/css'/>
<title>VideoPile - Administration</title>
</h:head>
<h:body>
<div id="body">
<ui:insert name="header" >
<ui:include src="/templates/header.xhtml" />
</ui:insert>
<div id="content">
Admin.
<h:form id="adminPanel">
<!--<h:commandButton id="admin" value="Administrative Actions" rendered="{adminService.hasAdminPrivileges()}">
<f:ajax render="#form" event="click" listener="{adminService.toggleAdminPane()}"/>
</h:commandButton>-->
<h:commandButton id="manager" type="button" value="Manager Actions" rendered="#{adminService.hasManagerPrivileges()}">
<f:ajax render="#form" event="click" listener="#{adminService.toggleManagerPane()}"/>
</h:commandButton>
<h:commandButton id="representative" type="button" value="Representative Actions" rendered="#{adminService.hasRepresentativePrivileges()}">
<f:ajax render="#form" event="click" listener="#{adminService.toggleRepresentativePane()}" />
</h:commandButton>
<br/>
<!--<f:subview id="administrativeActionPane" rendered="{userService.showAdminPane}">
Admin Pane
</f:subview>-->
<f:subview id="managerialActionPane">
<div class="#{adminService.getShowManagerClass()}">
Manager Pane:
<h:commandLink id="editmovies" value="Movies">
<f:ajax render="#form" event="click" listener="#{adminService.toggleMoviePane()}"/>
</h:commandLink>
<h:commandLink id="employes" value="Employees">
<f:ajax render="#form" event="click" listener="#{adminService.toggleEmployeePane()}"/>
</h:commandLink>
<h:commandLink id="sales" target="_blank" value="View Sales Report" action="/Admin/salesreport"/>
<h:commandLink id="employees" target="_blank" value="View Most Active Employees" action="/Admin/activeemployees"/>
<h:commandLink id="customers" target="_blank" value="View Most Active Customers" action="/Admin/activecustomers"/>
<h:commandLink id="movies" target="_blank" value="View Most Active Movies" action="/Admin/activemovies"/>
<br/>
<f:subview id="moviesEditPane">
<span class="#{adminService.getShowMovieClass()}">
Movies.
<ui:repeat value="#{adminService.currentMoviePage}" var="movie">
#{movie.name}
<h:commandLink id="edit" value="Edit">
<f:ajax render="#form" event="click" listener="#{adminService.editMovie(movie.id)}"/>
</h:commandLink>
<h:outputText rendered="#{adminService.movieId eq movie.id}" value="edit"/>
<br/>
</ui:repeat>
</span>
</f:subview>
<f:subview id="employeesEditPane">
<span class="#{adminService.getShowEmployeeClass()}">
Employees.
<ui:repeat value="#{adminService.currentEmployeePage}" var="employee">
#{employee.firstName} #{employee.lastName}
<h:commandLink id="edit" value="Edit">
<f:ajax render="#form" event="click" listener="#{adminService.editEmployee(employee.id)}"/>
</h:commandLink>
<h:outputText rendered="#{adminService.employeeId eq employee.id}" value="edit"/>
<br/>
</ui:repeat>
</span>
</f:subview>
</div>
</f:subview>
<f:subview id="representativeActionPane">
<div class="#{adminService.getShowRepresentativeClass()}">
Customer Representative Pane:
<h:commandLink id="recordOrder" value="Record Order">
<f:ajax render="#form" event="click" listener="#{adminService.toggleOrderPane()}"/>
</h:commandLink>
<h:commandLink id="customers" value="Customers">
<f:ajax render="#form" event="click" listener="#{adminService.toggleCustomerPane()}"/>
</h:commandLink>
<h:commandLink id="mailingList" target="_blank" value="View Mailing List" action="/Admin/mailinglist"/>
<f:subview id="orderPane">
<span class="#{adminService.getShowOrderClass()}">
Create new order.
</span>
</f:subview>
<f:subview id="customerPane">
<span class="#{adminService.getShowCustomerClass()}">
Customers.
<ui:repeat id="customersList" value="#{adminService.currentCustomerPage}" var="customer">
<f:subview id="editCustomer#{customer.id}">
<p class="#{adminService.getEditCustomerClass(customer.id)}">
<h:inputText id="email#{customer.id}" value="#{adminService.customerEmail}"/><br/>
<h:inputText id="firstName#{customer.id}" value="#{adminService.customerFirstName}"/>
<h:inputText id="lastName#{customer.id}" value="#{adminService.customerLastName}"/><br/>
<h:commandButton id="saveEdit#{customer.id}" type="submit" value="Save" actionListener="#{adminService.saveCustomer()}">
<f:ajax render="#form" event="click" execute="#form"/>
</h:commandButton>
<h:commandButton id="cancelEdit#{customer.id}" type="submit" value="Cancel" actionListener="#{adminService.cancelEdit()}">
<f:ajax render="#form" event="click" execute="#form" />
</h:commandButton>
</p>
</f:subview>
<f:subview id="viewCustomer#{customer.id}">
<p class="#{adminService.getViewCustomerClass(customer.id)}">
#{customer.email}<br/>
#{customer.firstName} #{customer.lastName}<br/>
<h:commandLink id="suggestion" target="_blank" value="View Suggestions" action="/Admin/customersuggestions">
<f:param name="user" value="#{customer.id}"/>
</h:commandLink>
<h:commandButton id="edit" type="submit" value="Edit" action="#{adminService.editCustomer(customer)}">
<f:ajax render="#form" event="click" execute="#form" />
</h:commandButton>
</p>
</f:subview>
<br/>
</ui:repeat>
</span>
</f:subview>
</div>
</f:subview>
</h:form>
</div>
</div>
</h:body>
</html>
I found the answer, and the cause of it is really quite strange, but it makes sense.
In my ID's, I was using EL to define unique ID's for UIComponents (even though this was not necessary). When I remove the EL from the ID's, the ajax works!
I'm presuming (though I'm sure BalusC would give a more thorough answer), was that because the id's aren't static, even though the ID in concept would be the same, it was affecting the way JSF finds UIComponents.
Now I feel dumb, because the problem would've been completely avoidable if I didn't add any superfluous elements.
For example, the code in my original post should be as follows:
<h:form id="adminPanel">
...
<f:subview id="editCustomer">
<p class="#{adminService.getEditCustomerClass(customer.id)}">
<h:inputText id="email" value="#{adminService.customerEmail}"/><br/>
<h:inputText id="firstName" value="#{adminService.customerFirstName}"/>
<h:inputText id="lastName" value="#{adminService.customerLastName}"/><br/>
<h:commandButton id="saveEdit" type="button" value="Save">
<f:ajax render="#form" event="click" listener="#{adminService.saveCustomer()}"/>
</h:commandButton>
<h:commandButton id="cancelEdit" type="button" value="Cancel">
<f:ajax render="#form" event="click" listener="#{adminService.cancelEdit()}"/>
</h:commandButton>
</p>
</f:subview>
...
</h:form>
Is there any reason for submitting the form by the Javascript Event onclick?
I suggest you to call the action like this:
<h:commandButton id="saveEdit#{customer.id}" value="Submit" actionListener="#{adminService.saveCustomer()}">
<f:ajax render="#form" execute="#form"/>
</h:commandButton>