JSF SelectManyCheckbox-Auswahl bedingt andere Komponenten

Phenix

Bekanntes Mitglied
Hallo zusammen,

ich habe zuerst einmal ein paar Verständnisfragen. Wenn man im Internet umher schaut sieht man häufg Code wie diesen, allerdings oft nur mit dürftigen Erklärungen:

[XML]
<h:selectOneMenu id="subcat" value="#{categoryController.subCategoryOptions}">
<f:selectItems value="#{categoryController.subCategoryOptions}" var="option" itemLabel="#{option.description}" itemValue="#{option.description}"/>
</h:selectOneMenu>
[/XML]

Meine Frage ist, wieso muss ich hier 2mal (1x im Tag selectOneMenu, 1x im Tag selectItems) die Liste der Elemente angeben? Was bedeutet diese Angabe im selectOneMenu-Tag?

2. Wie könnte man es am Besten lösen, wenn eine Auswahl eines Elementes in einer Dropdown-Box die Auswahlmöglichkeiten der anderen beeinflussen soll? Ich habe zum Beispiel Kategorien und Unterkategorien. Je nachdem, welche Kategorie ausgewählt wird, werden entsprechende Unterkategorien angezeigt.

Danke im Voraus
 

JimPanse

Bekanntes Mitglied
Hi,

1. Das value Attribute in der SelectOneMenu-Komponente ist die aktuelle Auswahl und die SelectItems ist eine Liste der möglichen Auswahl Felder Bsp (Pseudo Code -> nicht getestet):

Java:
@ManagedBean(name=SelectBean.NAME)
@ViewScope
public class SelectBean{

     public static final String NAME ="SelectBean";
     private String selected;
     private List<SelectItem> list;

