Primefaces Datatable disabledSelection update by check - spring

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>

Related

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,

How to get RowIndex from the actual selected Column into my Bean?

I try to get the rowindex from the actual selected Column to unselect it with:
public void rowSelect(SelectEvent event) {
MyDataView selected = (MyDataView) event.getObject();
if (!selectedData.remove(selected)) {
selectedData.add(selected);
} else {
RequestContext.getCurrentInstance().execute("PF('datatTable').unselectRow(rowindex);");
}
}
}
I know it is easy to unselect a row with the UnselectEvent and press "crtl" but my Customers want to unselect a row with one click.
<p:dataTable widgetVar="datatTable" id="idDataTable" value="#{bean.dataview}" var="data" scrollable="true" scrollHeight="150"
rowSelectMode="add" selectionMode="multiple"
selection="#{sendGroupSmsSimple.selectedReceivers}" rowKey="#{bean.id}" filteredValue="#{data.filterData}" rowIndexVar="dataRowIndex">
<p:column id="recColumn" headerText="Name" filterBy="#{bean.fullname}" filterFunction="#{data.filterData}">
<h:outputText value="#{bean.fullname}"/>
</p:column>
<p:ajax event="rowSelect" listener="#{sendGroupSmsSimple.rowSelect}" process="#this" update="mainForm:updatePanel"/>
</p:dataTable>
I don't want to update my whole Form because I want the actual state of my scrollbar.
My actual Primefaces Version is 6.0.
Scope of my Bean is GroupedConversationScoped.
Thanks

Update multiple components ajax [duplicate]

This question already has an answer here:
Ajax update/render does not work on a component which has rendered attribute
(1 answer)
Closed 7 years ago.
I want to update two components after ajax action but don't know how to do this (if it is even possible).
I have three pages:
<h:form id="loginForm">
<p:panelGrid columns="2" >
<h:outputText value="Login: "/>
<p:inputText value="#{bean.person.username}" requiredMessage="*" />
<h:outputText value="Hasło: "/>
<p:password value="#{bean.person.password}" requiredMessage="*"/>
<p:commandButton value="Login" action="#{bean.validatePerson}" update="loginConfirmationPage"/>
</p:panelGrid>
</h:form>
Menu page is similar to this above with menu items with rendered atribute (fe. show logout button when user is logged in) and loginConfirmationPage on which i want to show username.
I need to update both of these pm:pages to get logout button on menu page and also display username on confirmation page.
How can I do this? For now i can only update one page. I tried to type statement similar to these:
<p:commandButton value="Login" action="#{bean.validatePerson}" update="loginConfirmationPage,menuPage"/>
or
<p:commandButton value="Login" action="#{bean.validatePerson}" update="loginConfirmationPage;menuPage"/>
Both not working. How can i do this?
var name = "";
$.post("Path/To/Server/File", {'serverFileVariableName' : clientElementID},
//data is what the server file will return
function(data){
//In this case, the data is the username.
name = data;
//invoke the show method to display
logOut.show();
}
);
//done

primefaces selectonemenu change event not working for null value

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']}" />

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