How to dynamically disable/enable commandbutton in datatable in JSF/PrimeFaces - jsf

I am displaying list of some objects in primefaces datatable. Apart from object related columns, I have added two columns that contain commandbutton. Each of these commandbutton make ajax calls to desired methods in bean. I want to disable both commandbuttons in that row when any of the button is clicked and enable them again once action is completed successfully. The method execution is simulated by ajaxStatus which is working fine.
Following is selected code of xhtml
<h:form id="form1" >
<p:remoteCommand name="onload" action="#{controlBean.init}" autoRun="true" />
<h:outputtext>Sample Project</h:outputtext>
<p:ajaxStatus style="display:block;margin-bottom:2em;height:24px;">
<f:facet name="prestart">
<h:outputText value="Starting..." /> </f:facet>
<f:facet name="error"> <h:outputText value="Error" />
</f:facet>
<f:facet name="success"> <h:outputText value="Success" />
</f:facet>
<f:facet name="default"> <h:outputText value="Idle" />
</f:facet>
<f:facet name="start"> <h:outputText value="Please Wait" />
<p:graphicImage name="/images/ajaxloadingbar.gif" />
</f:facet>
</p:ajaxStatus>
<p:dataTable var="appl" id="tbl1" rowIndexVar="rowIndx" value="#{controlBean.applsList}">
<p:column headerText="Name">
<h:outputText value="#{appl.applName}" />
</p:column>
<p:column headerText="Type">
<h:outputText value="#{appl.applType}" />
</p:column>
<p:column headerText="Desc" rendered="true">
<h:outputText value="#{appl.applDesc}" />
</p:column>
<p:column headerText="Start Appl" id="col4">
<p:commandButton value="Submit" ajax="true"
process="#this"
widgetVar="startButtonVar"
id="startBtn" update="msgs, col4, startBtn"
action="#{controlBean.startAction}" style="margin-right:20px;"
styleClass="ui-priority-primary"
disabled="#{controlBean.startBtnDisabled}">
<f:setPropertyActionListener value="#{appl}" target="#{controlBean.selectedAppl}"/>
</p:commandButton>
</p:column>
<p:column headerText="Stop Appl" id="col5">
<p:commandButton value="Submit" ajax="true"
process="#this"
widgetVar="stopButtonVar"
id="stopBtn" update="msgs, col5"
action="#{controlBean.stopAction}" style="margin-right:20px;"
styleClass="ui-priority-primary"
disabled="#{controlBean.btnDisabled}">
<f:setPropertyActionListener value="#{appl}" target="#{controlBean.selectedAppl}"/>
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
backing bean methods are as under:
public void startAction()
{
System.out.println("In start action method");
this.btnDisabled = true;
for(int i=0;i<100000;i++)
{
if(i%10000 == 0)
{
System.out.println(i);
}
for(int j=0;j<10000;j++)
{
for(int k=0;k<1000;k++)
{
}
}
}
MessageUtils.info(getSelectedAppl().getApplName()+" has been started");
this.btnDisabled = false;
}
public void stopAction()
{
System.out.println("In stop action method");
this.btnDisabled = true;
for(int i=0;i<100000;i++)
{
if(i%10000 == 0)
{
System.out.println(i);
}
for(int j=0;j<10000;j++)
{
for(int k=0;k<1000;k++)
{
}
}
}
MessageUtils.info(getSelectedAppl().getApplName()+" has been stopped");
this.btnDisabled = false;
}
Everything is working fine except disabling/enabling of commandbuttons. Any help in this regard will be highly appreciated.
Regards

You could disable them on the onclick javascript handler:
<p:commandButton id="startBtn"
widgetVar="startButtonVar"
onclick="PF('startButtonVar').disable();"
.....
The onclick will be executed BEFORE the AJAX call. On return, as the button is updated, it will be reenabled.

Related

Pass parameter from a datatable to a p:dialog [duplicate]

