display dialogue immediately after selecting value in selectonemenu - primefaces

I have a requirement with p:selectonemenu when I am using inside dataTable.
<p:selectOneMenu value="#{buyerInProcessBean.subject}"
id="buyerResponseId" >
<f:selectItems
value="#{buyerInProcessBean.subjectMap[trans.decisionrule.ruleId]}"
var="subject" itemLabel="#{subject}" itemValue="#{subject}"></f:selectItems>
<f:selectItem itemLabel="Other" itemValue="Other"></f:selectItem>
</p:selectOneMenu>
If I choose 'other' a dialogue must compulsory get popup. otherwise it is not mandatory.
How can I achieve this type of requirement?

You should bind a function to an onchange event of your <p:selectOneMenu>, find out if the value of the desired option matches the value that should open the dialog, and trigger dialog.open() in that case.
Note, that Primefaces' component wraps the <select> tag within some divs and outputs the selected <option> in an intermediary component, therefore attachment of event to the hidden <select> element won't work. On the other hand, for example, JSF <h:selectOneMenu> tag renders a <select> element, so binding behaviour to the onchange will trigger the desired behaviour.
The view:
<h:form id="form">
<p:selectOneMenu value="#{buyerInProcessBean.subject}" id="buyerResponseId" onchange="changeEvent(this)">
<f:selectItems value="#{buyerInProcessBean.subjectMap[trans.decisionrule.ruleId]}"
var="subject" itemLabel="#{subject}" itemValue="#{subject}" />
<f:selectItem itemLabel="Other" itemValue="Other" />
</p:selectOneMenu>
</h:form>
<p:dialog widgetVar="dialog">
<h:outputText value="Additional Data" />
</p:dialog>
The JavaScript:
function changeEvent(element) {
var val = $(element).find('option:selected').text();
if(val === 'Other') {
dialog.show();
}
}

Related

Render component in primefaces by value [duplicate]

How can I show/hide component with JSF?
I am currently trying so do the same with the help of javascript but not successfull.
I cannot use any third party libraries.
Thanks| Abhi
You can actually accomplish this without JavaScript, using only JSF's rendered attribute, by enclosing the elements to be shown/hidden in a component that can itself be re-rendered, such as a panelGroup, at least in JSF2. For example, the following JSF code shows or hides one or both of two dropdown lists depending on the value of a third. An AJAX event is used to update the display:
<h:selectOneMenu value="#{workflowProcEditBean.performedBy}">
<f:selectItem itemValue="O" itemLabel="Originator" />
<f:selectItem itemValue="R" itemLabel="Role" />
<f:selectItem itemValue="E" itemLabel="Employee" />
<f:ajax event="change" execute="#this" render="perfbyselection" />
</h:selectOneMenu>
<h:panelGroup id="perfbyselection">
<h:selectOneMenu id="performedbyroleid" value="#{workflowProcEditBean.performedByRoleID}"
rendered="#{workflowProcEditBean.performedBy eq 'R'}">
<f:selectItem itemLabel="- Choose One -" itemValue="" />
<f:selectItems value="#{workflowProcEditBean.roles}" />
</h:selectOneMenu>
<h:selectOneMenu id="performedbyempid" value="#{workflowProcEditBean.performedByEmpID}"
rendered="#{workflowProcEditBean.performedBy eq 'E'}">
<f:selectItem itemLabel="- Choose One -" itemValue="" />
<f:selectItems value="#{workflowProcEditBean.employees}" />
</h:selectOneMenu>
</h:panelGroup>
Generally, you need to get a handle to the control via its clientId. This example uses a JSF2 Facelets view with a request-scope binding to get a handle to the other control:
<?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">
<h:head><title>Show/Hide</title></h:head>
<h:body>
<h:form>
<h:button value="toggle"
onclick="toggle('#{requestScope.foo.clientId}'); return false;" />
<h:inputText binding="#{requestScope.foo}" id="x" style="display: block" />
</h:form>
<script type="text/javascript">
function toggle(id) {
var element = document.getElementById(id);
if(element.style.display == 'block') {
element.style.display = 'none';
} else {
element.style.display = 'block'
}
}
</script>
</h:body>
</html>
Exactly how you do this will depend on the version of JSF you're working on. See this blog post for older JSF versions: JSF: working with component identifiers.
Use the "rendered" attribute available on most if not all tags in the h-namespace.
<h:outputText value="Hi George" rendered="#{Person.name == 'George'}" />
You should use <h:panelGroup ...> tag with attribute rendered. If you set true to rendered, the content of <h:panelGroup ...> won't be shown. Your XHTML file should have something like this:
<h:panelGroup rendered="#{userBean.showPassword}">
<h:outputText id="password" value="#{userBean.password}"/>
</h:panelGroup>
UserBean.java:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class UserBean implements Serializable{
private boolean showPassword = false;
private String password = "";
public boolean isShowPassword(){
return showPassword;
}
public void setPassword(password){
this.password = password;
}
public String getPassword(){
return this.password;
}
}
One obvious solution would be to use javascript (which is not JSF). To implement this by JSF you should use AJAX. In this example, I use a radio button group to show and hide two set of components. In the back bean, I define a boolean switch.
private boolean switchComponents;
public boolean isSwitchComponents() {
return switchComponents;
}
public void setSwitchComponents(boolean switchComponents) {
this.switchComponents = switchComponents;
}
When the switch is true, one set of components will be shown and when it is false the other set will be shown.
<h:selectOneRadio value="#{backbean.switchValue}">
<f:selectItem itemLabel="showComponentSetOne" itemValue='true'/>
<f:selectItem itemLabel="showComponentSetTwo" itemValue='false'/>
<f:ajax event="change" execute="#this" render="componentsRoot"/>
</h:selectOneRadio>
<H:panelGroup id="componentsRoot">
<h:panelGroup rendered="#{backbean.switchValue}">
<!--switchValue to be shown on switch value == true-->
</h:panelGroup>
<h:panelGroup rendered="#{!backbean.switchValue}">
<!--switchValue to be shown on switch value == false-->
</h:panelGroup>
</H:panelGroup>
Note: on the ajax event we render components root. because components which are not rendered in the first place can't be re-rendered on the ajax event.
Also, note that if the "componentsRoot" and radio buttons are under different component hierarchy. you should reference it from the root (form root).
check this below code.
this is for dropdown menu. In this if we select others then the text box will show otherwise text box will hide.
function show_txt(arg,arg1)
{
if(document.getElementById(arg).value=='other')
{
document.getElementById(arg1).style.display="block";
document.getElementById(arg).style.display="none";
}
else
{
document.getElementById(arg).style.display="block";
document.getElementById(arg1).style.display="none";
}
}
The HTML code here :
<select id="arg" onChange="show_txt('arg','arg1');">
<option>yes</option>
<option>No</option>
<option>Other</option>
</select>
<input type="text" id="arg1" style="display:none;">
or you can check this link
click here

