PrimeFaces ile Growl elementlerinin renklerini dinamik olarak değiştirmek

 

PrimeFaces

Selamlar,

Beni az çok tanıyanlar ve güncemi takip eden arkadaşlar başlığa bakıp “yahu bu adam da bir gwt yazıyor, bir c# yazıyor, bir java yazıyor, daldan dala atlıyor! Şimdi de tutmuş, PrimeFaces konusuna sarmış!” gibi bir yorumda bulunabilir 🙂

Haklılar!

Ancak…

Bilenler yine bilir 🙂

Güncemde yazacağım yazı konularını seçerken dikkat ettiğim tek bir konu var benim: işim dolayısıyla karşılaştığım teknolojik zorlukların çözümünü paylaşıp, aynı sorunlarla karşılaşabilecek diğer arkadaşlara yol göstermek ve yardımcı olmak. Yaklaşık 8 yıldır da, paylaştığım yazılara ilişkin aldığım olumlu tepkiler ve yorumlar da doğru yolda olduğumu gösteriyor sanırım. Güzel…

Neyse konuyu dağıtmayayım yine, yaklaşık son 1 buçuk – 2 aydır işyerimdeki bir proje dolayısıyla PrimeFaces + JFS konularına dalmış bulunuyorum. Konuyla ilgili de bayağı bir yol aldım sanırım…

Web development ile uğraşan çoğu arkadaşım, Bootstrap Notify yapısını kullanmıştır ya da en azından bilgi sahibidir diye tahmin ediyorum. Benim de, özellikle Bootstrap kullandığım projelerimde sıkça kullandığım, görsel ve işlevsel açıdan oldukça tatmin edici bir plugin Bootstrap Notify (Bootstap Growl olarak ta bilinir). Basitçe özetlemek gerekirse, bu plugin, standart Bootstrap uyarı ve mesajlarını, Growl (Mac OS X işletim sistemleri için uyarı/bilgi gösterim alt yapısı) tarzı bir biçimde sayfa üzerinde göstermenizi sağlıyor.

Mac OS X işletim sistemi içerisinde Growl uyarı/bilgi gösterim mekanizması

Mac OS X işletim sistemi içerisinde Growl uyarı/bilgi gösterim mekanizması

PrimeFaces, biliyorsunuz aslında bir JSF çatısı (framework). Çağatay CİVİCİ çok büyük emekler vererek gerçekten güzel bir iş çıkartmış, kendisini tebrik etmek ve hakkını vermek lazım gerçekten. Ancak bazı konularda çok fazla eksiği olduğunu düşünüyorum ve çok ta beğendiğimi söyleyemem açıkçası (PrimeFaces artıları ve eksileri başlığını başka bir yazımda ele almayı planlıyorum). Mesela bu yazımızın konusu olan Growl öğesinin arka plan renginin dinamik olarak değişmemesi gibi.

Aşağıda örnek olarak yaptığım bir PrimeFaces web uygulamasının ekran görüntüsünü görüyorsunuz.

primefaces-growl-all

PrimeFaces ile UI üzerinde 4 farklı seviye uyarı/bilgi mesajının growl ile gösterimi

Ekran görüntüsüne ait istemci taraflı kodumuz…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?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:p="http://primefaces.org/ui">
 
<h:head>
</h:head>
<h:body>
 <h1>PrimeFaces Growl</h1>
 
<h:form> 
 <p:growl id="growl" showDetail="true" sticky="true" /> 
 
 <p:panel header="Growl Örnekleri"> 
 <h:panelGrid columns="2" cellpadding="5"> 
 <p:outputLabel for="msg" value="Mesaj:" /> 
 <p:inputText id="msg" value="#{growlView.message}" required="true" /> 
 </h:panelGrid> 
 
 <p:commandButton value="Göster" actionListener="#{growlView.saveMessage}" update="growl" /> 
 </p:panel> 
</h:form> 
 
</h:body>
</html>

Ve ekran görüntüsüne ait sunucu taraflı kodumuz…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.abutun.growl;
 
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
 
@ManagedBean
public class GrowlView {
 
 private String message;
 
 public String getMessage() {
 return message;
 }
 
 public void setMessage(String message) {
 this.message = message;
 }
 
