React Native – ListView With Filter Header and Section Header

React Native – ListView With Filter Header and Section Header

Melanjutkan tulisan sebelumnya, kali ini kita akan mencoba menambahkan control untuk melakukan filter pada listview yang telah dibuat seperti gambar berikut :

screen-shot-2016-10-29-at-10-55-08-pm

Sebelum membuat sebuah screen seperti tampilan diatas, kita terlebih dahulu akan membuat sebuah screen yang terdiri dari ListView dan fitur untuk melakukan filter :

screen-shot-2016-10-26-at-3-43-04-pm

Untuk menambahkan component seperti gambar di atas, tambahkan header pada listview yang kita miliki dengan menambahkan code berikut pada code ListView :

         renderHeader={() =>
            <View style={styles.listview_header}>
              <TextInput style={styles.input}
                placeholder="Search..."
                onChangeText={(text) => console.log('searching for ', text)}
              />
            </View>
          }

Code di atas memasukkan code TextInput pada bagian header listview dimana jika diketikkan suatu karakter pada textinput tersebut, maka secara otomatis data pada listview akan difilter berdasarkan karakter yang kita ketikkan. Kok setelah diketik datanya masih belum ter-filter? Emang belum kita buat.. Untuk membuat fitur yang dapat melakukan filter data sesuai dengan data yang dimasukkan pengguna lakukan modifikasi code anda seperti berikut :

const data_array=[‘Music', ‘Movie', ‘Sport', 'Entertainment',];
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

export default class SampleMenu extends Component {
  constructor(props) {
    super(props);
    //definition of listview datasource
    this.state = {
      dataSource: ds.cloneWithRows(data_array),
      filter_string:'',
    };
  }

Rubah code pada bagian constructor seperti code di atas. Apa yang kita lakukan pada perubahan tersebut?

  1. Meletakkan data yang akan ditampilkan pada ListView di luar constructor/class. Kenapa ini dilakukan?
      • Jika data array diletakkan di dalam constuctor, kita tidak dapat menggunakan data array untuk di filter.
      • Antara data array dan dataSource harus dipisahkan sebab ketika proses filter berlangsung maka dataSource akan diperbaharui sesuai dengan data array yang sudah di filter.
  1. Nilai ds kita lettakkan di luar constructor/class. Kenapa?
      • Untuk memperbaharui nilai pada dataSource, kita akan menggunakan nilai ds. Jika diletakkan di constructor kita jadi tidak bisa menggunakan data ds tersebut.

Selain melakukan modifikasi code di atas, kita juga perlu menambahkan code yang akan mengeksekusi proses filter data ketika user memasukkan nilai untuk filter. Perbaharui nilai renderHeader anda seperti code berikut :

 renderHeader={() =>
            <View style={styles.listview_header}>
              <TextInput style={styles.input} placeholder="Search..."
                onChangeText={(text) =>{
                  var rows = [];
                  for (var i=0; i < data_array.length; i++) {
                     var stateName = data_array[i].toLowerCase();
                     if(stateName.search(text.toLowerCase()) !== -1){
                       rows.push(data_array[i]);
                     }
                   }
                   this.setState({dataSource:ds.cloneWithRows(rows)});
                }}
              />
            </View>
          }

Pada code di atas terdapat penambahan pada fungsi “onChangeText”. Code yang kita tambahkan adalah code yang melakukan pengecekan masing-masing data terhadap keyword untuk filter data. Setelah mendapatkan kumpulan data yang sudah sesuai dengan keyword, maka nilai dataSource akan diperbaharui kembali dengan data yang sudah ada. Setelah menambahkan code tersebut aplikasi yang kita buat akan melakukan filter sesuai keyword yang dimasukkan.

screen-shot-2016-10-26-at-11-20-13-pm

Section Header

ListView menyediakan fitur untuk melakukan grouping pada tampilan ListView anda. Hal ini sering digunakan untuk ListView yang memiliki data cukup banyak. Kita akan membuat ListView dengan section header dengan tampilan akhir seperti berikut :

screen-shot-2016-10-29-at-10-55-08-pm

Halaman tersebut menyediakan sebuah ListView dengan Section Header dan fitur filter pada bagian atas ListView. Baiklah, pertama-tama kita harus merubah jenis data yang ada pada ListView. Lakukan perubahan pada variabel data_array yang sebelumnya telah dibuat menjadi seperti berikut :

  const data_array=[];
  data_array['Sport']=['Soccer','Moto GP','Others'];
  data_array['IT & Technology']=['IT','Technology','Science'];
  data_array['Entertainment']=['Music','Movie','Art'];
  data_array['Interest']=['Travel','Style','Fashion','Business'];
  data_array['News & Info']=['Politics','World','Phenomenon'];
  data_array['Health']=['Health','Food','Lifestyle'];

Pada data sebelumnya aplikasi hanya menggunakan data array biasa sedangkan untuk kasus membuat ListView dengan section header data harus di-grouping di masing-masing data. Setelah itu pada constructor anda lakukan perubahan data pada variabel “dataSource” :

      dataSource: ds.cloneWithRowsAndSections(data_array),

Pada code ListView tepatnya code renderSeparator, lakukan perubahan berikut :

 renderSeparator={(sectionId, rowId) => <View key={sectionId+rowId} style={styles.separator_style} />}

Karena dilakukan perubahan pada struktur data_array, maka metode pada fitur filter harus kita modifikasi. Ganti code pada event “onChangeText” pada “renderHeader” menjadi seperti berikut :

                   var rows = [];
                   for (var key in data_array) {
                     if (!rows[key]) {
                       rows[key] = [];
                     }

                     for (var i=0; i < data_array[key].length; i++) {
                        var stateName = data_array[key][i].toLowerCase();
                        if(stateName.search(text.toLowerCase()) !== -1){
                          rows[key].push(data_array[key][i]);
                        }
                      }

                      if(rows[key].length==0)
                        delete rows[key];
                   }

                   this.setState({dataSource:ds.cloneWithRowsAndSections(rows)});

Yang terakhir tambahkan code renderSectionHeader pada ListView anda seperti berikut :

          renderSectionHeader={(rowData,sectionId)=>
            <View style={styles.sectionHeader}>
              <Text style={styles.sectionHeaderText}>{sectionId}</Text>
            </View>
          }

Silahkan jalankan aplikasi, jika code yang anda masukkan sudah benar maka akan tampil halaman seperti gambar aplikasi yang diinginkan.

Masih ga jalan?? Silahkan lihat project lengkap dari tulisan ini di : https://github.com/sabithuraira/react_native_playground. Untuk code tulisan ini bisa dicek langsung di https://github.com/sabithuraira/react_native_playground/blob/master/application/components/SampleMenu.js

Happy coding..

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: