JSF Primefaces set button enabled when table row is selected - javascript

I have a list of users in a table and with disabled Delete button. I need to enable the Delete button when I select the row in the table. How can I do this?
<p:dataTable value="#{userBean.patients}" var="item"
selectionMode="single" rowKey="#{item.id}"
selection="#{userBean.selected}"
onRowSelected="deleteButton.disabled='false';"> // HOW TO WRITE THIS EVENT CORRECTLY?????
// columns
</p:dataTable>
//This button must be enable after I click on any table row
<p:commandButton id="deleteButton" value="Delete" disabled="true" />
Maybe, I need to use onRowClick event. I dont know the name of this event

Thanks for jsfviky71 !
I write:
<h:form id="form">
<p:dataTable value="#{bean.patients}" var="item"
selectionMode="single" rowKey="#{item.id}"
selection="#{bean.selected}" >
<p:ajax event="rowSelect" update=":form:deleteButton" listener="#{bean.onRowSelect}" />
// data in rows
</p:dataTable>
<p:commandButton id="deleteButton" value="Delete" disabled="#{bean.disabled}"/>
And in my bean:
private Boolean disabled = true;
// getter and setter
public void onRowSelect(SelectEvent event) {
disabled = false;
}
Hope this will help to others

One solution could be using
<p:ajax event="rowSelect" update=":deleteButton" listener="#{bean.someListener}" />
inside datatable.
This catches the row selection event, calls a listener and updates the button.
Now you could define the listener in the backing bean that just updates the value of a boolean instance variable, that reflects the disabled/enabled status of the button in the view:
<p:commandButton id="deleteButton" value="Delete" disabled="#{bean.selectedBoolean}" />
You can take a look at primefaces showcase for a similar scenario:
http://www.primefaces.org/showcase/ui/datatableRowSelectionInstant.jsf
Hope this helps.

Related

Check if a datatable is empty in primefaces

I have a datatable in primefaces with jsf and I need to check when the datatable is empty with jquery/js, but I have just found tags for "normal" datatables that don't work on PF.
Bean
private ArrayList<Curso> curs = null;
private ArrayList<Curso> listado_filtrado;
private DefaultStreamedContent informe_cursos;
Html
<p:outputPanel id="opTabla" >
<p:dataTable id="tabla_elements"
value="#{Cursos.curs}"
var="element"
filteredValue="#{Cursos.listado_filtrado}"
emptyMessage="No se encontraron elementos"
paginator="true" rows="20"
currentPageReportTemplate="{startRecord} a {endRecord} de {totalRecords}"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
paginatorPosition="bottom">
<p:ajax event="filter" update="exportar"/>
<f:facet name="header">
<div class="header-field-col">
<p:commandButton id="anadir_curso" value="AƱadir curso nuevo" icon="ui-icon-plus" />
</div>
<div class="header-field-col">
<p:commandButton id="exportar" value="Exportar" ajax="false" disabled="#{empty Cursos.curs}"
icon="ui-icon-arrowreturnthick-1-s">
<p:fileDownload value="#{Cursos.informeCursos}" />
</p:commandButton>
</div>
</f:facet>
Your p:dataTable most likely references a list. Add an ajax event handler to it for e.g. the filter (all the ones that can make a page empty)
<p:dataTable value="#{myBean.myList}"...>
<p:ajax event="filter" update="exportButton" ... >
...
</p:dataTable>
use a p:commandButton with a disabled attribute like this:
<p:commandButton id="exportButton" value="export" disabled="#{empty myBean.myList}" ... />
It disables the commandButton client and serverside if the list is empty. So users cannot hack it client-side either.
The 'update' element in the commandButton makes sure the button state is, well,... updated on the relevant events. This is all rather basic ajax stuff, maybe read some tutorial on that

Set default value inputText jsf with javascript [duplicate]

