3
votes

Is there a way to dynamically enable/disable a commandButton on a table row selection basis?

In the next example, I want to enable ‘deleteBtn’ only if there is any row selected:

<p:dataTable
    var="department" value="#{departmentCtrl.departmentTable}"
    selection="#{departmentCtrl.departmentList}">

    <p:column selectionMode="multiple" styleClass="w18" /> 

    <p:column headerText="#{msgs.id}" sortBy="#{department.id}">
        <h:outputText value="#{department.id}" />
    </p:column>

    <p:column headerText="#{msgs.name}" sortBy="#{department.name}">
        <h:outputText value="#{department.name}" />
    </p:column>
</p:dataTable>

<p:commandButton id="deleteBtn" value="#{msgs.delete}" disabled="???" />

Thanks

4
how about using the <p:ajax event="rowSelect" or other events take a look at this example primefaces.org/showcase/ui/datatableRowSelectionInstant.jsf - Daniel
It doesnt works. I want to do the same as in the Checkbox Based Selection sample (primefaces.org/showcase-labs/ui/…); but working with the rowSelectCheckbox and rowUnselectcheckbox events as stated in the documentation (pg 141 of Primefaces USER’S GUIDE v3.3) - JLLMNCHR
so why don't you use something like this<p:ajax event="rowSelectCheckbox" listener="#{myBean.handleSelect}" update="someID" - Daniel

4 Answers

3
votes
  1. You should update your button every time a select or unselect event occurs.
  2. You should disable it when the departmentList is empty.

    <p:dataTable var="department" 
    
    value="#{departmentCtrl.departmentTable}" 
    
    selection="#{departmentCtrl.departmentList}">
    
            <p:ajax event="rowSelect" update="deleteBtn"/>
            <p:ajax event="rowUnselect" update="deleteBtn"/>
    
            <p:column selectionMode="multiple" styleClass="w18" /> 
    
            <p:column headerText="#{msgs.id}" sortBy="#{department.id}">
                <h:outputText value="#{department.id}" />
            </p:column>
    
            <p:column headerText="#{msgs.name}" sortBy="#{department.name}">
                <h:outputText value="#{department.name}" />
            </p:column>
    
    </p:dataTable>
    
        <p:commandButton id="deleteBtn" value="#{msgs.delete}" 
            disabled="#{fn:length(departmentCtrl.departmentList) == 0}" />
    

BTW don't forget to add the fn namespace to your facelets file.

1
votes

A bit late to the party perhaps, but here is what it took for me to enable and disable based on every possible type of click in a Checkbox selection table. In my case I just needed to tell the Print and Delete buttons to disable when there was nothing selected.

<p:ajax event="rowSelect" update=":form:printBtn,:form:deleteBtn" />
<p:ajax event="rowUnselect" update=":form:printBtn,:form:deleteBtn" />
<p:ajax event="toggleSelect" update=":form:printBtn,:form:deleteBtn" /> 
<p:ajax event="rowSelectCheckbox" update=":form:printBtn,:form:deleteBtn" />
<p:ajax event="rowUnselectCheckbox" update=":form:printBtn,:form:deleteBtn" />

It is possible that you don't actually need all five events but I did. rowSelect and rowUnselect handled the mouse clicks that are not in the checkboxes. toggleSelect handles the checkbox that selects all/none (the one in the column headers) and the rowSelectCheckbox and rowUnselectCheckbox handle the checkboxes in the rows.

0
votes

I am too late to response. But it might help someone. I got the same requirement to disable the button, when the user does not select any checkbox.

I am using Primefaces 5.1

Here is my proposed solution.

I am using widgetVar to check the selected row count and enable/disable the command button.

From the Primefaces document we have client side API for the data table:

enter image description here

Also we have client side API for command button

enter image description here

Now we will come back to the implementation part

<p:dataTable var="line" varStatus="loop"
                    value="#{myexpense.lazyModel}" paginator="true"
                    rows="#{myexpense.rows}"
                    rendered="#{myexpense.userIdSearch eq null}" 
                    rowIndexVar="row"
                    emptyMessage="#{tk.expense_table_empty}"
                    paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} 
                    {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                    widgetVar="expenseEntryTable"
                    rowsPerPageTemplate="#{myexpense.rowsPerPageTemplate}"
                    id="lazyDataTable" lazy="true"
                    selection="#{myexpense.selectedExpenseEntryList}"
                    rowKey="#{line.oid}">
                    <p:ajax event="toggleSelect" oncomplete="disableOrEnableCommandButton();" update="updateBtn"/> 
                    <p:ajax event="rowSelectCheckbox" oncomplete="disableOrEnableCommandButton();" update="updateBtn"/>
                    <p:ajax event="rowUnselectCheckbox" oncomplete="disableOrEnableCommandButton();" update="updateBtn"/>
                    <p:column selectionMode="multiple" width="3%" styleClass="centerAlignColumn selectAll" id="selectAll"/>
                    .... more column
                    <f:facet name="footer">
                        <p:commandButton process="lazyDataTable" value="#{tk.expense_update_selected}" partialSubmit="true"  ajax="true" widgetVar="updateBtn" disabled="#{myexpense.disableUpdateButton}"
                            actionListener="#{myexpense.updateSelected}" 
                            update="lazyDataTable @form" rendered="#{myexpense.form.myOnly}" />
                    </f:facet>
                </p:dataTable>

As you can see I have defined 2 widgetVar, one for data table (expenseEntryTable) and another one for command button (updateBtn).

Also I have defined disbaled attribute #{myexpense.disableUpdateButton}, which will be helpful when the page load.

private Boolean disableUpdateButton;
    public Boolean getDisableUpdateButton(){
            disableUpdateButton = !((selectedExpenseEntryList!=null) && (!selectedExpenseEntryList.isEmpty()));
            return disableUpdateButton;
        }

Now you can write the java script.

function disableOrEnableCommandButton() {
    if (PrimeFaces.widgets['expenseEntryTable']) {
        if (PF('expenseEntryTable').getSelectedRowsCount() > 0) {
            PF('updateBtn').enable();
        } else {
            PF('updateBtn').disable();
        }
    }
}

Hope it helps anyone!!!

-2
votes

[SOLVED]

In the manage bean I change from:

List departmentList;

to

Department[ ] departmentList;

Then I can use:

<p:ajax event="rowSelectCheckbox" listener="#{departmentCtrl.departmentSelected}"
                         update=":formManageDepartment:departmentBtnPanel,:formManageDepartment:deleteDepartmentBtn"/>
                    <p:ajax event="rowUnselectCheckbox" listener="#{departmentCtrl.departmentUnselected}"
                         update=":formManageDepartment:departmentBtnPanel,:formManageDepartment:deleteDepartmentBtn"/>