Home > Back-end >  Gridview - Pop-up Image in another box when clicked on
Gridview - Pop-up Image in another box when clicked on

Time:12-22

I am using Visual Studio 2017 with vb.net. I have a gridview in which one column is an image. I would like to click on the image and have the image pop-up in another box displaying the picture larger with a close button. I haven't programmed in forever, I'm relearning vb.net, and, of course, my boss needed this yesterday. So, just showing the image part of the grid, my code is:

<asp:TemplateField HeaderText="Image" ItemStyle-HorizontalAlign="Center" ItemStyle-Width="50px">
    <ItemTemplate>
        <asp:Imagebutton ID="Img" runat="server" ImageUrl='<%# Eval("ImageBase64", "{0}") %>' ControlStyle-Width="100" ControlStyle-Height = "100" />
    </ItemTemplate>
</asp:TemplateField>

So, the image shows in the grid:

Imports System.Configuration
Imports System.Data.SqlClient
Imports System.Drawing
Imports System.IO

Public Class _default
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim connectionStr As String = ConfigurationManager.ConnectionStrings("ictsqlConnection").ConnectionString

        Using con As SqlConnection = New SqlConnection(connectionStr)
            'open
            con.Open()

            Using cmd As SqlCommand = New SqlCommand("SELECT SurplusId, Department, Category, Item, VehicleMileage, SerialNo, AgeValueinYrs, AgeValueinMons, Visible, Image FROM Surplus", con)
                Using da As SqlDataAdapter = New SqlDataAdapter(cmd)

                    Dim dt As DataTable = New DataTable()

                   'fill DataTable with data from database
                    da.Fill(dt)

                   'add column that will store the image as a base64 string
                    dt.Columns.Add("ImageBase64", GetType(System.String))

                    For i As Integer = 0 To dt.Rows.Count - 1
                        'convert image Byte() from database to base64 string and store in a new column in the DataTable
                        dt(i)("ImageBase64") = "data:image/jpg;base64," & Convert.ToBase64String(CType(dt(i)("Image"), Byte()))

                    Next

                    'remove column that contains Byte() from DataTable
                    dt.Columns.Remove("Image")

                    GridView1.DataSource = dt
                    GridView1.DataBind()
                End Using
            End Using
        End Using
    End Sub
End Class

I've searched for how to display picture in pop-up and nothing is working. The ImageButton does allow me to click on the picture (lol), but I can't figure out what code to put behind it so the image comes up in a pop-up. I appreciate any help you can give me. Thank you in advance.

CodePudding user response:

I suggest that you use jQuery.UI. (you probably have jQuery available anyway).

So, we attach a client side click event to the Grid.

Our markup is this:

    <div style="width:50%">
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
            DataKeyNames="ID" CssClass="table" >
            <Columns>
                <asp:BoundField DataField="Fighter" HeaderText="Fighter"  />
                <asp:BoundField DataField="Engine" HeaderText="Engine"  />
                <asp:BoundField DataField="Thrust" HeaderText="Thrust"  />
                <asp:BoundField DataField="Description" HeaderText="Description" />

                <asp:TemplateField HeaderText="View">
                    <ItemTemplate>
                    <asp:ImageButton ID="btnImage" runat="server" Height="68px" Width="149px"
                        OnClientClick ="popimage(this);return false"
                        />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>

And our code to load the grid - pull image from database (used row data bound) is this:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not IsPostBack Then
        LoadGrid
    End If

End Sub

Sub LoadGrid()

    Using conn As New SqlConnection(My.Settings.TEST4)
        Using cmdSQL As New SqlCommand("SELECT * FROM Fighters", conn)

            conn.Open()
            Dim rstData = New DataTable
            rstData.Load(cmdSQL.ExecuteReader)
            GridView1.DataSource = rstData
            GridView1.DataBind()

        End Using
    End Using

End Sub

Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound

    If e.Row.RowType = DataControlRowType.DataRow Then

        Dim btnImage As ImageButton = e.Row.FindControl("btnImage")
        Dim gData As DataRowView = e.Row.DataItem
        Dim IBytes() As Byte = gData.Item("Image")
        btnImage.ImageUrl = "Data:Image/jpg;base64,"   Convert.ToBase64String(IBytes)

    End If

