Getting .value with .onchange in IE

Hi,
The following code works in both Firefox and Chrome but I get errors in IE.
In my HTML I have a select form with id=‘exam’

                                             <td class="left">                         
                                                <select name="exam" id="exam" style="background-color: #FFDDF4">
                                                    <option></option>
                                                     <?php foreach($exams as $key=>$option):
                                                           echo "<option value='$key'>$option</option>";
                                                      endforeach; ?>
                                                </select></td>

Then in JS I get this element using,

document.getElementById('exam').onchange = callFunctions;

this function calls another function and then I try to use exam.value like this,

function subjectHandler() {
    var subjectArray = [];
    var a = true;
    document.getElementById('subjectText').innerHTML = "";
    document.getElementById('subjectText').innerHTML = "Subject:...";
    document.getElementById('subject').innerHTML = "";
    console.log("testing times");
    if(exam.value=="AS"){
        subjectArray = <?php echo json_encode($ASsubjects, JSON_PRETTY_PRINT); ?>;        
    }else if(exam.value=="A2"){
        subjectArray = <?php echo json_encode($A2subjects, JSON_PRETTY_PRINT); ?>;
    }else if(exam.value=="GCSE"){............

But IE gives me this error,

Why does this not work in IE and is there any way around it?
Thanks

add

var exam = document.getElementById('exam');

inside the function (before you test the conditions).

1 Like

Brilliant that works. A lot of relief!!! I thought all the work that I had done would now not work in IE because I haven’t been checking it as I went.
Massive thanks for your help.
Shane

as a rule of thumb, you should never rely on (implicit) global variables (that are not ensured by a JavaScript API).

1 Like

Hi,
I am having a similar problem again, but this is a little more complicated and i am not sure how to solve it.
HTML checkbox form,

                                        <tr>                    
                                          <?php foreach($examSearch as $searchExam): ?>
                                               <td class="left"><input type="checkbox" class="year" id="<?php htmlout($searchExam['name']); ?>" name="exams[]" value="<?php htmlout($searchExam['name']); ?>">
                                            <?php htmlout($searchExam['name']); ?></td>
                                          <?php endforeach; ?>
                                      </tr>

Then the JS

var checkboxes = document.getElementsByClassName('year');
    for(var index in checkboxes){
        //bind event to each checkbox
        checkboxes[index].onchange = examTables;
    }

And although there is no error in IE’s development tools, I am sure the

var exam = this.value; 

doesn’t work.

var cellsAcross = 4;//number of cells across to display in creation of search tables
var pos = {};
var state = {};
var exist = {};
var years = {};
var yr = {};
var subjects = {};
var subs = {};
<?php foreach($exams as $element): ?>
type = <?php echo json_encode($element); ?>;
state[type] = false;
exist[type] = false;
<?php endforeach; ?>

function examTables(){
var exam = this.value;

if(!state[exam]){//if exam is checked or unchecked state must be changed
    state[exam] = true;
}else if(state[exam]){
    state[exam] = false;
    exist[exam];//if exam is not checked it might as well not exist
    //this means there will be no situation where the item is unchecked and exists
}

Thanks

please post the JavaScript as received in the browser. (=> view Source).

besides that, what do you need the state and exist objects for? chances are that the whole construct is unnecessary.

Hi,
The browser source in IE is,

<html lang="en"><head>
		<!-- <script src="/cuislegibney/js/searchJavaScript.js"></script> -->
	    <link href="/cuislegibney/css/stylesheet.css" rel="stylesheet" type="text/css">
	    <meta charset="utf-8">
	    <title>Search</title>
  	</head>
  	<body>
  	<link href="http://www.cuislegibney.com/cuislegibney/images/favicon.ico" rel="icon" type="image/x-icon">
  	<header>
  	<h1>Results archive</h1>
  	</header>
  	<!-- -->
		<div class="input">
			<p><a href="/cuislegibney">Return to Main Menu</a> ⇒ <a href="/cuislegibney/admin/authors/">Admin</a> ⇒ <a href="/cuislegibney/admin/input/?input">Input</a> ⇒ <a href="/cuislegibney/admin/search/?search">Refresh</a></p>
		  	<!-- <form action="?searchResults" method="post"> -->
		  	<form action="?" method="post" autocomplete="off">
			  	<input name="action" type="hidden" value="searchResults">
			  	<input type="submit" value="Submit"> 
				<fieldset>
					<legend>Search</legend>
					<table>
						<tbody id="examTypes">
							<tr>
								<td>
									<table class="inner" id="searchTable">
									 	<tbody><tr><th>Exam Type:</th><th></th><th></th><th></th><th></th><th></th><th></th><th></th>
									 	<tr>					
									  											   	<td class="left"><input name="exams[]" class="year" id="AS" type="checkbox" value="AS">
											AS</td>
									  											   	<td class="left"><input name="exams[]" class="year" id="A2" type="checkbox" value="A2">
											A2</td>
									  											   	<td class="left"><input name="exams[]" class="year" id="GCSE" type="checkbox" value="GCSE">
											GCSE</td>
									  											   	<td class="left"><input name="exams[]" class="year" id="AP" type="checkbox" value="AP">
											AP</td>
									  											   	<td class="left"><input name="exams[]" class="year" id="KET" type="checkbox" value="KET">
											KET</td>
									  											   	<td class="left"><input name="exams[]" class="year" id="PET" type="checkbox" value="PET">
											PET</td>
									  											   	<td class="left"><input name="exams[]" class="year" id="FCE" type="checkbox" value="FCE">
											FCE</td>
									  											   	<td class="left"><input name="exams[]" class="year" id="IELTS" type="checkbox" value="IELTS">
											IELTS</td>
									  										  </tr>
									</tbody></table>
								</td>
							</tr>
						</tbody>
					</table>
					<table id="studentNames">
						<tbody>
							<tr>
								<td>
									<table class="inner">
										<tbody><tr><th class="left">Student:</th><th></th>
										<tr>
											<td class="left">
												First name: <input name="last" id="firstname" onkeyup="checkStudent()" type="text" placeholder="first name">
											</td>
											<td class="left">
												Last name: <input name="first" id="lastname" onkeyup="checkStudent()" type="input" placeholder="last name">
											</td>
										</tr>		
									</tbody></table>	
								</td>
							</tr>
						</tbody>
					</table>
					<table>
						<tbody id="searchOptions">
						</tbody>
					</table>
				</fieldset>
				<input type="submit" value="Submit">
			</form>
		</div>
		<script language="javascript" type="text/javascript">

var cellsAcross = 3;//number of cells across to display in creation of search tables
var pos = {};
var state = {};
var exist = {};
var years = {};
var yr = {};
var subjects = {};
var subs = {};
type = "AS";
state[type] = false;
exist[type] = false;
type = "A2";
state[type] = false;
exist[type] = false;
type = "GCSE";
state[type] = false;
exist[type] = false;
type = "AP";
state[type] = false;
exist[type] = false;
type = "KET";
state[type] = false;
exist[type] = false;
type = "PET";
state[type] = false;
exist[type] = false;
type = "FCE";
state[type] = false;
exist[type] = false;
type = "IELTS";
state[type] = false;
exist[type] = false;

function examTables(){
var exam = this.value;

if(!state[exam]){//if exam is checked or unchecked state must be changed
	state[exam] = true;
}else if(state[exam]){
	state[exam] = false;
	exist[exam];//if exam is not checked it might as well not exist
	//this means there will be no situation where the item is unchecked and exists
}

for(var item in state)//iterate through state to create exist[]
{
	if(state[item]){//only concerned with the states that are true
					other = "AS";
			if(item == other) 
			{
									exist[item] = true;
				;
				//the test for exist needs to be state true first so no if else needed here
			}
					other = "A2";
			if(item == other) 
			{
									exist[item] = true;
				;
				//the test for exist needs to be state true first so no if else needed here
			}
					other = "GCSE";
			if(item == other) 
			{
									exist[item] = true;
				;
				//the test for exist needs to be state true first so no if else needed here
			}
					other = "AP";
			if(item == other) 
			{
				;
				//the test for exist needs to be state true first so no if else needed here
			}
					other = "KET";
			if(item == other) 
			{
									exist[item] = true;
				;
				//the test for exist needs to be state true first so no if else needed here
			}
					other = "PET";
			if(item == other) 
			{
									exist[item] = true;
				;
				//the test for exist needs to be state true first so no if else needed here
			}
					other = "FCE";
			if(item == other) 
			{
									exist[item] = true;
				;
				//the test for exist needs to be state true first so no if else needed here
			}
					other = "IELTS";
			if(item == other) 
			{
									exist[item] = true;
				;
				//the test for exist needs to be state true first so no if else needed here
			}
		;
	}else{
		exist[item] = false;
	}
}

function position(){/*assigns position of row and column to the subjects*/
	var pos = {}, i = 0, j = 0;
		for(var prop in state){
			if(exist[prop])
			{
				pos[prop] = {r:i, c:j};
				/*if(j%3 == 2)*/
				if(j%cellsAcross == cellsAcross-1)
				{
					i++;
					j=0;
				} else {
					j++;
				}
			}
		}
	return pos;
}

function result(){ /*get subjects in DB for checked states, for those that exist*/
	var resultArray = [];
	var subjects = [];
	var value, other;
	for(var prop in state){
		if(exist[prop])/*populates the resultArray for each exam type*/
		{
						other = "AS";
			if(prop == other) 
			{
				resultArray[prop] = [
    {
        "subject": "Mathematics"
    }
];
			}
						other = "A2";
			if(prop == other) 
			{
				resultArray[prop] = [
    {
        "subject": "Pure Mathematics"
    }
];
			}
						other = "GCSE";
			if(prop == other) 
			{
				resultArray[prop] = [
    {
        "subject": "gcseMathematics"
    }
];
			}
						other = "AP";
			if(prop == other) 
			{
				resultArray[prop] = [];
			}
						other = "KET";
			if(prop == other) 
			{
				resultArray[prop] = [
    {
        "subject": "English"
    }
];
			}
						other = "PET";
			if(prop == other) 
			{
				resultArray[prop] = [
    {
        "subject": "English"
    }
];
			}
						other = "FCE";
			if(prop == other) 
			{
				resultArray[prop] = [
    {
        "subject": "English"
    }
];
			}
						other = "IELTS";
			if(prop == other) 
			{
				resultArray[prop] = [
    {
        "subject": "English"
    }
];
			}
			;

		/*next get the value for each resultArray and make an array of values only*/
		var keys1 = Object.keys(resultArray[prop]);
		keys1.forEach(function(item1){
			var keys2 = Object.keys(resultArray[prop][item1]);
			//console.log(item1);
			keys2.forEach(function(items2){
				value = resultArray[prop][item1][items2];
				//subjects is an array of the subjects in the DB for each exam type which is checked and exists in the DB
				var newSubjects = subjects.push(value);
			});
		});		
		x = position();
		subs[prop] = {vals: subjects, rows: x[prop].r, columns: x[prop].c};//vals is an array of subject in DB associated with this exam type
		//clear this array each time
		subjects = [];
		}else{
			//if an exam in unchecked it is deleted from the object subs{}
			delete subs[prop];
		}
	}	
}
result();

function getYears(){ /*get subjects in DB for checked states, for those that exist*/
	var yearsArray = [];
	var yearsValues = [];
	var value, other;
	for(var prop in state){
		if(exist[prop])/*populates the resultArray for each exam type*/
		{
			;
			other = "AS";
			if(prop == other) 
			{
				yearsArray[prop] = [
    {
        "year": "2015"
    }
];
			}
			;
			other = "A2";
			if(prop == other) 
			{
				yearsArray[prop] = [
    {
        "year": "2015"
    }
];
			}
			;
			other = "GCSE";
			if(prop == other) 
			{
				yearsArray[prop] = [
    {
        "year": "2011"
    },
    {
        "year": "2015"
    },
    {
        "year": "2009"
    }
];
			}
			;
			other = "AP";
			if(prop == other) 
			{
				yearsArray[prop] = [];
			}
			;
			other = "KET";
			if(prop == other) 
			{
				yearsArray[prop] = [
    {
        "year": "2015"
    }
];
			}
			;
			other = "PET";
			if(prop == other) 
			{
				yearsArray[prop] = [
    {
        "year": "2015"
    }
];
			}
			;
			other = "FCE";
			if(prop == other) 
			{
				yearsArray[prop] = [
    {
        "year": "2015"
    },
    {
        "year": "2010"
    }
];
			}
			;
			other = "IELTS";
			if(prop == other) 
			{
				yearsArray[prop] = [
    {
        "year": "2009"
    }
];
			}
			;
			var keys1 = Object.keys(yearsArray[prop]);
			keys1.forEach(function(item1){
				var keys2 = Object.keys(yearsArray[prop][item1]);
				//console.log(item1);
				keys2.forEach(function(items2){
					value = yearsArray[prop][item1][items2];
					//console.log("value: " + value);
					//subjects is an array of the subjects in the DB for each exam type which is checked and exists in the DB
					var newyearsValues = yearsValues.push(value);
				});
			});	
		}

		yr[prop] = {yrValues: yearsValues};
		//clear this array each time
		yearsValues = [];

		/*for(var elem in yr)
		{
			console.log("yr[" + elem + "].yrValues " + yr[elem].yrValues);
		}*/
	}	
}
getYears();

subsOrdered = {};
i = 0;
j = 0;
for(var item in subs)
{
	subsOrdered[item] = {rows:i, columns:j, vals:subs[item].vals};
	j++;
	if(j>cellsAcross-1){
		i++;
		j = 0;
	}
//need a new object here subsOrdered{} which is a reordering of subs in the order row 0 cells 1 to 2 and then row 1 cells 0 to 2 etc.
//console.log("subsOrdered:  subjects: " + item + " rows: " + subsOrdered[item].rows + " columns: " + subsOrdered[item].columns + " result: " + subsOrdered[item].vals);
}
var countRows = document.getElementById('searchOptions').rows.length;
for(var i=countRows-1; i>=0; i--)
{
	//deletes all rows except row 0 each time
	document.getElementById('searchOptions').deleteRow(i);
}
//console.log("subjects: " + item + " rows: " + subs[item].rows + " columns: " + subs[item].columns + " result: " + subs[item].vals);
var tblBody = document.getElementById('searchOptions');
//var tblBody = document.createElement("table");
row = "";//clear the row variable
row = document.createElement("tr");
position();
for(var item in subsOrdered)
{
	//console.log(item);
	//console.log("subjects: " + item + " rows: " + subs[item].rows + " columns: " + subs[item].columns + " result: " + subs[item].vals);
	var cols = subsOrdered[item].columns;
	if(cols == 0)
	{
		//console.log("neither 0 nor 2, col: " + cols);
		row = document.createElement("tr");
	}
	//console.log("subs:  subjects: " + item + " rows: " + subs[item].rows + " columns: " + subs[item].columns + " result: " + subs[item].vals);
	//console.log("subsOrdered:  subjects: " + item + " rows: " + subsOrdered[item].rows + " columns: " + subsOrdered[item].columns + " result: " + subsOrdered[item].vals);
	cell = document.createElement("td");
	cell.setAttribute("class", "left");
	//var text = document.createTextNode(" " + item + " ");
	var num = subsOrdered[item].vals.length;
	var nums = yr[item].yrValues.length;
	//console.log("Subjects in " + item);
	innerTable = document.createElement("table");
	innerTable.setAttribute("class", "inner");
	//innerTable.setAttribute("id", "firstinnertable");
	innerHeader = document.createElement("th");//how to add header to table?
	innerHeader.innerHTML = item + " Subjects";
	innerTable.appendChild(innerHeader);
	
	//<input type="checkbox" class="year" id="IELTS" name="exams[]" value="IELTS">
	for(var i=0; i<num; i++)
	{
		//console.log("Subjects: "  + subsOrdered[item].vals[i]);
		innerRow = document.createElement("tr");//a new row for each checkbox
		innerCell = document.createElement("td");//a new cell for each checkbox
		//innerCell.setAttribute("class", "left");
		//innerText = document.createTextNode(subsOrdered[item].vals[i]);
		//innerCell.appendChild(innerText);
		innerInput = document.createElement("input");
		innerInput.name = "subject" + item + "[]";
		innerInput.type = "checkbox";
		innerInput.value = subsOrdered[item].vals[i]; 
		if(num==1)//if there is only one option it is checked by default
		{
			innerInput.checked = true;
		}
		innerCell.innerHTML = subsOrdered[item].vals[i] + " ";
		innerCell.appendChild(innerInput);
		innerRow.appendChild(innerCell);
		innerTable.appendChild(innerRow);
	}
	cell.appendChild(innerTable);
	row.appendChild(cell);
 
 	cell = document.createElement("td");
	innerTable = document.createElement("table");
	innerTable.setAttribute("class", "inner");
	innerHeader = document.createElement("th");//how to add header to table?
	innerHeader.innerHTML = item + " Years";
	innerTable.appendChild(innerHeader);
	
	//<input type="checkbox" class="year" id="IELTS" name="exams[]" value="IELTS">
	for(var i=0; i<nums; i++)//will iterate through specific year array for this subject
	{
		//console.log("Subjects: "  + subsOrdered[item].vals[i]);
		innerRow = document.createElement("tr");
		innerCell = document.createElement("td");

		innerCell.setAttribute("class", "left");
		//innerText = document.createTextNode(yr[item].yrValues[i]);
		
		innerInput = document.createElement("input");
		//innerInput.appendChild(innerText);
		innerInput.name = "years" + item + "[]";
		innerInput.type = "checkbox";
		innerInput.value = yr[item].yrValues[i]; 
		if(nums==1)//if there is only one option it is checked by default
		{
			innerInput.checked = true;
		}
		innerCell.innerHTML = yr[item].yrValues[i] + " ";
		innerCell.appendChild(innerInput);
		innerRow.appendChild(innerCell);
		innerTable.appendChild(innerRow);
	}
	cell.appendChild(innerTable);
	row.appendChild(cell);


	//console.log("Rows in current table: " + document.getElementById('examTables').rows.length);
	if(cols == cellsAcross-1)
	{
		//var row = document.createElement("tr");
		//console.log("end a row, col: " + cols);
		tblBody.appendChild(row);
	}
}
//var row = document.createElement("tr");
tblBody.appendChild(row);		
console.log("End of subs iteration");
//subs[item].vals.length
//console.log(Object.keys(subs).length);//can get length
}

function checkStudent(){
	var userInputFirst = document.getElementById('firstname').value;
	var userInputLast = document.getElementById('lastname').value;
	students = [
    {
        "first": "asdf",
        "last": "ghjk"
    },
    {
        "first": "zczczc",
        "last": "zczc"
    },
    {
        "first": "askbk",
        "last": "as"
    },
    {
        "first": "gcsename 1",
        "last": "gcselastname1"
    },
    {
        "first": "gcsename2",
        "last": "gcselastname2"
    },
    {
        "first": "petfirst1",
        "last": "petlast1pass"
    },
    {
        "first": "petfirst2",
        "last": "petlast2merit"
    },
    {
        "first": "petfirst3distinction",
        "last": "petlast3"
    },
    {
        "first": "test",
        "last": "test"
    },
    {
        "first": "fce",
        "last": "fce"
    },
    {
        "first": "fff",
        "last": "ccceee"
    },
    {
        "first": "fce1",
        "last": "fec2"
    },
    {
        "first": "test1",
        "last": "test2"
    },
    {
        "first": ",njn,",
        "last": "nnk"
    },
    {
        "first": "uuuuuuuu",
        "last": "uuuuuu"
    },
    {
        "first": "ket",
        "last": "ket"
    },
    {
        "first": "nbmn",
        "last": "mbm"
    },
    {
        "first": "null",
        "last": "nul"
    }
];
	console.log("userInputFirst: " + userInputFirst);
	console.log("userInputLast: " + userInputLast);
	for(var item in students){
		console.log("First name: " + students[item].first + " Last name: " + students[item].last);
		if(userInputFirst == students[item].first && userInputLast == students[item].last)
		{
			alert("We got a match");
		}
	}
}

var checkboxes = document.getElementsByClassName('year');
	for(var index in checkboxes){
	    //bind event to each checkbox
	    checkboxes[index].onchange = examTables;
	}
	</script>
	
</body></html>

The state object keeps track of whether the check boxes for each exam type are checked or unchecked. The exist object check which of the checked boxes have data for them in the database.
The script should be in a separate file to the HTML but it is difficult because of the PHP bits in there such as for JSON_encode().
Thanks

in the HTML use

<script src="externaljs.php"></script>

and in the PHP file use the following header to identify that the content is JavaScript:

header('Content-Type: application/javascript');

and it’s not possible to find that out on demand?

But the PHP file does not have JS in it.
There is a PHP file called index.php which pulls data from the DB and creates various php arrays.
Then there is the HTML file called search.html.php and it has some php embedded in the HTML. No problems with that as long as there is the .php file extension, even though it is mainly a HTML file.
Now I am creating a new file for the JavaScript which I call script.js. Or should that be called script.js.php ?
In search.html.php I have,

<script src="script.js.php" language="javascript" type="text/javascript"></script>

Is the following really to go on the index,php file? And if so does it go inside the <?php tag ?

header('Content-Type: application/javascript');

Thanks

that goes in the PHP at the top of any file that is to be read into the browser as JavaScript (your script.js.php file).

language=“javascript” was deleted about 15 years ago and type=“text/javascript” was deprecated at the same time but had to wait for IE8 to die before we could switch to the correct type.

That header would be if you are calling an external file into JavaScript tags.

If you want PHP values into JavaScript in the page itself it would be similar to how it can be done to insert PHP values into HT?ML eg.

<script> 
  function something() {
    var a_variable = "<?php echo $a_php_variable ; ?>"; 
⋮

Bottom of search.html.php looks like this,

   .....</div>
        <script src="script.js.php">


    </script>
    </body>
</html>

and top of script.js.php like this,

header('Content-Type: application/javascript');
var cellsAcross = 3;//number of cells across to display in creation of search tables
var pos = {};
var state = {};.......

Currently the JS is not working.
Thanks

What if I have PHP values from index.php which calls search.html.php and these values are needed in the JS? Should I use JSON_encode() in tags embedded in the HTML and then should be able to use them in the script.js.php ?

Sorry, but that is as helpful as me replying only.
“This will fix it”

What is the error message in the console and what code does the error message point to as the problem?

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.