2 Temmuz 2013 Salı

Richfaces ListShuttle Javascript Manipulation by jQuery

Hi again, for people who are still using Rich Faces with version 3.3.x and having problems in manipulating ShuttleList component via javascript, i have a solution for you. But i have to warn you before that it is not the best solution around. So I have a scenario in which when user selects not interested option then we need to deselect other options from the selected list. You may think that you can do it in server side but what if you have a problem with reRender because it does not works! Then here is my solution for you. Some people who just doesn't want to go to server side for such problem would like it i think.


   function beforeListChange(compId) {
       var srcValues = jQuery(jQuery(document.getElementById(compId))
           .find('.rich-shuttle-body').find('.rich-shuttle-internal-tab')[0]).find('tr');
       var tarValues = jQuery(jQuery(document.getElementById(compId))
           .find('.rich-shuttle-body').find('.rich-shuttle-internal-tab')[1]).find('tr');
       notInterestedWith = false;
       for (var i = 0; i & lt; srcValues.length; i++) {
           if (jQuery(srcValues[i]).find('label').text() == 'Not Interested') {
               notInterestedWith = true;
               break;
           }
       }
   }

   function listChanged(compId) {
       var hasInterestedWith = false;
       var tarValues = jQuery(jQuery(document.getElementById(compId)).find('.rich-shuttle-body').find('.rich-shuttle-internal-tab')[1]).find('tr');

       if (notInterestedWith) {
           for (var i = 0; i & lt; tarValues.length; i++) {
               if (jQuery(tarValues[i]).find('label').text() == 'Not Interested') {
                   hasInterestedWith = true;
                   break;
               }
           }
           if (hasInterestedWith) {
               removing = true;
               for (var i = tarValues.length - 1; i & gt; - 1; i--) {
                   if (jQuery(tarValues[i]).find('label').text() != 'İlgilenmiyor') {
                       jQuery(tarValues[i]).trigger('click');
                       jQuery(jQuery(document.getElementById(compId))).find('.rich-shuttle-control-remove').trigger('click');
                   }
               }
               removing = false;
           }
       } else {
           for (var i = 0; i & lt; tarValues.length; i++) {
               if (jQuery(tarValues[i]).find('label').text() == 'Not Interested') {
                   hasInterestedWith = true;
                   break;
               }
           }
           if (hasInterestedWith & amp; & amp; !removing) {
               for (var i = 0; i & lt; tarValues.length; i++) {
                   if (jQuery(tarValues[i]).find('label').text() == 'İlgilenmiyor') {
                       jQuery(tarValues[i]).trigger('click');
                       jQuery(jQuery(document.getElementById(compId)))
                           .find('.rich-shuttle-control-remove').trigger('click');
                       break;
                   }
               }
           }
       }

   }
                        


HTML

<rich:listShuttle
sourceValue="#{type.values}"
targetRequired="true"
targetValue="#{bean.selectedLikes[type.id]}"
var="items"
sourceCaptionLabel="Options"
onlistchange="beforeListChange(this.id)"
onlistchanged="listChanged(this.id)"
targetCaptionLabel="Selected" >
    <rich:column>
        <h:outputLabel
        value="#{items.description}"></h:outputLabel>
    </rich:column>
</rich:listShuttle>                      
Idea in here is simple with the function beforeListChange i control if there is Not Interested option in Options box if there is one i record this value for using with onlistchanged event. After complation of this method listChanged method is being called and in it again i control if there is Not Interested option in Selected box. If there is one then i need to deselect other options i do it by selecting items via jQuery you can realize how i do it above then i generate an event to move it to the options box by generating a click event on remove button. It looks maybe not the best solution but it works perfect programmatically and it doesn't invalidates component.

16 Mayıs 2013 Perşembe

Adding images dynamically via jQuery and resizing according to the container

Hi, suppose that you have a web service which returns image url's and you need to load them dynamically into your page via javascript with the help of jQuery but image sizes can vary and you need to resize them according to the size of your container div but if the image is smaller than the container div then you need to leave them as they are. You tried to set img tags display style as inline but it didn't work. Then you are welcome here is the solution for this trouble:
HTML

<div id="containerDivId" width="580" height="380" />
                        


Script

var img = $('<img>'); 
img.attr('src', 'http://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Rubber_duck.jpeg/512px-Rubber_duck.jpeg');
img.appendTo('#containerDivId');

if(img[0].width>580)
   img[0].width = 580;
if(img[0].height>380)
  img[0].height = 380;

13 Haziran 2012 Çarşamba

Richfaces reRender does not work after validation error

hi again folks, another strange problem with jsf behavior. For example you have a data grid and when u double click in a row you open up a pop up which contains a separate form and some fields on this pop up contains required attribute. When you submit this form required fields empty you will get a validation error. Till this time everything is ok but strange things starts after this.
You closed the form popup and this time clicked another row on data table and what you see is really strange you see the pop up form with the same values after validation error. According to guys at rich faces forums this is normal and it is because of nature of jsf. U may comment this situation as you should re set bean values but you are already doing this so what to do?
Yes again according to guys at rich faces forums you should reset the popup form. You can do this by defining an action listener each time opening the new form with the code given below. I took these code from rich faces forums and needed to change it a bit because of my page structure. Anyway here is the code and its explanation. Hope it ll work same as it worked for me.
Note all trick in this example is if rerender is not working for a form you need to define an action listener. And you need to indicate your form's id in the reRender list of your action. Indicating parent of the form does not work in this example.
Page Example:

<rich:dataTable width="100%" id="channelTable"
value="#{crmChannelAdminViewBean.chInfoList}" var="chan"
onRowMouseOver="this.style.backgroundColor='#F1F1F1'"
onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'"
onRowDblClick="selectRow('#{chan.id}')" rowClasses="gridCursor">
 
<a4j:jsFunction name="selectRow"
 action="#{crmChannelAdminViewBean.selectRow}" status="actionStatus"
 reRender="internetDetailForm,mpChannelDetail"
 ajaxSingle="true"
 oncomplete="if(data == true){#{rich:component('mpMessages')}.show();} else {#  {rich:component('mpChannelDetail')}.show();}" 
 data="#{channelTestViewBean.error}">
    <a4j:actionparam name="param1" assignTo="#{crmChannelAdminViewBean.selectedRow}"/> <f:actionListener    type="com.foobank.crm.common.util.A4JFormReset" /> 
</a4j:jsFunction>

  
package com.foobank.crm.common.util;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;

import org.ajax4jsf.context.AjaxContext;

public class A4JFormReset implements ActionListener {

 
 /**
  * This function resets form values before rerendering
  * the form. Sometimes you may see that rerendering does
  * not work after validation errors. Despite updating
  * bean values you may not see actual values on forms after
  * validation errors. To solve this you may use this action
  * listener class.
  * https://community.jboss.org/thread/8446?start=15&tstart=0
  */
     public void processAction(ActionEvent event) throws AbortProcessingException {                
         FacesContext facesContext = FacesContext.getCurrentInstance();
         AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext);
         UIComponent root = facesContext.getViewRoot();          
          ajaxContext.addRegionsFromComponent(event.getComponent());
         Set ids = ajaxContext.getAjaxAreasToRender();        
         List formIds = new LinkedList();

         for (String id : ids) {
               UIComponent form = root.findComponent(id);
               if (form != null && !formIds.contains(form.getId())) {
                   clearComponentHierarchy(form);
                   formIds.add(form.getId());
               }
          }
     }

    public UIComponent findParentForm(UIComponent component) {      
         for (UIComponent parent = component; parent != null; parent = parent.getParent()) {
               if (parent instanceof UIForm) {
                    return parent;
               }
          }          
          return null;
     }

     public void clearComponentHierarchy(UIComponent pComponent) {

          if (pComponent.isRendered()) {

               if (pComponent instanceof EditableValueHolder) {
                    EditableValueHolder editableValueHolder = (EditableValueHolder) pComponent;
                    editableValueHolder.setSubmittedValue(null);
                    editableValueHolder.setValue(null);
                   editableValueHolder.setLocalValueSet(false);
                    editableValueHolder.setValid(true);
               }          

               for (Iterator iterator = pComponent.getFacetsAndChildren(); iterator.hasNext();) {
                    clearComponentHierarchy(iterator.next());
               }          

          }
     }

}

17 Ocak 2012 Salı

Richfaces DataTable Fixed Header

Hi folks,
for people who want to have a datatable with a fixed header but not want to use richfaces:extendeddatatable you may use following solution. I seeked internet a lot to find a better solution but couldn't find any solution for this. anyway here is my solution:

first i need to tell you that you need to have jQuery for following solution:
please note that "#customerForm\\:custTable" is the id of the datatable
                    jQuery(document).ready(function() {
                        initFixedHeader();
                    });
                    
                    function initFixedHeader(){
                        if(jQuery('#myDiv').scroll())
                           jQuery('#myDiv').scroll(moveScroll); 
                        var componentId = '#{rich:clientId('custTable')}';
                        componentId = componentId.replace(/:/g, "\\\:");
                        jQuery('#inDiv').empty();
                        jQuery('#inDiv').height(jQuery('#'+componentId+' thead').children( 'tr:is(:first)' ).height());
                        var scrollBarWidth= jQuery('#myDiv').width()-jQuery('#myDiv')[0].clientWidth;
                        jQuery('#inDiv').width(jQuery('#myDiv').width()-scrollBarWidth);
                        clone_table=jQuery('#'+componentId).clone().attr('id', 'clone');
                        clone_table.find('*').removeAttr('id');
                        clone_table.find('*').removeAttr('onclick');
                        clone_table.find('*').removeAttr('onkeyup');
                        clone_table.find('*').removeAttr('onkeydown');
                        clone_table.find('*').removeAttr('name');
                        jQuery('#inDiv').append(clone_table).hide().slideToggle("fast");
                        jQuery('#inDiv').scrollLeft(jQuery('#myDiv').scrollLeft());
                        jQuery('#clone').css({'background-color': 'transparent'});
                        jQuery('#clone tbody').css({'visibility':'hidden'});
                        jQuery('#clone thead').children( 'tr:not(:first)' ).css({'visibility':'hidden'});
                    }
                    
                    
                    function moveScroll(){
                        jQuery('#inDiv').scrollLeft(jQuery('#myDiv').scrollLeft());
                    }

and you need to encapsulate your datatable component like below:

<div style="position:relative;width:100%;height:390px;" id="mainDiv">
<div style="position:absolute;top:0;overflow:hidden;" id="inDiv">
</div>
<div style="width:100%;height:390px;overflow: auto;" id="myDiv">
<rich:dataTable id="custTable" /> 
</div>
</div>


please not that each time you make an ajax request you need to recall initFixedHeader method to redraw heading cause each time size of the table may change. And in a page you may make ajax requests from several places. But luckliy i mostly use a4j:queue component to queue and limit my ajax requests. And i manage to recall initFixedHeader method like below after each ajax request :

<a4j:queue  ignoreDupResponce="true" requestDelay="10" oncomplete="initFixedHeader();"/>

25 Mart 2009 Çarşamba

Adobe Flex RIA Dünyasının Gerçek Başlangıçı

Web 2.0 öncesi dinamik web sayfalarımız ve onlardan beklentilerimiz oldukça basitti. Daha önceden mevcut olan Javascript , XMLHTTPRequest in birleşimiyle AJAX icat oldu sayfalardan beklentilerimiz arttı. Adını bile sayamıyacağımız kadar javascript , AJAX kütüphaneleri çıktı karşımıza birkaç insan bu frameworklere gerek duymadan kendi başlarına modüler olmayan javascriptlerle işlerini gördüler. Ancak burda dananın kuyruğunun koptuğu nokta javascript , css kullanılarak yaratılan bu kütüphanelerin her ne kadar her türlü browser da çalışma iddiaları olsa da pratik anlamda pek öyle olmadığı görüldü. En azından desktop application'ı kıvamında web uygulamaları yazmanın bu frameworklerde ezziyet olduğunu gözüm kapalı söyleyebilirim.
***
Lütfen şimdi bu işlere derinlemesine bulaşmaktan kaçınmayacak dirty programmerlar ve kütüphane geliştirecek kadar iyi javascript , CSS bilgisi olan arkadaşlar ne saçmalıyor bu cahil demesinler. Benim baktığım RIA dünyasında görmek istediğim WYSIWYG'den ibaret ve bunu şu ana kadar en iyi yaptığını gördüğüm Adobe Flex , open source , arka plandaki server teknolojisinden bağımsız , tüm browserlarla uyumlu. Zorlukları ne actionscript , client side'ın bazı tecrübesiz programcılar tarafından saçma sapan şekilde yazılabilme ihtimali. Ancak tüm bunlara rağmen geleceğin en azından kapsamlı web uygulamalarının flex ve benzeri RIA araçları ile yapılacağını gururla , onurla , inançla söyleyebilirim. Vakit kaçmadan treni yakalasak iyi olacak...


2 Mart 2009 Pazartesi

JSF Richfaces

Son zamanlarda en büyük zevkim java web frameworklerin cicili bicili component explorerlarına göz atıp evet işte aradığım framework bu demek. Şirketimizdeki araştırmalar ve yakın çevremde benden bu konuda daha iyi bilgili insanların gazları sayesinde bir java standartı olan JSF üzerinde durmak gerektiği düşüncesi hakim oldu.
***
Tabi jsf in standart implementasyonları ve myfaces gibi implementasyonların istenilen ajax şovları için yetersiz olduğu malumunuz bu yüzden jboss'un Richfacesını denemeye karar kıldım. Standart bir jsf input component'ine ajax desteği kazandırmak ve sayfadaki elemanları idleriyle ile sayfayı tamamen refresh etmeden reRenderlamak başta güzel kolay basit gibi gözüktü ancak malesef swing ile yazmanız 1 gün sürecek bir ekranı uzunca bir sürede çalışmasından memnun kalacak şekilde bitirmek mümkün olmadı. Başta bunun kendi eksikliğimden kaynaklandığını düşünürken konu üzerinde biraz daha uğraşmam sonucu Richfaces'ın vaat ettiklerinin ardından developmentı insanı deli edecek kadar zorlaştıran bir framework olduğuna karar vermemle sonuçlandı.
***
Bu esnada Richfaces dışında bir iş arkadaşım da bir başka JSF kütüphanesi olan icefaces ile uğraşıyordu ve gözlemlediğim icefaces'in jsf in standart backbean yazma alışganlığını sürdürdüğünü ama Richfaces'a nazaran kullanıcıyı ıvır zıvır dertlerden çok daha fazla soyutlayan bir kütüphane olduğunu gördüm ancak bu bile başlı başına bu framework üzerinde çalışmak için yeterli bir sebep midir bilinmez.
***
Son 2 yıldır mükemmel bir webframeworkü arayan benim sanırım son durağım Flex olacak. Getirdiği actionscript angaryasına rağmen en azından insanın ellerini kirletip işin temeline inerek client side da istediği atı koşturmasına olanak sağlayacağına inandığım flex sayesinde JSF ve benzeri javascript , html, css tabanlı karmaşık frameworklerin anlamsızlıklarıyla uğraşmak zorunda kalmayacağımı umut ediyorum. Evet bir pop up açmak için JSF de javascript yazağıma ya struts , spring MVC gibi frameworkler kullanıp javascriptlerimi tamamen hakim olacak şekilde yazarım veya Flex , GWT gibi swing benzeri geliştirmeye sahip frameworkleri kullanarak acaba şunu yapabilir miyim sorusundan uzak yaşamayı tercih ederim... Cahilliğimden olabilir maruz görün ama JSF'de yanarlı dönerli bir sayfa yaptığınızda web sayfanız ve beanlerinizdeki karmaşıklığa nasıl tahamül ediyorsunuz ...

6 Şubat 2009 Cuma

Web Frameworks ve Java

Java ve open source ... Evet bu iki kavram birbirlerinden bağımsız dursalar da şunu kabul etmek gerekir ki ikisi de birbirlerine sıkı şekilde bağımlılar. tabi ki open source yazılımlar için java şart değil veya javanın var olabilimesi open source olması gerekli değil. Ancak open source yazılımların geliştirilmesindeki en çok kullanılan dillerden biri bugün baktığımızda java. Başlığa bakarak ne zırvaladığımı sorabilirsiniz o vakit sadete gelmekte fayda var : Evet open source ve javanın etkileşiminden hepimiz son derece memnunuz tomcat , eclipse , struts , spring,hibernate ,gwt ve en önemlisi javanın kendisi opensource ve ücretsiz ancak java ile web programlama yapanlar bilirler ki konu web yazılımı geliştirmek olunca işler biraz kompleksleşiyor.
Tabi bu karmaşa sizin bir web frameworkünden beklentilerinizle de değişiyor basit bir tabloya basım ve form işlemleri için struts 2(struts değil) gayet yeterli olacakken web 2.0 kavramı ile hayatımıza giren ajax işleri zorlaştırdığı gibi sizden beklentileri yükseltiyor. Tabi ajax var olan teknolojilerin sentezinden doğdu bir çok başarılı web sitesinde de karşımıza çıktı ancak şu var ajax ile yaptığınız görsel bileşenler html , css ve javascriptin zorunlu dansından ibaret oluyor daha çok yani java , flash veya işletim sistemlerinde gördüğümüz görsel bileşenler gibi değiller daha çok farklı nesnelerin sentezlenip size suggestion box , autocomplete gibi komponentler sunuluyor bunun birçok başarılı örneği varken (jQuery,dojo,gwt) aslında bu komponentlerle development yapmanın sancılı ve zor olduğunu düşünüyorum örnek olarak klasik bir swing veya windows forms uygulaması geliştirmemiz için sadece tek bilmemiz gereken ilgili kütüphanelerken burda javascript , css , dhtml , html vede az biraz grafiker olmamız gerekiyor.
İşte insanlar bunlardan sıkılmış olacaklar ki karşımıza flex , java fx , silver light , open laszlo gibi teknolojiler çıktı ancak bunlarında kendilerine göre dezavantajları html in bir çok ortamda çalıştırılabilir olması ve örneğin flex gibi frameworklerle uygulama geliştirmenin server side tarafında pekte rahat olmadığı yönünde , kimileri bunun JEE ruhuna aykırı olduğunu düşünüyor açıkcası silverlight kısmı hakkında bir fikrim yok ama eminim microsoft bu entegrasyonu iyi sağlamıştır tabi flash gibi bir vm'niz varken browserda silverlighta insanların ne kadar ilgi göstereceği ayrı bir muamma. İşte kendilerine ait vmleri olan bu çözümleri bu sebeplerle geride bırakıp tekrar ajax destekli web frameworklerine geldiğimizde java tarafında bir çok eksikliklerin ve development sürecinin zorluğunu görüyorsunuz. Bazen insanlar bu kadar çok frameworkü takip ederken yoruluyorlar ve aklımıza şu soru geliyor bu kadar çok webframework olacağına ve bu kadar çok eksik web frameworkü geliştirmek için sunulan eforları birleştirip daha iyi bir şeyler ortaya çıkması sağlansa sanırım open source'un en kötü yanı bu güçlerin birleştirilmeyip heba olması.
Tabi konuya şu açıdan da bakabilirsiniz bu kadar katkı varken sen tüketmekten başka ne yapıyorsun ? Evet kişisel eleştiri olarak tüketiciliğimizle yeni bir web framework öğrenmekle övünmemizle dalga geçebiliriz ama bu da türkiye gerçeklerine kadar uzanan ayrı bir yazı konusuna işaret eder ki konudan tamamen sapmış oluruz. Evet kişisel gözlemlerim olarak java web frameworkleri konusunda şunları söyleyebilirim bu kadar geyikten sonra :
BEĞENDİKLERİM
  1. ZK : Tayvanlı bir firmanın arkasında olduğu güçlü seçenekleri olan ancak layoutları konusunda benim pek beğenmediğim bir framework ancak yeterince incelemediğimi de belirtmem gerek.
  2. GWT : Hepimizin duymuş olduğu Google Web Toolkits gram javascript yazmadan swing , swt uygulaması yazar gibi çıktı almak hatta arka planda server bağlantısı olmayan basit html , javascript tabanlı oyun , uygulamaları yazıp dağıtmanızı sağlıyacak yegane yazılımlardan. Kişisel gözlemime göre google elini ağırdan tutuyor gwt konusunda özellikle serverlarınızdan veri aktarmak veya serverınıza veri göndermek çeşitli sorunlardan dolayı zor olabilir örnek hibernate ve dinamik proxy objeleri gibi ancak gene de ilerleyen versiyonlarında gwt-ext gibi framework entegrasyonları ve instantations firmasının .net benzeri visual editorü ile iddialı olacağına eminim.
  3. JSF-Richfaces : ajax4JSF olarak ortaya çıkan ve önce exadel bünyesinde sonrada exadel'in jboss tarafından satınalınmasıyla meydana çıkan bir framework. Öncelikle kullanmak için JSF bilmeniz gerekli tabi JSF piyasada learning curve'i yüksek olan bir framework olarak nitelendiriliyor. Bunun dışında JSF in component modelinin server a çok yük getirdiği bir gerçek evet Richfaces burda ortaya çıkıyor istediğiniz bir JSF implementasyonuyla MyFaces , Standart Sun implementasyonuyla kullanıp sayfanın tümünü refresh etmenize gerek kalmadan AJAX requestleriyle uygulama geliştirmenizi acaip derecede kolaylaştırıyor ve tabi muhteşem gridler sunduğunu da belirtmeme gerek yok. Ancak şöyle eksiklikleri var : gridlerinde hidden column yok , ajax requestlerle de yapsak hala bir çok widgetın state ini serverside da tutmak zorundayız malesef client side da bu işi bizim için otomatize edecek kütüphanelerin varlığına rastlayamadım ancak şöyle özellikleri de yok değil javascript yazarak serverınıza gitmeye gerek kalmayabiliyor ancak bunu isteyen olur mu bilmiyorum...
  4. Flex : Development ı hakkında fikrim olmasa da widget olarak en solid widgetları sunan , browser uyumsuzluklarına her browser da çalışan vm iyle karşı gelen bir framework ancak önceden de belirtiğim gibi JEE ile konuşturmanız için yapmanız gerekenler ve muhakkak öğrenmeniz gereken bir action script dili var.
Evet şimdilik hakkında fikir beyanedebileceklerim bu kadardı ilerleyen yazılarda buluşabilmek ve yazılım adına birşeyler öğrenebilmek dileğiyle...