JSF ve PrimeFaces İle Seçime Bağlı Otomatik Değişim
Sık sık JSF yazan arkadaşlardan JSF’de bir değer seçildiğinde bunun seçilecek diğer değeri nasıl etkileyebileceğine dair sorular alıyordum. Örneğin bir selectOneMenu’den seçilecek değerin ikinci selectOneMenu’yu nasıl etkileyebileceği soruluyordu. Bu yazıda ben de bu durumu örneğe dökerek sorulara bir çözüm üretmeye çalışacağım.
Öncelikle şunu belirteyim ki örneğimizi JSF’in bir UI framewörkü olan PrimeFaces ile yapacağız. PrimeFaces ajax-built bir yapıda olduğundan bizim ihtiyacımızı çok rahat ve kolay bir şekilde karşılayacak.
İkinci olarak da bu uygulanmanın kodlarına https://github.com/ilkgunel/PrimeFacesAutoFillingExample adresinden ulaşabilirsiniz.
Şimdi başlayalım…
Örneğimizde 2 adet dosyamız olacak. Birisi Managed Bean sınıfımız, diğeri de xhtml sayfamız. Öncelikle Java kodunu inceleyelim.
BeanClass.java
package com.ilkaygunel.primefacesautofilling;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class BeanClass {
private List<String> cities;
private List<String> boroughs;
private List<String> istanbulBorough;
private List<String> ankaraBorough;
private List<String> samsunBorough;
private String selectedCity = "";
private String selectedBorough = "";
@PostConstruct
public void init() {
cities = new ArrayList<>();
boroughs = new ArrayList<>();
istanbulBorough = new ArrayList<>();
ankaraBorough = new ArrayList<>();
samsunBorough = new ArrayList<>();
cities.add("istanbul");
cities.add("ankara");
cities.add("samsun");
istanbulBorough.add("şişli");
istanbulBorough.add("eyüp");
istanbulBorough.add("beyoğlu");
ankaraBorough.add("keçiören");
ankaraBorough.add("mamak");
ankaraBorough.add("sincan");
samsunBorough.add("bafra");
samsunBorough.add("atakum");
samsunBorough.add("vezirköprü");
}
public List<String> getCities() {
return cities;
}
public void fillBoroughList(){
if(selectedCity.equals("istanbul")){
boroughs = istanbulBorough;
}
else if(selectedCity.equals("ankara")){
boroughs = ankaraBorough;
}
else{
boroughs = samsunBorough;
}
}
public String getSelectedCity() {
return selectedCity;
}
public void setSelectedCity(String selectedCity) {
this.selectedCity = selectedCity;
}
public List<String> getBoroughs() {
return boroughs;
}
public void setBoroughs(List<String> boroughs) {
this.boroughs = boroughs;
}
public String getSelectedBorough() {
return selectedBorough;
}
public void setSelectedBorough(String selectedBorough) {
this.selectedBorough = selectedBorough;
}
}
BeanClass sınıfımız içinde 7 adet nesne tanımlı. Bu nesnelerden cities listesi xhtml içinde iller selectOneMenu’sünü dolduracak. boroughs listesi iller selectOneMenu’sünden seçilen ile göre dolacak bir liste. İstanbul seçilirse İstanbul’un listeleri görünecek örneğin. istanbulBorough, ankaraBorough ve samsunBorough listeleri de seçilen ile göre doldurulması yapılacak listeye atanacak değerleri tutan listeler. Yani Ankara seçilirse Ankara’ya ait ilçeler gösterilmesi için hazırda tutuluyor ve seçim yapıldığında direk atanıyor. selectedCity nesnesi seçilen ili tutacak ve ikinci selectOneMenu’ü bu nesneye göre dolacak. selectedBorough ise seçilen ilçeyi tutacak.
@PostConstruct notasyonu ile işaretli metot sınıfın constructor’ının yani yapılandırıcısının hemen peşinden devreye girecek listeleri dolduracak.
fillBoroughList() burada yazının asıl amacını yerine getiren metot olacak. Xhtml içinden il selectOneMenu’sünden seçim yapıldığında bu metot çalışacak ve ilçe selectOneMenu’sünü seçilen ile göre dolduracak. Örneğin seçilen ilin İStanbul olması durumunda ilçe selectOneMenu’sünü dolduracak boroughs lsitesi istanbul’un ilçelerini tutan istanbulBoroughs ile doldurulacak.
Sınıfın geri kalanı ise xhtml içinde kullanılacak nesnelerin get-set metotlarından oluşmakta. Bildiğimiz gibi xhtml sayfaları managed bean içinde tanımlı nesnelere ulaşabilmek için get metoduna, o nesnelere yazabilmek için de set metoduna ihtiyaç duyar.
Şimdi xhtml sayfamızı inceleyelim.
index.xhtml
<?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://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<p:panelGrid columns="2">
<h:outputText value="İl Seçiniz"/>
<p:selectOneMenu id="citySelectOneMenu" value="#{beanClass.selectedCity}">
<f:selectItem itemLabel="İl Seçin" itemValue="#{null}" />
<f:selectItems value="#{beanClass.cities}"/>
<p:ajax update="boroughSelectOneMenu" listener="#{beanClass.fillBoroughList()}"/>
</p:selectOneMenu>
<h:outputText value="İlçe Seçiniz"/>
<p:selectOneMenu id="boroughSelectOneMenu" value="#{beanClass.selectedBorough}">
<f:selectItems value="#{beanClass.boroughs}"/>
</p:selectOneMenu>
</p:panelGrid>
</h:form>
</h:body>
</html>
Xhtml sayfamız gördüğünüz gibi çok sade. Burada Birinci selectOneMenu’nün value özelliğine beanClass.selectedCity atanması sureti ile seçilen ilin selectedCity nesnesine yazılmasını söylüyoruz. p:selectOneMenu bileşeninin içerisinde üç adet bileşen var.
Birincisi kullanıcıya il seçmesini bildiren bir eleman. Bu elemanı selectOneMenu’ye ilk eleman seçiminde ajax tetiklemesini sağlamak için koyduk arkadaşlar.
p:selectOneMenu içindeki ikinci bileşen ekranda hangi değerleri gösterecek bunu belirleyen f:selectItems. Bu bileşenin value özelliğine managed bean içinki şehirleri tutan cities listesini atıyoruz ve birinci selectOneMenu’nün illeri göstermesini söylüyoruz.
Son bileşen ise bir ajax tetiklemesi. Bu ajax tetiklemesi p:ajax etiketi ile kullanılacak ve ilgili selectOneMenu’den bir seçim yapıldığında yapılacak ve update özelliğine atanmış olan boroughSelectOneMenu id’li bileşeni güncelleyecek. Bu güncellemeyi de listener özelliğine atanmış metodun yardımı ile yapacak. Listener özelliğine atanmış metot güncellenecek selectOneMenu’nün doldurulacağı nesneyi güncellemeli. Bizde de ikinci selectOneMenu’yü dolduracak liste borough listesi ve fillBoroughList() metodu seçilen ile göre borough listesini güncelleyerek bu görevi yerine getiriyor.
Ekran Çıktıları
Projeyi çalıştırdığımızda karşımıza şöyle bir ekran geliyor.
Ben İstanbul’u seçtiğimde ilçe selectOneMenu’sü gördüğünüz gibi İstanbul’un ilçeleri ile doluyor.
Ankara’yı seçtiğimde de Ankara’nın ilçeleri ile doluyor.
Bu yazıda da bu kadar arkadaşlar. Bana sık sık gelen sorulardan birine böylece bir çözüm üretmiş olayım inşaAllah :)
Başka yazıda görüşene kadar sağlıcakla kalın. Selam ve Sevgilerimle