Tuesday, September 22, 2015

jQuery'de Seçiciler

jQuery, istemci tarafta Javascript (JS) tabanlı uygulama geliştirirken karşılaşılan bazı temel problemleri ortadan kaldırmak ve uygulama geliştirmeyi kolaylaştırmak amacıyla geliştirilmiş bir JS kütüphanesidir. jQuery'yi çeşitli amaçlarla JS projelerimizde kullanıyoruz:
  • HTML'i ya da CSS'i değiştirme
  • HTML olaylarını işleme
  • Animasyon ve efekt programlama
  • AJAX programlama
  • JS programlama için kolaylık fonksiyonları
Bu yazıda jQuery seçicilerini kullanarak HTML sayfaya yeni yetenekler nasıl kazandırılabileceğini inceleyeceğiz. jQuery seçicileri ile HTML dokümanındaki elemanları (takı ve öznitelik gibi) seçiyoruz. Seçilen elemanlar daha sonra jQuery fonksiyonları kullanılarak değiştirilebilir. Eğer CSS seçicilerini biliyorsanız, jQuery seçicilerini öğrenmek çok kolay olacaktır. jQueryCSS 1-3 seçicilerinin hepsini kullanır, bunun dışında kendine özel seçicileri bulunur. 
Şimdi üzerinde jQuery seçicilerini çalışacağımız HTML dokümanıyla tanışalım: movies.html.
Örneklerde kullanacağımız HTML doküman
movies.html içinde 299 adet film ile ilgili bilgiler yer alıyor: filmin adı, yönetmenleri, türleri ve yapım yılı. Bu bilgiler HTML tablo olarak düzenlenmiş olarak karşımıza çıkıyor.
jQuery ile HTML elemanları seçerken, seçimi üç farklı kritere göre yapabiliriz:
1. Takıya göre seçim
$(document).ready(function(){
   $('tr').css('border','solid red 3px');
});
Burada $('tr') ile tüm tablo satırlarını seçiyoruz:
Tüm çift satırları seçmek için aşağıdaki satırı yazmamız yeterli olur:
$(document).ready(function(){
   $('tr:even').css('border','solid red 3px');
});
2. id özniteliği ile seçim
Seçmek istediğimiz elemanın id özniteliğini biliyorsak, # sembolü ile tanımlayarak seçimi gerçekleştirebiliriz:
$(document).ready(function(){
   $('#movies').css('border','solid red 3px');
});
3. class özniteliğine göre seçim
HTML elemanı class değerine göre seçmek istersek, . sembolü ile class değerini tanımlayarak seçimi gerçekleştirebiliriz:
$(document).ready(function(){
   $('.panel-heading').css('border','solid red 3px');
});
Seçim yaparken bu üç kriteri beraberce de kullanabiliriz. Şimdi daha karmaşık seçimleri çalışmak için örnek alıştırma problemleri çözelim.
  • Basit bir seçici ile başlayalım. Sayfada çok sayıda <a> bulunuyor. Bu bağlantıları takip ettiğimizde bizi http://www.imdb.com sitesine götürüyor. Ancak biz sayfanın tarayıcıda yeni bir sekmede açılmasını istiyoruz:
$(document).ready(function(){
   $('#movies tbody a[href]').attr('target','_blank');
});
  • Şimdi ise tabloda 1970'li yıllara ait filmlerin listelenmesini sağlayalım:
$(document).ready(function(){
   $('#movies tbody tr').each(function(){
      var year= Number($(this).find('td:eq(4)').text().trim());
      if (year<1970 || year>1979)
         $(this).hide(); 
   });
});
1970'li yıllara ait filmlerin listesi
  • Birden fazla yönetmeni olan filmleri tabloda gösterelim:
$(document).ready(function(){
   $('#movies tbody tr').each(function(){
     var numberOfDirectors= $(this).find('td:eq(2) a').length;
     if (numberOfDirectors<2)
        $(this).hide(); 
   });
});
Birden fazla yönetmeni olan filmlerin listesi
  • Sadece Comedy ve Drama türündeki filmleri tabloda gösterelim:
$(document).ready(function(){
   $('#movies tbody tr').each(function(){
      td= $('td:eq(3)',$(this));
      var genres= td.text().trim().replace(/\s+/g,'').split(',');   
      if (genres.length!=2 || genres.indexOf('Comedy')<0 || genres.indexOf('Drama')< 0 )
         $(this).hide(); 
   });
});
Comedy ve Drama türündeki filmlerin listesi
  • Tablonun göstermek istediğimiz sütunlarını seçmemizi sağlayacak bir arayüz ekleyelim:
$(document).ready(function(){
 var columns= { 'No': 0, 
         'Title' : 1, 
         'Directors' : 2, 
         'Genres' : 3, 
         'Year': 4 
        };
 function createCheckbox(column){
  return   '<div class="checkbox-inline"><label><input id="'
         + column 
         + '" type="checkbox" checked />'
         + column+'</label></div>';
 }
 for (column in columns){
   $('#movies').before(createCheckbox(column));
      $('#'+column).click(function(){
         selectedColumn= $(this).parent().text();
         index= columns[selectedColumn];
         if (this.checked){
            $('#movies thead th:eq('+index+')').show();
            $('#movies tbody td:nth-child(5n+'+(index+1)+')').show();
         } else {
            $('#movies thead th:eq('+index+')').hide();
            $('#movies tbody td:nth-child(5n+'+(index+1)+')').hide();
         }
    });
  }
});
No, Title ve Year sütunları seçili durumdayken tablonun görünümü
Sadece Title sütunu seçili durumdayken tablonun görünümü
Herhangi bir sütun seçili olmadığı durumda tablonun görünümü
  • Tabloyu sütunlarına göre sıralayacak bir arayüz ekleyelim:
