hi there

if you look at the output of my first code or "instance". once a option is selected in the checkbox, the cell next to that cell changes and presents a form to the user, or input field based on the selected option... so in essence this is ONE instance of a Question..

the problem is that i want to ADD another question below that, I can add another row with a dropdownbox, BUT i do not know how to go further and let it act onchange and generate form like above mentioned...please help

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script>
function addRowToTable()
{
  var tbl = document.getElementById('tblSample');
  var lastRow = tbl.rows.length;
  // if there's no header row in the table, then iteration = lastRow + 1
  var iteration = lastRow;
  var row = tbl.insertRow(lastRow);
  
  // left cell
  var cellLeft = row.insertCell(0);
  var textNode = document.createTextNode("Question " + iteration);
  cellLeft.appendChild(textNode);
  
  // middle cell
  var cellMiddle = row.insertCell(1);
  var oSelect=document.createElement("select");
  oSelect.setAttribute('name','numflowers' + iteration);
  oSelect.setAttribute('id', 'numflowers' + iteration);
 
  
  var oOption4 = document.createElement("OPTION");
  var t = document.createTextNode("");
  oOption4.setAttribute("value", "4");
   oOption4.setAttribute("id", "divColor4");
  oOption4.appendChild(t);
  oSelect.appendChild(oOption4);
  
  var oOption = document.createElement("OPTION");
  var t = document.createTextNode("Short Question");
  oOption.setAttribute("value", "1");
  oOption.setAttribute("id", "divColor1");
  oOption.appendChild(t);
  oSelect.appendChild(oOption);
  
  var oOption1 = document.createElement("OPTION");
  var t = document.createTextNode("Long Question");
  oOption1.setAttribute("value", "2");
   oOption1.setAttribute("id", "divColor2");
  oOption1.appendChild(t);
  oSelect.appendChild(oOption1);
  
  var oOption2 = document.createElement("OPTION");
  var t = document.createTextNode("Multiple Question");
  oOption2.setAttribute("value", "3");
   oOption2.setAttribute("id", "divColor3");
  oOption2.appendChild(t);
  oSelect.appendChild(oOption2);
  
  var oOption3 = document.createElement("OPTION");
  var t = document.createTextNode("True / False");
  oOption3.setAttribute("value", "TF");
   oOption3.setAttribute("id", "divColor1");
  oOption3.appendChild(t);
  oSelect.appendChild(oOption3);
  
  cellMiddle.appendChild(oSelect);
  
  //cell Right
   var cellRight = row.insertCell(2);
  var textNode1 = document.createTextNode();
  cellRight.appendChild(textNode1);
}
function keyPressTest(e, obj)
{
  var validateChkb = document.getElementById('chkValidateOnKeyPress');
  if (validateChkb.checked) {
    var displayObj = document.getElementById('spanOutput');
    var key;
    if(window.event) {
      key = window.event.keyCode; 
    }
    else if(e.which) {
      key = e.which;
    }
    var objId;
    if (obj != null) {
      objId = obj.id;
    } else {
      objId = this.id;
    }
    displayObj.innerHTML = objId + ' : ' + String.fromCharCode(key);
  }
}
function removeRowFromTable()
{
  var tbl = document.getElementById('tblSample');
  var lastRow = tbl.rows.length;
  if (lastRow > 2) tbl.deleteRow(lastRow - 1);
}

function ShowMenu(num, menu, max)
{
                //num is selected value, menu is the name of the div, max is the number of divs
                for(i = 1; i <= max; i++){
                        //add number onto end of menu
                        var menu_div = menu + i;

                        //if current show
                        if(i == num) {
                                document.getElementById(menu_div).style.display = 'block';
                        } else {
                                //if not, hide
                                document.getElementById(menu_div).style.display = 'none';
                        }
                }



        }
</script>

</head>
<body>
<h3>Create Test Form</h3>
<form action="tableaddrow_nw.html" method="get">

<p style="border: 5px solid #000; width: 500px; height:100px; padding: 3px;">
<span id="spanOutput">sss </span>
</p>
<table border="1" id="tblSample" width="900px">
  <tr>
    <th colspan="3">Sample table</th>
  </tr>
  <tr>
    <td width="70px">Question 1</td><td width="100px">