This question already has an answer here:
How to show details of current row from p:dataTable in a p:dialog and update after save
(1 answer)
Closed 6 years ago.
The following code implements a datatable inside a layout, in the datatable i added an edit button in each row
<p:dataTable id="tbl" var="person" value="#{mybean.listPersons}" >
<p:column>
<f:facet name="header">
<h:outputText value="Name " />
</f:facet>
<h:outputText value="#{person.name}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Age :" />
</f:facet>
<h:outputText value="#{person.age}" />
</p:column>
<p:column>
<p:commandButton icon="ui-icon-pencil"
oncomplete="PF('dlg1').show();" action="mybean.setSelectedPerson(person)" />
</p:column>
</p:dataTable>
When i click on the edit button, the dialog box (code below) is shown but the inputs are empty, what i wanted is to show the infos of the row in the dialog bow, i'm still a beginner, i searched everywhere... but no results
<p:dialog header="Modify" widgetVar="dlg1" >
<h:form >
<p:growl id="msgs" showDetail="true" />
<h:panelGrid id="form2" value="#{myBean.person}" var="person">
<p:outputLabel value="Name :" />
<p:inputText value="#{person.name}" />
<p:outputLabel value="Age :" />
<p:inputText value="#{person.age}" />
<p:commandButton value="Submit" action="#{myBean.modifyPerson(person)}" />
</h:panelGrid>
</h:form>
</p:dialog>
#ManagedBean
#RequestScoped
public class muBean implements Serializable{
private Person selectedPerson;
//getter and setter
public void modifyPerson(Person p) {
this.selectedPerson = p;
}
}
i would be so grateful if anyone can help, i really need this
Change the command button to the following, use an actionlistener:
<p:commandButton icon="ui-icon-pencil" update=":persondlgid" oncomplete="dlg1.show();" actionListener ="mybean.findSelectedPerson">
<f:param name="personalid" value="#{person.id}" />
<p:commandButton/>
This is the dialog, add the id property to it. Then change the value of the panel grid to selectedPerson because this corresponds to the correct object in the managedbean:
<p:dialog header="Modify" widgetVar="dlg1" id="persondlgid" >
<h:form>
<p:growl id="msgs" showDetail="true" />
<h:panelGrid id="form2" value="#{myBean.selectedPerson}" var="person">
<p:outputLabel value="Name :" />
<p:inputText value="#{person.name}" />
<p:outputLabel value="Age :" />
<p:inputText value="#{person.age}" />
<p:commandButton value="Submit" action="#{myBean.modifyPerson(person)}" />
</h:panelGrid>
</h:form>
</p:dialog>
The managed bean function should look as follows. This action listener is called when the button is clicked and it then retrieves the id of the selected person and loops through the list of persons to find the one you are looking for:
public void findSelectedPerson(ActionEvent event){
if(event.getComponent().getAttributes().get("personid") != null){
Map<String,String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
int personid = (params.get("personid")!= null) ? Integer.parseInt(params.get("personid")) : -1;
// Loop through the persons array
for(Person p : listPersons){
if(p.getId() == personid){
selectedPerson = p;
break;
}
}
}

p:inputText values not coming in managed bean

I have p:treeTable in which i am having columns which contains all the text fields now after submitting form i want values inside p:inputText in managed bean which is not coming
TreeTable:
<h:form id="myform">
<p:dialog header="" widgetVar="dlg1" height="200" width="200" dynamic="true">
<p:ajax event="close" listener="#{popupTreeTableManagedBean.setScanParamsSubRootListNull}" />
<p:treeTable value="#{popupTreeTableManagedBean.root}" var="node" style="" >
<p:column>
<f:facet name="header">
Name
</f:facet>
<h:outputText value="#{node.name}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
Value
</f:facet>
<p:inputText value="#{node.value}" style="border-style: hidden;" immediate="true"/>
</p:column>
</p:treeTable>
<p:commandButton value="Save" onclick="loadValues();" actionListener="#{popupTreeTableManagedBean.handleSaveButton}"/>
</p:dialog>
</h:form>
MaangedBean :
public void handleSaveButton() {
int i = scanRoot.getChildren().size();
Iterator itr = scanRoot.getChildren().iterator();
HashMap<String,String> valueNameHashMap = new HashMap<String,String>();
while(itr.hasNext()) {
Object trc = itr.next();
DefaultTreeNode newDocument = (DefaultTreeNode) trc;
Document newData =(Document) newDocument.getData();
String nameOfVariable = newData.getName();
String value = newData.getValue();
}
System.out.println(valueNameHashMap);
}
Have you tried setting the ajax property of the command button to false?
<p:commandButton value="Save" ajax="false" actionListener="#{popupTreeTableManagedBean.handleSaveButton}"/>
This will reload the page and make sure that the form submissions will be completed.

commandLink within PickList in Primefaces passes null value to the managed bean

I am using Primefaces 5.0 and on one of my pages I have this picklist:
<h:form>
...
<p:pickList id="aspectPickList" styleClass="camsPickList" value="#{userAccountMB.aspects}" var="aspect" itemValue="#{aspect}"
itemLabel="#{aspect.aspectName}" showSourceFilter="true" showTargetFilter="true" converter="appAspectConverter">
<f:facet name="targetCaption">#{msg['createUser.userAspects.assignedAspects']}</f:facet>
<f:facet name="sourceCaption">#{msg['createUser.userAspects.availableAspects']}</f:facet>
<p:column>
<h:outputText id="aspectName" value="#{aspect.aspectName}" />
<p:tooltip id="toolTipAspectDescription" for="aspectName" value="#{aspect.description}" />
</p:column>
<p:column style="width:30px;">
#{aspect}
<p:commandLink process="#this" oncomplete="PF('aspectDetailsDialog').show();" actionListener="#{userAccountMB.setSelectedAspect(aspect)}">
<p:graphicImage value="#{resource['images:questionmark_icon.jpg']}" />
</p:commandLink>
</p:column>
</p:pickList>
...
</h:form>
Managed bean setSelectedAspect method looks like this:
public void setSelectedAspect(AppAspect selectedAspect) {
this.selectedAspect = selectedAspect;
}
The Scope of the Managed Bean is view.
When I click on the command link with icon, the setSelectedAspect method is invoked, but the selectedAspect parameter is null.
What I need to achieve is to show AspectDetails dialog after clicking the commandLink. The AspectDetails dialog contains details about the previously selected aspect.
if I update the code this way:
<p:column style="width:30px;">
#{aspect}
<p:commandLink process="#this" oncomplete="PF('aspectDetailsDialog').show();" actionListener="#{userAccountMB.selectAspect(aspect)}">
<p:graphicImage value="#{resource['images:questionmark_icon.jpg']}" />
</p:commandLink>
</p:column>
the #{aspect} directive correctly displays the object signature: com.xyz.app.domain.AppAspect#69e1f7aa.
What am I doing wrong? Do I miss something?
I had the same error, try this:
<p:pickList ...>
<p:ajax event="select" listener="#{userAccountMB.selectAspectEvent}">
<f:attribute name="aspectParam" value="#{aspect}" />
</p:ajax>
<f:facet ...>
<f:facet ...>
<p:column>...</p:column>
<p:column style="width:30px;">
<p:commandLink process="#this" oncomplete="PF('aspectDetailsDialog').show();">
<p:graphicImage value="#{resource['images:questionmark_icon.jpg']}" />
</p:commandLink>
</p:column>
</p:pickList>
And the controller:
public void selectAspectEvent(SelectEvent event) {
AppAspect aspectParam = (AppAspect) event.getObject();
if(aspectParam!=null){
this.selectedAspect = aspectParam;
}
}
Regards

Populate dialog from data grid

Solution
In order to set this thread as resolved, let me write down what i changed in order to have my code working:
Changed bean to #ViewScoped;
Alter the id of Update="" for the id of the dialog form;
After looking for the error (Cannot find component with expression.." i've re-checked the generated HTML to confirm the id and it was much longer since ther are automatically generated. After replacing the id with the automatic one, everything was ok.
Thanks to #Jaqen H'ghar for the help :)
I have this panel to update a given table columns, and I want to do this using a dialog box, populated with each column data.
This is my page:
<h:form prependId="true" id="tableForm">
<h:panelGrid columns="2" columnClasses="gridLabel, gridEntry">
<h:outputText value="Table Name: " />
<h:inputText value="#{updObj.title}" />
</h:panelGrid>
<p:dataTable var="column"
value="#{tableBean.getTableColumns(updObj)}"
id="columnsTable">
<p:column headerText="Name">
<h:outputText value="#{column.title}" />
</p:column>
<p:column headerText="Type">
<h:outputText value="#{column.type}" />
</p:column>
<p:column headerText="Size">
<h:outputText value="#{column.size}" />
</p:column>
<p:column headerText="Not null">
<p:selectBooleanCheckbox value="#{column.notNull}" />
</p:column>
<p:column headerText="Primary key">
<p:selectBooleanCheckbox value="#{column.primaryKey}" />
</p:column>
<p:column headerText="Edit column">
<p:commandButton value="Edit column"
actionListener="#{tableBean.personalmethod(column)}"
update="updateColumnDialog:updateColumnGrid" icon="ui-icon-pencil"
title="Edit this column"
oncomplete="PF('updateColumnDialog').show();" />
</p:column>
</p:dataTable>
<p:dialog id="updateColumnDialog" widgetVar="updateColumnDialog"
header="Edit Column" height="200">
<h:panelGrid columns="2" id="updateColumnGrid">
<h:outputText value="Column name: " />
<h:inputText id="updateColName"
value="#{tableBean.updatedColumnName}" />
<h:outputText value="Column type: " />
<h:selectOneMenu id="updateSelectColumnTypes"
value="#{tableBean.selectedColumnType}">
<f:selectItems value="#{tableBean.columnTypes}"
var="columnType" itemLabel="#{columnType}"
itemValue="#{columnType}" id="updateSelectColumnType" />
</h:selectOneMenu>
<h:outputText value="Size: " />
<p:spinner id="updateSize"
value="#{tableBean.updatedColumnSize}" />
<h:outputText value="Not null: " />
<p:selectBooleanCheckbox id="updateNotNull"
value="#{tableBean.updatedColumnNotNull}" />
<h:outputText value="Primary Key: " />
<p:selectBooleanCheckbox id="updatePrimaryKey"
value="#{tableBean.updatedColumnPrimaryKey}" />
</h:panelGrid>
</p:dialog>
</h:form>
TableBean:
private String updatedColumnName = "";
private String updatedColumnType = "";
private double updatedColumnSize = 0.0;
private boolean updatedColumnNotNull = false;
private boolean updatedColumnPrimaryKey = false;
private List<String> columnTypes = new ArrayList<String>();
public void personalmethod(ColumnDTO updateColumn) {
this.setUpdatedColumnName(updateColumn.getTitle());
this.setUpdatedColumnType(updateColumn.getType());
this.setUpdatedColumnSize(updateColumn.getSize());
this.setUpdatedColumnNotNull(updateColumn.isNotNull());
this.setUpdatedColumnPrimaryKey(updateColumn.isPrimaryKey());
}
public List<ColumnDto> getTableColumns(TableDTO contextTable) {
List<ColumnDto> contextTableColumns = new ArrayList<ColumnDto>();
for (ColumnDto myColumnDto: contextTable.getColumns().values()) {
contextTableColumns.add(myColumnDto);
}
return contextTableColumns;
}
From what I tried: put ID on the datagrid on the dialog, namings like <form:datagrid> and #RequestScoped but I can only have the dialog poping up, but with the form all blank.
Can you help me figuring out what's missing?
Kind regards,
Sam
You should set a property when h:commandButton is fired as explained in this article and the pass it to dialog.
As mentioned by Jaqen H'ghar, me either would switch to #ViewScoped and would use two different form and put the second one inside dialog.

p:commandLink actionListener is processed for each row of p:dataTable while rendering the page

I have a dataTable that shows data stored in a database. One of the column contains a commandLink (p:commandLink) to edit selected row which is fine.
I have a problem during the rendering of my xhtml page. It seems that the method of backingBean in the actionListener attribute of commandLink is processed for every row in the table, but the actionListener should be processed only when link is clicked.
Here is my xhtml page (part of):
<h:form id="formElenco">
<p:dataTable id="dt1" value="#{myBean.itemList}" var="item">
<f:facet name="header">
<h:outputText value="header" />
</f:facet>
<p:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{item.name}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="value" />
</f:facet>
<h:outputText value="#{item.value}"/>
</p:column>
<p:column>
<p:commandLink id="lnkItemUpdate" value="Edit"
onstart="document.getElementById('divUpdateItem').style.display = 'block';"
actionListener="#{myBean.updateItemAction(item)}" update=":formUpdateItem" />
</p:column>
</p:dataTable>
</h:form>
<div id="divUpdateItem" style="display:none" >
<h:form id="formUpdateItem">
Nome <h:inputText value="#{myBean.name}" /><br/>
Met <h:inputText value="#{myBean.value}" /><br/>
<h:inputHidden value="#{myBean.id}" />
<h:commandButton action="#{myBean.updateItemAction}" value="Save" />
</h:form>
</div>
Here are myBean's method (myBean is requestScoped):
public String updateItemAction(Entity item){
this.setId(item.getId());
this.setName(item.getName());
this.setValue(item.getValue());
return null;
}
public String updateItemAction() {
Entity entity = new Entity();
entity.setId(this.getId());
entity.setName(this.getName());
entity.setVAlue(this.getValue());
updateEntityQueryMethod(entity);
return null;
}
This isn't a valid method signature for an actionListener, so it's treated as a value expression by the <p:commandLink>.
You should be using action instead.
<p:commandLink id="lnkItemUpdate" value="Edit"
onstart="document.getElementById('divUpdateItem').style.display = 'block';"
action="#{myBean.updateItemAction(item)}" update=":formUpdateItem" />
Note that you can also just return void instead of a null String.
public void updateItemAction(Entity item) {
this.setId(item.getId());
this.setName(item.getName());
this.setValue(item.getValue());
}
A valid actionListener method signature would be a void method taking javax.faces.event.ActionEvent argument:
public void actionListener(ActionEvent event) {
// ...
}
See also:
Differences between action and actionListener

Resources