Belajar Programming | Chained Dropdown List, atau Chained Combo Box, atau Chained Select, atau jika di Indonesiakan menjadi Select Bertingkat atau Combo Box Bertingkat, adalah salah satu teknik yang sering ditanyakan di forum-forum pemrograman. Dengan teknik ini, kita membuat seolah-olah beberapa dropdown list atau combobox saling berhubungan, misalkan combobox nama-nama kota akan terisi otomatis sesuai dengan pilihan negara di combobox lainnya. Atau combobox list pegawai akan berubah sesuai dengan departemen yang dipilih. Teknik ini sebenarnya sangatlah sederhana, namun memerlukan pemahaman yang cukup komprehensif mengenai mengenai beberapa hal, seperti cara mengambil data dari database, cara mengisi data ke combobox atau dropdown list, dan cara mengambil pilihan pengguna sebagai referensi untuk mengisi combobox lainnya.
Belajar Programming | Chained Dropdown List, atau Chained Combo Box, atau Chained Select, atau jika di Indonesiakan menjadi Select Bertingkat atau Combo Box Bertingkat, adalah salah satu teknik yang sering ditanyakan di forum-forum pemrograman. Dengan teknik ini, kita membuat seolah-olah beberapa dropdown list atau combobox saling berhubungan, misalkan combobox nama-nama kota akan terisi otomatis sesuai dengan pilihan negara di combobox lainnya. Atau combobox list pegawai akan berubah sesuai dengan departemen yang dipilih. Teknik ini sebenarnya sangatlah sederhana, namun memerlukan pemahaman yang cukup komprehensif mengenai mengenai beberapa hal, seperti
- cara mengambil data dari database
- cara mengisi data ke combobox atau dropdown list
- cara mengambil pilihan pengguna sebagai referensi untuk mengisi combobox lainnya.
Berikut ini saya coba jabarkan implementasi Teknik Combo Box Bertingkat menggunakan query ADO.NET sederhana saja. Untuk studi kasus ini, kita akan coba menghubungkan 3 (tiga) buah combobox yang berisikan daftar benua – negara – kota. Combobox Negara akan terisi sesuai dengan Benua yang dipilih, dan Combobox Kota akan terisi sesuai dengan Negara yang dipilih. Sedangkan bahasa pemrograman yang dipakai adalah C# dan VB.net untuk memudahkan teman-teman memahaminya.
Devide and Conquer
Dengan sedikit analisa sederhana terhadap kasus ini, kita coba pecah kasus ini menjadi beberapa kasus kecil untuk mempermudah kita menyelesaikannya, antara lain,
- bagaimana desain yang pas untuk kasus seperti ini
- bagaimana cara mengisi combobox benua
- bagaimana cara mengisi combobox negara
- bagaimana cara mengisi combobox kota
- bagaimana cara menangkap perubahan pilihan benua
- bagaimana cara menangkap perubahan pilihan negara
Teknik "memecah problem besar menjadi beberapa problem-problem kecil" adalah salah satu teknik untuk membangun algoritma, yaitu teknik devide and conquer. Dengan memecah problem besar menjadi sejumlah problem kecil, kelihatannya memang seolah problem yang dihadapi menjadi semakin banyak, namun… walaupun kelihatan banyak, sejumlah problem kecil ini justru jauh lebih mudah kita selesaikan sehingga problem besar utama kita otomatis ikut terpecahkan.
Mari Kita Mulai…!
Pertama-tama, desain database harus kita buat dengan hati-hati agar mudah dalam proses retrieval atau pengambilan datanya. Cara paling efektif adalah denga membuat 3 (tiga) buah table yang saling berelasi, yaitu table Continents, table Countries dengan foreign key yang berelasi ke table Continents. dan terakhir, table Cities dengan foreign key yang berelasi dengan table Countries. Seperti terlihat pada gambar di bawah ini.
[collapsed title=Desain Database seperti ini] [/collapsed]
Sedangkan untuk desain Form, kita buat desain sederhana saja seperti yang ada di gambar ini.
[collapsed title=Desain Form seperti ini] [/collapsed]
Mengisi Combobox dari Database
Untuk mengisi Combo Box, algoritma-nya adalah seperti ini,
- Siapkan koneksi database
- Ambil data dari database
- Binding data ke combobox
Dengan mengetahui langkah-langkah dasar di atas, maka kita bisa dengan mudah menterjemahkannya ke bahasa pemrograman apapun. Untuk keperluan ini, kita membuat tiga buah fungsi FillComboContinents, FillComboCountries, dan FillComboCities, masing-masing untuk mengisi data benua, negara, dan kota. Dalam bahasa pemrograman VB.net seperti ini.
''' <summary> ''' Mengisi Combo Box pertama (continents) ''' </summary> Private Sub FillComboContinents() ' siapkan variable koneksi database Dim cn As New SqlCeConnection(My.MySettings.Default.dbSampleConnectionString) Dim da As New SqlCeDataAdapter("SELECT * FROM Continents", cn) ' siapkan data table untuk menampung data dari database Dim dt As New DataTable() ' selalu gunakan try-catch block Try ' isi dataset da.Fill(dt) ' binding dataset ke combobox kedua comboBox1.ValueMember = "ID" comboBox1.DisplayMember = "Name" comboBox1.DataSource = dt Catch ex As Exception ' infokan ke user, jika ada error MessageBox.Show(ex.Message) End Try End Sub ''' <summary> ''' Mengisi Combo Box kedua (countries) ''' </summary> ''' <param name="ContinentID"></param> Private Sub FillComboCountries(ContinentID As Integer) ' siapkan variable koneksi database Dim cn As New SqlCeConnection(My.MySettings.Default.dbSampleConnectionString) Dim da As New SqlCeDataAdapter("SELECT * FROM Countries WHERE ContinentID=@p1", cn) ' siapkan data table untuk menampung data dari database Dim dt As New DataTable() ' selalu gunakan try-catch block Try ' isikan parameter Continent'Benua da.SelectCommand.Parameters.AddWithValue("@p1", ContinentID) ' isi dataset da.Fill(dt) ' binding dataset ke combobox kedua comboBox2.ValueMember = "ID" comboBox2.DisplayMember = "Name" comboBox2.DataSource = dt Catch ex As Exception ' infokan ke user, jika ada error MessageBox.Show(ex.Message) End Try End Sub ''' <summary> ''' Mengisi Combo Box ketiga (cities) ''' </summary> ''' <param name="CountryID"></param> Private Sub FillComboCities(CountryID As Integer) ' siapkan variable koneksi database Dim cn As New SqlCeConnection(My.MySettings.Default.dbSampleConnectionString) Dim da As New SqlCeDataAdapter("SELECT * FROM Cities WHERE CountryID=@p1", cn) ' siapkan data table untuk menampung data dari database Dim dt As New DataTable() ' selalu gunakan try-catch block Try ' isikan parameter Continent'Benua da.SelectCommand.Parameters.AddWithValue("@p1", CountryID) ' isi dataset da.Fill(dt) ' binding dataset ke combobox kedua comboBox3.ValueMember = "ID" comboBox3.DisplayMember = "Name" comboBox3.DataSource = dt Catch ex As Exception ' infokan ke user, jika ada error MessageBox.Show(ex.Message) End Try End Sub
[/collapsed]
Sedangkan versi C# nya adalah sebagai berikut
/// <summary> /// Mengisi Combo Box pertama (continents) /// </summary> private void FillComboContinents() { // siapkan variable koneksi database SqlCeConnection cn = new SqlCeConnection(Properties.Settings.Default.dbSampleConnectionString); SqlCeDataAdapter da = new SqlCeDataAdapter("SELECT * FROM Continents", cn); // siapkan data table untuk menampung data dari database DataTable dt = new DataTable(); // selalu gunakan try-catch block try { // isi dataset da.Fill(dt); // binding dataset ke combobox pertama comboBox1.ValueMember = "ID"; comboBox1.DisplayMember = "Name"; comboBox1.DataSource = dt; } catch (Exception ex) { // infokan ke user, jika ada error MessageBox.Show(ex.Message); } } /// <summary> /// Mengisi Combo Box kedua (countries) /// </summary> /// <param name="ContinentID"></param> private void FillComboCountries(int ContinentID) { // siapkan variable koneksi database SqlCeConnection cn = new SqlCeConnection(Properties.Settings.Default.dbSampleConnectionString); SqlCeDataAdapter da = new SqlCeDataAdapter("SELECT * FROM Countries WHERE ContinentID=@p1", cn); // siapkan data table untuk menampung data dari database DataTable dt = new DataTable(); // selalu gunakan try-catch block try { // isikan parameter Continent/Benua da.SelectCommand.Parameters.AddWithValue("@p1", ContinentID); // isi dataset da.Fill(dt); // binding dataset ke combobox kedua comboBox2.ValueMember = "ID"; comboBox2.DisplayMember = "Name"; comboBox2.DataSource = dt; } catch (Exception ex) { // infokan ke user, jika ada error MessageBox.Show(ex.Message); } } /// <summary> /// Mengisi Combo Box ketiga (cities) /// </summary> /// <param name="CountryID"></param> private void FillComboCities(int CountryID) { // siapkan variable koneksi database SqlCeConnection cn = new SqlCeConnection(Properties.Settings.Default.dbSampleConnectionString); SqlCeDataAdapter da = new SqlCeDataAdapter("SELECT * FROM Cities WHERE CountryID=@p1", cn); // siapkan data table untuk menampung data dari database DataTable dt = new DataTable(); // selalu gunakan try-catch block try { // isikan parameter Continent/Benua da.SelectCommand.Parameters.AddWithValue("@p1", CountryID); // isi dataset da.Fill(dt); // binding dataset ke combobox ketiga comboBox3.ValueMember = "ID"; comboBox3.DisplayMember = "Name"; comboBox3.DataSource = dt; } catch (Exception ex) { // infokan ke user, jika ada error MessageBox.Show(ex.Message); } }
[/collapsed]
Menangkap Perubahan Pilihan Combo Box
Untuk menangkap perubahan pilihan pengguna, maka kita perlu mendeklarasikan beberapa event handler untuk menangani event SelectedValueChanged. Setiap kali ada perubahan di Combo Box yang berisikan data benua, maka otomatis event handler ini akan mengambil ID dari benua bersangkutan, kemudian memanggil fungsi FillCOmboCounteries yang sudah kita buat sebelumnya untuk mengisi combobox negara sesuai dengan pilihan benuanya. Logika yang sama diterapkan untuk combobox yang berisi data negara, otomatis fungsi FillComboCities akan dipanggil setiap kali ada perubahan pilihan negara. Implementasi pengambilan data dalam VB.net menjadi seperti ini,
''' <summary> ''' Form Constructor ''' Inisialisasi event handler dan mengisi combo box pertama ''' </summary> ''' <remarks></remarks> Public Sub New() InitializeComponent() InitializeEventHandlers() FillComboContinents() End Sub ''' <summary> ''' InitializeEventHandlers, menentukan event delegate ''' untuk menangani event SelectedValueChanged setiap kali ''' user memilih item baru di combo box pertama (continents) ''' dan memilih item baru di combo box kedua (countries) ''' </summary> Private Sub InitializeEventHandlers() AddHandler comboBox1.SelectedValueChanged, AddressOf comboBox1_SelectedIndexChanged AddHandler comboBox2.SelectedValueChanged, AddressOf comboBox2_SelectedIndexChanged End Sub ''' <summary> ''' Setiap kali user memilih benua baru, ''' maka isi combo box kedua dengan negara yang sesuai ''' </summary> Private Sub comboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) '' pastikan pilihan benar If (Not IsNothing(comboBox1.SelectedValue)) Then '' ambil ID benua yang dipilih user Dim id As Integer = comboBox1.SelectedValue '' isi combobox country berdasarkan benua yang dipilih FillComboCountries(id) End If End Sub ''' <summary> ''' Setiap kali user memilih negara baru, ''' maka isi combo box ketiga dengan kota yang sesuai ''' </summary> Private Sub comboBox2_SelectedIndexChanged(sender As Object, e As EventArgs) '' pastikan pilihan benar If (Not IsNothing(comboBox2.SelectedValue)) Then '' ambil ID benua yang dipilih user Dim id As Integer = comboBox2.SelectedValue '' isi combobox country berdasarkan benua yang dipilih FillComboCities(id) End If End Sub
[/collapsed]
Dan implementasi pengambilan data dalam bahasa C# menjadi seperti ini,
/// <summary> /// Form Constructor /// Inisialisasi event handler dan mengisi combo box pertama /// </summary> public frmMain() { InitializeComponent(); InitializeEventHandlers(); FillComboContinents(); } /// <summary> /// InitializeEventHandlers, menentukan event delegate /// untuk menangani event SelectedValueChanged setiap kali /// user memilih item baru di combo box pertama (continents) /// dan memilih item baru di combo box kedua (countries) /// </summary> private void InitializeEventHandlers() { comboBox1.SelectedValueChanged += new EventHandler(comboBox1_SelectedValueChanged); comboBox2.SelectedValueChanged += new EventHandler(comboBox2_SelectedValueChanged); } /// <summary> /// Setiap kali user memilih benua baru, /// maka isi combo box kedua dengan negara yang sesuai /// </summary> void comboBox1_SelectedValueChanged(object sender, EventArgs e) { // pastikan pilihan benar if (comboBox1.SelectedValue != null) { // ambil ID benua yang dipilih user int id = (int)comboBox1.SelectedValue; // isi combobox country berdasarkan benua yang dipilih FillComboCountries(id); } } /// <summary> /// Setiap kali user memilih negara baru, /// maka isi combo box ketiga dengan kota yang sesuai /// </summary> void comboBox2_SelectedValueChanged(object sender, EventArgs e) { // pastikan pilihan benar if (comboBox2.SelectedValue != null) { // ambil ID benua yang dipilih user int id = (int)comboBox2.SelectedValue; // isi combobox cities berdasarkan negara yang dipilih FillComboCities(id); } }[/collapsed]
Hasil Akhir
Begini tampilan untuk pilihan negara sesuai benua
Dan ini tampilan kota sesuai dengan pilihan negara
Source code silakan download di sini.