How to detect row selection in Primefaces Datatable? - primefaces

I use Prime Faces 6.2 to construct checkboxed column. Have this sample:
<p:dataTable id="List"
value="#{tickets}"
lazy="true"
paginator="true"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
currentPageReportTemplate="{startRecord}-{endRecord} из {totalRecords}"
rows="20"
rowKey="#{ticket.id}"
selection="#{ticketForm.abstractMTSBUExportTickets}"
var="ticket"
emptyMessage="Записи в данной категории отсутствуют">
<p:column selectionMode="multiple" style="width:40px; text-align:center">
<!-- <p:ajax event="click" listener="#{form.abstractMTSBUExportTickets}" /> --> // first try
<!-- <p:commandLink id="select" action="doSome" /> --> // second try
</p:column>
The purpose to use ajax is for making some button on page visible when at least one checkbox selected.
Firstly, I tried to insert p:ajax tag into column tag but got exception:
<p:ajax> Unable to attach behavior to non-ClientBehaviorHolder parent
More obviouse way was to insert command link into but it simply did nothing.
So, is there any practice to do this? Thanks for answers in advance.

Yes you are close but what you what is Ajax on the Datatable and not on the checkboxes. PF provides these two Ajax events on the datatable for being notified or boxes being checked or unchecked...
<p:datatable>
<p:ajax event="rowSelect" listener="#{dtSelectionView.onRowSelect}" update=":form:mybutton" />
<p:ajax event="rowUnselect" listener="#{dtSelectionView.onRowUnselect}" update=":form:mybutton" />
...
</p:datatable>
See the Select Events example from the Showcase for more info: https://www.primefaces.org/showcase/ui/data/datatable/selection.xhtml
You can simply do something like in the Select and Unselect methods will trigger updating your selection and you can enable the button using EL expression like...
<p:commandButton id="mybutton" disabled="#{ticketForm.abstractMTSBUExportTickets.size > 0}" />

Related

Primefaces 5.1 show tooltip on single cell of a datatable for each row without extensions

I faced a problem with primefaces and tooltip on a single cell column.I was not able to use it so I searched the web and I found many answer like this one. the first answer did not solved the problem, infact that did nothing at all and the second one gave me error at runtime, telling me that it cannot find the righ object in the page.
So,how can i use a tooltip on a single cell of a table for each row?
I'm using primefaces 5.1, jsf 2.2, java 1.6.
despite many answers that suggest you to use primefaces extensions, the only thing you have to do to see your tooltip is to use primefaces itself like this:
<p:tooltip id="toolTipGrow" value="#{row.property}" shared="true" for="idField" showEffect="clip" position="top"/>
where idField is the id from which you want to see the tooltip appear and row.property is the value that you want to show into it.
the thing is now simple to make. here it is an example with the datatable:
<p:dataTable var="row" value="#{....}" styleClass="myTable">
<p:column headerText="Header 2">
<h:outputText value="#{row.value2}" id="idField" />
<p:tooltip id="toolTipGrow" value="#{row.property}" shared="true" for="idField" showEffect="clip" position="top"/>
</p:column>
</p:dataTable>
I hope this will help.
Best Regards
Yes its possible. See..
<p:column>
<f:facet name="header">
<h:outputText
id="header"
value="Header"
/>
<p:tooltip
for="header"
showEffect="fade"
hideEffect="fade"
>
<!-- content of tooltip for header -->
</p:tooltip>
</f:facet>
<h:outputText
id="col"
value="#{object.valueA}"
/>
<p:tooltip
for="col"
showEffect="fade"
hideEffect="fade"
>
<!-- content of tooltip for cell -->
</p:tooltip>
</p:column>
In my scenario, I have all my data in cells inside h:outputText elements.
In that case, you can then use the title attribute.
<p:column>
<h:outputText value="#{row.data}" title="#{row.data}"/>
</p:column>

primefaces 4 datatable pager works only after first ajax update

i have an primefaces 4 datatable, when loading the page the paginator isn't working.. when i click the button nothing happens. But the first data is shown. Wehn i now sort/filter the table once the paginator starts to work.
<p:dataTable var="user" value="#{proxyUserListHandler.lazyModel}" paginator="true" rows="10" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="10,50,100,200,500" lazy="true">
<p:column headerText="Id" sortBy="id" filterBy="#{user.id}">
<h:outputText value="#{user.id}" />
</p:column>
<p:column headerText="Username" sortBy="username" filterBy="#{user.username}">
<h:outputText value="#{user.username}" />
</p:column>
<p:column headerText="apiKey" sortBy="apiKey" filterBy="#{user.apiKey}">
<h:outputText value="#{user.apiKey}" />
</p:column>
</p:dataTable>
the problem was
<p:dataTable value="#{listHandler.lazyModel}"
the function always returned a new LazyModel...somehow the function is called twice and only at the first object the "load" function was called.
You probably have another error on the page that you are not noticing (and quite likely is not being reported!)
Try to reduce the page functionality to the bare min in order to get the data table to react properly, then add the other page components back in until the datatable bahavior is impacted again.

Primefaces dataTable filter works only once

