primefaces selectonemenu change event not working for null value - ajax

I have a selectonemenu that includes some items. And a null item for showing "please choose one"..
MY goal is to query some data when I select one of them. And if i select the "please choose one" do another thing.
But eventually, the change event is fired for normal values but if I select "please choose one" item , it is not fired. Thanks for your help. Here is my code.
<p:selectOneMenu style="width: 200px" id="positionForward" value="#{hrProcessController.queryCriteria.positionForward}" converter="listConverter"
effect="fade" var="u" filter="true" filterMatchMode="startsWith" validator="#{hrProcessController.isOpenPositionForwValid}">
<f:selectItem itemLabel="#{menu['onemenu.choose']}" itemValue="#{null}"/>
<f:selectItems value="#{hrProcessController.positionList}" var="position" itemLabel="#{position.name}" itemValue="#{position}" />
<p:ajax event="change" listener="#{hrProcessController.onPositionSelect}" update="openPositionForward"/>
<p:column>
<h:outputText value="#{u==null ? menu['onemenu.choose'] : u.name}" />
</p:column>
</p:selectOneMenu>
public void onPositionSelect()
{
if(queryCriteria.getPositionForward()!=null)
{
OpenPositionQueryCriteria criteria = new OpenPositionQueryCriteria();
criteria.setPosition(queryCriteria.getPositionForward());
List<OpenPosition> openPositions = openPositionService.searchOpenPosition(criteria);
setOpenPositionList(openPositions);
}
else
{
List<OpenPosition> positions = openPositionService.getActiveOpenPositionList();
setOpenPositionList(positions);
}
}

If you use itemValue="#{null}" or itemValue="", the valueChangeListener method never will be called.
That's a better approach if you want your first item null:
<f:selectItem
itemDisabled="true"
itemLabel="#{null}"
itemValue="#{null}" />

I had the same problem.
Change event WON'T be fired by selecting default value. Why that is so is beyond me. Such things are normal usually.
I didn't find any real solution.
You should try to write custom validator and converter for this.
Try this:
Using a "Please select" f:selectItem with null/empty value inside a p:selectOneMenu
OK, I finally found the solution to this!
you need to add immediate="true" to ajax call.
Adding immediate tells ajax to ignore any potential validation errors and call the onChange anyway.
Try it.

I was with the same issue so I put the selectItem without the propertie itemValue like that:
<f:selectItem itemLabel="#{menu['onemenu.choose']}" />

Related

Primefaces Datatable disabledSelection update by check

I need to block some checkboxes when reach the limit of 20 checkboxes selected on my Primefaces Datatable, if the checkboxes is lower than 20 then I unblock the checkboxes
This is my code:
On my Datatable:
disabledSelection="#{trackingController.selectedVehicles.size() ge 20 and trackingController.checkboxChecked[vehicle.vehicleId] eq false}"
<p:column selectionMode="multiple" style="width:16px;text-align:center"/>
<p:column visible="false">
<p:outputLabel id="mapCol" styleClass="mapCol" value="#{trackingController.selectedValue(vehicle.vehicleId)}" />
</p:column>
On my Controller:
private Map<Long,Boolean> checkboxChecked = new HashMap<Long,Boolean>();
/*Some method when check*/
checkboxChecked.replace(vehicleEntity.getVehicleId(),true);
/*Some method when uncheck*/
checkboxChecked.replace(vehicleEntity.getVehicleId(),false);
/*To get the actual boolean of the check*/
public boolean selectedValue(long vehicleId){
Boolean res = checkboxChecked.get(vehicleId);
return res;
}
All of this works just fine actually:
reach to the 20 limit, then do a pagination:
The 21 value its disabled and cannot be checked (excellent)
But, if I uncheck one of the first 20, then check the lonely value of the pagination I've got one value of my first 20 disabled (ok):
If I uncheck other value of this first 20 values the behavior I expect its:
The blocked checkbox now can be check, on total 2 checkboxes can be checked now
But what I've got its that the blocked checkbox its still blocked:
The disabledSelection only works fine when do a pagination.
I haven't find a way of refresh the checkbox of some way to achieve the behavior I want.
If anyone have any idea of how update or refresh the table or disabledSelection I will be really grateful. Regards.
A can try add a p:ajax as children of p:dataTable updating the table on rowSelect, rowUnselect and toggleSelect events:
<p:dataTable ...>
<p:ajax event="rowSelect" process="#this" update="#this"/>
<p:ajax event="rowUnselect" process="#this" update="#this"/>
<p:ajax event="toggleSelect" process="#this" update="#this"/>
...
</p:dataTable>

How to Trigger Ajax To Load Nested Dropdowns After Loading A Form?

I have a button to display an edit dialog form with a selectOneMenu that holds prefix number values in it and, after selecting one of those prefix values, three selectCheckboxMenu are loaded with employees data. This is workinkg fine.
<p:outputLabel value="prefix" for="prefixo" />
<h:panelGroup>
<p:selectOneMenu id="prefixo" value="#{demandasController.selected.prefixo}" converter="prefixosConverter" filter="true" filterMatchMode="contains">
<f:selectItem itemLabel="#{adeBundle.SelectOneMessage}" itemValue="#{null}" />
<f:selectItems value="#{prefixosController.items}"
var="prefixoItem"
itemValue="#{prefixoItem}"
itemLabel="#{prefixoItem.prefixo} - #{prefixoItem.nomePrefixo}"
/>
<p:ajax event="valueChange" update="uorPosCollection uorPosCollection1 uorPosCollection2" listener="#{demandasController.changePrefixo}"/>
</p:selectOneMenu>
</h:panelGroup>
<p:outputLabel value="Executivo(s)" for="uorPosCollection" />
<p:selectCheckboxMenu id="uorPosCollection" value="#{demandasController.selected.uorPosCollection}" label="Executivo(s)" multiple="true" converter="uorPosConverter" filter="true" filterMatchMode="contains" >
<f:selectItems value="#{demandasController.availableExecutivos}"
var="uorPosCollectionItem"
itemValue="#{uorPosCollectionItem}"
itemLabel="#{uorPosCollectionItem.matricula} - #{uorPosCollectionItem.nome} (#{uorPosCollectionItem.prefixo.prefixo})" />
</p:selectCheckboxMenu>
<!-- analogous code ommited -->
The Listener:
public void changePrefixo(AjaxBehaviorEvent event) {
availableExecutivos = LoadExecutivosListCombo(super.getSelected().getPrefixo());
//analogous methods ommited
}
The methods to load the employees lists:
private List<UorPos> LoadExecutivosListCombo(Prefixos prefixos) {
List<SelectItem> listExecutivosCombo = new ArrayList<>();
List<UorPos> listExecutivos = uorPosFacade.findUorPosExecutivosByPrefixo(prefixos);
for (int i = 0; i < listExecutivos.size(); i++) {
listExecutivosCombo.add(new SelectItem(listExecutivos.get(i)));
}
return listExecutivos;
}
//analagous methods ommited
Native queries to retrieve database:
public List<UorPos> findUorPosExecutivosByPrefixo(Prefixos prefixo) {
return (List<UorPos>) getEntityManager().createNativeQuery("SELECT * FROM UorPos WHERE prefixo=9951", UorPos.class).setParameter(1, prefixo.getPrefixo()).getResultList();
}
//analagous methods ommited
But when editing a register that already has prefix and employee values (saved earlier by some user), the 3 selectCheckboxMenu are loaded showing (undesired) id's entity class name on its labels value and empty dropdowns:
e.g.: in the figure above, when the edit form was loaded, it shows the values saved earlier by some user: the prefix 9882 (displayed as expected) and the three (empty) dropdowns for employees (displayed with the undesired class names in it). If I select a different value than 9882, the dropdowns are (ajax) filled as expected and if I select 9882 again, the employees are displayed as expected (without the class names):
I'm trying to resolve it by activating the ajax as below, but don't know how to call it in the function:
<p:dialog onShow="CallAjaxFunction()" modal="true" >
<script>
function CallAjaxFunction() {
<!-- how to call the ajax here ? -->
alert("displaying after form was loaded.")
}
</script>
...
</p:dialog>
Does anyone knows how to trigger ajax to load nested dropdowns after loading a form?
Or if someone has any other solution to display the values in the labels (without the class name) and automattically load the nested dropdowns, I appreciate that.
Thanks in advance.
After researching, I've used the listener to update the combos, using for this the open ajax event in the dialog:
<p:dialog onShow="PF('prefixowv').selectValue(':selected').click();" update= DemandasEditForm:uorPosCollection DemandasEditForm:uorPosCollection1 DemandasEditForm:uorPosCollection2 />
And changed the ajax event to selectItem, instead of valueChange:
<p:selectOneMenu id="prefixo" value="#{demandasController.selected.prefixo}" converter="prefixosConverter" filter="true" filterMatchMode="contains">
<f:selectItem itemLabel="#{adeBundle.SelectOneMessage}" itemValue="#{null}" />
<f:selectItems value="#{prefixosController.items}"
var="prefixoItem"
itemValue="#{prefixoItem}"
itemLabel="#{prefixoItem.prefixo} - #{prefixoItem.nomePrefixo}"
/>
<p:ajax event="selectItem" update="uorPosCollection uorPosCollection1 uorPosCollection2" listener="#{demandasController.changePrefixo}"/>
</p:selectOneMenu>
Regards,

h:commandButton's onclick JavaScript method dosen't run before Submitting the form

hello all.I'am new to jsf.
Now i know that to set the Managed Bean attributes i can use forms, But i'm using JavaScript in my jsf page.
what i want is to execute the javascript methode onclickAdd() before submitting the form so the user can see what's changed in an anychart map of tunisia along to a table.
My jsf page have a dropdown list.
<h:form>
Gouvernorats   Temperature (C°) <br/>
<h:selectOneMenu id="list" value="#{GouvBean.name}" >
<f:selectItem itemValue="Tunis" itemLabel="Tunis" />
<f:selectItem itemValue="Médenine" itemLabel="Medenine"/>
<f:selectItem itemValue="Gabès" itemLabel="Gabès"/>
<f:selectItem itemValue="Sfax" itemLabel="Sfax"/>
<f:selectItem itemValue="Sidi Bou Zid" itemLabel="Sidi Bou Zid"/>
<f:selectItem itemValue="Kassérine" itemLabel="Kassérine"/>
<f:selectItem itemValue="Mahdia" itemLabel="Mahdia"/>
<f:selectItem itemValue="Sousse" itemLabel="Sousse"/>
<f:selectItem itemValue="Monastir" itemLabel="Monastir"/>
<f:selectItem itemValue="Tataouine" itemLabel="Tataouine"/>
<f:selectItem itemValue="Kebili" itemLabel="Kebili"/>
<f:selectItem itemValue="Tozeur" itemLabel="Tozeur"/>
<f:selectItem itemValue="Bèja" itemLabel="Bèja"/>
<f:selectItem itemValue="Jendouba" itemLabel="Jendouba"/>
<f:selectItem itemValue="Bizerte" itemLabel="Bizerte"/>
<f:selectItem itemValue="Manubah" itemLabel="Manubah"/>
<f:selectItem itemValue="Ben Arous" itemLabel="Ben Arous"/>
<f:selectItem itemValue="Zaghouan" itemLabel="Zaghouan"/>
<f:selectItem itemValue="Siliana" itemLabel="Siliana"/>
<f:selectItem itemValue="Le Kef" itemLabel="Le Kef"/>
<f:selectItem itemValue="Gafsa" itemLabel="Gafsa"/>
<f:selectItem itemValue="Kairaouan" itemLabel="Kairaouan"/>
<f:selectItem itemValue="Nabeul" itemLabel="Nabeul"/>
</h:selectOneMenu>
<h:inputText id="Temperature" value="#{GouvBean.temperature}" ><f:ajax listener="#{GouvBean.inchange}"/></h:inputText>
<h:commandButton value="+"onclick="onClickAdd();" >
<f:ajax execute="#form"/>
</h:commandButton>
</h:form>
The javascript method changes a table and an AnyChart map:
this is the table:
<table id="myTable">
<thead><tr><th>Gouvernorats</th><th>Temperature</th> </tr></thead>
<tbody></tbody>
</table>
and this is JavaScript method:
//Define a JavaScript method
function onClickAdd(){
//saving the value of the list
var Gov = document.getElementById("list");
var Gid=Gov.options[Gov.selectedIndex];
//deleting the current valye(added value) from the list
Gov.remove(Gov.selectedIndex)
var C°=document.getElementById('Temperature');
//Getting refrence to tbody
var tbodyRef=document.getElementById("myTable").getElementsByTagName("tbody")[0];
//appending a row to tbody
var row=tbodyRef.insertRow(tbodyRef.rows.length);
var cell1=row.insertCell(0);
var cell2=row.insertCell(1);
var cell3=row.insertCell(2);
//Creation of delete button
var del=document.createElement("BUTTON");
var t=document.createTextNode("-");
//Giving value to the cells
cell1.innerHTML=Gid.value;
cell2.innerHTML=C°.value;
cell3.appendChild(del);
//adding a listener to the button
del.appendChild(t);
//OnAddChangeValue(cell1.innerHTML,cell2.innerHTML);
del.addEventListener("click",function(){
//1)knowing the row where the button is(index)
var x=del.parentNode.parentNode.rowIndex;
x=x-1;
//2)moving the value of the first cell back to the list
var l=document.getElementById("list");
//create option node
var node=document.createElement("option");
//create attribute value
var attr1=document.createAttribute("value");
//creation of label
var label=document.createTextNode(tbodyRef.rows[x].cells[0].innerHTML);
//setting a value to the attribute
attr1.value=tbodyRef.rows[x].cells[0].innerHTML;
//linking...
node.setAttributeNode(attr1);
node.appendChild(label);
l.appendChild(node);
//3)deleting the row from the tbody
tbodyRef.deleteRow(x);
// OnDeleteChangeValue(cell1.innerHTML);
});
}
</script>
and this is h:head
<h:head><title>Hello world-JSF-Input Form</title>
</h:head>
help me please
NB: IT WORKS WHEN I ADD h:form before but in this case javascript dont work !
You use ajax in the h:selectOneMenu and h:inputText that sends the values to the server/beans already if they are in an h:form (as you found out). But instead of asking how do I send data without a form (which makes the commandButton 'work'), the question should have been
How do I prevent an h:commandButton from refreshing the page.
For which the answer is given here:
How make commandButton not fully refresh page? How to use f:ajax?
But since you do not seem to need (or even want) to send anything to the server on clicking the (command)Button, a plain non submitting html button with an onClick would be sufficient. This can be achieved by adding type="button" to the h:commandButton (or by using the plain html counterpart which is legal too)
What's exactly is the difference between types of h:commandbutton?
Some more general knowledge:
commandButton/commandLink/ajax action/listener method not invoked or input value not set/updated
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
https://www.mkyong.com/jsf2/jsf-2-button-and-commandbutton-example/
After debugging the page in google chrome browser , i found that i need to:
1) include<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.15/proj4.js"/>
2) i realized that the id value in jsf is changed in html :
if an id of an element is "list" in jsf it becomes "j_idt6:list" in html.so in getElmentbyid i need to do like this: document.getElementById("j_idt6:list") instead of document.getElementById("list")
now everything work fine.