Why does my form isn't reseting his styling after render?

I have a form with tree buttons on in. One of them is the "Cancel" button that goes back to the previous page.
The problem is there is any validation issue, like a mandatory field not submited, the styling of the field is not reset when I go back to the form.
This is a simplified structure of the xhtml:
<panel id="horizontal">
<form id="filterVipLoungeForm">
</form>
<form id="frmAddPax">
<form id="frmAccessType">
</form>
</form>
<panelGrid>
<commandButton value="agregar" />
<commandButton value="limpiar" />
<commandButton value="cancelar" />
</panelGrid>
</panel>
The code of the button that calls the add passenger form:
<p:commandButton
value="#{label['manageVipLoungeEntrance.button.addPassenger']}"
action="#{manageVipLoungeEntranceExtMB.setRenderStatus(3, 1)}"
actionListener="#{manageVipLoungeEntranceExtMB.hideMainForm}"
update=":filterVipLoungeForm :horizontal">
</p:commandButton>
The code of the cancel button:
<p:commandButton
value="#{label['manageVipLoungeEntrance.button.cancel']}"
onclick="showLocalDate()"
action="#{manageVipLoungeEntranceExtMB.setRenderStatus(0, 1)}"
actionListener="#{manageVipLoungeEntranceExtMB.setRenderStatus(3, 0)}"
update=":filterVipLoungeForm :horizontal">
</p:commandButton>
This calls a method from the backing bean calls setRenderStatus that set the form and he's render status to be evaluated in the rendered attribute.
In this process the render status of the cancel button's form is set to false and the render status of the previous form is set to true.
The hideMainForm method calls two times the setRenderStatus method, setting the main form render status to false and the add passenger render status to true.
The problem there is any validation error and if I go back to the previous page and come back to the form I'm still getting the validation errors.
[EDIT]
Sorry I forgot to add the code of the rendered evaluation of the two forms involucrated in this:
Render status validation for form "frmAddPax"
<h:form id="frmAddPax" rendered="#{manageMB.renderStatus.isRenderFormAddPax()}">
Render status validation for form "filterVipLoungeForm"
<h:form id="filterVipLoungeForm" style="width:95% !important;"
rendered="#{manageMB.renderStatus.isRenderFormMain()}"
onkeypress="return event.keyCode != 13">
I have tried by using the <p:resetInput>but it didn't work, with this I was expecting the form with the id frmAddPax reset his status but it didn't work:
<p:commandButton
value="#{label['manageVipLoungeEntrance.button.cancel']}"
onclick="showLocalDate()"
action="#{manageVipLoungeEntranceExtMB.setRenderStatus(0, 1)}"
actionListener="#{manageVipLoungeEntranceExtMB.setRenderStatus(3, 0)}"
update=":filterVipLoungeForm :horizontal">
<p:resetInput target=":frmAddPax" />
</p:commandButton>
I used the <p:ajax resetValues="true"> and this one works as I needed.
I really don't know why work with the ajax and not with the resetInput.
<p:commandButton
value="#{label['manageVipLoungeEntrance.button.cancel']}"
onclick="showLocalDate()"
action="#{manageVipLoungeEntranceExtMB.setRenderStatus(0, 1)}"
actionListener="#{manageVipLoungeEntranceExtMB.setRenderStatus(3, 0)}"
update=":filterVipLoungeForm :horizontal">
<p:ajax update=":frmAddPax" resetValues="true" />
</p:commandButton>

