0

I'm trying to implement a JSF page in which the user should insert some data. In particular, when pressing a button a dialog box should appear asking for user input. The main problem is that the execution of the backing bean should be stopped waiting for a user response.

A toy example is the following.

JSF page:

        <h:form id="label">
            <p:dialog header="User input" widgetVar="dlg2"
                visible="true" modal="false"
                resizable="false" height="100" width="300">
                <br />
                <h:inputText value="#{userInputMB.userInput}"></h:inputText>
            </p:dialog>
            <p:commandButton action="#{userInputMB.pressButton}"></p:commandButton>
        </h:form>

UserInputMB:

package jsfpackage;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class UserInputMB {
    private String userInput;
    private boolean visualizeDialog = false;

    public UserInputMB() {

    }

    public void pressButton() {
        System.out.println("Executing the pressButton method..");
        //here I need to visualize the dialog and wait for the user input
        System.out.println(userInput);
    }
    public String getUserInput() {
        return userInput;
    }

    public void setUserInput(String userInput) {
        this.userInput = userInput;
    }

    public boolean isVisualizeDialog() {
        return visualizeDialog;
    }

    public void setVisualizeDialog(boolean visualizeDialog) {
        this.visualizeDialog = visualizeDialog;
    }
}

In this example, when pressing the button, the pressButton method should visualize the dialog box and wait for the user input and then continue the execution.

I also found this similar question on stackoverflow: Synchronous dialog invocation from managed bean

but my situation is quite different. I'm forced to implement this kind of behavior. Thanks in advance!

Paolopast
  • 197
  • 1
  • 11
  • If you just want a confirm like dialog, you can use PrimeFaces Confirm Dialog: https://www.primefaces.org/showcase/ui/overlay/confirmDialog.xhtml Otherwise create your own dialog, remove the action from your commandButton and only show the dialog you need. Add a new button in your dialog, that calls your action in the backing bean. You can also add a listener on your inputText that calls an action, instead of a new button. – TomStroemer Apr 30 '20 at 09:46
  • No, the main problem is that I have a system that dynamically asks questions to the user. So the questions should be visualized in this dialog and the backing Bean execution should be stopped waiting for user input. So, i need a backing bean that "waits" for an action from the user – Paolopast Apr 30 '20 at 09:51
  • 1
    I would split that in two methods - one to show the question and one to process the user input. As your bean is already SessionScoped you can store any data you need in the second action in your bean. – TomStroemer Apr 30 '20 at 10:03
  • Ok, but how to stop the execution waiting for user input? – Paolopast Apr 30 '20 at 10:09
  • 1
    Sorry, I don't understand - what do you mean by "stop the execution"? If you don't do anything more in your action then preparing the userInput nothing more will be executed. – TomStroemer Apr 30 '20 at 10:14
  • In the pressButton method I need to show the dialog and get the user input in order to print it. Everything should be done in the execution of that method like when you ask for input in a stand alone application with the Scanner class – Paolopast Apr 30 '20 at 10:22
  • 1
    Sorry, but that's not how JSF/Web works. You need two HTTP requests (one to preapre, one for the input), you can't block on server side to wait for another request to come in. – TomStroemer Apr 30 '20 at 10:24
  • 1
    @TomStroemer is right... Not a JSF specific limitation and most likely there already is a 'duplicate' of this Q in stackoverflow. – Kukeltje Apr 30 '20 at 10:34

1 Answers1

2

The following sample contains a dialog and a button. The button prepares the input and opens the dialog. In the dialog the second button calls the action to process the input.

JSF:

<!-- dialog for input -->
<p:dialog id="inputDialog" widgetVar="inputDialog" header="Input here">
    <p:inputText value="#{userInputMB.userInput}" />
    <p:commandButton action="#{userInputMB.processInput}" />
</p:dialog>

<!-- Calls the action to prepare the input and updates and opens the dialog -->
<p:commandButton value="show dialog" action="#{userInputMB.prepareInput}"
                 oncomplete="PF('inputDialog').show()" process="@this" update=":inputDialog" />

Bean:

@ManagedBean
@SessionScoped
public class UserInputMB {

    private String userInput;

    public void prepareInput() {
        userInput = "Please enter your input here";
    }

    public void processInput() {
        if("inputYouWanted".equals(userInput)) {
            System.out.println("hurray, correct input!");
        }
    }

    public String getUserInput() {
        return userInput;
    }

    public void setUserInput(String userInput) {
        this.userInput = userInput;
    }
}
TomStroemer
  • 1,390
  • 8
  • 28