display a panel after just a select Item - jsf-2

I want to display a panel after just a select Item, I think of that but it give me an error.
Code:
<h:outputText value="* produit" />
<h:selectOneMenu id="produit" value="#{clientMB.selectProduit}">
<p:ajax update="client" listener="#{clientMB.getClientsProduit}" />
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{produitMB.produits}" noSelectionValue="" var="prod" itemValue="#{prod.refProd}" itemLabel="#{prod.libProd}" />
<f:selectItem itemLabel="Autre" itemValue="" value="lazyload()"/>
</h:selectOneMenu>
<p:outputPanel id="lazypanel" layout="block">
<h:outputText value="This part of page is lazily loaded on demand using a RemoteCommand" rendered="#{requestScope.shouldRender}"/>
</p:outputPanel>
Error:
javax.servlet.ServletException: java.lang.String cannot be cast to javax.faces.model.SelectItem

Solution
<h:outputText value="* produit" />
<h:selectOneMenu id="produit" value="#{clientMB.selectProduit}" onchange="lazyload()">
<p:ajax update="client" listener="#{clientMB.getClientsProduit}" />
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{produitMB.produits}" noSelectionValue="" var="prod" itemValue="#{prod.refProd}" itemLabel="#{prod.libProd}" />
<f:selectItem itemLabel="Autre" itemValue="" />
</h:selectOneMenu>
<p:outputPanel id="lazypanel" layout="block">
<h:outputText value="This part of page is lazily loaded on demand using a RemoteCommand" rendered="#{requestScope.shouldRender}"/>
</p:outputPanel>
<p:remoteCommand name="lazyload" update="lazypanel">
<f:setPropertyActionListener value="#{true}" target="#{requestScope.shouldRender}" />
</p:remoteCommand>

Related

p:splitButton menuitem with immediate="true" always removes last row of p:dataTable

p:splitButton menuitem for delete functionality with immediate="true" always removes last row of data table even when middle row is deleted it always delete last row. How is this caused and how can I solve it?
The below data table is inside p:wizard and I have to validate data table field values on pressing next button of p:wizard only.
<p:dataTable id="nomineeEducation" var="education" value="#{nominee.prospective.schoolHistoryToSave}" rowIndexVar="status"
rendered="#{fn:length(nominee.prospective.schoolHistoryToSave) > 0}">
<p:column headerText="School" width="250">
<p:selectOneMenu value="#{education.lookupSchoolId}" required="true"
requiredMessage="Education# #{status+1}: Please select School.">
<f:selectItem itemLabel="--School--" itemValue="#{null}" />
<f:selectItems value="#{selectItemList.schoolList}" />
</p:selectOneMenu>
</p:column>
<p:column headerText="Degree Obtained" width="250">
<p:selectOneMenu value="#{education.schoolAffiliations[0].educationId}" required="true"
requiredMessage="Education# #{status+1}: Please select Degree Obtained.">
<f:selectItem itemLabel="--Degree--" itemValue="#{null}" />
<f:selectItems value="#{selectItemList.educationList}" />
</p:selectOneMenu>
</p:column>
<p:column headerText="Dates Attended" width="150">
<p:selectOneMenu value="#{education.underGradMonth}" required="true"
requiredMessage="Education# #{status+1}: Please select Degree Month.">
<f:selectItem itemLabel="--Month--" itemValue="#{null}" />
<f:selectItems value="#{selectItemList.monthList}" />
</p:selectOneMenu>
<p:selectOneMenu value="#{education.underGradYear}" required="true"
requiredMessage="Education# #{status+1}: Please select Degree Year.">
<f:selectItem itemLabel="--Year--" itemValue="#{null}" />
<f:selectItems value="#{selectItemList.yearList}" />
</p:selectOneMenu>
</p:column>
<p:column headerText="Action" width="150">
<p:splitButton value="Select">
<p:menuitem value="Delete" action="#{nominee.deleteEducation(education, false)}" update="nomineeEducation" icon="ui-icon-close" immediate="true"/>
<p:menuitem value="Add New" action="#{nominee.addEducation(false)}" update="nomineeEducation" icon="ui-icon-plus"
rendered="#{fn:length(nominee.prospective.schoolHistoryToSave) eq (status+1)}" />
</p:splitButton>
</p:column>
</p:dataTable>
As said on http://forum.primefaces.org/viewtopic.php?f=3&t=38506, you cannot send data to backing bean if you use immediate="true".
A workaround would be to change your splitButton code for something like:
<p:splitButton value="Select">
<p:menuitem value="Delete"
action="#{nominee.deleteEducation(education, false)}"
update="nomineeEducation"
icon="ui-icon-close"
process="#this"
global="false"
/>
<p:menuitem value="Add New"
action="#{nominee.addEducation(false)}"
update="nomineeEducation"
icon="ui-icon-plus"
rendered="#{fn:length(nominee.prospective.schoolHistoryToSave) eq (status+1)}"
/>
</p:splitButton>