I have a JSF 2 application that has two pages, one to list students and one to show details of a given student. The listing page has a link to the details page in each row of the students table, that opens a new tab in browser to show those details, when clicked.
Now the requirements changed to no more show details in a new tab, but in a modal dialog in the listing page.
My idea is to simply embed the details page content in the modal dialog so the listing page will not get too big and hard to maintain. Here start my doubts. After some research I changed the link in each row of the listing to the following button:
<p:commandButton value="Details" type="button"
onclick="PF('dialog-details').show()">
</p:commandButton>
The dialog is declared as follows:
<p:dialog widgetVar="dialog-details" header="Details" modal="true" width="95%">
<ui:include src="student_details.xhtml">
<ui:param name="id" value="#{student.id}"/>
</ui:include>
</p:dialog>
Finally, the details page was changed to be something like this:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui" xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<f:metadata>
<f:viewParam name="id" value="#{studentBean.id}" />
</f:metadata>
<h1 class="title ui-widget-header ui-corner-all">Details of #{studentBean.bean.name} / #{studentBean.bean.number}</h1>
</ui:composition>
When I click the button, the dialog really shows and the content is the details page. I see the following content in the dialog:
Details of /
No errors at all, but the data that should be shown, isn't. A breakpoint was set in StudentBean.setId() (this method loads a property named bean with the Student instance corresponding to the passed id) but it is never hit.
After some time thinking about it, I came to understand why it does not work. The parameter passed to the details page is student.id, but student is the name used as the var in the <p:datatable/> that show all the students, so student is not valid in <p:dialog/> which is outside the <p:datatable/>.
So, what I need is a way to show the dialog using the id of the corresponding student in a given row. Ideally, I would like an ajax call here, so the details would loaded only when neded.
Any ideas?
The button should be an ajax button which sets the currently iterated entity in the bean, and then updates the dialog's content, and finally shows it. The dialog should just reference that entity in the bean and update the list and table on save. It's very important that dialog is placed outside the main form and that it has its own form.
Here's a kickoff example:
<h:form id="master">
<p:dataTable value="#{bean.entities}" var="entity">
<p:column>#{entity.property1}</p:column>
<p:column>#{entity.property2}</p:column>
<p:column>#{entity.property3}</p:column>
...
<p:column>
<p:commandButton value="View" action="#{bean.setEntity(entity)}"
update=":detail" oncomplete="PF('detail').show()" />
</p:column>
</p:dataTable>
</h:form>
<p:dialog id="detail" widgetVar="detail">
<h:form>
<p:inputText value="#{bean.entity.property1}" />
<p:inputText value="#{bean.entity.property2}" />
<p:inputText value="#{bean.entity.property3}" />
...
<p:button value="Close" onclick="PF('detail').hide(); return false" />
<p:commandButton value="Save" action="#{bean.save}"
update=":master" oncomplete="if(!args.validationFailed) PF('detail').hide()" />
</h:form>
</p:dialog>
With this inside a #ViewScoped bean:
private List<Entity> entities; // +getter
private Entity entity; // +getter+setter
#EJB
private EntityService entityService;
#PostConstruct
public void load() {
entities = entityService.list();
entity = null;
}
public void save() {
entityService.save(entity);
load();
}
See also:
Creating master-detail pages for entities, how to link them and which bean scope to choose
Creating master-detail table and dialog, how to reuse same dialog for create and edit
Keep p:dialog open when a validation error occurs after submit
Difference between rendered and visible attributes of <p:dialog>
How to display dialog only on complete of a successful form submit

Primefaces doesn't recognize the value of the cell/field if I don't leave the cell/field.

I'm having this issue with saving data from the grid in PrimeFaces. When I set the value in the cell, and then change another and another cell, click here and there, and then I click on the save button, everything is working perfect. But if I miss to exit the cell (to change the focus), and just click the save button, the value from that last cell is lost.
Here is my cell:
<p:cellEditor>
<f:facet name="output"><h:outputText style="text-transform: uppercase" value="#{bBean.someData}" /></f:facet>
<f:facet name="input">
<p:inputText style="text-transform: uppercase" value="#{bBean.someData}" label="Some data">
</p:inputText>
</f:facet>
</p:cellEditor>
It looks like PrimeFaces is not able to recognize the change if some event is not fired.
Any ideas?
Giving your <p:inputText> onmouseout event you can additionally save value when user leaves cell with mouse pointer:
<p:ajax event="mouseout" process="#this" partialSubmit="true"/>
Ok, now I fixed it for sure :)
I created a hidden button:
<p:commandButton process="#this" style="display:none !important" id="btn" value="SB"/>
and a javascript function that will simulate clicks on the hidden button:
function takefocus(){
$(PrimeFaces.escapeClientId('form:btn')).click();
}
and I added to the save button, before calling save:
<p:commandButton value="Save" onclick="takefocus();PF('waitDialog').show();saveData();"/>
and it is working fine.
The following works for Firefox, but not for Chrome.
So if you find a better solution please share it here.
<p:inputText onblur="triggerChange(this)... />
function triggerChange(el) {
var e = jQuery.Event('keydown');
e.which = 13;
e.keyCode = 13;
$(el).trigger(e);
}

