Devils Work

—Blog By DotNetRuler

Archive for the ‘JavaScript’ Category

multiple file upload control Using JavaScript

Posted by DotnetRuler on March 18, 2009

In this Post I am going to explain about Multiple File Upload Control Designed at the Client side. This Control is an Extension for the Example provided in the ASP.NET videos section.

You can see the Video here.

The Main Purpose of Creating This control is

1)      We cannot Save the State of an ASP.NET File Upload Control between Post backs.  We can create a Asp.NET textboxes or other Controls Dynamically (by Recreating and Reassigning the values to the Controls). But Due to security Issue You cannot reassign a File path to an ASP.NET File upload Control. [“File System is a part of Operating System”]

I have added these features to the existing control developed in the video.

1)      You  can have a textbox and a dropdown button

Textbox is for the description and Dropdown is for giving an option for the user to categorizing the uploaded File.

2)      I have added an option to remove if users don’t want the added control on the Page.

The Following is the Snap Shot of the Control.

Single File

singlefile

Multiple Files

multipleFiles

I will be explaining the code by taking it into small pieces.

I am placing this whole control in an user control and created an event handler to handle the Upload button event in the main page (aspx).

The Code that you are seeing below is the Code in the ascx page.

<body onload=”FileType()”>

    <table>

        <tr>

            <td >

                <asp:Image runat=”server” ID=”Add” Style=”cursor: pointer; ImageUrl=”~/add.png” onClick=”addFileUploadBox()” />

                <a id=”Addcontrol” style=”cursor: pointer; onclick=”addFileUploadBox()”><b>Add</b></a>

                <asp:ImageButton runat=”server” ID=”Image1″ Style=”cursor: pointer; ImageUrl=”~/Upload.png” OnClick=”btnUpload_Click” />

                <asp:LinkButton ID=”btnUpload” Style=”background: none; cursor: pointer; text-decoration: none; color: Black; Font-Bold=”true” runat=”server” Text=”Upload” OnClick=”btnUpload_Click” />

            </td>

        </tr>

        <tr>

            <td >

                <asp:Label ID=”Label1″ runat=”server” Text=”File Upload Control” Font-Bold=”true” Font-Underline=”true” Style=”margin-left: 60px; />

                <asp:Label ID=”Label2″ runat=”server” Text=”Description” Font-Bold=”true” Font-Underline=”true” Style=”margin-left: 235px; />

                <asp:Label ID=”Label3″ runat=”server” Text=”Type” Font-Bold=”true” Font-Underline=”true” Style=”margin-left: 85px; />

            </td>

        </tr>

        <tr>

            <td >

                <p id=”upload-area”>

                    <input id=”File1″ type=”file” runat=”server” size=”45″ />

                    <input id=”Text1″ type=”text” name=”Text1″ style=”margin-left: 5px; size=”25″ />

                </p>

            </td>

        </tr>

    </table>

</body>

This is Simple Piece of code which initially control is having.  On body load I am calling a javascript function FileType().

In this Function I am adding a html select Control on the fly. This was done using JSON (Java Script Object Notation). In this Example I am just using a simple list. You can even bind this Select Control to the DataSource.

The function is as follows…

    function FileType(){

        var uploadArea = document.getElementById(“upload-area”);

        var newTypeDdl = document.createElement(“select”);

        var types = <asp:Literal ID=“typesJson” runat=“server” />;

        for(var t in types) {

            var typ = types[t];

            newTypeDdl.options.add(new Option(typ, typ));

        }

        newTypeDdl.setAttribute(“id”, “Select1”);

        newTypeDdl.setAttribute(“name”, “Select1”);

        newTypeDdl.style.marginLeft = “8px”;

        uploadArea.appendChild(newTypeDdl);

    }

I am Creating a ASP Server Side Literal Control Which I will access in the code behind and bind the list to the HTML Select Control. You can see the Code behind code below.

protected void Page_Load(object sender, EventArgs e)

        {

            List<string> fakeTypes = new List<string>();

            fakeTypes.Add(“Project1”);

            fakeTypes.Add(“Project2”);

            fakeTypes.Add(“Project3”);

            fakeTypes.Add(“Project4”);

            StringBuilder sb = new StringBuilder();

            foreach (string t in fakeTypes)

            {

                if (sb.Length > 0)

                {

                    sb.Append(“,”);

                }

                sb.AppendFormat(“”{0}””, t);

            }

            typesJson.Text = string.Format(“[{0}]”, sb);

            typesJson1.Text = string.Format(“[{0}]”, sb);//For Dynamically                                                                                                                                           added Select Control

        }

The following Code Snippet will be called when User wants to add one more file. This will create a html input of type File and a html textbox and html select Control.

