Asp.net: Dinamic Gridview

Sebelumnya saya telah menulis tentang pembuatan tabel dinamis. Tapi dalam penerapannya, saya banyak menemui kesulitan. Kemudian, berdasarkan saran teman, saya tidak lagi menggunakan asp-table untuk pembuatan tabel dinamis tapi menggunakan gridview. Salah satu kelebihan gridview, kita bisa mengambil informasi data tanpa memusingkan baris header ataupun footer. Header dan footer inilah yang cukup merepotkan jika menggunakan table. Kelebihan lain menggunakan gridview adalah, kita bisa menambahkan AJAX control kedalam control yang ada di dalam gridview.

Pertama, buat lebih dulu gridviewnya.

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" ShowFooter="true">
    <Columns>
        <asp:TemplateField HeaderText="No.">
            <ItemTemplate>
                <%#Container.DataItemIndex + 1%>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Propinsi">
            <ItemTemplate>
                 <asp:DropDownList ID="ddlPropinsi" AutoPostBack="true" OnSelectedIndexChanged="PilihPropinsi" runat="server" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Kabupaten">
            <ItemTemplate>
                <asp:DropDownList ID="ddlKabupaten" runat="server" />
            </ItemTemplate>
            <FooterTemplate>Jumlah</FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Nama">
            <ItemTemplate >
                <asp:TextBox ID="tbNama" runat="server" Text='<%#bind("Nama") %>' />
            </ItemTemplate>
            <FooterTemplate>
                <asp:Label ID="lbjumlah" runat="server"  />
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Keterangan">
            <ItemTemplate>
                <asp:TextBox ID="tbKeterangan" runat="server" Text='<%#bind("Keterangan") %>'/>
            </ItemTemplate>
            <FooterTemplate>
                <asp:Label ID="lbjumlah2" runat="server"  />
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="">
            <ItemTemplate>
                <asp:CheckBox ID="cb1" runat="server" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>
<br />
<asp:Button ID="btAdd" runat="server" Text="Add" />
<asp:Button ID="btDelete" runat="server" Text="Delete" />
<br /><br />
<asp:Button ID="btUpdate" runat="server" Text="Bind data dari database untuk di edit" />

Saya menambahkan attribut Text='<%#bind(“Keterangan”) %>, tujuannya adalah, ketika saya ingin merubah data di database, data dapat langsung di tampilkan di textbox dan dapat langsung di edit.

Secara default, ketika tidak ada data yang di bind ke gridview, gridview tidak akan tampil. Karena itu perlu dibuat data dummy, sehingga seolah-olah ada data yang di bind ke gridview. Simpan data ini ke session

Protected Sub InitialGridview()
    Dim dt As New DataTable
    Dim dr As DataRow = Nothing

    dt.Columns.Add(New DataColumn("IdPropinsi", GetType(Integer)))
    dt.Columns.Add(New DataColumn("IdKabupaten", GetType(Integer)))
    dt.Columns.Add(New DataColumn("Nama", GetType(String)))
    dt.Columns.Add(New DataColumn("Keterangan", GetType(String)))

    dr = dt.NewRow()
    dr("IdPropinsi") = 0
    dr("IdKabupaten") = 0
    dr("Nama") = String.Empty
    dr("Keterangan") = String.Empty

    dt.Rows.Add(dr)

    GridView1.DataSource = dt
    GridView1.DataBind()
	'Simpan data ke session
    Session.Add("DATA", dt)
End Sub

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not Page.IsPostBack Then
        InitialGridview()
    End If
End Sub

Ketika gridview tampil pertama kali, dropdownlist di kolom ke2 diisi dengan data awal. Prosedur untuk mengisi dropdownlist di kolom ke-2 dilakukan di method gridview row databound

Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
	If e.Row.RowType = DataControlRowType.DataRow Then
		If Session("DATA") Is Nothing Then
			Dim ddlProp As DropDownList = DirectCast(e.Row.Cells(1).FindControl("ddlPropinsi"), DropDownList)
			BindPropinsi(ddlProp)
		Else
			'Jika data di session ada, bind data sesuai data yang tersimpan dalam session
            Dim dt As DataTable = DirectCast(Session("DATA"), DataTable)
            Dim roIndek As Integer = e.Row.RowIndex
            Dim ddlProp As DropDownList = DirectCast(e.Row.Cells(1).FindControl("ddlPropinsi"), DropDownList)
            BindPropinsi(ddlProp)
            ddlProp.SelectedIndex = ddlProp.Items.IndexOf(ddlProp.Items.FindByValue(dt.Rows(roIndek).Item("IdPropinsi").ToString()))

            Dim ddlkab As DropDownList = DirectCast(e.Row.Cells(2).FindControl("ddlKabupaten"), DropDownList)
            BindKabupaten(ddlkab, ddlProp.SelectedValue)
            ddlkab.SelectedIndex = ddlkab.Items.IndexOf(ddlkab.Items.FindByValue(dt.Rows(roIndek).Item("IdKabupaten").ToString()))

            Dim tb1 As TextBox = DirectCast(e.Row.Cells(3).FindControl("tbNama"), TextBox)
            tb1.Text = dt.Rows(roIndek).Item("Nama").ToString()

            Dim tb2 As TextBox = DirectCast(e.Row.Cells(3).FindControl("tbKeterangan"), TextBox)
            tb2.Text = dt.Rows(roIndek).Item("Keterangan").ToString()
		End If
	End If
