3.0.5

Index is reset in arrays after filtering

Hello,

thanks to this forum I got a solution for filtering data with paging. Having done this I wanted to output some of the data from a selected line to a text field. This is being done using a function:

var message = function(){
window.status = document.inquiryForm.ticker.value=myData[this.getSelectionProperty("index")][0];
}

The above function works fine so long as the data is not filtered. But after filtering returns the data from the second array GlobData and not the array myData which is being displayed. By adding alerts at various points in the code I have found out that the FilterGrid function is correctly setting new index values to the myData array after filtering. After leaving the FilterGrid function it seems that the index values of myData are reset to those in GlobData. The complete code demonstrating this can be found below - any ideas?


<html>
<head>
<title>ActiveWidgets Grid</title>
<style> body, html {margin:0px; padding: 0px; overflow: hidden;} </style>

<!-- ActiveWidgets stylesheet and scripts -->
<link href="../runtime/styles/xp/grid.css" rel="stylesheet" type="text/css" ></link>
<script src="../runtime/lib/grid.js"></script>

<!-- Include patches here -->
<script src="../patches/paging1.js"></script>


<!-- grid format -->
<style>
.active-controls-grid {height: 310px; font: menu;}

.active-column-0 {width: 80px;}
.active-column-1 {width: 200px; background-color: threedlightshadow;}
.active-column-2 {text-align: right;}
.active-column-3 {text-align: right;}
.active-column-4 {text-align: right;}

.active-grid-column {border-right: 1px solid threedshadow;}
.active-grid-row {border-bottom: 1px solid threedlightshadow;}
</style>

<!-- grid data -->
<script>
var message = function(){
window.status = "index=" + this.getSelectionProperty("index") + GlobData[this.getSelectionProperty("index")][0]; document.inquiryForm.ticker.value=myData[this.getSelectionProperty("index")][0];
}

var Datalen = 0;
var myData =[];
var GlobData =[];
var rowidValues = [];
var resfilter = "ALL";
var restot = "ALL";

var myColumns = ["Ticker", "Company Name", "Market Cap.", "$ Sales", "Employees"];

// create ActiveWidgets data model - text-based table
var table = new Active.Text.Table;

// provide data URL - plain text comma-separated file
table.setURL("../data/companies.csv");

// create javascript object
var obj = new Active.Controls.Grid;
obj.setId("grid1");
obj.setModel("row", new Active.Rows.Page);

var defaultResponse = table.response;

//begin table response
table.response = function(data){
defaultResponse.call(table, data);
Datalen=table.getCount();

//load CSV and convert to array
for(var x=0; x< Datalen; x++) {
GlobData.push([table.getText( x, 0), table.getText( x, 1), table.getText( x, 2), table.getText( x, 3), table.getText( x, 4)]);
}








//Clone array (GlobData allways stores all csv items)
myData = GlobData;

restot = Datalen;

obj.setRowProperty("count", Datalen);
obj.setColumnProperty("count", 5);
obj.getDataText = function(i, j){return myData[i][j]};
obj.setDataText = function(value, i, j){myData[i][j] = value};
obj.setColumnProperty("text", function(i){return myColumns[i]});
obj.setProperty("row/pageSize", 15);
obj.setAction("selectionChanged", message);


// SET TIMEOUT ( )
window.setTimeout(function(){
goToPage(0);
obj.refresh();
}, 0);

} //(end of tableresponse method)

// start asyncronous data retrieval
table.request();


function populateListBox() {
for(var c=0; c<myColumns.length; c++) {
document.write("<option value="+c+">"+myColumns[c]+"</option>");
}
}
//*********************************************
function FilterGrid()
{
var myData =[];

resetRowValuesGrid1()



var colToBeSearched = document.forms['gridSearchForm'].colSearchName.value;
var toSearch = document.forms['gridSearchForm'].keyword.value;
var rowidValues = [];
var res = 0;

for(var x=0; x<GlobData.length; x++)
{
if((GlobData[x][colToBeSearched].indexOf(toSearch)) >= 0) {
myData.push(GlobData[x]);
res++;
}
}



obj.sort(0, "ascending");
resfilter = res;



obj.setModel("row", new Active.Rows.Page);

obj.setRowProperty("count", resfilter);
obj.setColumnProperty("count", 5);
obj.getDataText = function(i, j){return myData[i][j]};



obj.setDataText = function(value, i, j){myData[i][j] = value};
obj.setColumnProperty("text", function(i){return myColumns[i]});
obj.setProperty("row/pageSize", 15);
obj.setAction("selectionChanged", message);
goToPage(0);



document.getElementById('result').innerHTML = "<b>Number of matches : "+resfilter+" of: " + restot +"</b>";

alert("myData:" + myData[0] + "\n" + "GlobData:" + GlobData[0] );

}
///***************************************



//**************************************
// RELOAD ROW-VALUES (AFTER ROWCOUNT IS NEEDED)
//*************************************

function resetRowValuesGrid1()
{
obj.setRowCount(myData.length);
var rowValues = [];

for(var i=0; i < myData.length; ++i) { rowValues.push(i);}

obj.setRowProperty("values", rowValues);
obj.setSortProperty("index", null);
}
//********************************



</script>
</head>
<body>
<script>

// write grid html to the page
document.write(obj);

</script>

<!-- bottom page control buttons -->
<div>
<button onclick='goToPage(-Infinity)'>&lt;&lt;</button>
<button onclick='goToPage(-1)'>&lt;</button>
<span id='pageLabel'></span>
<button onclick='goToPage(1)'>&gt;</button>
<button onclick='goToPage(Infinity)'>&gt;&gt;</button>
</div>

<script>

function goToPage(delta){
var count = obj.getProperty("row/pageCount");
var number = obj.getProperty("row/pageNumber");
number += delta;
if (number < 0) {number = 0}
if (number > count-1) {number = count-1}
document.getElementById('pageLabel').innerHTML = "Page " + (number + 1) + " of " + count + " ";

obj.setProperty("row/pageNumber", number);
obj.refresh();
}

</script>

<form name=gridSearchForm id=gridSearchForm>
<input type=text name=keyword>

<select name=colSearchName>
<script>
populateListBox();
</script>
</select><input type=button value=" Filter " onclick="javascript:FilterGrid();">
</form>
<div id=result>
</div>

<script>
document.getElementById('result').innerHTML = "<b>Number of matches : "+resfilter+" OF: " + restot +"</b>";
</script>

<form name=inquiryForm id=inquiryForm>
Ticker: <input type=text name=ticker>

<input type=button value = "Get" onclick='javascript:alert("myData:" + myData[0] + "\n" + "GlobData:" + GlobData[0] );'>
</form>
</body>
</html>

Andrew
August 17,
I encountered similar effects. What I do is remember the indices in the filter array and use that as an index to mydata.

John
August 17,
Hello John,

I don't think that is going to help, in my opinion there is something funny going on with the global variable mydata. In a normal script a value assigned to a global variable in a function is also retained outside of the function. In the case of myData the variable is always reset to its original data even though the data was deleted in the FilterGrid function. I can prove this by adding the following code to the end of the FilterGrid function:

for(var x=0; x<myData.length; x++) {alert(myData[x]); }

The message shows just the filtered data showing that mydata only consists of the filtered fields. If I put the code in a function in the head of the fill call it using a button after filtering I recieve the orginal contents of myData and not the new deleted contents. Does any one know how to fix this, or even why this is happening?
Andrew
August 17,
Andrew,

I see one glaring problem with your FilterGrid function. To 'delete the data' you use the line :

var myData = [];

What you are doing here is creating a local array called myData and setting it to empty. This line has nothing to do with your global myData array. If you remove the var declaration your problem should go away. Also remember that any variable passed into a function is passed in by COPY not by REFERENCE, so if you did FilterGrid(myData) and emptied the array in the function it again would not effect the actual array as it made a copy of it to use inside the function.

Hope this helps.
Jim Hunter
August 17,

This topic is archived.

See also:


Back to support forum