function addFileUploadBox() {

 

        // The new box needs a name and an ID

        if (!addFileUploadBox.lastAssignedId)

            addFileUploadBox.lastAssignedId = 2;

 

        if (!document.getElementById || !document.createElement)

            return false;

 

        var uploadArea = document.getElementById(“upload-area”);

 

        if (!uploadArea)

            return;

 

        var container = document.createElement(“div”);

       container.setAttribute(“id”, “Div” + addFileUploadBox.lastAssignedId);

 

        var newUploadBox = document.createElement(“input”);

        var newTextBox = document.createElement(“input”);

        var newDelBtn = document.createElement(“img”);

        var newTypeDdl = document.createElement(“select”);

        var types = <asp:Literal ID=“typesJson1” runat=“server” />;

        for(var t in types) {

            var typ = types[t];

            newTypeDdl.options.add(new Option(typ, typ));

        }

       

        // Set up the new input for file uploads

        newUploadBox.type = “file”;

        newUploadBox.size = “45”;

 

        newTextBox.type = “text”;

        newTextBox.size = “25”;      

 

 newUploadBox.setAttribute(“id”, “File” + addFileUploadBox.lastAssignedId);

 newUploadBox.setAttribute(“name”, “File” + addFileUploadBox.lastAssignedId);

 

 newTextBox.setAttribute(“id”, “Text” + addFileUploadBox.lastAssignedId);

 newTextBox.setAttribute(“name”, “Text” + addFileUploadBox.lastAssignedId);

 newTextBox.style.marginLeft = “8px”;

       

 newTypeDdl.setAttribute(“id”, “Select” + addFileUploadBox.lastAssignedId);

 newTypeDdl.setAttribute(“name”, “Select” + addFileUploadBox.lastAssignedId);

 newTypeDdl.style.marginLeft = “8px”;

 

 newDelBtn.setAttribute(“id”, “img” + addFileUploadBox.lastAssignedId);

 newDelBtn.src = “/cancel.png”;

    

 newDelBtn.style.marginLeft = “4px”;

 newDelBtn.onclick = function() { RemoveUploadBox(this.id) };

 

 container.appendChild(newUploadBox);

 container.appendChild(newTextBox); 

 container.appendChild(newTypeDdl);

 container.appendChild(newDelBtn);

 uploadArea.appendChild(container);

 addFileUploadBox.lastAssignedId++;  }

You can Create a html element using  

var newUploadBox = document.createElement(“input”);

then u can Assign a type to that element like     

      newUploadBox.type = “file”; //It can be Text, or Button or Else.

Then Using SetAttribute method you can assign a name and ID to that control.

We can assign the ID and Name either this way also

      newUploadBox.ID = “SomeID”; newUploadBox.name = “SomeName”;

 

Then you can even create a click event for a button,link or to any control.

 

This is the Tricky Part I have faced when I created this control.

 

If you use the setattribute method to create a link it will work in both FireFox, Chrome and Safari. IE wont recognise that attribute.

After an Intense Google Search I found that if it has to work in IE we need to assign that attribute in the following way.

newDelBtn.onclick = function() { RemoveUploadBox(this.id) };

 

Then On the button Cancel(image) Click We will call this function.

 

    function RemoveUploadBox(id) {

        var str;

        str = id.substring(3);

        var Container = document.getElementById(“Div” + str);

        Container.removeChild(document.getElementById(id));

        Container.removeChild(document.getElementById(“File” + str));

        Container.removeChild(document.getElementById(“Text” + str));

        var uploadArea = document.getElementById(“upload-area”);

        uploadArea.removeChild(Container);

    }

 

This Fucntion takes the the Id of that Cancel button and from there I splitted the ID to find which row we need to remove.

 

So With this USER can add or remove a file dynamically. Then Next Part is Uploading. I have created an EventHandler to handle this upload event in the main page where this control loaded.

 

        public event EventHandler uploadClick;

        protected void btnUpload_Click(object sender, EventArgs e)

        {

            if (uploadClick != null)

            {

                uploadClick(sender, e);

            }

  }

I guess Every thing is straight forward in the above code. I guess some people Don’t know why we need to write this piece of line

if (uploadClick != null)

We must write this line because If the user forgets to write an event for the button click in the main page , and if he clicks upload button in the user control It will give you a null reference Exception.  So If we write this line first it will check whether user raised uploadClick event in the main page or not If he raises then it will do some action or else it wont send the request to main page.

Coming to Main page The code is as follows in aspx Page.

 

<uc1:FileUploadControl ID=”FileUploadControl1″ OnuploadClick=”Upload_Click” runat=”server” />

 

You can see I have raised the event “OnuploadClick”.  In the Code behind in the page load event I checking whether the destination directory exists or not. If it not exists I am creating the directory.

 

        protected void Page_Load(object sender, EventArgs e)

        {

            String UpPath;

            UpPath = “C:\temp”;

 

            if (!Directory.Exists(UpPath))

            {

                Directory.CreateDirectory(“C:\temp\”);

            }

        }

When User Clicks Upload button in the User control it will check whether there is an event raised in the main page or not , if raised it will send the request to main page where user control was placed.

The Code is as follows..

 

     protected void Upload_Click(object sender, EventArgs e)

        {

            HttpFileCollection uploads = HttpContext.Current.Request.Files;

            for (int i = 0; i < uploads.Count; i++)

            {

                HttpPostedFile upload = uploads[i];

 

                if (upload.ContentLength == 0)

                    continue;

 

                try

                {

                    //Retrieving the fullpath of the File.

             string SourceFileName = Path.GetFileName(upload.FileName);

 

                    //Saving it in temperory Directory.

                    upload.SaveAs(“c:\temp\” + SourceFileName);

 

                    //Retrieving HTML TextBox Value using C#

              string Description = Request.Form[“Text” + (i + 1).ToString()];

 

                    //Retrieving HTML Select Value using C#

                  string Type = Request.Form[“Select” + (i + 1).ToString()];

 

                }

                catch

                {

                }

            }

        }

 

Comments are Highly Appreciated. Happy Coding.

 

Thanks,

DotnetRuler 🙂

Keep Rocking as Always m/

Posted in ASP.NET, JavaScript | Tagged: , | 9 Comments »