p:selectOneMenu inside selectManyMenu trouble - jsf

I have an element selectOneMenu inside element selectManyMenu (component names have been changed).
<p:selectManyMenu id="#{id}MyItemsList" converter="#{backend.myItemsConverter}"
value="#{backend.selectedItem}"
rendered="#{backend ne null}" var="item">
<f:selectItems value="#{backend.getMyItems()}"
var="varItems"
itemLabel="#{varItems.name}" itemValue="#{varItems.id}"/>
<p:column>
<h:outputText value="#{item.name}" title="#{item.title}"/>
</p:column>
<p:column>
<p:selectOneMenu value="#{item.subId}" converter="#{backend.subItemsConverter}">
<p:ajax listener="#{backend.onSubItemClick}"/>
<f:selectItems value="#{backend.subItems}" var="varSubItems"
itemLabel="#{varSubItems.name}"
itemValue="#{varSubItems.id}"/>
</p:selectOneMenu>
</p:column>
</p:selectManyMenu>
They are displayed normally, but when I change the value of the selectOneMenu in one line, it changes in all. What am I doing wrong?
example

<p:remoteCommand name="subItemChange" action="#{backend.onSubItemChange}"
process="#this"
update="#form:ButtonsPanel"/>
<p:dataTable id="#{id}MyItemsListReadOnly" converter="#{backend.myItemsConverter}"
value="#{backend.selectedItem}"
rendered="#{backend ne null}" var="item">
<p:column style="width: 50%">
<h:outputText value="#{item.name}" title="#{item.title}"/>
</p:column>
<p:column style="width: 50%">
<p:selectOneMenu value="#{item.subId}" converter="#{backend.subItemsConverter}"
onchange="subItemChange();" >
<f:selectItems value="#{backend.subItems}" var="varSubItems"
itemLabel="#{varSubItems.name}"
itemValue="#{varSubItems.id}"/>
</p:selectOneMenu>
</p:column>
</p:dataTable>
dataTable saved my time. In addition, to call onSubItemChange from it, need to use remoteCommand. Hope this helps to somebody.

Related

Tooltip in the Column Header of a Primefaces Datatable