 public void saveMessage() {
 FacesContext context = FacesContext.getCurrentInstance();
 
 context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Başarılı", "Mesajınız: " + message));
 context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Uyarı!", "Mesajınız: " + message));
 context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Hata!", "Mesajınız: " + message));
 context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Ciddi Hata!", "Mesajınız: " + message));
 }
}

Kod içerisinden de anlaşılacağı üzere, 4 farklı seviyede (info, warning, error, fatal) Growl mesajını ekrana yazdırıyoruz ancak UI üzerindeki Growl elementlerinin yalnızca simgelerinin değiştiğini görüyoruz.  Daha kullanıcı dostu bir arayüz için bu uyarı mesajlarının arka plan renklerinin de farklı olması çok daha iyi olurdu elbette. PrimeFaces içerisinde, bu konuda neden böyle bir yaklaşım tercih edilmiş gerçekten merak ediyorum ve anlamakta zorlanıyorum…

PrimeFaces içerisinde Growl elementlerine dinamik arka plan rengi değiştirebilme özelliği kazandırabilmemiz için aşağıdaki adımları takip etmemiz gerekiyor.

Öncelikle, PrimeFaces uygulamanızın içerisinde her bir farklı seviye için ayrı bir Growl elementi tanımlıyoruz aşağıdaki  gibi.

1
2
3
4
5
6
<h:form id="growlForm">
 <p:growl id="growl-fatal" showDetail="true" sticky="false" rendered="#{facesContext.maximumSeverity.ordinal eq 3}"/>
 <p:growl id="growl-error" showDetail="true" sticky="false" rendered="#{facesContext.maximumSeverity.ordinal eq 2}"/>
 <p:growl id="growl-warning" showDetail="true" sticky="false" rendered="#{facesContext.maximumSeverity.ordinal eq 1}"/>
 <p:growl id="growl-success" showDetail="true" sticky="false" rendered="#{facesContext.maximumSeverity.ordinal eq 0}"/>
</h:form>

Burada dikkat edilmesi gereken nokta, her bir elemente ait “rendered” özelliği. Dikkat edeceğiniz üzere, sayfanın mevcut Context’ inin severity seviyesine göre (ki bu seviyeyi kod içerisinde bir argüman olarak biz belirliyoruz) yalnızca bir adet Growl elementinin render edilmesini sağlıyoruz. Ve unutmadan, her bir Growl elementi için, seviyesine uygun olarak bir ID tanımı yapıyoruz; “growl-info, growl-warn, growl-error” gibi..

Daha sonra ise, her bir tanıma uygun olarak, Growl elementlerinin arka plan renklerine ait CSS tanımlarını eklememiz gerekiyor. Bu CSS tanımlarını eklerken, Growl elementinin PrimeFaces resmi sitesi üzerindeki dokümantasyonunun “skinning” bölümüne dikkat etmemiz lazım elbette.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
div[id="growlForm:growl-fatal_container"] > div {
 background-color: red !important;
 }
 
 div[id="growlForm:growl-error_container"] > div {
 background-color: red !important;
 }
 
 div[id="growlForm:growl-warning_container"] > div{
 background-color: orange !important;
 }
 
 div[id="growlForm:growl-success_container"] > div{
 background-color: green !important;
 }
 
 .ui-growl-image-info ~ .ui-growl-message {
 color:#fff;
 }
 .ui-growl-image-error ~ .ui-growl-message {
 color:#fff;
 }
 .ui-growl-image-warn ~ .ui-growl-message {
 color:#fff;
 }
 .ui-growl-image-fatal ~ .ui-growl-message {
 color:#fff;
 }

CSS ile de ne yapmaya çalıştığımızı kısa anlatayım. PrimeFaces, “context maximumSeverity” seviyesine göre ilgili growl elementlerini render ettiğinde (yalnızca bir tane render edilmiş growl elementi olacak haliyle), ilgili elementin ID’sini temel alarak “ID_container” şeklinde bir DIV elementi oluşturuyor. Biz de bu elementin arka plan rengine ilişkin CSS tanımını yapıyoruz seviyesine göre (div[id=”growlForm:ID_container”] > div tanımı ile). Ayrıca growl elementine ait yazı renklerini de “.ui-growl-image-SEVERITY ~ .ui-growl-message” tanımlamaları ile yapıyoruz.

