GMail-Like Attachment Forms using DOM Scripting

The web development discussion for today will be about dynamically adding HTML elements using DOM and Javascript. We will be emulating a feature you’ve probably seen all over the web, most notably on GMail when it let’s you add attachments to emails. GMail presents the user with an attachment button. The user can then click it to reveal one attachment. All of this takes place dynamically without any browser refreshes. The user can then add more and more attachments all dynamically. This effect is very useful and also intuitive, which is great for us designers.
You will want to download this zip file to get all the images and sample code. Now let’s learn some DOM and try to emulate this cool effect. As a sidenote, I totally blundered the spelling of “attachment” in the Javascript code. It’s all fixed in this tutorial, but just as a note, it sucks when you misspell something in your code. Ok, now let’s start.
Let’s take a look at where we are headed:
You can play around with this. Click the plus and minus buttons to see it dynamically add and delete. You can choose files, but I haven’t implemented an uploading system or the like since this is not our goal. I’d also like to point out that this effect can be implemented on so many possible objects. Do not simply limit it to attachments. It’s very useful for advanced searching and many other areas. What we want to do first is set up some CSS, so take a look:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | a img { border: 0; outline: 0; /*no firefox dotted border*/ } body { font-family: "Lucida Grande", Arial, Sans-Serif; } input,label,img { display: inline; vertical-align: middle; } .attachment { margin-bottom: 5px; } |
Some quick notes. I always use this a img selector in any site or code I make. I just recently learned of this outline property. It will remove the dotted border around images when they are clicked in Firefox. I’ve always hated that about Firefox, but now I can fix it! Anyways, the other things to note are the input,label,img properties, which are a nice way to get all these elements to line up along a vertical center. The other selectors are simple preferences for my example. There isn’t much to this CSS, so let’s move on to some HTML.
1 2 3 4 5 6 7 | <div id="attachment_container"> <input type="hidden" value="1" id="attachment_counter" /> <div id="attachment_1" class="attachment"> <label>Select file #1: </label><input type="file" size="14" id="file_1" name="file_1" /><a href="" onclick="removeAttachmentElement(1);return false;"><img id="RemoveButton_1" src="minusButton.png" onmousedown="this.src='minusButtonDown.png';" onmouseup="this.src='minusButton.png';" alt="Remove" /></a> </div> </div> <a href="" onclick="addAttachmentElement();return false;"><img id="AddButton_1" src="plusButton.png" onmousedown="this.src='plusButtonDown.png';" onmouseup="this.src='plusButton.png';" alt="Add" /></a> |
Let me note here, that if you wanted to not even show an attachment field at start, you could remove that div with id=”attachment_1″. Also, be sure to reduce your counter value to 0. Now, let me walk you through the code. We start with a container div that will hold all of our attachment rows. You will probably want to surround this div in a form element so you can do something with the results the user gives. Inside this div we create a hidden input with a value of 1 (representing how many attachments we have) and give it an id.
Each time we create an attachment row we will create a new div inside this container. We have one here now. Its id is attachment_1 we also assign it to the attachment class. Each of these inner divs will contain a label telling the user what the field is for (in this case Select file #x). It contains the input type that we want. It then has an image of a minus sign (with some mousedown and mouseup effects) wrapped inside of a link tag which will call the removeAttachmentElement() function. We pass in the parameter 1 since this specific attachment is an id of 1.
Finally, outside all of these divs, we have the add button. It’s also a simple image wrapped in a link that calls addAttachmentElement(). Now that we are finished with all of our HTML, we will need to move onto our Javascript that powers all of this.
1 2 3 4 | function removeAttachmentElement(num_id) { var container = document.getElementById('attachment_container'); container.removeChild( document.getElementById('attachment_'+num_id) ); } |
Let’s start with this short code. This will be the code used to remove an attachment div. Line 2 sets our container div to the variable container. We then call the function removeChild() on this container. To it, we pass the div that contains the attachment. In the HTML above, it would be the div with id attachment_1. What we are using here is DOM (Document Object Model) scripting. It allows us to simply remove a child element from the HTML using javascript, immediately rendered in the browser. Now that we have the simple remove code out of the way, let’s get to the adding code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | function addAttachmentElement() { var container = document.getElementById('attachment_container'); var counter = document.getElementById('attachment_counter').value; counter++; document.getElementById('attachment_counter').value = counter; var attachment_div = document.createElement('div'); attachment_div.setAttribute('id','attachment_'+counter); attachment_div.setAttribute('class','attachment'); var attachment_label = document.createElement('label'); attachment_label.innerHTML = "Select file #"+counter+": "; attachment_div.appendChild(attachment_label); var attachment_input = document.createElement('input'); attachment_input.setAttribute('type','file'); attachment_input.setAttribute('size','14'); attachment_input.setAttribute('id','file_'+counter); attachment_input.setAttribute('name','file_'+counter); attachment_div.appendChild(attachment_input); var attachment_a2 = document.createElement('a'); attachment_a2.setAttribute('href',''); attachment_a2.setAttribute('onclick','removeAttachmentElement('+counter+');return false;'); var attachment_img2 = document.createElement('img'); attachment_img2.setAttribute('id','RemoveButton_'+counter); attachment_img2.setAttribute('src','minusButton.png'); attachment_img2.setAttribute('alt','Remove'); attachment_img2.setAttribute('onmousedown',"this.src='minusButtonDown.png';"); attachment_img2.setAttribute('onmouseup',"this.src='minusButton.png';"); attachment_a2.appendChild(attachment_img2); attachment_div.appendChild(attachment_a2); container.appendChild(attachment_div); } |
This function might look a little complex, but it is rather simple. Let’s break it down. The first two lines set up variables that point to our container object and a counter, which will keep track of the number of attachments we have. Line 4 increases the counter and then the 5th line saves that update to our hidden input field. Now we are on to the dynamic DOM code. On line 6 you see document.createElement(‘div’). This function will create a new html object of type div. See, it’s actually really easy. The next two lines set attributes for this div object. Those 3 lines, 6-8 are basically like:
1 | <div id="attachment_#" class="attachment"> |
We are just turning HTML creation into scripting functions. The next 2 lines of code create the label tag. Line 12 then takes that label tag and adds it inside of the attachment_div tag. What lines 6-12 look like in HTML is:
1 2 3 | <div id="attachment_#" class="attachment"> <label>Select the file ## </label> </div> |
This should hopefully start to make sense. The next set of code creates the input button and then adds it also to the attachment_div. The next part of code creates an a tag with the same settings as our first attachment (see the first HTML code section). We then add a child to the a tag. This child is the image of the minus button. Finally, on line 31, we add the a tag (which also includes the image tag) to the attachment_div. And then on line 33, we add this entirely created new div to our container. And it is displayed to the screen. Quite simple, and very efficient.
Well folks, that’s about it to the tutorial. You should now be prepared to create your own GMail-like attachment forms that dynamically update. You should also have a good solid start into DOM scripting. Please let me know if you have any questions, comments, suggestions, or code complaints by leaving a comment. I hope you enjoyed this and look ahead for more tutorials coming soon. You may want to add this blog to your RSS reader by clicking here.
-
ljlj
-
ljlj
-
Pai
-
shihab
-
Rajesh
-
Rajesh
-
Richard
-
Dustin Bachrach
-
Richard
-
Knowledge Chikuse
-
Dustin Bachrach
-
kenny
-
Dustin Bachrach
-
Lenny