im using Primefaces 3.5 to create a dataTable with filters.
<h:form id="table">
<div class="showRuleStyle">
<p:dataTable id="RuleTable" var="e" value="#{ruleListBean.rules}" filteredValue="#{ruleListBean.filteredRules}" styleClass="ruleTable" paginator="true" paginatorPosition="bottom" rows="15" emptyMessage="Keine Einträge gefunden.">
<p:column id="companyColumn" headerText="Name" filterBy="#{e.name}" filterOptions="#{ruleListBean.filterNameOptions}" >
<h:outputText value="#{e.name}"></h:outputText>
</p:column>
...
<p:column>
<f:facet name="header"></f:facet>
<h:commandButton id="DeleteRuleButton" value="Löschen" styleClass="buttondefault" action="#{ruleListBean.removeRule(e)}" update=":table"></h:commandButton>
</p:column>
</p:dataTable>
</div>
</h:form>
Now, i get the table as intended and can choose an filter which updates the table. But now, if i try to choose a different filter or select the empty filter, nothing happens. If I click the button, it works again, which i think is because of the update of the form.
I tried to add
<p:ajax event="filter" update=":table">
and other events, but it won't work.
Any suggestions?
Greets
Alex
What is the scope of the ruleListBean? I've tried your code and it worked as expected (without the p:ajax).
My ruleListBean is in view scope.
It is suggested to use a scope longer than request like viewscope to
keep the filteredValue so that filtered list is still accessible after
filtering. (PrimeFaces User’s Guide pg. 135)
NOTE: Change h:commandButton to p:commandButton so that you can use the update feature.

Primefaces Tabview resetting inputs

I use primeface 3.5. I have a tabview and each tabview has got inputMasks with a form. I want to reset inputMask when i change the tab. I listen ontabchange event and reset value to="" but bean reset values but View doesn't reset.
<p:tabView id="tabViewOS" binding="#{docData.tabView}" dynamic="true" cache="true" rendered="#{userData.opRendered}">
<p:ajax event="tabChange" listener="#{docData.onTabChange}" immediate="true"/>
<p:tab id="tab1" title="AB">
<h:form id="ABForm">
<h:panelGrid id="abgrid" columns="3" cellpadding="5">
<h:outputText value="AB NO: " />
<p:inputMask value="#{docData.abNo}" mask="999-99999999"
id="ABinput" required="true"
</p:inputMask>
<p:message id="msgAB" for="ABinput" showDetail="true" autoUpdate="true" />
<h:outputText value="" />
<p:commandButton value="GETİR" style="float:right;" ajax="false"
action="#{docData.getDoc}" />
</h:panelGrid>
</h:form>
</p:tab>
public void onTabChange(TabChangeEvent event) {
this.activeTabIndex = tabView.getChildren().indexOf(event.getTab());
FacesContext.getCurrentInstance().renderResponse();
System.out.println(this.activeTabIndex);
this.abNo="";
documents.clear();
}
Try changing the way the event is called. Instead of immediate=true use process="#this".
Change this:
<p:ajax event="tabChange" listener="#{docData.onTabChange}" immediate="true"/>
To this:
<p:ajax event="tabChange" listener="#{docData.onTabChange}" process="#this" update="ABinput"/>
i guess as you said -dynamic="true" cache="false">- is solve my problem. Actually I tested program faulty, my problem has already solved. I think in my case cause of this situation cache=false as documentation said. Thank you.
Have a look at the primefaces documentation on p:tabView. On the one hand you have the property dynamic which specifies if the content of a tab is loaded with AJAX when you select some tag. On the other hand there is the property cache which specifies wheter or not the content of a tab is only dynamically loaded the first time you select a tab.
So regarding this informations setting dynamic="true" cache="false" on the p:tabView should do the trick for you.
Another interesting property for you would be activeIndex. As I see you are setting the index of the active tab manually on tab change. If you can submit tabview on tabchange and you have set activeIndex="#{docData.activeTabIndex}" the active tabindex is tracked automatically. Have a look at the documentation if this fits your requirements.

why isn't this jsf/ajax code submitting the values?

I'm embedding here a simplified version of a code that is not working for me.
What happens here is that there are 2 forms.
The first form contains an ajaxified <h:commandLink> (Using <f:ajax>)
The second form contains a form with values.
When the <h:commandLink> is pressed, the values in the second form are supposed to be submitted.
What happens in practice is that values are retrieved (the getter function is run) but are not submitted (the setter function never runs).
The <f:ajax> runs because I can see the listener method running and the second form does get rerendered after clicking the <h:commandLink> but, again, the setter functions are never run.
<body>
<h:form prependId="false">
<h:panelGroup >
<h:commandLink >
<f:ajax event="click"
execute=":form_with_values_to_update" render=":form_with_values_to_update"
listener="#{mrBean.clickListenerAction}" />
Do something
</h:commandLink>
</h:panelGroup>
</h:form>
<h:panelGroup>
<h:form id="form_with_values_to_update">
<fieldset>
<ui:repeat value="#{mrBean.aMemberOfBean.aListInAMemberOfBean}" var="listItem">
<h:panelGroup>
<h:outputText value="#{listItem.label}" />
<h:inputText id="contact_details_input"
value="#{listItem.value}" />
</h:panelGroup>
</ui:repeat>
</fieldset>
</h:form>
</h:panelGroup>
</body>
P.S - Using MyFaces JSF 2.1
The commandlink/button has to go in the same form as where the data of interest is in.
If that's not an option due to some design or business restrictions, then you need a second commandlink/button. First move the original commandlink/button back in the right form, give it an id and hide it using CSS display: none;.
Then put the second commandlink/button in the other form which does something like
<h:commandLink onclick="document.getElementById('form_with_values_to_update:linkid').click(); return false;">
Do something
</h:commandLink>