property not found + ajax

I'm trying to use primefaces component called rating inside a datatable.
<p:column headerText="Minha Dificuldade" syle="text-align: center; width: 100px">
<p:rating readonly="false" stars="10" value="#{cadastroDificuldadeBean.calculaMinhaDificuldade(jogo)}" >
<f:param name="jogoId" value="#{jogo.id}" />
<p:ajax event="rate" listener="#{cadastroDificuldadeBean.onrate}" />
</p:rating>
</p:column>
On page load my column is visible with p:rating calculated (method with parameter). When I click on star to rating an ajax call is submitted (event = "rate") and a throw is shown Property 'calculaMinhaDificuldade' not found on type 'my class'.
Any ideas?

Primefaces 5 Delete button inside a datagrid with confirmation box Pass parameter value to the bean on click of yes of confirmation box

We are using Primefaces 5
We are having one datagrid for search results. Inside datagrid there is one delete button for every row. Onclick of delete button a confirmation box is being displayed when the user clicks on yes button of confirmation dialog box then deleteUser method of bean should be called and the user with value of parameter id ‘testUserId’ should be deleted. Problem is the value of ‘testUserId’ which is being sent to bean is always value of userId of the last row of the datagrid. How to pass the value of the 'testUserId' of the current row from where delete button is clicked to the bean method?
Given below is the snippet of the code
Xhtml:-
<p:commandButton action="#{bean.deleteUser}" value="Delete"
ajax="false" onclick="PF('confirmation').show()" type="button">
</p:commandButton>
<p:confirmDialog
message="Are you sure about deleting the user?"
header="Initiating user deletion" severity="alert"
widgetVar="confirmation" appendTo="">
<p:commandButton value="Yes Sure" ajax="false" onclick="resetSearchForm()"
oncomplete="PF('confirmation').hide()" action="#{bean.deleteUser}" >
<f:param name="testUserId" value="#{user.id}"></f:param>
</p:commandButton>
<p:commandButton value="Not Yet" onclick="PF('confirmation').hide()"
type="button" />
</p:confirmDialog>
Bean:-
public void deleteUser() {
String id = FacesContext.getCurrentInstance().getExternalContext()
.getRequestParameterMap().get("testUserId ");
}
Use a property action listener:
<p:commandButton value="Delete" ajax="false" onclick="PF('confirmation').show()" type="button">
<f:setPropertyActionListener value="#{tableRowVar}" target="#{bean.selectedUser}" />
</p:commandButton>
Where tableRowVar is the name of the var in your dataTable and bean.selectedUser a property in your bean which will hold the selected row. Remove the action from the commandButton and leave it only in the confirm dialog's button.
Let me know if this works.

Avoid focus in datatable filter in dialog

I have a popup dialog with datatable and I want to have no focus in filter inputText fields. I want to have focus on button under this table.
I tried this:
<p:focus id="focus" for="buttonFocus" context="dialog"/>
<p:dialog id="dialog" header="Выбор организации" widgetVar="vDialog" modal="true" resizable="false">
<p:dataTable
dblClickSelect="true"
id="table"
var="record"
value="#{myBean.tableList}"
rowKey="#{record.waId}"
filteredValue="#{myBean.filteredList}"
lazy="true"
>
<p:column headerText="Name" filterBy="#{recordp.name}" sortBy="#{recordp.name}">
#{record.name}
</p:column>
</p:dataTable>
<p:commandButton id="buttonFocus" actionListener="#{myBean.fill}"/>
</p:dialog>
it doesn't help.
So, how to set focus on button in such situation?
I found several suggestions.
So first one, which worked for me is:
<script type="text/javascript">
PrimeFaces.widget.Dialog.prototype.applyFocus = function() {
var firstInput = this.jq.find('#buttonFocus');
firstInput.focus();
}
</script>
You don't need p:focus for this method. And also don't forget add prependId="false" to form, because otherwise id will change.
Second which worked with input elements only (not with button):
<script type="text/javascript">
PrimeFaces.widget.Dialog.prototype.applyFocus = function() {
}
</script>
Here you need p:focus element, but like I said this works with inputs only.
And third solution you can look in this blog , if you have right versions of primefaces (not tested)