CSS bu yazımızın konusu olmadığı için tanımlarla ilgili detaylara girmiyorum ama merak eden arkadaşlar için şu bağlantıyı takip etmelerini öneririm.

Sunucu taraflı kodumuzda herhangi bir değişiklik yapmıyoruz. Dolayısıyla istemci taraflı kodumuzun en son hali aşağıdaki gibi oluyor yukarıdaki düzenlemeleri yaptıktan sonra.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<?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:p="http://primefaces.org/ui">
 
<h:head>
 <style>
 div[id="growlForm:growl-fatal_container"] > div {
 background-color: black !important;
 }
 
 div[id="growlForm:growl-error_container"] > div {
 background-color: red !important;
 }
 
 div[id="growlForm:growl-warning_container"] > div{
 background-color: orange !important;
 }
 
 div[id="growlForm:growl-success_container"] > div{
 background-color: green !important;
 }
 
 .ui-growl-image-info ~ .ui-growl-message {
 color:#fff;
 }
 .ui-growl-image-error ~ .ui-growl-message {
 color:#fff;
 }
 .ui-growl-image-warn ~ .ui-growl-message {
 color:#fff;
 }
 .ui-growl-image-fatal~ .ui-growl-message {
 color:#fff;
 }
 </style>
</h:head>
<h:body>
 <h1>PrimeFaces Growl</h1>
 
 <h:form id="growlForm">
 <p:growl id="growl-fatal" showDetail="true" sticky="true" rendered="#{facesContext.maximumSeverity.ordinal eq 3}"/>
 <p:growl id="growl-error" showDetail="true" sticky="true" rendered="#{facesContext.maximumSeverity.ordinal eq 2}"/>
 <p:growl id="growl-warning" showDetail="true" sticky="true" rendered="#{facesContext.maximumSeverity.ordinal eq 1}"/>
 <p:growl id="growl-success" showDetail="true" sticky="true" rendered="#{facesContext.maximumSeverity.ordinal eq 0}"/>
 </h:form>
 
 <h:form> 
 <p:panel header="Growl Örnekleri"> 
 <h:panelGrid columns="2" cellpadding="5"> 
 <p:outputLabel for="msg" value="Mesaj:" /> 
 <p:inputText id="msg" value="#{growlView.message}" required="true" /> 
 </h:panelGrid> 
 
 <p:commandButton value="Göster" actionListener="#{growlView.saveMessage}" update=":growlForm" /> 
 </p:panel> 
 </h:form> 
 
</h:body>
</html>

Herşey güzel gibi görünüyor, projemizi yeniden derliyoruz ve çalıştırıyoruz! Fakat o da ne…

PrimeFaces sucks!

Amerigalıların bi lafı var bildin mi? PrimeFaces sucks!

Kod içerisinde, en son olarak seviyesi “FATAL” olan bir uyarı mesajı oluşturduğumuz için, Context maximumSeverity seviyesi 3 oluyor ve PrimeFaces yalnızca ID’si “growl-fatal” olan Growl elementini render ediyor ve tüm mesajları bu elemente ait container’e ekliyor. Dolayısıyla tüm growl elementlerinin arka plan rengi kırmızı oluyor her birisi için farklı seviyeler belirtmemize rağmen! Gerçekten sinir bozucu bir durum…

Peki nasıl çözeceğiz bu sorunu? Benim önerilerim şunlar:

  • Çağatay‘ı bir yerde yakalayıp ağız burun dalarak PrimeFaces içerisindeki Growl elementine ait çalışma yapısını değiştirmesini sağlayabiliriz (bu riskli biraz, zira resimlerine baktığımda Çağatay kalıplı bir arkadaşa benziyor! o da bizim ağzımızı burnumuzu kırabilir!).
  • CSS Selector 4 draft versiyonun bir an önce tamamlanmasını bekleyip gerekli CSS tanımlarını yaparak bu durumu çözebiliriz.
  • Context’e eklenen her bir mesaj sonrası sayfayı render işlemine zorlayacağız (başka sorunlar oluşturacaktır)
  • Growl mesajları gösterilmeden önce JQuery ile araya girip, HTML elementlerine CSS tanımları ekleyebiliriz.