How to pass multiple component values to listener via ajax on button click

I have select box for list of account numbers, an input field to enter amount and a button to calculate total debit. I want to pass the amount and account values via ajax to an event handler on click event.
Some how I am not able to pass the values entered to event handler.
Can someone suggest me, on how to do ?
My Xhtml:
<h:selectOneMenu class="RUIFW-from-el form-control"
id="fromAccountIndex" value="#{parentBean.fromAccountIndex}"
validator="#{tptValidator.validateFromAccount}">
<f:selectItems value="#{parentBean.fromAccountUIMap}"/>
</h:selectOneMenu>
<h:inputText id="amount" name="amount" value="#{parentBean.amount}" class="RUIFW-form-el form-control" validator="#{tptValidator.validateAmount}"/>
Updated code:
<h:commandLink class="RUIFW-btn mar-lft-10 veraligntop">
<h:outputLabel value="#{GIBBundle.tpt_btn_calculate}"/>
<f:ajax execute="#this fromAccountIndex amount onclick" listener="#{parentBean.calculateClickedListener}"/>
</h:commandLink>
My Bean Method
public void calculateClickedListener(AjaxBehaviorEvent event) {
System.out.println("getFromAccountIndex()....."+getFromAccountIndex());
System.out.println("getAmount()....."+getAmount());
}
You're not setting the execute attribute on the f:ajax. That attribute defaults to #this, and as a result, no other component will be processed and no values will be set. This is why the value bindings of your input components are likely to turn out null.
Set your execute="#form" or execute="#this fromAccountIndex amount" to get the values updated in your bean
Reference:
f:ajax Javadoc

JSF selectOneMenu validation and ajax rendering

I have a validation on my selectOneMenu to prevent the user to select "None" item in the list.
<h:selectOneMenu id="selectMenu" value="#{bean.selectedValue}" required="true" requiredMessage="Please select an item">
<f:ajax render="toRender selectMenuMessage" listener="#{bean.onSelect}"/>
<f:selectItem itemLabel="None" noSelectionOption="true"/>
<f:selectItems value="#{bean.items}" var="item" itemValue="#{item.id}" itemLabel="#{item.label}"/>
</h:selectOneMenu>
I have my panel below and a want to show it only when my item is not "None".
So when I select "None", the message should render and the panel disappear.
<h:panelGroup id="toRender">
<h:panelGrid rendered="#{bean.selectedValue == 0 ? false : true">
...
</h:panelGrid>
</h:panelGroup>
It's working without the validation but I can't make both work.. It's like if validation prevents rendering.
Any suggestion?
Thanks
I guess that bean.selectedValue is an Integer, so try this:
<f:selectItem itemValue="0" itemLabel="None" noSelectionOption="true"/>
Edit:
Ah sorry, I think misunderstood your problem a little bit.
The problem here is, that if you are requiering a value for the selectOneMenu the value will not submitted if it is empty. And if the item with noSelectionOption="true" is selected, it will be handled as empty, so no value will be submitted. When you are checking against bean.selectedValue == 0, selectedValue will never - except maybe initially - be 0, because when you select the item with value 0 it will not be submitted, as described above.
So you are right, your validation and the check for bean.selectedValue == 0 can not work together. I would recommend you to just remove the validation.
If this is no option for you, please explain me why you need it to work that way in more details.
I have a response, it's not the solution but it's another way to do this...
<h:selectOneMenu id="selectMenu" value="#{bean.selectedValue}">
<f:ajax render="toRender selectMenuMessage" listener="#{bean.onSelect}"/>
<f:selectItem itemLabel="None" noSelectionOption="true"/>
<f:selectItems value="#{bean.items}" var="item" itemValue="#{item.id}" itemLabel="#{item.label}"/>
</h:selectOneMenu>
And in the bean
public void onSelect() {
if(this.selectedValue != 0) {
// Do smthg here
} else {
// Display error message
UIComponent component = Outils.getFacesContext().getViewRoot().findComponent(":form:selectMenu");
if(component != null) {
Outils.getFacesContext().addMessage(component.getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "", "Test msg"));
}
}
}
This way the validation process is not launched and the verification is done in the bean.
If someone find something better, let me know!

Resources