Array won't display properly. DESPERATE!

Ok this code starts by creating foodArray, 2 dimensional array. Body onload calls fillTable, which fills the table with the first 5 elements of foodArray. In the bottom right is next and last buttons to display different pages of elements in the array. It works fine for foodArray, and because theres 5 elements per page, the 3rd page shows results 11, 12, and 13 as it should.

The problem happens when you conduct a search. Enter “o” in the textbox labelled “food” and it searches foodArray in the appropriate column and returns 8 results. The first 5 results display fine. But when you click next, instead of showing the last 3 results, all 3 entries are undefined. I cannot for the life of me figure out what’s wrong. There’s lots of comments to hopefully help you out.

Also, i seem to have to declare the foodArray and resultArray and initialize them with empty values in order for the script to work? Aren’t JS arrays supposed to be dynamic? a solution to this problem would really help me a lot as well.

If you could provide a simple fix without totally rewriting the code I would be really greatful. Thanks in advance, G.


<!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>

<style type="text/css">
#content1 {
	position: absolute;
	right: 10px;
	z-index: 1;
	top: 100px;
}
</style>

<link href="basicstyle.css" rel="stylesheet" type="text/css" />
<link href="advancestyle.css" rel="stylesheet" type="text/css" />
<link href="tablestyle.css" rel="stylesheet" type="text/css" />

<script type="text/javascript">

var food1 = new Array("-", "100% Parmesan Cheese", "Kraft", "Dairy & Alternatives", "2 Tbsp", "12g", 45, 2.5, 1.5, 0.1, 5, 230, 1, 0, 0, 5);
var food2 = new Array("-", "100% Whole wheat bread", "Dempsters", "Grain Products", "2 slices", "71g", 180, 2, 0.5, 0, 0, 240, 33, 4, 3, 7);
var food3 = new Array("-", "Canned Cut Asparagus", "Selection", "Fruit & Vegetables", "1/2 cup", "125mL", 25, 0.3, 0, 0, 0, 260, 4, 2, 2, 2);
var food4 = new Array("-", "Chinese Fried Rice", "Uncle Ben's Fast & Fancy", "Grain Products", "1/4 package", "42g", 150, 0.5, 0.2, 0, 0, 370, 33, 1, 1, 3);
var food5 = new Array("-", "Cooked Turkey Breast", "Pillar's", "Meat & Alternatives", "2 slices", "40g", 40, 0.5 ,0.3, 0, 20, 460, 1, 0, 1 ,8); 
var food6 = new Array("-", "Diet Coke", "Coke", "Beverages", "-", "250mL", 0, 0, 0, 0, 0, 35, 0, 0, 0, 0.1, "-");	
var food7 = new Array("-", "Honey Nut O's Cereal", "Selection", "Grain Products", "3/4 cup", "30g", 120, 0.5, 0, 0, 0, 150, 26, 2, 12, 2);
var food8 = new Array("-", "Hot dogs", "Schneider's", "Meat & Alternatives", "1 wiener", "37g", 120, 10, 3.5, 0.1, 20, 410, 2, 0, 0, 5);
var food9 = new Array("-", "Milk Chocolate Crispie Joys", "Harry London", "Treats", "About 4", "40g", 190, 10, 6, 0, 5, 55, 26, "<1g", 18, 3);
var food10 = new Array("-", "Mozzarella cheese", "Black Diamond", "Dairy & Alternatives", "1/4 inch cube", "30g", 110, 8, 5, 0.2, 25, 230, 1, 0, 0, 8);
var food11 = new Array("-", "Pancake and Waffle Mix", "Selection", "Grain Products", "1/3 cup", "34g", 120, 1.5, 0.4, 0, 15, 510, 23, 1, 3, 3);
var food12= new Array("-", "Rancher's Choice Calorie Wise", "Kraft", "Oils & Fats", "1 Tbsp.", "15mL", 35, 2.5, 0.4, 0, 5, 170, 3, 0, 1, 0.1);
var food13 = new Array("-", "Strawberry Cereal Bars", "Selection", "Grain Products", "1 bar", "38g", 130, 2.5, 0.2, 0, 5, 210, 25, 3, 10, 2);
var foodArray = [food1, food2, food3, food4, food5, food6, food7, food8, food9, food10, food11, food12, food13];
var resultArray = [ [ ], [ , ], [ , ], [ , ], [ , ], [ , ], [ , ], [ , ], [ , ], [ , ], [ , ], [ , ], [ , ] ];

var arrayRows;
var arrayColumns;

var buttonValue = "Add";
var onclickString = "addRow()";

var page = 1; 
var resultCount = 0;

var searchDone = false;

var outputTableRows = 5;
var outputTableColumns = 16;