My event ajax keydown is too slow

I have a problem with a h:inputText and i don't know how to solve it.
I'm working on a xhtml page using JSF and RichFaces which contains fields as Calendar, SelectOneMenu, InputTextArea, Input. At the end of my form, there are two buttons Print and Save.
If one of the fields is modified (text, date, etc), i have to disable the Print button. In every field, i have add ajax event.
For example :
<rich:calendar datePattern="dd/MM/yyyy" timeZone="#{timeZone.timeZone}" value="#{myBean.date}">
<f:ajax event="change" listener="#{myBean.verifyModification}" render="myForm"/>
</rich:calendar>
If my date is changed, i call a method stored in my bean and it's ok.
But, i have a problem with my inputText and inputTextArea.
<h:inputText value="#{myBean.name}" maxlength="50">
<a4j:ajax event="keydown" render="myForm" listener="#{myBean.verifyName}" />
</h:inputText>
If i write fastly, for example i stay on the letter a to write aaaaaaaa in my field. The field will contain aaaaaaaa then aaaa. Is it because the ajax event is too slow? The problem doesn't come from my bean method because i only test a value.
Because of that, i can't test this field. I have tried the others events like blur, change. If i use these events, i have to click out of my field then my button is refresh.
Could you help me, please?
Thank you.
The problem is most likely that you render your complete form, not only the part of it that needs updating. JSF will then replace your form with the values you submitted on the first ajax request. Try:
<h:inputText value="#{bean.name}">
<f:ajax event="keydown" render="myButtonP" listener="#{bean.verifyName}" />
</h:inputText>
<h:panelGroup id="myButtonP">
<h:commandButton id="printBtn" value="Print" action="#{bean.printMe}"
disabled="#{bean.canPrint}" />
<h:commandButton id="saveBtn" value="Save" action="#{bean.save}" />
</h:panelGroup>
If you use disabled instead of rendered on the button, you can even reference printBtn directly in the render attribute.

Datatables row id in JavaScript

I would like to get the id of datatables row to call click() on a hidden button in the same table cell.
It is done that way because all buttons have to look like h:commandButton and i couldn't force p:commandButton look like them. And h:commandbutton doesn't have oncomplete event. I know I could use DataModel, but is there another way to do it (using JS, JQuery)?
When i put hardoced id (p:table:4:hiddenButton) everything is ok, but how to get that row number for each cell??
<h:form id="p">
<h:dataTable value="#{bean.paymentList}" var="pmt" id="table" >
...
<h:column>
<f:facet name="header">
<h:outputText value="#{bundle.action}" />
</f:facet>
<h:commandButton type="button" value="#{bundle.approve}"
onclick="document.getElementById('p:table:??:hiddenButton').click();" />
<p:commandButton id="hiddenButton" value="hidden" style="display: none;"
oncomplete="if (#{pmt.errorsNum} > 0) {
return confErrDial.show();
} else {
return confDial.show();};">
<f:setPropertyActionListener value="#{pmt.id}" target="#{bean.holder}" />
</p:commandButton>
</h:column>
</h:dataTable>
</h:form>
EDIT:
Ok i did some trick using JQuery, it may be not nice but works.
What I did:
I added id to h:commandButton and on onclick event i get id of h:commandButton and replace its id with id of hidden p:commandbutton, so its code is now:
<h:commandButton id="button" type="button" value="#{bundle.approve}"
onclick="document.getElementById(($(this).attr('id')).replace('button','hiddenButton')).click();"
Still maybe someone knows better solution.
PS: It is strange because $(this).parent().attr('id') is null. I think it has something with that no element is created with id p:table:0 p:table:1 etc...

Categories

Resources