In an application based on JSF 2.1 and Primefaces 6.0, I am trying to add a tooltip to the header of a datatable.
In my current solution, the tooltip appears only when pointing the mouse precisely on the text title ("Projekttyp"). I need the tooltip to appear whenever the mouse pointer is in the column header. Unfortunately, it is not possible to assign an id to the facet header.
I understand that the global tooltip as described here Primefaces Showcase Tooltip can only be used in higher Versions of JSF (JSF 2.2).
Here is my code:
<p:column sortBy="#{d.auftraggeber.typ}" filterBy="#{d.auftraggeber.typ}" field="auftraggeber.typ"
filterFunction="#{filterController.filterByString}" filterable="true" sortable="true"
width="6%" styleClass="#{Constants.STRING_COL_STYLE_CLASS}">
<f:facet name="filter">
<p:inputText onkeyup="clearTimeout(window.customFilterDelay);window.customFilterDelay=setTimeout(function() {PrimeFaces.getWidgetById('#{component.parent.parent.clientId}').filter();},1500)"
value="#{sucheForm.filter.typFilter}"
tabindex="1"
styleClass="input-filter #{Constants.NO_DIRTY_CHECK_STYLE_CLASS}">
<p:ajax event="keyup" update="#(.updateableFromTableFilter)" delay="1500" />
</p:inputText>
</f:facet>
<f:facet name="header">
<h:outputText id="typColumntitle" title="Projekttyp" value="Projekttyp"/>
<p:tooltip id="typTooltip"
for="typColumntitle"
rendered="true"
myPosition="left bottom" atPosition="right bottom"
hideDelay="500">
<p:scrollPanel style="width: 300px;height:200px">
<p:dataTable id="projektTypTable" var="typ" value="#{projekttypListProducer.typAndDescList}">
<p:column headerText="Projekttyp" width="30%">
<h:outputText value="#{typ.inhalt}"/>
</p:column>
<p:column headerText="Bemerkung" width="70%">
<h:outputText value="#{typ.bemerkung}"/>
</p:column>
</p:dataTable>
</p:scrollPanel>
</p:tooltip>
</f:facet>
<h:outputText value="#{d.auftraggeber.typ}"/>
</p:column>
Add the f:facet tag like the above and it will work fine (I mean tooltip value will be displayed); if you hover your mouse anywhere inside the column header.
Even outside the text in the column header.
<p:column id= "keyColumnId">
<f:facet name="header">
<h:outputText value="YOUR COLUMN HEADER" />
<p:tooltip value="TOOLTIP VALUE TO SHOW" for="keyColumnId" />
</f:facet>
</p:column>
PrimeFaces supports 'jquery' selectors in the for attribute of the p:tooltip. You effectively need to select the 'parent' of the element with id typColumntitle, so this will (most likely) work.
<p:tooltip id="typTooltip"
for="#(#typColumntitle:parent)"
rendered="true"
myPosition="left bottom" atPosition="right bottom"
hideDelay="500">
Solving this problem turned out to be easy in the end. I just had to assign an id to the column <p:column id="columnwithtooltip" and adjust the for="columnwithtooltip" in the tooltip accordingly:
<p:column id="projekttypColumn" sortBy="#{d.auftraggeber.typ}" filterBy="#{d.auftraggeber.typ}" field="auftraggeber.typ"
filterFunction="#{filterController.filterByString}" filterable="true" sortable="true"
width="6%" styleClass="#{Constants.STRING_COL_STYLE_CLASS}">
<f:facet name="filter">
<p:inputText onkeyup="clearTimeout(window.customFilterDelay);window.customFilterDelay=setTimeout(function() {PrimeFaces.getWidgetById('#{component.parent.parent.clientId}').filter();},1500)"
value="#{sucheForm.filter.typFilter}"
tabindex="1"
styleClass="input-filter #{Constants.NO_DIRTY_CHECK_STYLE_CLASS}">
<p:ajax event="keyup" update="#(.updateableFromTableFilter)" delay="1500" />
</p:inputText>
</f:facet>
<f:facet name="header">
<h:outputText id="typColumntitle" title="Projekttyp" value="Projekttyp"/>
<p:tooltip id="typTooltip"
for="projekttypColumn"
rendered="true"
myPosition="left bottom" atPosition="right bottom"
hideDelay="500">
<p:scrollPanel style="width: 300px;height:200px">
<p:dataTable id="projektTypTable" var="typ" value="#{projekttypListProducer.typAndDescList}">
<p:column headerText="Projekttyp" width="30%">
<h:outputText value="#{typ.inhalt}"/>
</p:column>
<p:column headerText="Bemerkung" width="70%">
<h:outputText value="#{typ.bemerkung}"/>
</p:column>
</p:dataTable>
</p:scrollPanel>
</p:tooltip>
</f:facet>
<h:outputText value="#{d.auftraggeber.typ}"/>
</p:column>

JSF enable/disable commandLink depending on filling two inputText and boolean flag without javaScript

I am trying to enable/disable a commandLink depending more than one condition.
At the beginning the commandLink is disabled. To enable it, I must click on a commandButton that activates a boolean flag (this point is currently working) and two inputText must be filled.
CommandLink:
<p:commandLink id="buttonGuardar" action="#{vinculacionesGestionDetalleController.buttonGuardar}" update="#form" process="#form" styleClass="fa-commandlink fa-floppy-o" immediate="true" disabled="#{vinculacionesGestionDetalleController.flagGuardar and empty vinculacionesGestionDetalleController.vinculacionLaboral.denominacionCas and empty vinculacionesGestionDetalleController.vinculacionLaboral.denominacionVal}">
<h:outputText value="#{msg.guardar}" />
</p:commandLink>
commandButton that returns a boolean flag from the controller:
<p:commandButton id="validacionesValidarCodigoButton" actionListener="#{vinculacionesGestionDetalleController.buttonValidar}" value="Validar" styleClass="searchButton" icon="fa fa-button fa-check-circle" process="#form" style="margin-left: 20px;" update="buttonGuardar">
</p:commandButton>
inputText:
<p:row>
<p:column styleClass="alignTextRight">
<h:outputLabel value="#{msg.vinculaciones_gestion_detalle_denominacionCas}" for="inputDenominacionCas" />
</p:column>
<p:column>
<p:inputText id="inputDenominacionCas" style="width:100%" value="#{vinculacionesGestionDetalleController.vinculacionLaboral.denominacionCas}" />
</p:column>
</p:row>
<p:row>
<p:column styleClass="alignTextRight">
<h:outputLabel value="#{msg.vinculaciones_gestion_detalle_denominacionVal}" for="inputDenominacionVal" />
</p:column>
<p:column>
<p:inputText id="inputDenominacionVal" style="width:100%" value="#{vinculacionesGestionDetalleController.vinculacionLaboral.denominacionVal}" />
</p:column>
</p:row>
As you can see, I have tried using more than two conditions on disable property of commandLink:
disabled="#{vinculacionesGestionDetalleController.flagGuardar and not empty vinculacionesGestionDetalleController.vinculacionLaboral.denominacionCas and not empty vinculacionesGestionDetalleController.vinculacionLaboral.denominacionVal}"
But it is not working.
Firstly, logical operations that in "disabled" attribute are wrong. As I understood, you want to enable the link when flag is true and inputTexts are not empty.
enabled="#{flag and not empty inputText1 and not empty inputText2}"
Oh no, commandLink doesn't have enabled attribute. No problem:
disabled="#{not (flag and not empty inputText1 and not empty inputText2)}"
Now the changes at the values of inputTexts must trigger an ajax event that will update the commandLink.
<p:row>
<p:column styleClass="alignTextRight">
<h:outputLabel value="#{msg.vinculaciones_gestion_detalle_denominacionCas}" for="inputDenominacionCas" />
</p:column>
<p:column>
<p:inputText id="inputDenominacionCas" style="width:100%" value="#{vinculacionesGestionDetalleController.vinculacionLaboral.denominacionCas}" >
<p:ajax event="keyup" update="buttonGuardar"/>
</p:inputText>
</p:column>
</p:row>
<p:row>
<p:column styleClass="alignTextRight">
<h:outputLabel value="#{msg.vinculaciones_gestion_detalle_denominacionVal}" for="inputDenominacionVal" />
</p:column>
<p:column>
<p:inputText id="inputDenominacionVal" style="width:100%" value="#{vinculacionesGestionDetalleController.vinculacionLaboral.denominacionVal}" >
<p:ajax event="keyup" update="buttonGuardar"/>
</p:inputText>
</p:column>
</p:row>
If you want ajax event get triggered only when inputText lose focus, you can use "blur" event instead of "keyup".