How to render p:selectOneMenu inside an editable p:dataTable

I would like to render p:selectOneMenu inside p:dataTable upon rowEditInit event. I tried update="degreeType", update=formid:editTable:degreeType but it didn't work. update="#this is not a option as it refreshes whole table and clears the edit selection. As it is a dataTable, the exact id for the element is formid:editTable:0:degreeType, 0 being row number. How should I get the current row id number and put in update field?
<p:dataTable id="editTable" value="#{bean.emp}" var="stud" disabledSelection="true" editable="true" >
<p:ajax event="rowEditInit" listener="#{bean.onRowInit}" update="degreeType"/>
<p:ajax event="rowEdit" listener="#{bean.onRowEdit}" />
<p:ajax event="rowEditCancel" listener="#{bean.onRowCancel}" />
<!-- a bunch of p:column tags -->
<p:column headerText="Degree">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{stud.degree}" /></f:facet>
<f:facet name="input">
<p:selectOneMenu value="#{stud.degree}" style="width: 100%" >
<f:ajax event="change" listener="#{bean.degreeListener}" render="degreeType" />
<f:selectItem itemLabel="Select One" itemValue=""/>
<f:selectItem itemLabel="MS" itemValue="MS"/>
<f:selectItem itemLabel="BS" itemValue="BS"/>
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="DegreeType">
<p:cellEditor id="test">
<f:facet name="output"><h:outputText value="#{stud.degreeType}" /></f:facet>
<f:facet name="input">
<p:selectOneMenu id="degreeType" value="#{stud.degreeType}" rendered="true">
<f:selectItem itemLabel="Select One" itemValue="" noSelectionOption="true"/>
<f:selectItems value="#{stud.degreeTypes}"/>
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column style="width: 30px">
<p:rowEditor />
</p:column>
</p:dataTable>

primefaces save on datatable edit not working