<form action="processorder.php" method="post">
<select id='numflowers' 
onChange="javascript: ShowMenu(document.getElementById('numflowers').value,'divColor', 4);">
        <option value='0'>Choose Type of Question
        <option value='1'>Short Question
        <option value='2'>Long Question
        <option value='3'>Mutiple Choice
        <option value='4'>True / False
       

</select>

</td><td width="730px">
<div id='divColor1' style="display: none; background-color:#06C; padding:5px; " >
                <p>Question: <input type="text" name="color1" value=""/></p>
                <p>
                Possible Answers: 
                <input type="text" name="color1" value=""/>
                 <input type="text" name="color1" value=""/>
                  <input type="text" name="color1" value=""/>
                </p>
                
</div>

<div id='divColor2' style="display: none;">
                               <p>Question: <textarea name="color2" value="" cols="70" rows="10"></textarea>
                               </p>
</div>

<div id='divColor3' style="display: none;">
                Mutiple Choice:<br><br>
                <input type="radio" name="color3" value="">Red<br>
                <input type="radio" name="color3" value="">White<br>
                <input type="radio" name="color3" value="">Yellow<br>
</div>

<div id='divColor4' style="display: none;">
                Choose type of flower 4:<br><br>
                <input type="radio" name="color4" value="red">Red<br>
                <input type="radio" name="color4" value="white">White<br>
                <input type="radio" name="color4" value="yellow">Yellow<br>
</div>


<br>

</form></td></tr>
</table>
<input type="button" value="Add" onclick="addRowToTable();" />
<input type="button" value="Remove" onclick="removeRowFromTable();" />
</form>
</body>
</html>

Recommended Answers

All 6 Replies

You can't nest <form> elements. If one <form> is started, then you must close it before adding a new form.

As far as onChange, you have it almost correct. Your only problem is that you included javascript: in the front of your code execution. The onChange event is similar to other events such as onClick -- it is not a URL execution but a direct JavaScript execution.

Try this:

<select onChange="ShowMenu(document.getElementById('numflowers').value,'divColor', 4);">

Hoektoe,

I was about to post, "it's easy, create a prototype in HTML, then clone it" but then I decided to try it out.

The concept is easy but the reality a bit harder as you need to renumber all id and name attributes to ensure they are unique. And then you have to make sure everything renumbers ok when a row is deleted.

I would talk you through the changes but they are numerous and moderately complex . Now that it's written, it's much easier to post the code.

It should be much easier to maintain now as an HTML prototype is much easier to work with than many lines of document.createElement() etc. The javascript has been written to cater for foreseeable eventualities within the prototype, as long as you stay within a table wrapper. Just amend the HTML prototype to make your question types exactly as you want them.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Airshow :: untitled</title>
<script>
function addRowToTable(tableId, protoId){
	var targetTable = document.getElementById(tableId);
	if(!targetTable) {
		alert('Target table not found.');
		return false;
	}
	var proto = document.getElementById(protoId);
	if(!proto) {
		alert('Question prototype not found.');
		return false;
	}
	var c = proto.cloneNode(true);
	targetTable.appendChild(c);
	renumber(targetTable);
}
function renumber(targetTable){
	var qBlocks = targetTable.childNodes;
	for(var i=0; i<qBlocks.length; i++){
		if(qBlocks[i].id == 'questionBlock' || qBlocks[i].baseId == 'questionBlock') { renumberIt(qBlocks[i], i); }
		var q = document.getElementById('qNumber_'+i);
		if(q) { q.innerHTML = i; }
	}
}
function renumberIt(targetElement, n){
	if(targetElement.nodeType != 1) { return; }
	if(targetElement.id) {
		if(!targetElement.baseId) { targetElement.baseId = targetElement.id; }
		targetElement.id = targetElement.baseId + '_' + n;
	}
	if(targetElement.name) {
		if(!targetElement.baseName) { targetElement.baseName = targetElement.name; }
		targetElement.name = targetElement.baseName + '_' + n;
	}
	if(targetElement.className == 'q_Control') { targetElement.n = n; }
	if(targetElement.className == 'b_remove') { targetElement.n = n; }
	var ch = targetElement.childNodes;
	for(var i=0; i<ch.length; i++){
		renumberIt(ch[i], n);//drilldown with a recursive call.
	}
}
function remove(button){
	var q = document.getElementById('questionBlock' + '_' + button.n);
	var t = q.parentNode;
	if(q) { q.parentNode.removeChild(q); }
	if(t && t.tagName.toUpperCase() == 'TABLE') { renumber(t); }
}
function showMenu(menu) {
	var n = menu.n;
	var val = menu.options[menu.selectedIndex].value;
	for(i=0; i<=4; i++) {
		var div = document.getElementById('qType' + i + '_' + n);
		if(div){
			if(i==val) { div.style.display = 'block'; }
			else { div.style.display = 'none'; }
		}
	}
}
</script>