Primefaces action is not fired in datagrid

I have the following Primefaces 3.5 page where I defined two commandLink. My problem is that action of lockout is not fired (checked with breakpoint) although lockoutTest with the same setting works. oncomplete works on both commandLink No exception is thrown.
<p:dataTable id="calendar" value="#{calendarView.calendarData.entrySet().toArray()}" var="row">
<f:facet name="header">
<p:panelGrid>
<p:row>
<p:column>
<p:commandLink id="lockoutTest"
value="test lockout"
update=":mainForm:lockoutEditorDialog"
process="#this"
action="#{calendarView.editLockout(15,15)}"
oncomplete="lockoutDialogWidget.show()">
<f:attribute name="title" value="valami" escape="true" />
</p:commandLink>
</p:column>
</p:row>
</p:panelGrid>
</f:facet>
<p:column style="width: 50px; text-align: right">
<f:facet name="header">
<h:outputText value="#{msgs.calendar_room}" />
</f:facet>
<h:outputText value="#{row.key.roomNumber}" />
</p:column>
<p:columns value="#{calendarView.columns}" var="column" style="text-align: center; #{not empty row.value[column].color ? 'background-color:#'.concat(row.value[column].color):''}">
<f:facet name="header">
<h:outputText value="#{column}" />
</f:facet>
<p:commandLink id="lockout"
value="#{row.value[column].text}"
update=":mainForm:lockoutEditorDialog"
process="#this"
action="#{calendarView.editLockout(row.key.roomNumber,column)}"
oncomplete="lockoutDialogWidget.show()"
rendered="#{row.value[column].text == 'K'}">
<f:attribute name="title" value="#{row.value[column].label}" escape="true" />
</p:commandLink>
</p:columns>
</p:dataTable>
UPDATE:
I've changed p:columns to a simple p:column for testing and it works:
<p:column id="testcolumn">
<p:commandLink id="lockouttest"
value="T"
update=":mainForm:lockoutEditorDialog"
process="#this"
action="#{calendarView.editLockout(15,15)}"
oncomplete="lockoutDialogWidget.show()"
>
</p:commandLink>
</p:column>
Use actionListener instead of action when you want to call a method in your backing bean.
Also, make sure your p:commandLink is placed within a h:form (I assume you've ommited it here since it should be a parent of your p:datatable)

ajax listener was not updated the panels for selected item in primefaces

Iam trying to update a panel based selected data using primefaces selectonemenu and ajax listener was taken care by updating the panels.But my panel was not updated and selected item was shown at console window.That means ,The ajax call was got into managed bean.but its not updated at faces pages and mentioned my code
<p:panelGrid columns="1" style="align:center;width:80%" styleClass="companyHeaderGrid">
<p:row>
<p:column><h:outputLabel for="runobject" value="Run Object: " /></p:column>
<p:column>
<p:selectOneMenu id="selectedState" value="#{TAScheduleBean.selectedRunObjectItem}" >
<p:ajax listener="#{TAScheduleBean.changePanelState}" render="#this" update=":form:displayDailyPanel"/>
<f:selectItem itemLabel="Select One" itemValue="Select One" />
<f:selectItems value="#{TAScheduleBean.runObjectsValue}" />
</p:selectOneMenu>
</p:column>
</p:row>
<p:row id="displayDailyPanel" rendered="#{TAScheduleBean.appSelectedRunObject eq 'Daily'}">
<p:column>
<p:outputLabel value=" N days" />
<p:outputLabel value="Days=" /><p:inputText id="s"/>
</p:column>
</p:panelGrid>
I read relevant issues in the same forums and other forums also. but the issue is not resolved.How can i resolve this.Please help me
Update :-
ManagedBean
public class TAScheduleBean extends TASBean {
private String selectedRunObjectItem="";
private String appSelectedRunObject="";
TAScheduleBean(){
}
public void changePanelState(){
String methodName="changePanelState";
setPanelIsVisible(true);
TALogger.log(Logger.INFO, className,
methodName, "---------"+getSelectedRunObjectItem());
setAppSelectedRunObject(getSelectedRunObjectItem().trim());
}
}
Thanks guys.I resolved the issue.when we are selected item up to that time the row was not created because we called 'rendered' attribute.So i created panel and mentioned below code
<p:panel id="toppanel"> <------- added panel
<p:panelGrid columns="1" style="align:center;width:80%" styleClass="companyHeaderGrid">
<p:row>
<p:column><h:outputLabel for="runobject" value="Run Object: " /></p:column>
<p:column>
<p:selectOneMenu id="selectedState" value="#{TAScheduleBean.selectedRunObjectItem}" >
<p:ajax listener="#{TAScheduleBean.changePanelState}" render="#this" update="toppanel"/> <------changed
<f:selectItem itemLabel="Select One" itemValue="Select One" />
<f:selectItems value="#{TAScheduleBean.runObjectsValue}" />
</p:selectOneMenu>
</p:column>
</p:row>
<p:row id="displayDailyPanel" rendered="#{TAScheduleBean.appSelectedRunObject eq 'Daily'}">
<p:column>
<p:outputLabel value=" N days" />
<p:outputLabel value="Days=" /><p:inputText id="s"/>
</p:column>
</p:panelGrid>
</p:panel>
then its working fine.

primefaces panelgrid colspan not working

I'm trying to set a panelgrid inside a dialog. Everything seems to be working except the colspan. I've check this post PrimeFaces panelGrid but its year and half old. From the primefaces manual and showcase, colspan should be accepted by datatable and panelGrid.
<h:form id="idFormAddDialog">
<p:panelGrid id="idPanelAddUsers" columns="2">
<h:outputLabel for="dAddOutUser" value="Username:"></h:outputLabel>
<h:inputText id="dAddOutUser" value="#{userController.username}"></h:inputText>
<h:outputLabel for="dSelRole" value="Role:"></h:outputLabel>
<h:selectOneMenu id="dSelRole" value="#{userController.role}">
<f:selectItem itemLabel="Admin" itemValue="1"></f:selectItem>
<f:selectItem itemLabel="Researcher" itemValue="2"></f:selectItem>
<f:selectItem itemLabel="User" itemValue="3"></f:selectItem>
</h:selectOneMenu>
<h:outputLabel for="dAddINPassword1" value="Password: "></h:outputLabel>
<p:password id="dAddINPassword1" value="#{userController.password}" feedback="true"></p:password>
<p:row>
<p:column colspan="2">
<p:separator></p:separator>
<!-- <p:separator></p:separator>-->
</p:column>
</p:row>
<p:commandButton value="OK" actionListener="#{userController.addUser()}" ></p:commandButton>
<p:button value="Cancel"></p:button>
</p:panelGrid>
</h:form>
But I'm not able to find what I'm doing wrong.
First, if you want to use p:row and p:column in p:panelGrid remove columns attribute, and manage rows and column manually with p:row and p:column tags. Everything inside p:panelGrid must be inside p:row tags. Example:
<p:panelGrid id="idPanelAddUsers">
<p:row>
<p:column></p:column>
<p:column></p:column>
<p:column></p:column>
</p:row>
<p:row>
<p:column colspan="2"></p:column>
<p:column></p:column>
</p:row>
</p:panelGrid>

Resources