thedigitalfeed.co.uk content

thedigitalfeed.co.uk/Code

Multiple File Uploads using Javascript and cloneNode()

Posted on Wednesday the 7th of February, 2007

www.thedigitalfeed.co.uk/code/2007/02/07/multiple-file-uploads-using-javascript-and-clonenode

Forms with multiple file upload boxes are a nuisance. You're stuck with hard-coding a defined number of uploads or using PHP or ASP to decide how many upload fields to have. Or are you? Here's a way to dynamically add file upload boxes on the fly using Javascript.

If there's one truism that I have learned, it is that your web application can always be improved upon – at least from a user's point of view. Fortunately, we do have options. Depending on the web application we are writing, we can customise aspects of our application based on how the user interacts with it.

Javascript is very versatile when building a flexible user interface. You can decide how your web application will react to many different interactive events. Using Javascript techniques we can build dynamic forms capable of modifying themselves during user input.

File uploads are a very common tool in web interfaces whether they are used inside Content Management Systems, CRM applications, B2B environments and so on. One thing I try never to do is limit the user – and nor do I overwhelm them. This Javascript technique will allow you to add file upload boxes on the fly, using a single file upload box and an <a> tag that triggers a Javascript function.

The Javascript functions we will be using are:

  1. onclick()
  2. cloneNode() and removeChild()
  3. getElementById() and getElementsByTagName()
  4. getAttribute() and setAttribute()


The logic is very simple. We create a <div> that holds the file upload box and the Javascript link. Once the link is triggered, the <div> is duplicated and inserted after the original <div>. The original Javascript link is also removed, since the new <div> also contains a copy of it - and we only ever want one link. Finally, some error checking is added to make sure that the link only triggers if the preceding file upload box contains a value.

On to the code. Here's what my main div looks like:

<div>
   <input type="file" name="0"/>
   <a onclick="clone(this);return false" href="#" title="Add">
      <img src="add_new.gif"/>
   </a>
</div>
<p id="btn_upload">Maximum file: 8MB</p>


I have the <p> tag there so that I have a local point of reference to insert the cloned element ahead of. You could change the functionality to use appendChild() instead, however this <p> is right next to the code (so it won't be lost), and also provides an accessibility message to the user – that of the maximum filesize that the server will accept (I use PHP to dynamically add this value, as it varies from server to server as well as within Apache .conf files).

The Javascript function clone() looks like this:

function clone(_el){
   if(_el.previousSibling.value!=''){
      var _new = _el.parentNode.cloneNode(true);
      var _id =
_el.parentNode.getElementsByTagName('input')[0].getAttribute('name');
      var _newInput = _new.getElementsByTagName('input')[0];
      _newInput.setAttribute('name',_id+1);

      _el.parentNode.parentNode.insertBefore(_new,document.getElementById('btn_upload'));
      _el.parentNode.removeChild(_el);
   }
}


And that's all there is to it. Once clicked, Javascript duplicates the <div>, increments the name attribute of the new input, and inserts it as the last element before the ending <p> tag.