End Sub

And now we have this:

enter image description here

So, we need to add a div for the pop dialog - so we add that, and the js code for the popup.

(this markup is right after the grid)

            <div id="imagepop" style="display:none;text-align:center;height:80%">
                <asp:Image ID="Image1" runat="server" ClientIDMode="Static"
                style="height:96%"/>
            </div>

        <script>
            function popimage(btn) {
                FromImage = $(btn)
                ToImage = $("#Image1")
                ToImage.attr("src", FromImage.attr("src"))

                pHeight = ($(window).height() * 0.96)
                pWidth = ($(window).width() * 0.80)

                myDialog = $("#imagepop");                    
                myDialog.dialog({
                    title: "Fighter",
                    modal: true,
                    height: pHeight,
                    width: pWidth,
                    buttons: {

                        Ok: function () {
                            myDialog.dialog("close")
                        }
                    }
                })
            }
        </script>

And now, if we click on the image button in the grid, we get this:

enter image description here

so, what the code does is "this" in the click event passes the image control we click on. We then grab the picture, and shove it into a "div", and then pop a jQuery.UI dialog - and you get the above.

Edit: Handle null image

Question was how to handle database rows with null columns? (well, we could feed the grid with a query that checks and does not include rows with no picture). But that might not be a valid assumption. Hence this would check for rows with no image:

Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound

    If e.Row.RowType = DataControlRowType.DataRow Then

        Dim btnImage As ImageButton = e.Row.FindControl("btnImage")
        Dim gData As DataRowView = e.Row.DataItem
        If IsDBNull(gData.Item("Image")) = False Then

            Dim IBytes() As Byte = gData.Item("Image")
            btnImage.ImageUrl = "Data:Image/jpg;base64,"   Convert.ToBase64String(IBytes)

        End If
    End If

End Sub

Edit #2 - using jQuery and jQuery.UI

So, as a general rule, you download the jQuery, and jQuery.ui librarys. Drop them in a foler for your project - I tend to create a folder called scripts, and place jQuery, and jQuery.UI into that folder. Hence, you reference(s) in that page will look "something" like this:

 <link href="../Content/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="../Scripts/jquery-1.12.4.js"></script>
<script src="../Scripts/jquery-ui-1.12.1.js"></script>
<script src="../Scripts/bootstrap.js"></script>

But, in place of downloading - you can use CDN (content delivery network). That's just a fancy term that in place of downloading and dropping those JavaScript librares into a folder, you reference their web site. Some people like this choice, some don't (since your web page is now referencing a outside external URL to consume those libaries). So, lets use this option for this example. Here is my full working mark-up for this page:

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>

     <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
     <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>

     <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css" />
</head>
<body>
    <form id="form1" runat="server">
        <div style="width:50%">
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
                DataKeyNames="ID" CssClass="table" >
                <Columns>
                    <asp:BoundField DataField="Fighter" HeaderText="Fighter"  />
                    <asp:BoundField DataField="Engine" HeaderText="Engine"  />
                    <asp:BoundField DataField="Thrust" HeaderText="Thrust"  />
                    <asp:BoundField DataField="Description" HeaderText="Description" />

                    <asp:TemplateField HeaderText="View">
                        <ItemTemplate>
                        <asp:ImageButton ID="btnImage" runat="server" Height="68px" Width="149px"
                            OnClientClick ="popimage(this);return false"
                            />
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
        </div>

                <div id="imagepop" style="display:none;text-align:center;height:80%">
                    <asp:Image ID="Image1" runat="server" ClientIDMode="Static"
                    style="height:96%"/>
                </div>

            <script>
                function popimage(btn) {
                    FromImage = $(btn)
                    ToImage = $("#Image1")
                    ToImage.attr("src", FromImage.attr("src"))

                    pHeight = ($(window).height() * 0.96)
                    pWidth = ($(window).width() * 0.80)

                    myDialog = $("#imagepop");                    
                    myDialog.dialog({
                        title: "Fighter",
                        modal: true,
                        height: pHeight,
                        width: pWidth,
                        closeText :"",
                        show : "fade",
                        buttons: {

                            Ok: function () {
                                myDialog.dialog("close")
                            }
                        }
                    })
                }
            </script>

    </form>
</body>
</html>
  • Related