Search code examples
c#asp.netwebformsjsajaxfileuploader

How to execute client-side code after ajax FileUpload event on ASP.NET?


I have an ASP.NET Webforms app where I upload some files to send by email using ajaxFileUpload. Given my business logic, I want to allow up to 5 files per email, and I want to disable the file selector if the limit is reached. I know that ajaxFileUpload does have client and server side events on upload start, complete and complete all, but as the files are stored temporarily between the selections, I'd like to disable the selector on the client inside the OnUploadComplete event (at the server) if the uploaded files reach 5.

I have tried using

ClientScript.RegisterStartupScript(this.GetType(), "files", "$("#ajaxCargarAdjunto_SelectFileContainer")[0].style.display = "none"", false);

and

ScriptManager.RegisterStartupScript(this.Page, Page.GetType(), "key", "$("#ajaxCargarAdjunto_SelectFileContainer")[0].style.display = "none"", false);

but it doesn't trigger the scripts. Even passing the UpdatePanel and its type to the methods, but nothing.

I also tried using hidden fields and calling LoadPostData(), but I get the Invalid postback or callback argument exception.

IPostBackDataHandler textoAdjuntosCorreo = txtAdjuntosCorreo IPostBackDataHandler;
textoAdjuntosCorreo.LoadPostData(txtAdjuntosCorreo.UniqueID, Request.Params);

The ajaxFileUpload event is

protected void ajaxCargarAdjunto_UploadComplete(object sender, AjaxFileUploadEventArgs e)
{
    ClientScript.RegisterStartupScript(this.GetType(), "files", "$("#ajaxCargarAdjunto_SelectFileContainer")[0].style.display = "none"", false);
}

Solution

  • You can't inject scripts in the 3 server side events of the AjaxfileUpload, and the reason why is because those 3 events do NOT have a post-back, and return of web page to the client side. To use script register, the web page has to travel up to the server. The page + code behind runs, including any script injection, and THEN the whole page travels back to the client side.

    However, since the AjaxFileUpLoad does not post-back, then you note in the 3 server side events you cannot touch, see, change ANY controls in the web page which of course are still sitting on the client side. And that also is why you can't inject scripts in those 3 events - the browser page is still sitting on the user's desktop.

    So, those 3 server side events have to be treated like web methods, and thus they don't have use of the web page sitting on the client side. So, you can't change controls on the page, nor can you register scripts.

    Without a page post-back, you of course can't register scripts.

    However, why not consider setting the MaxAllowedFiles?

    Eg this:

    <ajaxToolkit:AjaxFileUpload ID="AjaxFileUpload1" runat="server" 
        OnUploadComplete="AjaxFileUpload1_UploadComplete" 
            ChunkSize="8192" MaxFileSize="-1"
        MaximumNumberOfFiles="5"
        />
    

    That way, the user can only select a max of 5 files.

    eg this:

    enter image description here

    Now, of course after the user selects say 5 files and up-loads, then the counter is re-set, but then again, you could trigger post-back after all the files are up-loaded. You can do this with the 3rd and final "client" side event of the AJ upload by adding a post-back.

    At that point, you would have a actual file count, and with a post-back, then you could even disable the upload control, or even hide it. It really depends on after up-loading do you have or require a final post-back of the page.

    Of course if your page does not post-back after the 5 files, then on up-load, the file counter is re-set. I suppose then, you could simply have a file counter client side. Note that each of the 3 events also have a client side function that can be called. Hence, you could in theory then simply increment a counter, and if it reaches 5 up-loads, then you disable or "hide" the up-load control preventing additional up-loads. This depends on if after all files are up-loaded you have a post-back or not?

    If no post-back occurs after all files are up-loaded, then you have to count the files up-loaded client side, and that can be done.

    So, say this markup:

            <asp:Label ID="lblFilecount" runat="server" Text="0" ClientIDMode="Static"></asp:Label>
            <br />
            <div id="myuploader" style="width:500px">
    
            <ajaxToolkit:AjaxFileUpload ID="AjaxFileUpload1" runat="server" 
                OnUploadComplete="AjaxFileUpload1_UploadComplete" 
                    ChunkSize="8192" MaxFileSize="-1"
                MaximumNumberOfFiles="5"
    
                OnClientUploadComplete="onefiledone" />
    
            </div>
    
            <div id="nomorefiles" style="display:none">
                <h3>5 files uploaded - no more files allowed</h3>
            </div>
    
            <script>
    
                function onefiledone() {
                    var lblcount = $('#lblFilecount')
                    var fcount = parseInt(lblcount.text())
                    fcount += 1
                    lblcount.text(fcount)
    
                    if (fcount == 5) {
                        // no more files allowed
                        $('#myuploader').hide()
                        $('#nomorefiles').show()
                    }
                }
    
            </script>
    

    Note how in above, we define a "OnClientUploadComplete" event. Also, a bit of a "quirk" since you do NOT include the () for the client side js function to call.

    Hence, we now see this:

    enter image description here

    So, note how there is provisions for calling client side js code. As each file is uploaded, we increment the value in the label, and when we reach 5 files, we simply hide the div area showing the up-loader, and then show a simple div with a message inside.