my xhtml page. the add functionality works fine. So the converters are working and as ViewScope is not working, I tried SessionScope and it works fine.
<p:commandButton id="addOfficeButton" icon="ui-icon-circle-plus" oncomplete="AddOfficeDialog.show();"/>
<h:form id="officeform">
<p:growl id="growl" showDetail="true" sticky="true" />
<p:dataTable id="officeDT" var="office" value="#{offices}" rowKey="#{office.id}" style="width:40%"
selection="#{officeManagementController.selectedOffice}" selectionMode="single" editable="true">
<p:ajax event="rowSelect" listener="#{officeManagementController.onRowSelect}" oncomplete="editDlg.show()"
update=":tabView:officeform:growl,:tabView:officeform:editPanel"/>
<p:column sortBy="#{office.id}" headerText="Office ID">
<h:outputText value="#{office.id}" />
</p:column>
<p:column headerText="System">
<h:outputText value="#{office.department.name}" />
</p:column>
<p:column headerText="Section">
<h:outputText value="#{office.role.name}" rendered="#{office.role!=null}"/>
</p:column>
<p:column headerText="Options" style="width:50px">
<p:rowEditor></p:rowEditor>
</p:column>
</p:dataTable>
<p:dialog id="AddOfficeDialog" widgetVar="AddOfficeDialog" modal="true" header="Add/Edit Office" hideEffect="fade" showEffect="fade">
<p:outputPanel layout="block" id="officeDetail">
<p:panelGrid columns="2">
<h:outputText value="Systemmm" />
<h:selectOneMenu value="#{officeManagementController.selectedSystem}" converter="#{applicationSystemConverter}">
<f:selectItem itemLabel="Select One" itemValue="#{null}" />
<f:selectItems value="#{departmentss}" var="appdepartment" itemLabel="#{appdepartment.name}" itemValue="#{appdepartment}"/>
<f:ajax event="change" listener="#{officeManagementController.onDepartmentChanged}" render="role"/>
</h:selectOneMenu>
<h:outputText value="Section" />
<h:selectOneMenu id="role" validate="true" value="#{officeManagementController.newOffice.role}" converter="#{departmentSectionConverter}">
<f:selectItem itemLabel="Select One" itemValue="#{null}" />
<f:selectItems value="#{officeManagementController.assignableRoles}" var="role" itemLabel="#{role.name}" itemValue="#{role}"/>
</h:selectOneMenu>
</p:panelGrid>
<p:outputPanel layout="block" style="text-align:center;">
<p:commandButton actionListener="#{officeManagementController.createOffice}" id="addOffice"
value="Add Office" title="Add new office" oncomplete="AddOfficeDialog.hide();" update="growl,officeform"/>
</p:outputPanel>
</p:outputPanel>
</p:dialog>
<p:dialog id="editDlg" widgetVar="editDlg" modal="true" header="Add/Edit Office" hideEffect="fade" showEffect="fade">
<p:outputPanel id="editPanel">
<p:panelGrid columns="2">
<h:outputLabel value="Office ID: " />
<h:outputText value="#{officeManagementController.selectedOffice.id}"/>
<h:outputText value="System" />
<h:selectOneMenu value="#{officeManagementController.selectedOffice.department}" converter="#{applicationSystemConverter}">
<f:selectItem itemLabel="Select One" itemValue="#{null}" />
<f:selectItems value="#{applicationSystems}" var="appdepartment" itemLabel="#{appdepartment.name}" itemValue="#{appdepartment}"/>
<f:ajax event="change" listener="#{officeManagementController.onApplicationSystemChanged}" render="sect"/>
</h:selectOneMenu>
<h:outputText value="Section" />
<h:selectOneMenu id="sect" validate="true" value="#{officeManagementController.selectedOffice.role}" converter="#{departmentSectionConverter}">
<f:selectItem itemLabel="Select One" itemValue="#{null}" />
<f:selectItems value="#{officeManagementController.assignableSysSections}" var="role" itemLabel="#{role.name}" itemValue="#{role}"/>
</h:selectOneMenu>
</p:panelGrid>
<p:outputPanel layout="block" style="text-align:center;">
<h:inputHidden binding="#{officeManagementController.selectedOfficeId}" />
<p:commandButton actionListener="#{officeManagementController.updateOffice()}"
value="Update Office" title="Update office" oncomplete="editDlg.hide();" update="#this,editPanel,growl,officeform"/>
</p:outputPanel>
</p:outputPanel>
</p:dialog>
</h:form>
Backing Bean:
public void updateOffice() {
selectedOffice.setId(Long.valueOf((String)selectedOfficeId.getValue()));
officeManagementService.update(selectedOffice);
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, CrudStatusMessage.SUCCESS.toString(), "Successfully updated Module: " + selectedOffice.getName()));
}
I am getting the dialog populated with the row values but the issue is onclick of update button, i am getting a Value is not Valid error on dept, but the main thing is the selectedModule's values are not set. Please help. stuck with it since a week.
I think you actually need actionListener (instead of action) on you button. You should read about the differences in API docs but the bottom line is that actionListener will perform an AJAX post-back while action will lead to a redirect (which in turn will destroy your view and replace it with a new one).
Firstly you don't need () in:
<p:commandButton action="#{officeManagementController.updateOffice}" value="Update Office" title="Update office" oncomplete="editDlg.hide();" update="#this,editPanel,growl,officeform"/>
Try using <f:ajax/> in your <h:selectOneMenu> and check if it works.

Dynamically adding new rows in JSF