Ben 4. seçeneği gerçekleyip size aktarmaya çalışacağım.

Öncelikle sayfamıza aşağıdaki JavaScript kodunu ekliyoruz.

1
2
3
4
5
6
 function init () { 
 $(".ui-growl-image-info").parent().parent().addClass("g-info");
 $(".ui-growl-image-warn").parent().parent().addClass("g-warn");
 $(".ui-growl-image-error").parent().parent().addClass("g-error");
 $(".ui-growl-image-fatal").parent().parent().addClass("g-fatal");
 }

Yazımızın başında, PrimeFaces’ın growl elementlerinin seviyelerine göre yalnızca simgelerini değiştirdiğinden bahsetmiştim. Bunu da CSS kullanarak yapıyor, işte bu noktada yukarıdaki script, farklı seviyelerdeki growl simgelerini JQuery ile bularak, bu elementin babasının babasına (dedesine), yeni CSS sınıfları ekliyor (g-info, g-warn, g-error, g-fatal). Bu noktadan itibaren tek yapmamız gereken, yeni eklediğimiz bu sınıflara özel arka plan tanımlarını CSS ile yapmamız ve yukarıdaki JavaScript metodunun, mesajlar gösterilmeden önce çalıştırılmasını sağlamak.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<?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:p="http://primefaces.org/ui">
 
<h:head>
 <style>
 div[id="growlForm:growl_container"] > div[class~="g-fatal"] {
 background-color: black !important;
 }
 
 div[id="growlForm:growl_container"] > div[class~="g-error"] {
 background-color: red !important;
 }
 
 div[id="growlForm:growl_container"] > div[class~="g-warn"]{
 background-color: orange !important;
 }
 
 div[id="growlForm:growl_container"] > div[class~="g-info"]{
 background-color: green !important;
 }
 
 .ui-growl-image-info ~ .ui-growl-message {
 color:#fff;
 }
 .ui-growl-image-error ~ .ui-growl-message {
 color:#fff;
 }
 .ui-growl-image-warn ~ .ui-growl-message {
 color:#fff;
 }
 .ui-growl-image-fatal ~ .ui-growl-message {
 color:#fff;
 }
 </style>
 <script>
 function init () { 
 $(".ui-growl-image-info").parent().parent().addClass("g-info");
 $(".ui-growl-image-warn").parent().parent().addClass("g-warn");
 $(".ui-growl-image-error").parent().parent().addClass("g-error");
 $(".ui-growl-image-fatal").parent().parent().addClass("g-fatal");
 }
 </script>
</h:head>
<h:body>
 <h1>PrimeFaces Growl</h1>
 
 <h:form id="growlForm">
 <p:growl id="growl" showDetail="true" sticky="true"/>
 </h:form>
 
 <h:form> 
 <p:panel header="Growl Örnekleri"> 
 <h:panelGrid columns="2" cellpadding="5"> 
 <p:outputLabel for="msg" value="Mesaj:" /> 
 <p:inputText id="msg" value="#{growlView.message}" required="true" /> 
 </h:panelGrid> 
 
 <p:commandButton value="Göster" actionListener="#{growlView.saveMessage}" update=":growlForm" oncomplete="init();"/> 
 </p:panel> 
 </h:form> 
 
</h:body>
</html>

Mesajları gösteren düğmenin “oncomplete” olayında yukarıdaki script’in çalıştırılmasını sağladık ve yeni CSS tanımlarını ekledik (CSS tanımları ile ilgili detaylı açıklamalara yine girmiyorum, merak eden ya da anlamakta zorlanan arkadaşlar lütfen yorum olarak bildirsin durumlarını)

İşte sonuç!

primefaces-growl-all-jquery

Bu yazımı da burada bitirirken, buradan sevgili Çağatay CİVİCİ kardeşime, PrimeFaces’in bundan sonraki sürümlerinde, biz yazılım geliştirici arkadaşlara bu şekilde saç baş yolduran hareketlerden kaçınmasını tavsiye ediyorum. Bir framework bu kadar yorar mı bi insanı müdür yahu!

Çavvvv…

UYGULAMANIN KODLARINI İNDİRMEK İÇİN TIKLAYIN LÜTFEN!

, , , ,

No comments yet.

Bir Cevap Yazın

Font Resize