</head>
<body>
<h3>Create Test Form</h3>
<form action="tableaddrow_nw.html" method="get">

<p style="border:5px solid #000; width:500px; height:100px; padding:3px;"><span id="spanOutput">sss </span></p>

<!-- start : hidden Prototype  -->
<table style="display:none;">
<tbody id="questionBlock" class="questionBlock">
<tr>
<td width="70px">Question&nbsp;<span id="qNumber"></span></td>
<td width="100px">
<select id='q_Control' class="q_Control" onchange="showMenu(this)">
	<option value='0'>Choose Type of Question
	<option value='1'>Short Question
	<option value='2'>Long Question
	<option value='3'>Mutiple Choice
	<option value='4'>True / False
</select>
</td>
<td width="730px">
<div id='qType0'><input class="b_remove" type="button" value="Remove" onclick="remove(this)"></div>
<div id='qType1' style="display: none; background-color:#06C; padding:5px;">
	<p>Question: <input type="text" name="color1" value=""/></p>
	<p>Possible Answers:
	<input type="text" name="color1" value=""/>
	<input type="text" name="color1" value=""/>
	<input type="text" name="color1" value=""/>
	</p>
</div>
<div id='qType2' style="display: none;">
	<p>Question: <textarea name="color2" value="" cols="70" rows="10"></textarea></p>
</div>
<div id='qType3' style="display: none;">
	Mutiple Choice:<br><br>
	<input type="radio" name="color3" value="">Red<br>
	<input type="radio" name="color3" value="">White<br>
	<input type="radio" name="color3" value="">Yellow<br>
	</div>
<div id='qType4' style="display: none;">
	Choose type of flower 4:<br><br>
	<input type="radio" name="color4" value="red">Red<br>
	<input type="radio" name="color4" value="white">White<br>
	<input type="radio" name="color4" value="yellow">Yellow<br>
</div>
</td>
</tr>
</tbody>
</table>
<!-- end : hidden Prototype  -->

<form action="processorder.php" method="post">
<table border="1" id="tblSample" width="900px">
<tbody><tr><th colspan="3">Sample table</th></tr></tbody>
</table>
</form>
<input type="button" value="Add" onclick="addRowToTable('tblSample', 'questionBlock');" />
</form>
</body>
</html>

Give it a try. I hope I'm not too far off the mark.

Airshow

WOW, i did get bit further last nite, by getting onchange to work, but not completely like you did airshow.

Airshow thank you so MUCH is exactly what i wanted as the id's should be unique as im going to insert these question value into an database now... thanx really for the help as my knowledge of javascript is fairly limited as im more php orientated... but im definately gonna have a indepth look at your code.

itsjareds, i took airshow prototype code and unnested the forms, may i ask why you can't nest forms, just for interest.. now that you have mentioned it, it does sound silly to nest forms.

Hoektoe,

You'll see that names as well as ids get renumbered.

Unique ids are critical for the javascript to work properly, whilst names will be important server side as they determine the elements you pick up in $_POST.