I have the following code that allows a user enter some data:
<h:panelGrid columns="2" cellspacing="5">
<h:outputLabel value="#{msg.FrequencyOfSpending}" />
<h:selectOneMenu id="ruleFrequencyOptions" value="#{Rule.ruleControls.ControlOne.controlParams.Period.valueSelected}" styleClass="commonSelect">
<f:selectItems value="#{Rule.ruleControls.ControlOne.controlParams.Period.validValues}" itemLabelEscaped="true" />
<f:ajax event="valueChange" listener="#{Rule.ruleControls.ControlOne.controlParams.Period.valueSelectedChange}" onerror="handleAjaxError" render="rulesGroup" />
</h:selectOneMenu>
</h:panelGrid>
<h:panelGroup id="rulesGroup">
<a4j:repeat value="#{Rule.ruleParams.Action.properties}" var="RuleParamProperty" id="budgetRuleIterator">
<h:panelGrid columns="4" cellspacing="5" columnClasses="ruleParamCheckbox, ruleParamAction, ruleParamActionFrequency, ruleParamActionInput">
<h:selectBooleanCheckbox value="#{RuleParamProperty.selected}" immediate="true">
<a4j:ajax event="click" listener="#{RuleParamProperty.selectedChange}" onerror="handleAjaxError" />
</h:selectBooleanCheckbox>
<h:outputText value="#{msg[RuleParamProperty.name]}" />
<h:panelGrid columns="3">
<h:outputText value="#{msg.Action_1}" />
<h:outputText value="#{msg[Rule.ruleControls.ControlOne.controlParams.Period.valueSelected]}" class="italic-text" />
<h:outputText value="#{msg.Action_3}" />
</h:panelGrid>
<h:inputText value="#{RuleParamProperty.inputValue}" />
</h:panelGrid>
</a4j:repeat>
</h:panelGroup>
<!--******* Link here to generate row with exact same format as all code above ***-->
<h:panelGrid columns="2">
<img id="AddIcon" src="#{facesContext.externalContext.requestContextPath}/images/icons/add.png" alt="#{msg.addControl}" />
<h:link value="#{msg.addControl}" />
</h:panelGrid>
I need to add a link to allow them add different variations of this data i.e. user clicks add new control link and a new row appears that allows them enter more data (of the exact same format). They should be able to add multiple rows of the same data.
What is the best way to approach this with JSF2 and Richfaces4?
Should I put my panelGroups within a table?
Thanks
I used a datatable as suggested by Luiggi:
<h:dataTable value="#{rule}" var="currentRuleItem">
<h:column>
<h:panelGrid columns="2" cellspacing="5">
<h:outputLabel value="#{msg.FrequencyOfSpending}" />
<h:selectOneMenu id="ruleFrequencyOptions" value="#{currentRuleItem.ruleControls.ControlOne.controlParams.Period.valueSelected}" styleClass="commonSelect">
<f:selectItems value="#{currentRuleItem.ruleControls.ControlOne.controlParams.Period.validValues}" itemLabelEscaped="true" />
<f:ajax event="valueChange" listener="#{currentRuleItem.ruleControls.ControlOne.controlParams.Period.valueSelectedChange}" onerror="handleAjaxError" render="rulesGroup" />
</h:selectOneMenu>
</h:panelGrid>
<h:panelGroup id="rulesGroup">
<a4j:repeat value="#{currentRuleItem.ruleParams.Action.properties}" var="RuleParamProperty" id="budgetRuleIterator">
<h:panelGrid columns="4" cellspacing="5" columnClasses="ruleParamCheckbox, ruleParamAction, ruleParamActionFrequency, ruleParamActionInput">
<h:selectBooleanCheckbox value="#{RuleParamProperty.selected}" immediate="true">
<a4j:ajax event="click" listener="#{RuleParamProperty.selectedChange}" onerror="handleAjaxError" />
</h:selectBooleanCheckbox>
<h:outputText value="#{msg[RuleParamProperty.name]}" />
<h:panelGrid columns="3">
<h:outputText value="#{msg.Action_1}" />
<h:outputText value="#{msg[currentRuleItem.ruleControls.ControlOne.controlParams.Period.valueSelected]}" class="italic-text" />
<h:outputText value="#{msg.Action_3}" />
</h:panelGrid>
<h:inputText value="#{RuleParamProperty.inputValue}" />
</h:panelGrid>
</a4j:repeat>
</h:panelGroup>
</h:column>
</h:dataTable>
<!--******* Link here to generate row with exact same format as all code above ***-->
<h:panelGrid columns="2">
<img id="AddIcon" src="#{facesContext.externalContext.requestContextPath}/images/icons/add.png" alt="#{msg.addControl}" />
<h:commandLink value="#{msg.addControl}" action="#{myBean.addRule}" />
</h:panelGrid>
// my bean method
public void addRule()
{
iRuleSet.get("RuleControl1").add(createRule());
}

Can I add/remove Primefaces components dynamically?

How can I add/ remove the primefaces inputText dynamically?
To add/remove textboxes, try the following snippets.
<h:panelGrid columns="1" cellpadding="10">
<h:commandButton value="+" action="#{contactBean.addPhone}"
image="../images/addbtn.png" />
<p:dataTable border="0" value="#{contactBean.phoneNos}" var="p"
rowIndexVar="rowIndex" emptyMessage="No phone numbers entered">
<p:column>
<h:selectOneMenu id="extraTask1" value="#{p.phoneType}">
<f:selectItem itemLabel="Select" itemValue="" />
<f:selectItem itemLabel="Mobile" itemValue="Mobile" />
<f:selectItem itemLabel="Work" itemValue="Work" />
<f:selectItem itemLabel="Others" itemValue="Others" />
</h:selectOneMenu>
</p:column>
<p:column>
<p:inputText value="#{p.phoneNo}" />
</p:column>
<p:column>
<h:commandButton value="remove" image="../images/button_remove.gif"
actionListener="#{contactBean.removePhone}">
<f:param name="columnToRemove" value="#{rowIndex}" />
</h:commandButton>
</p:column>
</p:dataTable>
</h:panelGrid>
This is the easy mode:
<h:inputText rendered="#{object.visibile}" />
if object.visibile == true the inputText is visible.

Resources