Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

b:selectOneMenu doesn't recognize value from SelectItems collection with disabled attribute set to true. #907

Closed
modima65 opened this issue Jan 26, 2018 · 7 comments
Assignees
Milestone

Comments

@modima65
Copy link

  • Overview of the issue

No error, silent.

  • Motivation for or Use Case

b:selectOneMenu value and SelectItems collection are prepared and set in the same bean prior to render page. One of the values in the collection matches exactly the value in b:selectOneMenu. When b:selectOneMenu disabled attribute is false or not specified (default), the value in such component matches correctly the one in the f:selectItems collection. When b:selectOneMenu disabled attribute is true, the value in such component does not match the value in the f:selectItems collection and the component shows empty value.

When BootsFaces b:selectOneMenu is replaced by JSF h:selectOneMenu the value matches the one in the f:selectItems collection whether disabled attribute be set to true or false.

  • BootsFaces Version(s)
    1.2
  • Browsers and Operating System
    Safari 11.0.2
    macOS 10.13.2
  • Reproduce the error

The Bean:

@Named(value = "fletesController")
@ViewScoped
public class FletesController implements Serializable{
    private Flete selectedFlete; // Row selected from b:dataTable with onEdit listener
    private List<SelectItem> tipos;    
    private FleteDaoImpl dao;

    @PostConstruct
    private void initController() {
        tipos = new ArrayList<>();
        tipos.add(new SelectItem("01", "Wood"));
        tipos.add(new SelectItem("02", "Steel"));
        tipos.add(new SelectItem("03", "Plastic"));
        dao = new FleteDaoImpl();
    }

     // Listener in b:dataTable commandButton
    public onEdit(Flete flete) {
        selectedFlete = dao.findById(Flete.class, flete.id);
        System.out.println("The value TIPO comes from database: " + selectedFlete.getTipo());
    }

        // Getters and Setters
}

The XHTML:

<h:form>
...
<b:dataTableColumn label="Consultar" searchable="false" orderable="false" headerStyle="text-align: center;" contentStyle="text-align: center;">
     <b:commandButton look="info" icon="eye-open" ajax="true" process="@this" actionListener="#{fletesController.onEdit(flete)}" update="@(.modalFleEdit)" oncomplete="$('.modalFleEdit').modal('show')">
          <f:param name="disabledToggle" value="true" transient="true"/>
     </b:commandButton>
</b:dataTableColumn>
...
<b:modal title="Flete Id: #{fletesController.selectedFlete.id}" class="modalFleEdit" closable="false">
     <b:panelGrid id="panelFleEdit" columns="2">
          <b:selectOneMenu value="#{fletesController.selectedFlete.tipo}" label-col-md="8" label="Tipo:" disabled="#{param['disabledToggle']}">
           <f:selectItems value="#{fletesController.tipos}"/>
          </b:selectOneMenu>
...
     </b:panelGrid>
</b:modal>
...
</h:form>
  • Related issues
  • Suggest a Fix

I have to use two components: one h:outputText for disabled situation and one b:selectOneMenu when enabled, but toggling rendered.

@stephanrauh
Copy link
Collaborator

Thanks for your detailed bug description! That should help us to find and solve the bug quickly.

@stephanrauh stephanrauh self-assigned this Jan 26, 2018
@stephanrauh stephanrauh added this to the v1.5.0 milestone Jan 26, 2018
@stephanrauh
Copy link
Collaborator

Did I simplify your example too much? My version works like charm. Can you have a look at it, please? Maybe it helps to track down the bug.

BTW, you can also inspect the result of the AJAX response after clicking the button. Maybe there's a difference between the disabled and the regular case?