$(document).ready(function(){
    function numeric(val1,val2){
      return Number(val1)-Number(val2); 
    }
    function dictionary(val1,val2){
     return val1.localeCompare(val2); 
    }
    function sortTableByColumn(table,index,compareFunction){
     tbody= table.find('tbody');
     tbody.find('tr').sort(
         function(p,q){
            pval= $('td:eq('+index+')',p).text().trim();
            qval= $('td:eq('+index+')',q).text().trim();
            return compareFunction(pval,qval);
         }
     ).appendTo(tbody);
    }
    var columns=  { 
      'No'        : { index: 0 , sort: sortTableByColumn, compareBy: numeric }, 
      'Title'     : { index: 1 , sort: sortTableByColumn, compareBy: dictionary }, 
      'Directors' : { index: 2 , sort: sortTableByColumn, compareBy: dictionary }, 
      'Genres'    : { index: 3 , sort: sortTableByColumn, compareBy: dictionary }, 
      'Year'      : { index: 4 , sort: sortTableByColumn, compareBy: numeric } 
    };
    function createButton(column){
       return '<button class="btn btn-success" id="'+column.toLowerCase()+'">'
              +   column 
              + '</button>';
    }
    for (column in columns){
        th= $('table thead th:eq('+columns[column].index+')');
        th.text('');
        th.append(createButton(column));
        $('#'+column.toLowerCase()).click(function(){
             selectedColumn= columns[$(this).text()];
             selectedColumn.sort( 
$('#movies'), selectedColumn.index, selectedColumn.compareBy 
);
          });
        }
});
Filmin adına göre sıralamak yapmak için Title butonuna basıldığında tablonun görünümü
Yönetmen adına göre sıralamak yapmak için Directors butonuna basıldığında tablonun görünümü
Filmin yılına göre sıralamak yapmak için Year butonuna basıldığında tablonun görünümü
  • Film türlerini farklı arka plan renginde etiket olarak gösterelim:
colorIndex= 0;

colors = [ 
    'Khaki', 'LightSlateGray' , 'Blue', 
    'BlueViolet', 'Brown', 'CadetBlue',
    'Chocolate', 'Crimson', 'DarkBlue', 
    'DarkGoldenRod', 'DarkMagenta', 'DarkOrange',
    'DeepSkyBlue', 'Gold', 'Green',
    'Maroon', 'MediumAquaMarine', 'Moccasin',
    'Navy', 'OliveDrab', 'PaleVioletRed'
] ;

function getNextColor() {
   return colors[colorIndex++]; 
}

var colorMap = {} ;

function getColor(genre){
   if (!colorMap.hasOwnProperty(genre))
      colorMap[genre]= getNextColor();
   return colorMap[genre];
}

$(document).ready(function(){
  $('#movies tbody tr').each(function(){
     td= $('td:eq(3)',$(this));
     genres= td.text().trim().replace(/\s+/g,'').split(',');
     td.text('');
     $.each(genres,function(index,genre){
         td.append(  '<span class="label" style="background-color: ' 
                   + getColor(genre) 
                   + ';">' + genre 
                   + '</span>'); 
     });
  });
});

Her bir film türü farklı bir arka plan renginde
  • Birden fazla yönetmeni olan filmler için sadece ilk yönetmeni gösterelim:
$(document).ready(function(){
  $('#movies tbody tr').each(function(){
     directors= $('td:eq(2)',this);   
     directorAnchors= $('a',directors);   
     $(directors).empty();
     $(directors).append(directorAnchors[0]);
  });
});
  • Tablodaki yönetmen ve film türleri sütunlarının yerlerini takas edelim:
$(document).ready(function(){
  $('#movies tbody tr').each(function(){
     directors= $('td:eq(2)',this);   
     genres= $('td:eq(3)',this);   
     $(genres).after($(directors));
  });
  thead= $('#movies thead tr');
  $('th:eq(3)',thead).after($('th:eq(2)',thead));
});
Yönetmen ve Film türleri sütunlarının takas edilmesi
  • Film türlerinin hemen yanında, o türden kaç film olduğunu gösterelim:
var histogram= {};
var badges= {};

function createBadge(genre){
   if (badges.hasOwnProperty(genre)){
      return badges[genre];
   }
   badge= '<li role="presentation" class="active">'
     + genre
     + '<span class="badge">'
     + histogram[genre]
      + '</span></a></li>';
   badges[genre]= badge;
   return badge;
} ;

function extractGenreColumn(tr){
   return $('td:eq(3)',$(tr));
};

function extractGenres(td){
   return td.text().trim().replace(/\s+/g,'').split(',');
};

function computeHistogram(){
   td= extractGenreColumn(this);
   $.each(extractGenres(td),function(index,genre){
      if(!histogram.hasOwnProperty(genre)){
        histogram[genre] = 0; 
      } 
      histogram[genre] = histogram[genre] + 1; 
   });
};

function badgeHistogram(){
   td= extractGenreColumn(this);
   genres= extractGenres(td);
   td.empty();
   ul= $('<ul class="nav nav-pills" role="tablist">').appendTo(td);
   $.each(genres,function(index,genre){
       ul.append(createBadge(genre));
   });
   $(this).append('</ul>');
};

$(document).ready(function(){
   $('#movies tbody tr').each(computeHistogram);
   $('#movies tbody tr').each(badgeHistogram);
});
Film türlerinin hemen yanında histogram bilgisi gösteriliyor
Projenin tamamına bu bağlantıdan ulaşabilirsiniz. jQuery ile ilgili daha detaylı bilgi almak isterseniz jQuery and jQuery UI eğitimini öneririm.

No comments:

Post a Comment