Adding file-fields to form as previously gets filled

JavaScript and client side scripting.

Moderator: General Moderators

User avatar
vigge89
Forum Regular
Posts: 875
Joined: Wed Jul 30, 2003 3:29 am
Location: Sweden

Adding file-fields to form as previously gets filled

Post 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.
User avatar
hawleyjr
BeerMod
Posts: 2170
Joined: Tue Jan 13, 2004 4:58 pm
Location: Jax FL & Spokane WA USA

Post 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
&#123;
		if(document.layers)	 //NN4+
		&#123;
		 document.layers&#1111;div_id].visibility = iState ? "show" : "hide";
		 document.layers&#1111;div_id].position = iState ? "relative" : "absolute";
		 
		&#125;
		else if(document.getElementById)	 //gecko(NN6) + IE 5+
		&#123;
			var obj = document.getElementById(div_id);
			obj.style.visibility = iState ? "visible" : "hidden";
			obj.style.position = iState ? "relative" : "absolute";
		&#125;
		else if(document.all)	// IE 4
		&#123;
			document.all&#1111;div_id].style.visibility = iState ? "visible" : "hidden";
			document.all&#1111;div_id].style.position = iState ? "relative" : "absolute";
			
		&#125;
&#125;
User avatar
vigge89
Forum Regular
Posts: 875
Joined: Wed Jul 30, 2003 3:29 am
Location: Sweden

Post 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 :)
User avatar
hawleyjr
BeerMod
Posts: 2170
Joined: Tue Jan 13, 2004 4:58 pm
Location: Jax FL & Spokane WA USA

Post by hawleyjr »

Check out innerHTML this may help. I don't have time to explain further.
User avatar
vigge89
Forum Regular
Posts: 875
Joined: Wed Jul 30, 2003 3:29 am
Location: Sweden

Post by vigge89 »

ok, ill check it out, thanks :)
User avatar
vigge89
Forum Regular
Posts: 875
Joined: Wed Jul 30, 2003 3:29 am
Location: Sweden

Post 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 :(
User avatar
hawleyjr
BeerMod
Posts: 2170
Joined: Tue Jan 13, 2004 4:58 pm
Location: Jax FL & Spokane WA USA

Post by hawleyjr »

Code: Select all

function setPrimary(div_id,iState) // 1 visible, 0 hidden 
&#123; 
if(document.layers)	 //NN4+
 &#123;
 document.layers&#1111;elemID].innerHTML = text;
 &#125;
 else if(document.getElementById)	 //gecko(NN6) + IE 5+
 &#123;
 document.getElementById(elemID).innerHTML = text;

 &#125;
 else if(document.all)	// IE 4
 &#123;
 document.all.elemID.innerHTML = text;
 &#125;
&#125;

<DIV id='div_id_whatever'>&nbsp;</DIV>


setPrimary('<B>Some HTML Code</b>','div_id_whatever');
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

file fields are read-only.. they cannot be preset with information.
User avatar
vigge89
Forum Regular
Posts: 875
Joined: Wed Jul 30, 2003 3:29 am
Location: Sweden

Post 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
User avatar
CoderGoblin
DevNet Resident
Posts: 1425
Joined: Tue Mar 16, 2004 10:03 am
Location: Aachen, Germany

Post by CoderGoblin »

This is a generic function I use to add new content to an existing document...

Code: Select all

function changeElemContent(elementId,content) &#123;
  if(document.implementation &&
    document.implementation.hasFeature &&
    document.implementation.hasFeature('Range','2.0')) &#123;

    // 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);

  &#125; else &#123;
    if(document.getElementById) &#123;
      // Process using inner HTML (Explorer 5&6)
      document.getElementById(elementId).innerHTML=content;
    &#125; else &#123;
      // Other generic tries to match other browsers. Do not always work (e.g Netscape 4)
      if (document.all) &#123;
        document.all&#1111;elementId].innerHTML=content;
      &#125; else &#123;
        if(document.layers) &#123;
          with(document.layers&#1111;elementId].document) &#123;
            open();
            write(content);
            close();
          &#125;
        &#125;
      &#125;
    &#125;
  &#125;
&#125;
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...
User avatar
vigge89
Forum Regular
Posts: 875
Joined: Wed Jul 30, 2003 3:29 am
Location: Sweden

Post by vigge89 »

thanks, ill check it out :D

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 ( :P ):

Code: Select all

<html>

<head>

<script type='text/javascript'>
/* function AddFileField(elementId) */
function AddFileField(elementId) &#123;
if(document.implementation && document.implementation.hasFeature && document.implementation.hasFeature('Range','2.0')) &#123;
	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);

&#125; else &#123;

	if(document.getElementById) &#123;
		// Process using inner HTML (Explorer 5&6)
		document.getElementById(elementId).innerHTML=newFileHtml;
	&#125; else &#123;
		// Other generic tries to match other browsers. Do not always work (e.g Netscape 4)
		if (document.all) &#123;
			document.all&#1111;elementId].innerHTML=newFileHtml;
		&#125; else &#123;
			if(document.layers) &#123;
				with(document.layers&#1111;elementId].document) &#123;
					open();
					write(newFileHtml);
					close();
				&#125;
			&#125;
		&#125;
	&#125;
&#125;
&#125;
</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) &#123;

foreach ($_FILES as $key => $value) &#123;
	echo "<br />&#123;$value&#1111;'name']&#125;";
&#125;

&#125;

?>
Does anyone know why it doesn't work in IE, nothing happens when i select a file in the first field :(

Thanks again.
User avatar
CoderGoblin
DevNet Resident
Posts: 1425
Joined: Tue Mar 16, 2004 10:03 am
Location: Aachen, Germany

Post 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.
User avatar
vigge89
Forum Regular
Posts: 875
Joined: Wed Jul 30, 2003 3:29 am
Location: Sweden

Post 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
User avatar
CoderGoblin
DevNet Resident
Posts: 1425
Joined: Tue Mar 16, 2004 10:03 am
Location: Aachen, Germany

Post 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...
User avatar
CoderGoblin
DevNet Resident
Posts: 1425
Joined: Tue Mar 16, 2004 10:03 am
Location: Aachen, Germany

Post 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 8O
Post Reply