Here`s my bean:

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;

@ManagedBean
@ViewScoped
public class FletesController implements Serializable {
	private static final long serialVersionUID = 1L;

	private List<SelectItem> tipos;

	private SelectItem selectedFlete = new SelectItem("02", "Steel");

	public FletesController() {
		tipos = new ArrayList<>();
		getTipos().add(new SelectItem("01", "Wood"));
		getTipos().add(new SelectItem("02", "Steel"));
		getTipos().add(new SelectItem("03", "Plastic"));
	}

	// Listener in b:dataTable commandButton
	public void onEdit(SelectItem flete) {
       setSelectedFlete(new SelectItem("03", "Plastic"));
    }

	public SelectItem getSelectedFlete() {
		return selectedFlete;
	}

	public void setSelectedFlete(SelectItem selectedFlete) {
		this.selectedFlete = selectedFlete;
	}

	public List<SelectItem> getTipos() {
		return tipos;
	}

	public void setTipos(List<SelectItem> tipos) {
		this.tipos = tipos;
	}
}

And the JSF file:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets">
  <h:head>
  </h:head>
  <h:body style="padding-top: 60px">
<h:form>
      <b:panelGrid id="panelFleEdit" columns="2">
        <b:commandButton look="info" icon="eye-open" ajax="true" process="@this" actionListener="#{fletesController.onEdit(flete)}" update="@next">
          <f:param name="disabledToggle" value="true" transient="true"/>
     	</b:commandButton>
      
          <b:selectOneMenu class="modalFleteEdit" value="#{fletesController.selectedFlete.value}" label-col-md="8" label="Tipo:" disabled="true">
           <f:selectItems value="#{fletesController.tipos}"/>
          </b:selectOneMenu>
     </b:panelGrid>
</h:form>
  </h:body>
</html>l

@modima65
Copy link
Author

Hi, yes it's a little simplified, but let me take a look again, the least I want is make you lose time, though I spent a day trying to make it work without success. May it be a mix of object identity, the param I'm setting inside command button, and the render phase? I'll keep you informed. Thanks.

@stephanrauh
Copy link
Collaborator

¡Muchisimas gracias! BTW, if you want to tackle the problem from the other (my) side: I've uploaded my attempt to reproduce your bug in our showcase. The showcase is a simple Maven application running in a Tomcat. The only thing you might want to change is the dependency to BootsFaces (currently 1.2.1-SNAPSHOT in the pom.xml).

@modima65
Copy link
Author

Hi, again. The problem is with the <f:converter /> tag. Unfortunately, I DID simplified my initial example too much. I'm using a converter to save a pojo from selected item collection as required value, the value has already a pojo that matches one in the collection; the collection is a Map<String, Tipo> but I tried also a List<SelectItem> in vain. It's like, when b:selectOneMenu component is rendered initially with attributes disabled="true", and required="true", the converter is ignored; then, when the component's disabled attribute is updated and set to false, everything seem Ok to the eyes until form validation: the required value is missing due to converter failure. If I remove the disabled attribute at all from b:selectOneMenu, the converter works and validation succeeds. What do you suggest? Do I edit my first example? Or is there already a issue open for this case?

From your showcase:

Since BootsFaces 1.1.0, you can use converters as defined by the JavaEE documentation and described by M. K. Yong. In rare cases, this may turn out to be a breaking change. Previous versions of BootsFaces simply ignored the converter. In some case, such as issue 713, this can be surprising because JavaEE allows you to define converters via annotations. In this case, the converter isn't mentioned by the <b:selectOneMenu /> declaration directly.

The list of items can be defined as an <f:selectItems /> tag. BootsFaces uses a modified version of the algorithm PrimeFaces 5.1 uses to implement <f:selectItems />. As a result, you can use <b:selectOneMenu> almost the same way as <b:selectOneMenu>.

Thank you.

@chongma
Copy link
Collaborator

chongma commented Jan 29, 2018

related to #797 ?

@stephanrauh
Copy link
Collaborator

@modima65 Maybe it's a good idea to send us a reproducer - i.e. a minimal but complete project showing the bug. Among other things, "minimal" means there's no database, so all we need to do is to take your Maven project and deploy it in Tomcat or (say) Wildfly.

Alternatively, you can also debug BootsFaces yourself. More likely than not, the bug (if there's one) is in the class SelectOneMenuRenderer. If you need more hints, just tell me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants