I'm trying to create a web page with form fields and a WebUpload control.. It's a support forum kind of thing that allows the user to enter details and add files as attachments.
A few questions..
If you select a few files to attach and then do something else on the page that causes a postback, the WebUpload control loses its contents and reverts back to original state.. is there a way of retaining the content ?
How can I use one button on the page to do a postback and have it upload the files at that time, not as a separate operation.. the files are going into the DB.
Hi Deyan,
I managed to fix my js, but have found a problem.. might be a bug..
<script type="text/javascript"> var _Key = ""; function WebUpload1_OnFormDataSubmit(e, args) { $(e.target).igUpload("addDataField", args.formData, { "name": "myID", "value": _Key }); } $("#MainForm").submit( function (e) { e.preventDefault(); var Dat = JSON.stringify({ Name: $("#MainContent_txtName").val() }); _Key = "unset"; $.ajax({ type: 'POST', contentType: 'application/json; charset=utf-8', dataType: 'json', url: '/Msg.asmx/Add', data: Dat, success: function (json) { if (!$.isEmptyObject(json)) { json = $.parseJSON(json.d); _Key = json.result; } }, error: function (xhr, status, err) { _KeyID = "ErrorFromService"; }, async: false }); var that = this; var UP = $("#MainContent_WebUpload1"); var fileInfoData = UP.igUpload("getFileInfoData"); fileInfoData.filesInfo.forEach(function (file) { console.log("File Name:" + file.file.name + " formNumber:" + file.formNumber); UP.igUpload("startUpload", file.formNumber); }); setTimeout(function () { that.submit(); }, 0); } ) </script>
The problem comes when it hits the code to do the start upload for each file.. the formNumber is 0 for all files, so it only uploads the first one.
Do you think I could just use a counter and increment it each loop and use that ?
Thanks for the reply, I've been working on a solution using your script, and I think my approach should work once I can get it running.
The problem I have is that the file upload runs outside of the application scope, so you don't have access to the screen controls when the file(s) are uploaded. So, using your script, I added in an ajax call a the top to post the field data to the server and return an 'key' to the client.. then using the onFormDataSubmit, I pass that key to the UploadFinished event on the server.
Here is the web service
Imports System.Web.Services Imports System.ComponentModel Imports System.Web.Script.Services Imports System.Web.Script.Serialization <ScriptService()> <WebService(Namespace:="thecompany.co.uk")> <WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> <ToolboxItem(False)> Public Class Msg Inherits WebService <WebMethod()> <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> Public Function Add(Name As String) As Object Try Dim MyID As String = Name + "_banana" Return ConvertToJSON(MyID) Catch ex As Exception Return ConvertToJSON(ex) End Try End Function Public Function ConvertToJSON(ByVal ex As Exception) As Object Dim jsSerializer As JavaScriptSerializer = New JavaScriptSerializer Dim json As New Dictionary(Of String, Object) From { {"error_message", ex.Message}, {"error_stackTrace", ex.StackTrace} } Return jsSerializer.Serialize(json) End Function Public Function ConvertToJSON(ByVal str As String) As Object Dim jsSerializer As JavaScriptSerializer = New JavaScriptSerializer Dim json As New Dictionary(Of String, Object) From { {"result", str} } Return jsSerializer.Serialize(json) End Function End Class
And my content page..
<%@ Page Title="Home Page" Language="VB" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.vb" Inherits="WebFileUploadTest._Default" %> <asp:Content ID="HeadContent" ContentPlaceHolderID="HeaderContent" runat="server"> <style type="text/css"> #MainContent_WebUpload1_spbtncncl { display:none; } </style> </asp:Content> <asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> <link type="text/css" href="/ig_ui/css/themes/infragistics/infragistics.theme.css" rel="stylesheet" /> <link type="text/css" href="/ig_ui/css/structure/infragistics.css" rel="stylesheet" /> <script type="text/javascript" src="/Scripts/jquery-3.4.1.min.js"></script> <script type="text/javascript" src="/Scripts/jquery-ui-1.12.1.min.js"></script> <script type="text/javascript" src="/ig_ui/js/infragistics.js"></script> <script type="text/javascript"> var _PostbackID = "unset"; function WebUpload1_OnFormDataSubmit(e, args) { $(e.target).igUpload("addDataField", args.formData, { "name": "myID", "value": _PostbackID }); } $("#MainForm").submit( function (e) { var Dat = JSON.stringify({ Name: $("#MainContent_txtName").val() }); _PostbackID = "no-hit"; console.log("Calling Msg.Add [" + Dat + "]"); $.ajax({ type: 'POST', contentType: 'application/json; charset=utf-8', dataType: 'json', url: '/Msg.asmx/Add', data: Dat, success: function (json) { console.log("Success : " + json.d); _PostbackID = json.d; }, error: function (xhr, status, err) { console.log("AJAX ERROR: [" + err + "] [" + xhr.status + "]"); console.log(status); _PostbackID = "ErrorFromService"; }, complete: function (xhr, status) { console.log("Msg.Add Complete"); } }); console.log("After AJAX call"); var that = this; var fileInfoData = $("#MainContent_WebUpload1").igUpload("getFileInfoData"); fileInfoData.filesInfo.forEach(function (file) { $("#MainContent_WebUpload1").igUpload("startUpload", file.formNumber); }); setTimeout(function () { that.submit(); }, 0); return false; } ) </script> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <br /> <table style="width:400px;border:1px solid silver;"> <tr> <td><asp:Label runat="server" ID="lab1" text="Enter Name"/></td> <td><asp:TextBox runat="server" ID="txtName" /></td> </tr> <tr> <td colspan="2" style="min-height: 80px;height: 80px;border: 1px solid silver;"> <ig:WebUpload ID="WebUpload1" runat="server" MultipleFiles="true" Mode="Multiple" MaxUploadedFiles="5" ClientEvents-OnFormDataSubmit="WebUpload1_OnFormDataSubmit"> </ig:WebUpload> </td> </tr> <tr> <td colspan="2"> <asp:Button ID="btnSubmit" runat="server" Text="Submit" /> </td> </tr> </table> </ContentTemplate> </asp:UpdatePanel> </asp:Content>
And finally the server side code
Imports System.IO Imports Infragistics.Web.UI.EditorControls Public Class _Default Inherits Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load End Sub Private Sub WebUpload1_UploadFinished(sender As Object, e As UploadFinishedEventArgs) Handles WebUpload1.UploadFinished Dim IDKey As String For Each ADF As AdditionalDataField In e.AdditionalDataFields IDKey = ADF.Value Next Dim data() As Byte = File.ReadAllBytes(e.FileInfo.FileName) ' insert data into table using IDkey End Sub End Class
I'm pretty sure this will work but at the moment the ajax call doesn't return properly so it doesn't hit any of the success, error or even complete events.. or the variable doesn't get set and nothing comes out to the console. It does carry on and uploads the files however.
the joys of unmanaged code.
Anyway, many thanks, you got me a lot further that I was
Regards
Adrian
Hello Adrian,
You can bind to submit event of your form and prevent the submitting. At that point you can access current status of the file upload - $("#WebUpload2").igUpload("getFileInfoData"); and store those files, once that's done you could invoke submit method of the form manually.
Here's what I did in order to upload all my pending files:
$("#form1").submit(function (e) { e.preventDefault(); var that = this; var fileInfoData = $("#WebUpload2").igUpload("getFileInfoData"); fileInfoData.filesInfo.forEach(function (file) { $("#WebUpload2").igUpload("startUpload", file.formNumber); }); setTimeout(function () { that.submit(); }, 0); });
Please let me know if this helps, or you need more details.