3

I wanted to make the possibility of booking /remove booking the product page. Reservations is ok, removing unfortunately not ...

@ManagedBean(name = "wardrobeDetailsBean")
@SessionScoped
//@RequestScoped
public class WardrobeDetailsBean implements Serializable {

    @Inject
    WardrobeService wardrobeService;
    @Inject
    AuthBean authBean;

    // other fields + setters, getters

    @ManagedProperty("#{param.id}")
    private Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsernameReserving() {
        this.selectedWardrobe = wardrobeService.getWardrobeById(id);
        String usernameById = selectedWardrobe.getReservingUserId().getUsername();
        StringBuilder sb = new StringBuilder();
        sb.append(usernameById.substring(0, 2));
        sb.append("...");
        sb.append(usernameById.substring(usernameById.length() - 2, usernameById.length()));
        return sb.toString();
    }

    @PostConstruct
    public void init() {
        if (FacesContext.getCurrentInstance().getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
            dbImage1 = new DefaultStreamedContent();
        } else if (id != null) {
            this.selectedWardrobe = wardrobeService.getWardrobeById(id);
            }
        }
    }

    public String reserve() {
        this.selectedWardrobe = wardrobeService.getWardrobeById(id);
        if (authBean.getUser() != null && authBean.getUser().getId() != null) {
            selectedWardrobe.setReservingUserId(authBean.getUser());
            wardrobeService.reserveProduct(selectedWardrobe);
            return null;
        } else {
            return "/login.xhtml?faces-redirect=true";
        }
    }

    public void unreserve() {
        this.selectedWardrobe = wardrobeService.getWardrobeById(id);
        selectedWardrobe.setReservingUserId(null);
        wardrobeService.reserveProduct(selectedWardrobe);
    }
}

productView.xhtml

<h:commandButton id="reserve" styleClass="btn-u btn-u-sea-shop btn-u-lg" rendered="#{wardrobeDetailsBean.selectedWardrobe.reservingUserId eq null}"
    value="Reserve" action="#{wardrobeDetailsBean.reserve()}">
        <f:ajax execute="@form" render="reservePanel"/>
</h:commandButton>

<h:outputText value="This product has been reserved by #{wardrobeDetailsBean.usernameReserving}" rendered="#{wardrobeDetailsBean.selectedWardrobe.reservingUserId ne null}"/>
<br />
 <input type="hidden" name="remoteUser" value="#{request.remoteUser}"/> 
// added using guidance from the answers
<h:commandButton id="unreserve" styleClass="btn-u btn-u-red btn-u-lg" rendered="#{request.remoteUser eq wardrobeDetailsBean.selectedWardrobe.reservingUserId.username}"
    value="Unreserve" action="#{wardrobeDetailsBean.unreserve()}">
        <f:ajax execute="@form" render="reservePanel"/>
</h:commandButton>

When I removed the rendered="#{request.remoteUser eq wardrobeDetailsBean.selectedWardrobe.reservingUserId.username}", it works.

When the reservation is clicked it should only be visible button for removal. What is wrong, it does not work? The log any errors I have not.

After using guidance from the answers, application works like this. enter image description here

I click "Reserve". The product has been reserved, the button will be swapped.

enter image description here

I click "Unreserve" and still the method is not called, I lose the information about the product (refresh the page returns information about the product, but the product is still reserved)

enter image description here

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
user3128303
  • 747
  • 1
  • 11
  • 26

1 Answers1

2

Rendered attribute of button is evaluated in the process of submitting form before request is reached to your bean method,

and as you checked request.remoteUser in rendered method, it will be empty for new request (post request of action), the rendered evaluation will be "false", so your method is not called.

So you must make sure that rendered attribute of your button and its parents remain to true during form submission.

That's the cause when you remove rendered attribute, it works fine.

As a workaround you can add a hidden input to your form:

<input type="hidden" name="remoteUser" value="#{request.remoteUser}"/>
<input type="hidden" name="id" value="#{param.id}"/> 


Update: another solution

another solution is to use one single button, but use a conditional value attribute and a toggle method:

<h:commandButton id="toggle" 
    styleClass="btn-u btn-u-#{(wardrobeDetailsBean.selectedWardrobe.reservingUserId eq null) ? 'sea-shop' : 'red' } btn-u-lg" 
    value="#{(wardrobeDetailsBean.selectedWardrobe.reservingUserId eq null) ? 'Reserve' : 'Unreserve'}" 
    action="#{wardrobeDetailsBean.toggle()}">
        <f:ajax execute="@form" render="reservePanel"/>
</h:commandButton>

And in your bean, use a toggle method:

public String toggle() {
        this.selectedWardrobe = wardrobeService.getWardrobeById(id);
        if(selectedWardrobe.getReservingUserId() == null){
            if (authBean.getUser() != null && authBean.getUser().getId() != null) {
                selectedWardrobe.setReservingUserId(authBean.getUser());
                wardrobeService.reserveProduct(selectedWardrobe);
                return null;
            } else {
                return "/login.xhtml?faces-redirect=true";
            }
        }else{
            this.selectedWardrobe = wardrobeService.getWardrobeById(id);
            selectedWardrobe.setReservingUserId(null);
            wardrobeService.reserveProduct(selectedWardrobe);
        }

    }
Shirin Safaeian
  • 950
  • 6
  • 18