AjaxControlToolkit AsyncFileUpload : Get file path after upload by JavaScript

19 Views Asked by At

I build a Web Form with ASP.NET and VB.NET.

After uploading an image with AsyncFileUpload, the uploaded image should be shown in an image box. The AsyncFileUpload doesn't raise a page postback, therefore I have to handle this on client side by JavaScript.

Question : How can I get the upload file path from AsyncFileUpload by JavaScript ?

<asp:Image ID="imgCategory" runat="server" Height="225px" Width="300px" />
<ajaxToolkit:AsyncFileUpload ID="ajxAsyncFileUpload" runat="server" OnClientUploadComplete="UploadComplete"/>


<script type="text/javascript">
    function UploadComplete() {
        var uploadpath = document.getElementById('<%=ajxAsyncFileUpload.ClientID%>').???????;

        document.getElementById('<%=imgCategory.ClientID%>').setAttribute('src', uploadpath);
    }
</script>

1

There are 1 best solutions below

0
Albert D. Kallal On

Use of any file upload never passes to the server the client-side path name.

As for no post-back when the uploading of files is done?

Well, there is a client side "all files done uploading" event, and hence you can use that to trigger a post back, and even better is to have that routine "click" a button, so then server side you have a nice code stub for when all files uploaded on done.

So, say this simple markup:

<asp:RadioButtonList ID="MyTabs" runat="server" CssClass="rMyChoice"
    RepeatDirection="Horizontal" AutoPostBack="true"
    OnSelectedIndexChanged="MyTabs_SelectedIndexChanged">
    <asp:ListItem Value="0" Selected="True">Upload Files</asp:ListItem>
    <asp:ListItem Value="1">View Uploaded Files</asp:ListItem>
</asp:RadioButtonList>


<div id="myfiles" runat="server">

    <h3>Files uploaded</h3>
    <asp:GridView ID="GVFiles" runat="server" AutoGenerateColumns="False"
        DataKeyNames="ID" CssClass="table table-hover" Width="35%">
        <Columns>
            <asp:BoundField DataField="UserName" HeaderText="User Name" />
            <asp:BoundField DataField="UpLoadDate" HeaderText="Uploaded" />
            <asp:BoundField DataField="FileName" HeaderText="File" />
            <asp:TemplateField HeaderText="Preview">
                <ItemTemplate>
                    <asp:Image ID="iPreview" runat="server"
                        Width="128px" Height="96px" />
                </ItemTemplate>
            </asp:TemplateField>

            <asp:TemplateField HeaderText="Download"
                ItemStyle-HorizontalAlign="Center">
                <ItemTemplate>
                    <button id="cmdDownLoad" runat="server" class="btn"
                        onserverclick="cmdDownLoad_ServerClick"
                        style="margin-top: 32px">
                        <span aria-hidden="true" class="glyphicon  glyphicon-cloud-download"></span>
                    </button>

                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
</div>

<div id="myupload" runat="server" style="width: 40%">

    <h4>Select Files to upload</h4>
    <br />
    <ajaxToolkit:AjaxFileUpload ID="AjaxFileUpload1" runat="server"
        OnUploadComplete="AjaxFileUpload1_UploadComplete"
        OnClientUploadCompleteAll="alldone" />
</div>

<asp:Button ID="cmdAllDone" runat="server" Text="Hidden all done upload Button"
    OnClick="cmdAllDone_Click" ClientIDMode="Static" Style="display: none" />


<script>

    function alldone() {

        $('#cmdAllDone').click()
    }

</script>

So, note how we have a "hidden" button, and when all files up-loaded are done, then we click that button. That gets us a final code behind stub to run when all the files are uploaded.

So, code behind is this:

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

    If Not IsPostBack Then
        Session("UserName") = "Albert" ' testing
        LoadGrid()

        myfiles.Visible = False
        myupload.Visible = True

    End If
End Sub


Sub LoadGrid()

    GVFiles.DataSource = MyRst("SELECT * FROM MyFiles ORDER BY UpLoadDate")
    GVFiles.DataBind()

End Sub



Protected Sub AjaxFileUpload1_UploadComplete(sender As Object, e As AjaxControlToolkit.AjaxFileUploadEventArgs)

    ' save file to UpLoadFiles folder
    Dim strF As String = Server.MapPath($"~/UpLoadFiles/{e.FileName}")

    AjaxFileUpload1.SaveAs(strF)

    ' add this row to database.

    Using conn As New SqlConnection(My.Settings.TEST4)
        Using cmdSQL As New SqlCommand("INSERT INTO MyFiles 
                                       (UserName, FileName, SaveFilePath, UpLoadDate)
                                        VALUES (@User, @FileName, @FPath, @UpLoadDate)", conn)

            cmdSQL.Parameters.Add("@User", SqlDbType.NVarChar).Value = Session("UserName")
            cmdSQL.Parameters.Add("@FileName", SqlDbType.NVarChar).Value = e.FileName
            cmdSQL.Parameters.Add("@FPath", SqlDbType.NVarChar).Value = strF
            cmdSQL.Parameters.Add("@UpLoadDate", SqlDbType.DateTime).Value = DateTime.Now
            conn.Open()
            cmdSQL.ExecuteNonQuery()
        End Using
    End Using

End Sub

And for a "nice touch" and bonus points? We display file types or an image preview by using the row data bound event of the GridView.

Hence this code:

Protected Sub GVFiles_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GVFiles.RowDataBound

    If e.Row.RowType = DataControlRowType.DataRow Then

        Dim gRow As DataRowView = e.Row.DataItem
        Dim RowImage As Image = e.Row.FindControl("iPreview")
        Dim sFile As String = gRow("FileName")

        Select Case Path.GetExtension(sFile).ToUpper
            Case ".JPG", ".JPEG", ".JPE", ".BMP", ".GIF", ".PNG"
                RowImage.ImageUrl = $"~/UpLoadFiles/{sFile}"
            Case ".ZIP"
                RowImage.ImageUrl = $"~/Content/zips.png"
            Case ".PDF"
                RowImage.ImageUrl = $"~/Content/pdf5.png"
            Case Else
                RowImage.ImageUrl = $"~/Content/file2.png"
        End Select

    End If

End Sub

The end result is now this:

enter image description here

So, in most cases, you don't get nor have a path name passed client side. However, since each file upload triggers the UpLoadComplete event, then we save the file to some folder, and we for this example added a row to a database.

And our "hidden" button that we click from the client-side JavaScript routine when all files done uploading? That is this simple code:

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

    myfiles.Visible = True
    myupload.Visible = False

    LoadGrid()
    MyTabs.SelectedIndex = 1

End Sub

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

    Select Case MyTabs.SelectedIndex
        Case 0
            myupload.Visible = True
            myfiles.Visible = False
        Case 1

            myupload.Visible = False
            myfiles.Visible = True

    End Select
End Sub

I often use a RadioButtonList as a "tab like" control, and just hide or show the 2 divs for the uploading part, or the viewing of uploaded files.