Alex Wilson
Alex Wilson

Reputation: 1

Looping through a repeater control to delete all files where a checkbok is checked in asp.net

I am creating a dropbox application where I would like the use to be able to check all the checkboxes next to the file name and the do a multiple delete. For flexibility with the design, I have the files and checkboxes printed on the page using an ASP.net repeater rather than gridview.

See below my current code which I have made using similar examples on the internet. The main issue I'm having is I'm unsure who to get the loop to pick up on whether the checkbox is checked for each unique repeater item.

.aspx code


 <asp:Button  ID="ButtonDelete" runat="server" CssClass="btn-uploader "OnClick="ButtonDelete_Click" Text="Delete" />

<asp:Repeater ID="Repeater2" runat="server">
        <ItemTemplate> 
          <!-- Drag and Drop Uploader --> 
          
          <!-- Carry on -->
          <div id="rptCard" class="card card-style fileItemMainBorder" >
            <div class="content fileItemMainBorder2" style="display: flex;">
              <p class="font-50 pt-3 dragtext" style="float: left;">
                <input id="checkboxes" class="file-check-input me-2" type="checkbox" value="">
                <span style="font-size: 1em; color: #ff6a00;"><i class="fas fa-file-alt"></i></span>&nbsp; <a href="exampleModalLabel<%# DataBinder.Eval(Container.DataItem, "FileID")%>" data-bs-toggle="modal" class="fileItemMain" data-bs-target="#exampleModal<%# DataBinder.Eval(Container.DataItem, "FileID")%>"><%# DataBinder.Eval(Container.DataItem, "FileName").ToString().Replace("%20", " ")%></a> </p>
              <div class="pe-3 pt-3" style="margin-left: auto;"><a href="Content/Files/<%# DataBinder.Eval(Container.DataItem, "UserID")%>/<%# DataBinder.Eval(Container.DataItem, "Filename").ToString().Replace("%20", " ")%>"><img src="img/icons/icon_download.png" class="iconhover me-3" style="width: auto; height: 20px;" alt="Download"></a> 
                  
              <a href="deleteLabel<%# DataBinder.Eval(Container.DataItem, "FileID")%>" data-bs-toggle="modal" data-bs-target="#delete<%# DataBinder.Eval(Container.DataItem, "FileID")%>"><img src="img/icons/icon_delete.png" class="iconhover" style="width: auto; height: 20px;" alt="Delete"></a> </div>
            </div>
            <!-- document viewer -->
            <div class="modal fade" id="exampleModal<%# DataBinder.Eval(Container.DataItem, "FileID")%>" tabindex="-1" aria-labelledby="exampleModalLabel<%# DataBinder.Eval(Container.DataItem, "FileID")%>" aria-hidden="true">
              <div class="modal-dialog modal-fullscreen">
                <div class="modal-content">
                  <div class="modal-header"> <span class="close ms-3" data-bs-dismiss="modal">&times;</span> </div>
                  <div class="modal-body">
                    <embed src="Content/Files/<%# DataBinder.Eval(Container.DataItem, "UserID")%>/<%# DataBinder.Eval(Container.DataItem, "Filename").ToString().Replace("%20", " ")%>" frameborder="0" width="100%" height="100%"> 
                  </div>
                </div>
              </div>
            </div>
            <!-- end modal --> 
            <!-- modal-2 -->
            <div class="modal fade" id="delete<%# DataBinder.Eval(Container.DataItem, "FileID")%>" tabindex="-1" aria-labelledby="deleteLabel<%# DataBinder.Eval(Container.DataItem, "FileID")%>" aria-hidden="true">
              <div class="modal-dialog">
                <div class="modal-content">
                  <div class="modal-header">
                    <h5 class="modal-title">Please confirm you want to delete this file.</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                  </div>
                  <div class="modal-body justify-content-center text-center">
                    <p>Are you sure you want to delete:<br />
                    <h5><%# DataBinder.Eval(Container.DataItem, "FileName").ToString().Replace("%20", " ")%></h5>
                    </p>
                    <p class="font-12" style="color:red">This action will delete this file and CANNOT be undone.</p>
                  </div>
                  <a href="file-delete.aspx?fid=<%# DataBinder.Eval(Container.DataItem, "FileID")%>" style="float:right; display: inline;" class="btn btn-sm btn-danger">Yes, I understand, proceed with file delete</a> </div>
              </div>
            </div>
          </div>
          <!-- end modal-2 --> 
        </ItemTemplate>
      </asp:Repeater>

VBScript Code

 Protected Sub ButtonDelete_Click(ByVal sender As Object, ByVal e As EventArgs)
        ' Connect to your database (e.g., using SqlConnection)
        Dim sSqlConnectionString As String = WebConfigurationManager.ConnectionStrings("constr").ToString

        Dim uid As Integer
        Try
            uid = Session("sessUID")
        Catch ex As Exception
            uid = 0
        End Try


        ' Get the list of files and checkboxes from the form

        Dim checkboxes As String() = Request.Form.GetValues("checkboxes") ' Assuming 'checkboxes' is an array of checkbox values

        ' Loop through the files and checkboxes
        For i As Integer = 0 To getFileName().Length - 1
            If checkboxes(i) = "on" Then ' Assuming the checkbox value is "on" when checked
                ' Delete the file
                Dim filePath As String = "C:\Liaison\training.liaisonsystems.com\Content\Files\" & uid & "\" & getFileName() 'Adjust the path As needed
                If System.IO.File.Exists(filePath) Then
                    System.IO.File.Delete(filePath)
                End If

                ' Delete the record from the database
                Dim sDeleteSQL As String = "DELETE FROM Files WHERE FileID = @FileID"
                Dim SqlConn As SqlConnection = New SqlConnection(sSqlConnectionString)
                Dim SqlCmd As SqlCommand = New SqlCommand(sDeleteSQL, SqlConn)
                SqlCmd.Parameters.AddWithValue("@FileID", getFileName())
                SqlConn.Open()
                SqlCmd.ExecuteNonQuery()
                SqlConn.Close()

            End If
        Next

        ' Redirect back to the original page or display a success message
        Response.Redirect("file-uploader.aspx")

    End Sub

Any help would be appreciated.

Upvotes: 0

Views: 127

Answers (1)

Albert D. Kallal
Albert D. Kallal

Reputation: 48989

Just drop in a asp.net check box, no need to use a HTML one. (not particular clear why you did???).

So, say this markup:

<div style="width: 16%">
    <asp:Repeater ID="Repeater1" runat="server">
        <HeaderTemplate>
            <h3>Select Hotels</h3>
        </HeaderTemplate>

        <ItemTemplate>
            <asp:HiddenField ID="DataPK" runat="server"
                Value='<%# Eval("ID") %>' />

            <asp:Label ID="lblHotel" runat="server" Width="250px"
                Text='<%# Eval("HotelName") %>'>
            </asp:Label>

            <asp:CheckBox ID="chkSEL" runat="server" />
            <br />
            <hr style="background-color: black; height: 1px" />
        </ItemTemplate>
    </asp:Repeater>
</div>

<br />
<asp:Button ID="cmdShowSel" runat="server" Text="Process Selected"
    OnClick="cmdShowSel_Click"
    CssClass="btn" />
<br />
<asp:Label ID="lblSel" runat="server" Text=""></asp:Label>

And code behind is this:

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