The renumbering rules are very simple. The id/name in the prototype are all appended with _n where n is the number of the question. n is itself determined dynamically as questions are added/removed to give sequentially numbered questions starting at 1. The renumbering rule is manifest in four places; in renumberIt() (x2), remove(), and showMenu(). n is therefore not a unique ID (uid) that you could use for storeage/retreival of the questions from a database. If this is an issue, then you might consider moving the whole prototype HTML server-side and delivering it with AJAX in lieu of clone(). That's what I would do. Then you can also use the prototype for building the page server-side when re-presenting questions retreived from a database. In both cases (new and retreived question), uid can be put into a hidden form field for each question such that it will be sent back to the server in the POST. This could be achieved with only fairly light mods to my javascript.

Probably as clear as mud but I think I know what I mean.

Hope this sheds a little light. Please ask if you need help penetrating my code/ideas further.

Airshow

sorry to bother again, i would like to know if this is possible and if you could help me with just short question inserting into database, in the submit () i have kinda explained what i need to continue..thanx

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Airshow :: untitled</title>
<script>
function doallthese()
{
 addRowToTable('tblSample', 'questionBlock');

 
}
submit ()
{
	//get number of rows
	
	
	//start loop of rows
	
	//check type of quiestion , qType1_ =short, qType2_ =long, qType3_ =multiple, qType4_ = TF 
	//each new question gets value after qType1_* ,  where * is question number ####### 
	
	//if statements for each type
	//when type is mathced to one use preset php insert quesry into database
	//if (##### = qType1_) 
	//{(stud_id, mod_id )VALUES ( '$name' ,'$value')
		//<php INSERT INTO question (test_id, que_type, que_mark ) VALUES ('watever','short','short_mark');
		//	<php INSERT INTO que_short (test_id, short_q, que_text1, que_text2, que_text3 ) VALUES ('watever','short_q','que_text1', 'que_text2', 'que_text3');
		
	//}
	
	//end
	//stop when all rows have been inserted
}
function addRowToTable(tableId, protoId){
	var targetTable = document.getElementById(tableId);
	if(!targetTable) {
		alert('Target table not found.');
		return false;
	}
	var proto = document.getElementById(protoId);
	if(!proto) {
		alert('Question prototype not found.');
		return false;
	}
	var c = proto.cloneNode(true);
	targetTable.appendChild(c);
	renumber(targetTable);
}
function renumber(targetTable){
	var qBlocks = targetTable.childNodes;
	for(var i=0; i<qBlocks.length; i++){
		if(qBlocks[i].id == 'questionBlock' || qBlocks[i].baseId == 'questionBlock') { renumberIt(qBlocks[i], i); }
		var q = document.getElementById('qNumber_'+i);
		if(q) { q.innerHTML = i; }
	}
}
function renumberIt(targetElement, n){
	if(targetElement.nodeType != 1) { return; }
	if(targetElement.id) {
		if(!targetElement.baseId) { targetElement.baseId = targetElement.id; }
		targetElement.id = targetElement.baseId + '_' + n;
	}
	if(targetElement.name) {
		if(!targetElement.baseName) { targetElement.baseName = targetElement.name; }
		targetElement.name = targetElement.baseName + '_' + n;
	}
	if(targetElement.className == 'q_Control') { targetElement.n = n; }
	if(targetElement.className == 'b_remove') { targetElement.n = n; }
	var ch = targetElement.childNodes;
	for(var i=0; i<ch.length; i++){
		renumberIt(ch[i], n);//drilldown with a recursive call.
	}
}
function remove(button){
	var q = document.getElementById('questionBlock' + '_' + button.n);
	var t = q.parentNode;
	if(q) { q.parentNode.removeChild(q); }
	if(t && t.tagName.toUpperCase() == 'TABLE') { renumber(t); }
}
function showMenu(menu) {
	var n = menu.n;
	var val = menu.options[menu.selectedIndex].value;
	for(i=0; i<=4; i++) {
		var div = document.getElementById('qType' + i + '_' + n);
		if(div){
			if(i==val) { div.style.display = 'block'; }
			else { div.style.display = 'none'; }
		}
	}
}
</script>

</head>
<body>
<form action="processorder.php" method="post">
<table border="1" id="tblSample" width="900px">
<tbody><tr><th colspan="3">Question Paper</th></tr></tbody>
</table>
<input type="button" value="Submit" onclick="submit();" />
</form>
<form action="tableaddrow_nw.html" method="get">

<!-- start : hidden Prototype  -->
<table style="display:none;">
<tbody id="questionBlock" class="questionBlock">
<tr>
<td width="70px">Question&nbsp;<span id="qNumber"></span></td>
<td width="100px">
<select id='q_Control' class="q_Control" onchange="showMenu(this)">
	<option value='0'>Choose Type of Question
	<option value='1'>Short Question
	<option value='2'>Long Question
	<option value='3'>Mutiple Choice
	<option value='4'>True / False
</select>
</td>
<td width="730px">
<div id='qType0'><input class="b_remove" type="button" value="Remove" onclick="remove(this)"></div>
<div id='qType1' style="display: none; background-color:#06C; padding:5px;">
	<p>Question: <input type="text" name="short_q" value=""/></p>
	<p>Possible Answers:
	<input type="text" name="short_p1" value=""/>
	<input type="text" name="short_p2" value=""/>
	<input type="text" name="short_p3" value=""/></p>
    <p>Points: <input type="text" name="short_mark" value=""/>
	</p>
</div>
<div id='qType2' style="display: none;">
	<p>Question: <textarea name="long_q" value="" cols="70" rows="10"></textarea></p>
    <p>Points: <input type="text" name="long_mark" value=""/>
	</p>
</div>
<div id='qType3' style="display: none;">
	Correct Answer:<br/> <input type="text" name="multiple_ans" value=""/><br/>
    Incorrect Answers:<br/>	 <input type="text" name="multiple_incorrect1" value=""/>	<br/>
	<input type="text" name="multiple_incorrect2" value=""/><br/>
	<input type="text" name="multiple_incorrect3" value=""/><br/>
     <p>Points: <input type="text" name="multiple_incorrect4" value=""/>
	</p>
	</div>
<div id='qType4' style="display: none;">
	Question:<br/> <input type="text" name="true_false_que" value=""/><br/>
	<input type="radio" name="TF_ans" value="True">True<br>
	<input type="radio" name="TF_ans" value="False">False<br>
     <p>Points: <input type="text" name="color5" value=""/>
	</p>
</div>
</td>
</tr>
</tbody>
</table>
<!-- end : hidden Prototype  -->


<input type="button" value="Add" onclick="doallthese();" />

</form>

</body>
</html>
CREATE TABLE IF NOT EXISTS `question` (
  `que_id` int(5) NOT NULL,
  `test_id` varchar(5) NOT NULL,
  `que_type` varchar(5) NOT NULL,
  `que_mark` varchar(3) NOT NULL,
  PRIMARY KEY  (`que_id`)
)

CREATE TABLE IF NOT EXISTS `question_short` (
  `que_id` int(5) NOT NULL,
  `short_q_` varchar(500) NOT NULL,
  `que_text1` varchar(500) NOT NULL,
`que_text2` varchar(500) NOT NULL,
`que_text3` varchar(500) NOT NULL,
  PRIMARY KEY  (`que_id`)
)

Hoektoe,

I realised all this might be a but tricky.

Before trying to dive into the details of the code, you need to address a macroscopic issue - what do you want to present to the user after saving questions to database? As I see it, two main choices:

  1. Go to another page (eg short feedback message with a meta-refresh to go some place eles after a short delay)
  2. Display feedback message on same page

For (1) we simply submit the form and let a server-side script handle the save then serve up whatever HTML the user needs to see (complete with a meta-refresh if that's what you want).

For (2) we can do similar to (1) and re-serve the same page, or we can use Ajax, though I would recommend developing the php as a non-Ajax script initially - with a mind to calling it Ajax-wise eventually. In my limited experience of Ajax, this is easier than going straight to Ajax though folks with more Ajax experience may be able to advise differently (and I would be very interested to learn best practise).

I'm a bit too busy on something else to get into this any deeper right now. It may be a couple of days before I get back here. In the meantime, your pseudo-code looks good (I often write pseudo-code to get a function started) and maybe someone else will be able to pick it up before I get back here.

Airshow

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.