Page 1 of 2
Adding file-fields to form as previously gets filled
Posted: Mon Aug 16, 2004 7:05 am
by vigge89
I'm currently coding a uploader, which should let the user upload multiple files. After the page loads, there should only be one file-field available in the form. When the user have selected a file, another file-field should go visible, so if the user want to upload another file, he should select it in the second field. Maximum number of fields available should be 6, and when the user have selected a file in the sixth box, no file-box should get visible anymore.
The different boxes should have a name which is changed (ie, file1 for box 1, file2 for box 2 and file3 for box 3).
The problem is that I have nearly no knowledge of javascript, and I couldn't find anything like this by searching on google, so i'm asking if someone have got code for this, or if they know a link to some site which shows how to do this (either tutorial or just the script).
Thanks in advance, vigge.
Posted: Mon Aug 16, 2004 7:25 am
by hawleyjr
Try something like this: Its untested but you should be able to get it to work.
//UNTESTED
Code: Select all
<table width="30%" border="0" cellspacing="0" cellpadding="0">
<tr id="trid1" style="visibility:hidden;position:absolute;width:100%;">
<td><input type="file" name="file1" onChange="toggleDiv(1,trid2);"></td>
</tr>
<tr id="trid2" style="visibility:hidden;position:absolute;width:100%;">
<td><input type="file" name="file2" onChange="toggleDiv(1,trid3);"></td>
</tr>
<tr id="trid3" style="visibility:hidden;position:absolute;width:100%;">
<td><input type="file" name="file3"></td>
</tr>
</table>
function toggleDiv(div_id,iState) // 1 visible, 0 hidden
{
if(document.layers) //NN4+
{
document.layersїdiv_id].visibility = iState ? "show" : "hide";
document.layersїdiv_id].position = iState ? "relative" : "absolute";
}
else if(document.getElementById) //gecko(NN6) + IE 5+
{
var obj = document.getElementById(div_id);
obj.style.visibility = iState ? "visible" : "hidden";
obj.style.position = iState ? "relative" : "absolute";
}
else if(document.all) // IE 4
{
document.allїdiv_id].style.visibility = iState ? "visible" : "hidden";
document.allїdiv_id].style.position = iState ? "relative" : "absolute";
}
}
Posted: Mon Aug 16, 2004 8:45 am
by vigge89
is it possible to create the fields on the fly instead? the fields which aren't visible shouldn't have been created yet, so that they dont get submitted.
thanks for the reply btw

Posted: Mon Aug 16, 2004 8:48 am
by hawleyjr
Check out innerHTML this may help. I don't have time to explain further.
Posted: Mon Aug 16, 2004 8:48 am
by vigge89
ok, ill check it out, thanks

Posted: Mon Aug 16, 2004 10:15 am
by vigge89
hmm, i can't find any good guide or example with innerHTML

the one i found just mentioned that you should use DOM instead, i looked it up @ w3c, but I couldn't find any code

Posted: Mon Aug 16, 2004 5:38 pm
by hawleyjr
Code: Select all
function setPrimary(div_id,iState) // 1 visible, 0 hidden
{
if(document.layers) //NN4+
{
document.layersїelemID].innerHTML = text;
}
else if(document.getElementById) //gecko(NN6) + IE 5+
{
document.getElementById(elemID).innerHTML = text;
}
else if(document.all) // IE 4
{
document.all.elemID.innerHTML = text;
}
}
<DIV id='div_id_whatever'> </DIV>
setPrimary('<B>Some HTML Code</b>','div_id_whatever');
Posted: Mon Aug 16, 2004 6:01 pm
by feyd
file fields are read-only.. they cannot be preset with information.
Posted: Tue Aug 17, 2004 4:37 am
by vigge89
feyd wrote:file fields are read-only.. they cannot be preset with information.
nono, that's not want I want to either, i just want another file-box to get created when the first one have been set
Posted: Tue Aug 17, 2004 5:08 am
by CoderGoblin
This is a generic function I use to add new content to an existing document...
Code: Select all
function changeElemContent(elementId,content) {
if(document.implementation &&
document.implementation.hasFeature &&
document.implementation.hasFeature('Range','2.0')) {
// Can use ranges (Netscape 6+)
node = document.getElementById(elementId);
var newRange = document.createRange();
newRange.selectNodeContents(node);
newRange.deleteContents();
var newHTML = newRange.createContextualFragment(content);
node.appendChild(newHTML);
} else {
if(document.getElementById) {
// Process using inner HTML (Explorer 5&6)
document.getElementById(elementId).innerHTML=content;
} else {
// Other generic tries to match other browsers. Do not always work (e.g Netscape 4)
if (document.all) {
document.allїelementId].innerHTML=content;
} else {
if(document.layers) {
with(document.layersїelementId].document) {
open();
write(content);
close();
}
}
}
}
}
}
It needs an existing element with a named id attribute such as..
Code: Select all
<div id="file1"></div>
<div id="file2"></div>
<div id="file3"></div>
Example of insert
Code: Select all
..... onchange="javascript:changeElemContent('file1','<input type=text name="value2" value="">;');
Hope this may be of use...
Posted: Tue Aug 17, 2004 5:15 am
by vigge89
thanks, ill check it out
edit: after alot of tweaking, it works perfectly in Firefox, but not in Internet Explorer
Here's the code i used, there's probably some errors soemwhere, since i've never coded javascript before, so i had to guess myself trough (

):
Code: Select all
<html>
<head>
<script type='text/javascript'>
/* function AddFileField(elementId) */
function AddFileField(elementId) {
if(document.implementation && document.implementation.hasFeature && document.implementation.hasFeature('Range','2.0')) {
var newId = elementId + 1;
elementId = 'file'+elementId;
// Can use ranges (Netscape 6+)
node = document.getElementById(elementId);
var newRange = document.createRange();
newRange.selectNodeContents(node);
newRange.deleteContents();
var newFileHtml = "<input type='file' name='"+elementId+"' onchange='javascript:AddFileField("+newId+");' />";
var newHTML = newRange.createContextualFragment(newFileHtml);
node.appendChild(newHTML);
} else {
if(document.getElementById) {
// Process using inner HTML (Explorer 5&6)
document.getElementById(elementId).innerHTML=newFileHtml;
} else {
// Other generic tries to match other browsers. Do not always work (e.g Netscape 4)
if (document.all) {
document.allїelementId].innerHTML=newFileHtml;
} else {
if(document.layers) {
with(document.layersїelementId].document) {
open();
write(newFileHtml);
close();
}
}
}
}
}
}
</script>
</head>
<body>
<form enctype='multipart/form-data' action='file.php' method='post'>
<div id='file0'><input type='file' name='file0' onchange='javascript:AddFileField(1);' /></div>
<div id='file1'>File 1</div>
<div id='file2'>File 2</div>
<div id='file3'>File 3</div>
<input type='submit' value='upload!' />
</form>
<?php
if ($_FILES) {
foreach ($_FILES as $key => $value) {
echo "<br />{$valueї'name']}";
}
}
?>
Does anyone know why it doesn't work in IE, nothing happens when i select a file in the first field
Thanks again.
Posted: Tue Aug 17, 2004 6:36 am
by CoderGoblin
Do you get a little triangle box on IE indicating an error ?. If you click on it it should provide more information..
Playing on LINUX at present so cannot check it out on IE.
Posted: Tue Aug 17, 2004 6:37 am
by vigge89
no error or anything, and it appears that it doesn't work for another guy using Firefox 0.8, could anyone try it out?
http://vigge.ath.cx
Posted: Tue Aug 17, 2004 6:48 am
by CoderGoblin
Your code works on my Firebird 0.7.
Stupid question but have you enabled javascript for the browsers that are not working ?
To help debugging try putting in some additional code into javascript "alert('I am here');" will bring a box up saying what is in the quote. That may help you track down the problem...
Posted: Tue Aug 17, 2004 7:23 am
by CoderGoblin
Just as a point of interest does your onchange event get called...
To check instead of calling the function try onchange="javascript:alert('Need Change');"
I have noticed that on Konquerer browser it doesn't get called