Sub LoadData()

    Dim rstData As DataTable =
        MyRst("SELECT * FROM tblHotelsA
               ORDER BY HotelName")

    Repeater1.DataSource = rstData
    Repeater1.DataBind()

End Sub

Protected Sub cmdShowSel_Click(sender As Object, e As EventArgs)

    Dim strSelectedPK As String = ""
    For Each rRow As RepeaterItem In Repeater1.Items

        ' get check box, and database PK id
        Dim chkSel As CheckBox = rRow.FindControl("chkSEL")
        Dim hPKID As HiddenField = rRow.FindControl("DataPK")

        If chkSel.Checked Then

            If strSelectedPK <> "" Then strSelectedPK &= ","

            strSelectedPK &= hPKID.Value
        End If

    Next


    ' now delete rows selected

    Dim strSQL =
        $"DELETE FROM tblHotelsA WHERE ID IN ({strSelectedPK})"

    '  MyExecute(strSQL)

    lblSel.Text = $"PK id list selected = {strSelectedPK} <br/>
                  SQL to execute <br/>{strSQL}"


End Sub

And result is now this:

enter image description here

Of course in above I used 2 helper routines, since typing "over and over" code to setup a connection string and to execute SQL is something one will do over and over. So, in my module of helper routines, I have these 2 helper routines.

Public Function MyRst(strSQL As String) As DataTable

    Dim rstData As New DataTable
    Using conn As New SqlConnection(My.Settings.TEST4)
        Using cmdSQL As New SqlCommand(strSQL, conn)
            conn.Open()
            rstData.Load(cmdSQL.ExecuteReader)
            rstData.TableName = strSQL
        End Using
    End Using
    Return rstData
End Function

Public Sub MyExecute(strSQL As String)

    Using conn As New SqlConnection(My.Settings.TEST4)
        Using cmdSQL As New SqlCommand(strSQL, conn)
            conn.Open()
            cmdSQL.ExecuteNonQuery()
        End Using
    End Using

End Sub

Edit: SQL injection safe example.

Protected Sub cmdShowSel_Click(sender As Object, e As EventArgs)

    Dim strSelectedPK As String = ""
    Dim sParms As String = ""
    Dim cmdSQL As New SqlCommand()
    For Each rRow As RepeaterItem In Repeater1.Items

        ' get check box, and database PK id
        Dim chkSel As CheckBox = rRow.FindControl("chkSEL")
        Dim hPKID As HiddenField = rRow.FindControl("DataPK")

        If chkSel.Checked Then

            If strSelectedPK <> "" Then strSelectedPK &= ","
            strSelectedPK &= hPKID.Value

            If sParms <> "" Then sParms &= ","
            Dim sP As String = $"@p{rRow.ItemIndex}"
            sParms &= sP
            cmdSQL.Parameters.Add(sP, SqlDbType.Int).Value = hPKID.Value
        End If

    Next

    ' now delete rows selected
    cmdSQL.CommandText = $"DELETE FROM tblHotelsA WHERE ID IN ({sParms})"

    Dim strSQL As String =
        $"DELETE FROM tblHotelsA WHERE ID IN ({strSelectedPK})" ' for display only

    'MyRstPE(cmdSQL)

    lblSel.Text = $"PK id list selected = {strSelectedPK} <br/>
                  SQL to execute <br/>{strSQL}"

End Sub

And my helper routine:

Public Sub MyRstPE(cmdSQL As SqlCommand)


    Dim rstData As New DataTable
    Using conn As New SqlConnection(My.Settings.TEST4)
        Using (cmdSQL)
            cmdSQL.Connection = conn
            conn.Open()
            cmdSQL.ExecuteNonQuery()
        End Using
    End Using

End Sub

And with all of the "ui" update code removed, then we get this:

Protected Sub cmdShowSel_Click(sender As Object, e As EventArgs)

    Dim sParms As String = ""
    Dim cmdSQL As New SqlCommand()
    For Each rRow As RepeaterItem In Repeater1.Items

        ' get check box, and database PK id
        Dim chkSel As CheckBox = rRow.FindControl("chkSEL")
        Dim hPKID As HiddenField = rRow.FindControl("DataPK")

        If chkSel.Checked Then
            If sParms <> "" Then sParms &= ","
            Dim sP As String = $"@p{rRow.ItemIndex}"
            sParms &= sP
            cmdSQL.Parameters.Add(sP, SqlDbType.Int).Value = hPKID.Value
        End If

    Next

    ' now delete rows selected
    cmdSQL.CommandText = $"DELETE FROM tblHotelsA WHERE ID IN ({sParms})"

    MyRstPE(cmdSQL)

End Sub

Upvotes: 0

Related Questions