0
votes

EDIT: Everything worked after I tried to populate the collection when the view is constructed, in the @PostContsruct init()-method of that view's backing bean class. It is @ViewScoped. So the problem lies in that the component somehow doesn't recognize the collection that is used as a value of the datatable, actually having values because it is populated in an uncommon way. Anyway, everything works perfectly if I populate the collection when the view builds. But of course that's not a solution because the collection must be populated on that mentioned blur ajax event. So it's some kind of a lifecycle / scope problem.

EDIT2: I tried to add the table to the same form as the component that has ajax blur effect in it, showing the popup and the datatable in that popup and populating the collection. That worked too. So, somehow the lifecycle / scope was different in that ajax blur event and the datatable functionality since they were in different forms. Now I should somehow manage to keep them in the same scope while having the datatable in the popup dialog. Now the datatable clumsily resides in the same form for aforementioned testing purposes.

I have a Primefaces p:dataTable in a p:confirmDialog and when I select an item, the setter of that item just gets null value. So a null value is set and the following operation obviously doesn't work because we don't have a value to work with.

I think the problem has something to do with me having to use RequestContext to show the dialog. This is because the dialog should be shown when a collection is checked in a blur event of a form.

First, a blur event is checked from a InputText:

<p:inputText id="customerIdInput"
             value="#{newCustomerCaseController.id}"
             label="custId" required="true">
    <f:ajax event="blur" listener="#{newCustomerCaseController.performBackgroundSearch}" />
</p:inputText>

Then, on that blur event a listener method will be called in the backing bean, which shows a dialog via RequestContext as follows:

public void performBackgroundSearch() {
    showPopUpBecauseCertainConditionsAreMet();
}

public void showPopUpBecauseCertainConditionsAreMet() {

    setExistingCustomerCases(customerCaseService.searchByEmployerId(employerId));
    RequestContext.getCurrentInstance().update("caseform");
    RequestContext.getCurrentInstance().execute(
            "PF('employerAlreadyHasCustomerCasesDialog').show()");
    }
}

Here's the confirm dialog and table in xhtml:

<p:confirmDialog widgetVar="employerAlreadyHasCustomerCasesDialog" width="500" appendTo="@(body)" showEffect="fade" hideEffect="fade"
                 closable="false" >
<h:form id="caseform">
        <p:dataTable id="casetable"  var="custcase" rowKey="#{custcase.caseId}" value="#{newCustomerCaseController.existingCustomerCases}"
                     selectionMode="single" selection="#{newCustomerCaseController.selectedAlreadyExistingCustomerCase}" >
            <p:ajax event="rowSelect" process="@this" listener="#{newCustomerCaseController.onExistingCaseRowSelect()}" />
            <p:column headerText="caseId">
                <h:outputText value="#{custcase.caseId}" />
            </p:column>
        </p:dataTable>
</h:form>
<!--some unimportant buttons which we don't touch in this example-->
</p:confirmDialog>

Lastly, let's see what the onExistingCaseRowSelect listener method does. It only tries to redirect, as in navigate to different url using the caseId of that customerCase that we try to select in the p:dataTable.

public void onExistingCaseRowSelect(SelectEvent event) {
    try {
        facesContext.getExternalContext().redirect("/customercase.xhtml?caseId=" + selectedAlreadyExistingCustomerCase.getCaseId());
    }catch (Exception e) {
    }
}

The problem here is that the selectedAlreadyExistingCustomerCase doesn't get set in the backing bean when it is clicked in the table. A null is being set when I click the row in the table. I've checked this with printlines in getter and setter. I think the problem here is that something happens because of the update of the view via RequestContext.getCurrentInstance().update("componentName");

How can I get the clicked row value in the table - a customerCase that is - to be set as the selected value in the backing bean, instead of a null?

1
Can you get access to the selected item in the ajax call via event.getObject()? If I use ajax in the datatable, I never use the selection attribute with ajax calls. Selection always seems null then. If it is still null there, check the rowkey attribute. stackoverflow.com/questions/22816268/…Kukeltje
@Kukeltje event.getObject() is null in this case, but not after I tried to populate the collection when the view is constructed, in the (at)PostContsruct init()-method of that backing bean class. So the problem lies in that the component somehow doesn't recognize the collection that is used as a value of the datatable, actually having values because it is populated in an uncommon way. Anyway, everything works perfectly if I populate the collection when the view builds. But of course that's not a solution because the collection must be populated on that mentioned blur ajax event.Steve Waters
@Kukeltje I added two EDITS in the beginning of the problem description.Steve Waters

1 Answers

0
votes

Managed to get it to work. So this is how I did it: I placed the dialog window with the datatable and all into the same form that the ajax blur event is launched from. But I never got the setter to work, it was still null. Anyway, as @Kukeltje suggested in a comment, I used event.getObject(), which worked only after putting everything in the same form.