End Sub

Private Sub BindPropinsi(ByVal ddl As DropDownList)
    Try
        Dim dt As New DataTable
        Dim con As New SqlConnection(strKoneksi)
        con.Open()
        Dim cmd As New SqlCommand()
        cmd.Connection = con
        cmd.CommandText = "select * from propinsi"
        Dim dtadapter As New SqlDataAdapter()
        dtadapter.SelectCommand = cmd
        dtadapter.Fill(dt)

        ddl.DataSource = dt
        ddl.DataValueField = "IdPropinsi"
        ddl.DataTextField = "Propinsi"
        ddl.DataBind()
        ddl.Items.Insert(0, ".:Pilih:.")
        ddl.Items(0).Value = 0
    Catch ex As Exception
        Throw New Exception(ex.Message)
    End Try
End Sub

Private Sub BindKabupaten(ByVal ddl As DropDownList, ByVal idProp As String)
    Try
        Dim dt As New DataTable
        Dim con As New SqlConnection(strKoneksi)
        con.Open()
        Dim cmd As New SqlCommand()
        cmd.Connection = con
        cmd.CommandText = "select * from kabupaten where idPropinsi = " & idProp
        Dim dtadapter As New SqlDataAdapter()
        dtadapter.SelectCommand = cmd
        dtadapter.Fill(dt)

        ddl.DataSource = dt
        ddl.DataValueField = "IdKabupaten"
        ddl.DataTextField = "Kabupaten"
        ddl.DataBind()
        ddl.Items.Insert(0, ".:Pilih:.")
        ddl.Items(0).Value = 0
    Catch ex As Exception
        Throw New Exception(ex.Message)
    End Try
End Sub

Perhatikan, di dropdownlist ddlPropinsi, ada attribut OnSelectedIndexChanged=”PilihPropinsi”. Buat prosedur ini

Protected Sub PilihPropinsi(ByVal sender As Object, ByVal e As EventArgs)
    Dim ddlprop As DropDownList = DirectCast(sender, DropDownList)
    Dim gvRow As GridViewRow = DirectCast(ddlprop.Parent.Parent, GridViewRow)
    Dim roIndek As Integer = gvRow.RowIndex

    Dim ddlkab As DropDownList = DirectCast(GridView1.Rows(roIndek).FindControl("ddlKabupaten"), DropDownList)
    BindKabupaten(ddlkab, ddlprop.SelectedValue)
End Sub

Buat prosedur untuk menambah baris baru di gridview. Baris baru ditambahkan ketika tombol ‘Add’ di click.

Protected Sub btAdd_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btAdd.Click
    'Untuk menambah baris baru.
    'Simpan dulu informasi yang ada di gridview
    SaveGridviewData()
    If Not Session("DATA") Is Nothing Then
        Dim dt As DataTable = DirectCast(Session("DATA"), DataTable)
        Dim dr As DataRow = dt.NewRow()
        dr("IdPropinsi") = 0
        dr("IdKabupaten") = 0
        dr("Nama") = String.Empty
        dr("Keterangan") = String.Empty

        dt.Rows.Add(dr)
        GridView1.DataSource = dt
        GridView1.DataBind()
    End If
End Sub

Sebelum baris baru ditambahkan, simpan dulu data di gridview ke session

Private Sub SaveGridviewData()
    'Simpan semua data yang ada di gridview ke session
    Dim data As New DataTable
    Dim dr As DataRow = Nothing
    Dim ddl As DropDownList
    Dim tb As TextBox

    data.Columns.Add(New DataColumn("IdPropinsi", GetType(Integer)))
    data.Columns.Add(New DataColumn("IdKabupaten", GetType(Integer)))
    data.Columns.Add(New DataColumn("Nama", GetType(String)))
    data.Columns.Add(New DataColumn("Keterangan", GetType(String)))

    For i As Integer = 0 To GridView1.Rows.Count - 1
        dr = data.NewRow
        ddl = DirectCast(GridView1.Rows(i).Cells(1).FindControl("ddlPropinsi"), DropDownList)
        If ddl.SelectedIndex > 0 Then
            dr("IdPropinsi") = ddl.SelectedValue
        Else
            dr("IdPropinsi") = 0
        End If
        ddl = DirectCast(GridView1.Rows(i).Cells(2).FindControl("ddlKabupaten"), DropDownList)
        If ddl.SelectedIndex > 0 Then
            dr("IdKabupaten") = ddl.SelectedValue
        Else
            dr("IdKabupaten") = 0
        End If

        tb = DirectCast(GridView1.Rows(i).Cells(3).FindControl("tbNama"), TextBox)
        dr("Nama") = tb.Text
        tb = DirectCast(GridView1.Rows(i).Cells(4).FindControl("tbKeterangan"), TextBox)
        dr("Keterangan") = tb.Text

        data.Rows.Add(dr)
    Next

    Session.Add("DATA", data)