     @PostConstruct
     public void init(){

     list = new ArrayList<SelectItem>();
     for(int i = 0; i < 10; i++){
        list.add(new SelectItem("Auswahl"+i,"Auswahl"+i);
     }
   }
//getter & setter
}

// JSF
<h:selectOneMenu id="subcat" value="#{SelectBean.selected}">
        <f:selectItems value="#{SelectBean.list}" 
</h:selectOneMenu>

2. Für diesen Anwendungsfall verwendest du einen ValueChangeListener
Java:
@ManagedBean(name=SelectBean.NAME)
@ViewScope
public class SelectBean{
//.... von oben
private String selected2;
private List<SelectItem> list2;
public void change(ValueChangeEvent arg0){

String newSelectItem = arg0.getNewValue();

//mache was damit
}
}

<h:selectOneMenu id="subcat" value="#{SelectBean.selected}" valueChangeListener="#{SelectBean.change}">
    <f:selectItems value="#{SelectBean.list}"/>
    <f:ajax execute="@this" render="subcat2"/>                                 
 </h:selectOneMenu>

<h:selectOneMenu id="subcat2" value="#{SelectBean.selected2}" >
      <f:selectItems value="#{SelectBean.list2}" />
</h:selectOneMenu>

Das ist jetzt alles ungestestet und aber sollte das Prinzip verdeutlichen... In die SelectItems kannst du natürlich auch andere primitiven Datentypen bzw. deren Wrapper-Klassen verwenden -> für Objekte brauchst du einen Converter.

"...dürftigen Erklärungen" -> kann ich mir nicht vorstellen zu JSF gibst es maßig Info's im Netz, z.B.
-> http://jsfatwork.irian.at/semistatic/introduction.html

Grüße
 

Phenix

Bekanntes Mitglied
Hallo,

danke erstmal soweit. Werde es ausprobieren.

Das mit den dürftigen Erklärungen bezog sich nur auf meine 1. Frage, wofür genau welche Liste gut ist. Der Rest ist wohl m.E. ganz gut dokumentiert.
 

Phenix

Bekanntes Mitglied
Ich habe es ausprobiert und bin ein wenig überrascht. Deiner Antwort zufolge hätte ich jetzt erwartet, dass beim Ändern der Auswahl der aktuell ausgewählte Wert in selected gespeichert wird. Dem ist aber nicht so. Ich habe es scheinbar doch flasch verstanden. Wie komme ich denn jetzt mit dem Listener an den aktuell ausgewählten Wert?
Im newValue steht immer nur null.

Java:
<h:selectOneMenu id="cat" value="#{categoryController.selected}" valueChangeListener="#{categoryController.change}">
                                            <f:selectItems value="#{categoryController.categoryOptions}" var="option" itemLabel="#{option.description}" itemValue="#{option.description}"/>
                                            <f:ajax execute="@this" render="subcat"/>
                                        </h:selectOneMenu>


private String selected="";
...

public void change(ValueChangeEvent event)
    {
event.getNewValue(); //null
 
Zuletzt bearbeitet:

JimPanse

Bekanntes Mitglied
Also den Code habe ich aus den Kopf gepostet und nicht getestet aber ich habe gerade nach geschaut genauso habe ich es in meinem letzten Projekt gemacht... d.h. Poste bitte deinen ganzen Code!
 

JimPanse

Bekanntes Mitglied
Ich habe es ausprobiert und bin ein wenig überrascht. Deiner Antwort zufolge hätte ich jetzt erwartet, dass beim Ändern der Auswahl der aktuell ausgewählte Wert in selected gespeichert wird. Dem ist aber nicht so. Ich habe es scheinbar doch flasch verstanden. Wie komme ich denn jetzt mit dem Listener an den aktuell ausgewählten Wert?
Im newValue steht immer nur null.

Mich überracht das es bei dir nicht geht... Ich habe es gerade mal getestet funz wunderbar:

Java:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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"
	xmlns:c="http://java.sun.com/jsp/jstl/core">


<f:view contentType="text/html">

	<!-- Define the head parameters -->
	<h:head>
		<title>My Test App</title>

		<!-- Meta-Information -->
		<meta name="robots" content="noindex" />
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<meta http-equiv="Content-Script-Type" content="text/javascript" />
		<meta http-equiv="Content-Style-Type" content="text/css" />

	</h:head>

	<!-- Define the body content  -->
	<h:body>
		<h:form id="myform">
		<h:panelGrid columns="1">
			<h:selectOneMenu id="subcat" value="#{Controller.selected}"
				valueChangeListener="#{Controller.change}">
				<f:selectItems value="#{Controller.list}" />
				<f:ajax execute="@this" render="subcat2" />
			</h:selectOneMenu>

			<h:selectOneMenu id="subcat2" value="#{Controller.selected2}">
				<f:selectItems value="#{Controller.list2}" />
			</h:selectOneMenu>
			
			</h:panelGrid>
		</h:form>
	</h:body>
</f:view>
</html>

und die ManagedBean dazu

Java:
@ManagedBean(name = "Controller")
@ViewScoped
public class Controller {

	private String selected;
	private String selected2;

	private List<SelectItem> list;
	private List<SelectItem> list2;

	@PostConstruct
	public void init() {
		list = new ArrayList<SelectItem>();

		for (int i = 0; i < 10; i++) {
			list.add(new SelectItem("Auswahl" + i, "Auswahl" + i));
		}
	}

	public void change(ValueChangeEvent arg0) {

		selected = (String) arg0.getNewValue();
		System.out.println("selected: "+selected);
		
		
		if(selected!= null && selected.endsWith("0")) {
			list2 = new ArrayList<SelectItem>();
			for (int i = 0; i < 10; i++) {
				list2.add(new SelectItem("Andwere Auswahl" + i, "Andere Auswahl" + i));
			}
		} else {
			list2 = new ArrayList<SelectItem>();
			for (int i = 0; i < 10; i++) {
				list2.add(new SelectItem("Was ganz anderes" + i, "Was ganz anderes" + i));
			}
		}
	}


// getter & setter

}

Greetz
 

Phenix

Bekanntes Mitglied
Also in die ValueChangemethode springt er wohl rein, nur beinhaltet das event dort als oldValue einen Leerstring und als newValue null. Das habe ich mir mit dem Debugger angeschaut.

Java:
<h:outputLabel for="cat" value="Kategorien: " />
                                        <h:selectOneMenu id="cat" value="#{categoryController.selected}" valueChangeListener="#{categoryController.list}">
                                            <f:selectItems value="#{categoryController.categoryOptions}" />
                                            <f:ajax execute="@this" render="subcat"/>
                                        </h:selectOneMenu>
                                        <h:outputLabel for="subcat" value="Subkategorien: " />
                                        <h:selectOneMenu id="subcat" value="#{categoryController.subCategoryOptions}">
                                            <f:selectItems value="#{categoryController.subCategoryOptions}" var="option" itemLabel="#{option.description}" itemValue="#{option.description}"/>
                                        </h:selectOneMenu>


package controller.categories;

import Navigation.Controller;
import controller.entries.EntryController;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

/**
 *
 * @author Phenix
 */
@ManagedBean
@SessionScoped
public class CategoryController extends Controller<CategoryBean>
{

    private List<CategoryBean> subCategories = new ArrayList<CategoryBean>();
    private List<SelectItem> subCategoryOptions = new ArrayList<SelectItem>();
    private List<SelectItem> categoryOptions = new ArrayList<SelectItem>();
    private String selected="";
//    private MenuModel model = new DefaultMenuModel();

    public CategoryController()
    {
        super();
        try
        {
            //Save all
            allItems = new ArrayList<CategoryBean>();

            ResultSet all = reader.readAll("CATEGORIES");
            while (all.next())
            {
                String description = all.getString("CATEGORYNAME");
                ResultSet ownReadStatement = reader.ownReadStatement("SELECT CATEGORYNAME FROM SUBCATEGORIES WHERE CATEGORY='" + description + "'");

                Collection<SubCategoryBean> temp = new ArrayList<SubCategoryBean>();
                while (ownReadStatement.next())
                {
                    String categoryName = ownReadStatement.getString("CATEGORYNAME");
                    SubCategoryBean subCategoryBean = new SubCategoryBean(categoryName, description);
                    temp.add(subCategoryBean);
                }
                CategoryBean categoryBean = new CategoryBean(description, temp);
                allItems.add(categoryBean);
                categoryOptions.add(new SelectItem(categoryBean.getDescription(), description));
            }
        }
        catch (SQLException ex)
        {
            Logger.getLogger(EntryController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void list(ValueChangeEvent event)
    {
        System.out.println(event.getNewValue());
    }

//Getter/Setter

In die Methode setSelected wird auch nicht hinein gesprungen. Wohl aber in die Methode getSelected. :bahnhof:
 

JimPanse

Bekanntes Mitglied
1. Hast du mal meinem Code test weise eingepflegt???
2. Ist das ganze in einem form-element?
3. In der zweiten SelectOneMenue Komponente setzt du wieder statt einer Auswahl eine Liste!
4. was soll: var="option" itemLabel="#{option.description}" itemValue="#{option.description}" das bringen???????`
du setzt doch bereits in new SelectItem den label und das value????
 

Phenix

Bekanntes Mitglied
Wenn ich auf der Seite nur dieses Formular habe, funktioniert es. Auf meiner bisherigen Seite nicht. Jetzt muss ich nur noch herausfinden, wieso?
 

Phenix

Bekanntes Mitglied
Es funktioniert jetzt. Vorher hatte ich ein h:form-Tag um eine ganze Reihe von Elementen gesetzt. Nun habe ich dieses große Form in mehrere kleine zerlegt und siehe da: es funktioniert. Danke :applaus:
 

Ähnliche Java Themen

Neue Themen


Oben