function fillTable( arr, p ) {
	//fill the output table with whatever array is passed to it in form of arr parameter.
	alert("Array length: " + arr.length);
	alert("Page: " + p)

	//for x = 0 to 4
	for (var x = 0; x < outputTableRows; x++) {

		//var xPage =  5 to 9 on page 2
		var xPage = (x + 5 * (p - 1));
		
		//for y = 0 to 15
		for (var y = 0; y < outputTableColumns; y++) {		
			
			//set id variable in order to refer to each cell in the output table by this id.
			var id = x + "_" + y;

			//&& (arr[xPage][y] != undefined)
			// if a search as done, if resultCount > xPage
			if ( ( (searchDone == true ? resultCount : arr.length) > xPage ) ) {
				
				//if its the first column, put in a button, 
				if (y == 0) { 
					document.getElementById(id).innerHTML = "<input id=\\"b" + id + "\\" type=\\"button\\" value=\\"" + buttonValue + "\\" onclick=\\"" + onclickString + "\\">"; 
				} else { 
					//
					document.getElementById(id).innerHTML = arr[xPage][y];
				}
			//else if the resultArray entry is undedefined, just put in a dash in the output table cell.							
			} else {
				document.getElementById(id).innerHTML = "-";
			}
		}			
		
	}
}

function searchArray( arr ) {
	//search the array containing all database food items (foodArray), a 2 dimensional array.
	//find array entries that match search results.
	//put search results into 2 dimesional array foodArray.
	//display foodArray in output table.

	//re-intitialize resultArray to empty it, and resultCount to 0.
	var resultArray = [ [ , ], [ , ], [ , ], [ , ], [ , ], [ , ], [ , ], [ , ], [ , ], [ , ], [ , ], [ , ], [ , ] ];

	//set rows and columns dynamiically and for the output table
	//this uses foodArray to start.
	//only works if all rows of foodArray have the correct length, because always uses the first row to count length.
	arrayRows = arr.length;
	arrayColumns = arr[0].length;

	searchDone = true;
	resultCount = 0;	
	page = 1;
	
	//get search terms.
	food = document.getElementById("foodsearch").value;
	brand = document.getElementById("brandsearch").value;
	foodType = document.getElementById("foodtypesearch").value;

	//if a search term is entered for food
	if (food != "") {
		//for each row in the foodArray table
		for (var x = 0; x < arrayRows; x++) {
			//search the second column of each foodArray item for the search term.
			var result = arr[x][1].indexOf(food);
			//if a match was found, put the result into a new row for resultArray referred to by resultCount.
			if (result != -1) {
				for (var y = 0; y < arrayColumns; y++) {
					resultArray[resultCount][y] = arr[x][y];
				}
				alert("Result: " + resultCount);
				alert(resultArray[resultCount][1]);
				resultCount += 1;
			}
		}	

		fillTable( resultArray, page );
	}

	//if a search term is entered for brand
	if (brand != "") {
		//for each row in the foodArray table
		for (var x = 0; x < arrayRows; x++) {
			//search the second column of each foodArray item for the search term.
			var result = arr[x][2].indexOf(brand);
			//if a match was found, put the result into a new row for resultArray referred to by resultCount.
			if (result != -1) {
				for (var y = 0; y < arrayColumns; y++) {
					resultArray[resultCount][y] = arr[x][y];
				}
				resultCount += 1;
			}
		}	
	
		fillTable ( resultArray, page );
	}

	//if a search term is entered for foodType
	if (foodType != "") {
		//for each row in the foodArray table
		for (var x = 0; x < arrayRows; x++) {
			//search the second column of each foodArray item for the search term.
			var result = arr[x][3].indexOf(foodType);
			//if a match was found, put the result into a new row for resultArray referred to by resultCount.
			if (result != -1) {
				for (var y = 0; y < arrayColumns; y++) {
					resultArray[resultCount][y] = arr[x][y];
				}
				resultCount += 1;
			}
		}
	
		fillTable ( resultArray, page );
	}
}



function resetSearch() {
	page = 1;
	fillTable ( foodArray, page );
	document.getElementById("foodsearch").value = "";
	document.getElementById("brandsearch").value = "";
	document.getElementById("foodtypesearch").value = "";
}

function start() {
	alert("Start pressed");
	page = 1;
	fillTable ( (searchDone == true ? resultArray : foodArray ), page );
}

function last() {
	alert("Last");
	page -= 1;
	fillTable ( (searchDone == true ? resultArray : foodArray ), page );
}

function next() {
	alert("Next");
	page += 1;
	fillTable ( (searchDone == true ? resultArray : foodArray ), page );
}

function end() {
	alert("End");
	page = 3;
	fillTable ( (searchDone == true ? resultArray : foodArray ), page );
}


</script>

</head>



<body onload="fillTable( foodArray, 1 )">

<div id="dcontainer" class="type3div">

  <div id="dheader" class="type2div">
		<div id="dlogo" class="type1div"></div>
    <div id="dlogin" class="type1div"></div>  
  </div>
    
	<div id="dmenubar" class="type2div">
  	<a href=""><div id="dmenu1" class="navigation">Page 1</div></a>
		<a href=""><div id="dmenu2" class="navigation">Page 2</div></a>
  	<a href=""><div id="dmenu3" class="navigation">Page 3</div></a>
		<a href=""><div id="dmenu4" class="navigation">Page 4</div></a>
		<a href=""><div id="dmenu5" class="navigation">Page 5</div></a>
	</div>

	<div id="dcontent" class="type2div">
	  
		<h1>Grocery Store - Aisle 1:</h1>
		<h2>Select food items from a database</h2>  
  	
		</div>
		
		<div id="content2" class="type1div">
			<div id="search">
			  <h2>Search Aisle 1</h2>
				<form id="form1" name="form1" method="post" action=""> 
          <table border="1">
            <tr>
              <td>Food:</td>
              <td><input id="foodsearch" type="text" size="30" /></td>
            </tr>
            <tr>
							<td>Brand:</td>
              <td><input id="brandsearch" type="text" size="30" /></td>
            </tr>
            <tr>
            	<td>Food Type:</td>
              <td><input id="foodtypesearch" type="text" size="30" /></td>
						<tr>
							<td colspan="2" align="right">
              	<input id="resetsearch" type="button" size="20" value="Reset Search" onclick="resetSearch()" />
								<input id="gosearch" type="button" size="20" value="Search" onclick="searchArray( foodArray )" />
            	</td>
						</tr>
          </table>
				</form>
			</div>
		</div>
			
		<div id="content3" class="type1div">
			<h2>Results</h2>
			
			<div id="table1" class="outputTable">
				
				<table border="1">
					<thead>
						<tr>
							<th class="tableHeadMediumCenter">Edit</th>
							<th class="tableHeadLargeLeft">Food</th>
							<th class="tableHeadLargeLeft">Brand</th>
							<th class="tableHeadLargeLeft">Food Type</th>
							<th class="tableHeadLargeLeft">Serving Amount</th>
							<th class="tableHeadSmallCenter">SS</th>
							<th class="tableHeadSmallCenter">Cal</th>
							<th class="tableHeadSmallCenter">Fat</th>
							<th class="tableHeadSmallCenter">Sat</th>
							<th class="tableHeadSmallCenter">Trans</th>
							<th class="tableHeadSmallCenter">Chol</th>
							<th class="tableHeadSmallCenter">Sod</th>
							<th class="tableHeadSmallCenter">Carb</th>
							<th class="tableHeadSmallCenter">Fib</th>
							<th class="tableHeadSmallCenter">Sug</th>
							<th class="tableHeadSmallCenter">Pro</th>
						</tr>
					</thead>

					<tbody>
						<tr>
							<td id="0_0" class="tableCellCenterTop">-</td>
							<td id="0_1" class="tableCellLeftTop">-</td>
							<td id="0_2" class="tableCellLeftTop">-</td>
							<td id="0_3" class="tableCellLeftTop">-</td>
							<td id="0_4" class="tableCellLeftTop">-</td>
							<td id="0_5" class="tableCellCenterTop">-</td>
							<td id="0_6" class="tableCellCenterTop">-</td>
							<td id="0_7" class="tableCellCenterTop">-</td>
							<td id="0_8" class="tableCellCenterTop">-</td>
							<td id="0_9" class="tableCellCenterTop">-</td>
							<td id="0_10" class="tableCellCenterTop">-</td>
							<td id="0_11" class="tableCellCenterTop">-</td>
							<td id="0_12" class="tableCellCenterTop">-</td>
							<td id="0_13" class="tableCellCenterTop">-</td>
							<td id="0_14" class="tableCellCenterTop">-</td>
							<td id="0_15" class="tableCellCenterTop">-</td>
						</tr>
						<tr>
							<td id="1_0" class="tableCellCenterTop">-</td>
							<td id="1_1" class="tableCellLeftTop">-</td>
							<td id="1_2" class="tableCellLeftTop">-</td>
							<td id="1_3" class="tableCellLeftTop">-</td>
							<td id="1_4" class="tableCellLeftTop">-</td>
							<td id="1_5" class="tableCellCenterTop">-</td>
							<td id="1_6" class="tableCellCenterTop">-</td>
							<td id="1_7" class="tableCellCenterTop">-</td>
							<td id="1_8" class="tableCellCenterTop">-</td>
							<td id="1_9" class="tableCellCenterTop">-</td>
							<td id="1_10" class="tableCellCenterTop">-</td>
							<td id="1_11" class="tableCellCenterTop">-</td>
							<td id="1_12" class="tableCellCenterTop">-</td>
							<td id="1_13" class="tableCellCenterTop">-</td>
							<td id="1_14" class="tableCellCenterTop">-</td>
							<td id="1_15" class="tableCellCenterTop">-</td>
						</tr>
						<tr>
							<td id="2_0" class="tableCellCenterTop">-</td>
							<td id="2_1" class="tableCellLeftTop">-</td>
							<td id="2_2" class="tableCellLeftTop">-</td>
							<td id="2_3" class="tableCellLeftTop">-</td>
							<td id="2_4" class="tableCellLeftTop">-</td>
							<td id="2_5" class="tableCellCenterTop">-</td>
							<td id="2_6" class="tableCellCenterTop">-</td>
							<td id="2_7" class="tableCellCenterTop">-</td>
							<td id="2_8" class="tableCellCenterTop">-</td>
							<td id="2_9" class="tableCellCenterTop">-</td>
							<td id="2_10" class="tableCellCenterTop">-</td>
							<td id="2_11" class="tableCellCenterTop">-</td>
							<td id="2_12" class="tableCellCenterTop">-</td>
							<td id="2_13" class="tableCellCenterTop">-</td>
							<td id="2_14" class="tableCellCenterTop">-</td>
							<td id="2_15" class="tableCellCenterTop">-</td>
						</tr>
						<tr>
							<td id="3_0" class="tableCellCenterTop">-</td>
							<td id="3_1" class="tableCellLeftTop">-</td>
							<td id="3_2" class="tableCellLeftTop">-</td>
							<td id="3_3" class="tableCellLeftTop">-</td>
							<td id="3_4" class="tableCellLeftTop">-</td>
							<td id="3_5" class="tableCellCenterTop">-</td>
							<td id="3_6" class="tableCellCenterTop">-</td>
							<td id="3_7" class="tableCellCenterTop">-</td>
							<td id="3_8" class="tableCellCenterTop">-</td>
							<td id="3_9" class="tableCellCenterTop">-</td>
							<td id="3_10" class="tableCellCenterTop">-</td>
							<td id="3_11" class="tableCellCenterTop">-</td>
							<td id="3_12" class="tableCellCenterTop">-</td>
							<td id="3_13" class="tableCellCenterTop">-</td>
							<td id="3_14" class="tableCellCenterTop">-</td>
							<td id="3_15" class="tableCellCenterTop">-</td>
						</tr>
						<tr>
							<td id="4_0" class="tableCellCenterTop">-</td>
							<td id="4_1" class="tableCellLeftTop">-</td>
							<td id="4_2" class="tableCellLeftTop">-</td>
							<td id="4_3" class="tableCellLeftTop">-</td>
							<td id="4_4" class="tableCellLeftTop">-</td>
							<td id="4_5" class="tableCellCenterTop">-</td>
							<td id="4_6" class="tableCellCenterTop">-</td>
							<td id="4_7" class="tableCellCenterTop">-</td>
							<td id="4_8" class="tableCellCenterTop">-</td>
							<td id="4_9" class="tableCellCenterTop">-</td>
							<td id="4_10" class="tableCellCenterTop">-</td>
							<td id="4_11" class="tableCellCenterTop">-</td>
							<td id="4_12" class="tableCellCenterTop">-</td>
							<td id="4_13" class="tableCellCenterTop">-</td>
							<td id="4_14" class="tableCellCenterTop">-</td>
							<td id="4_15" class="tableCellCenterTop">-</td>
						</tr>
					</tbody>
				</table>

			</div>
			
			<div id="scroll">
				<span onclick="start()">‹‹Start</span>
				<span onclick="last()">‹Last</span>
				<span onclick="next()">Next›</span>
				<span onclick="end()">End››</span>
			</div>

		</div>


	</div>

</div>

</body>

</html>

The resultArray variable is local to the searchArray function. When that function has finished running, the resultArray variable is no longer accessible.

You need to store resultArray where it won’t get lost. Some people badly use global variables for that. A preferred technique is to store the data as a property of the form instead.


var form = document.getElementById('form1');
form.resultsArray = [];
...

By the way, the ancient old inline event to attach an onclick event
onclick=“searchArray( foodArray )”
makes your script more brittle, because it doesn’t let you easily gain access to the form.

You will be better off using javascript to attach such onclick events instead, because the function can then use the this.form keyword to get to the element that was clicked. The best place to easily attach such events at the end of the body, just before the </body> tag.


document.getElementById('gosearch').onclick = function () {
    searchArray( foodArray );
};

Now the searchArray function can easily gain a reference to the input button that was clicked, and all form fields let you easily get to the form.


var form = this.form;
form.resultsArray = [];
...

As an end result, that part of the script will now work no matter what the form id is changed to.