End Sub

Sekarang buat prosedur untuk menghapus baris tertentu di gridview. Saya menyediakan checkbox di kolom terakhir untuk memilih baris-baris yang akan dihapus. Untuk menghapus, pertama, simpan semua data di session, kemudian periksa checkbox mana yang di centang. Berdasarkan informasi checkbox ini, hapus data yang ada di session. Setelah di hapus, bind data ke gridview. Jadi yang dihapus bukan data di gridview, tapi data yang telah tersimpan di session.

Protected Sub btDelete_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btDelete.Click
        SaveGridviewData()

        'kumpulin dulu, checkbox mana yang di chek
        Dim cb As CheckBox
        Dim i As Integer = 0
        Dim indek() As Integer = Array.CreateInstance(GetType(Integer), 1)

        For Each row As GridViewRow In GridView1.Rows
            cb = row.FindControl("cb1")
            If cb.Checked Then
                If i > 0 Then
                    Array.Resize(indek, i + 1)
                End If
                indek(i) = row.RowIndex
                i += 1
            End If
        Next

        If Not Session("DATA") Is Nothing Then
            Dim dt As DataTable = DirectCast(Session("DATA"), DataTable)
            'hapus data di datatable sesuai dengan indek yang di chek
            If i > 0 Then
                Dim z As Integer = indek.Length - 1
                Do Until z < 0
                    dt.Rows.RemoveAt(indek(z))
                    z -= 1
                Loop
            End If

            Session.Add("DATA", dt)
            GridView1.DataSource = dt
            GridView1.DataBind()
        End If
    End Sub

Dalam penerapan sesungguhnya, akan lebih mudah jika menggunakan data class objek daripada datatable.

Happy coding

Download Sample

About Yuniar

Penulis sekarang lebih banyak bekerja menggunakan teknologi Microsoft .NET secara umum dan TIDAK lagi menggunakan aplikasi MapXtreme.net dari MapInfo. Karena itu mohon maaf, jika pertanyaan-pertanyaan mengenai MapXtreme sudah tidak bisa saya jawab lagi.

Posted on 3 Mei 2010, in ASP.net and tagged , , , . Bookmark the permalink. 5 Komentar.

  1. Assalamualaikum…
    Mas Yuniar…

    Saya mau tanya kalo data dari gridview itu dsimpan di database sql server gmn sintaknya?

    Klo yg mas tunjukin itu kn disimpan di session….

    Mohon bantuannya….
    Ssya sedang dikejar deadline….

    • Sebenarnya, tujuan data yang disimpan di session itu sifatnya hanya temporary. Jadi ketika user menambahkan atau mengurangi data yang ada di gridview, yang diolah adalah data yang ada di session. Nah kalo semua proses sudah selesai atau sudah final. User tinggal menjalankan prosedur untuk menyimpan data tersebut (yg ada di session) ke database.
      Untuk bagaimana cara menyimpan ke database sql, silahkan anda cari mengenai ADO.net di om google

  2. mas yuniar,

    mohon bantuannya.. saya menggunakan datagrid, dan sebelum data disimpan ke database data tersebut disimpan dalam session dan dapat di edit atau dihapus dalam datagrid tersebut. lalu setelah data itu disimpan di session akan muncul data grid selanjutnya yang berisi dropdownlist dan nilai dari dropdownlist diambil dari data yang disimpan disession. mohon bantuannya bagaimana cara mengambil nilai di session untuk diletakan pada dropdownlist..

    terimakasih

    • Data yang disimpan dalam session bentuknya apa? dataset ? datatable? ato lainnya?
      kalo data table, ty tinggal bind aja ke dropdownlistnya
      DropDownList1.DataSource = dt
      DropDownList1.DataValueField = dt.Columns(0).ColumnName ‘–> nama kolom yang datanyanya sebagai value
      DropDownList1.DataTextField = dt.Columns(1).ColumnName ‘ –> nama kolom yang datanya muncul di ddl nya

  3. dalam bentuk dataset, hanya saja saya masih bingung… jadi kasusnya

    1. ada dua data grid
    2. data grid yang pertama menyimpan data sementara di session (session1)
    3. saat menyimpan data tersebut, datagrid ke 2 akan muncul
    4. datagrid ke 2 terdapat dropdownlist yang isinya adalah data dari session1

    bagaimana alur untuk menyelesaikan kasus seperti diatas, mohon bantuannya.. terimakasih

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: