...

View Full Version : alert() statement lets code work, remove it, code errors out



arcanerain
12-17-2007, 03:01 PM
I am a novice, almost to an intermediate-level JavaScript guy, so much of this is new to me. I appreciate your patience reading this.

I have a routine that creates some HTML on the fly (updateFilters() function) and after the HTML is created, I attempt to access some fields (elements) on the form itself.

I works fine if I place an alert() statement after the HTML is created, but when I remove, the code errors out.

I have tried the setTimeout() statement, but I cannot grab the element --- undefined or null is returned. It seems that the form is the only element I can get a handle on --- everything else is undefined or null...

Here is the code:


function editQuery() {
var f;
var x;
var myForm = document.forms[0];
// Get the row filters that were used in the last query..
for (f = 1; f < 16; f++) {
var filter = eval("myForm.FilterList_" + f);
if (filter.selectedIndex > 0) {
var methodElement = element("FilterMethod_" + f);
var methodIndex = methodElement.selectedIndex;
var savedFilterMethodValue = methodElement.options[methodIndex].text;
var choicesElement = element("FilterChoices_" + f);
var choicesIndex = choicesElement.selectedIndex;
if (isNaN(choicesIndex)) {
var savedFitlerValues = choicesElement.value;
}
else {
var savedFitlerValues = choicesElement.options[choicesIndex].text;
}
updateFilters(filter); // update the filters
// take the saved methods and values and then update the selections
// Alert here makes the code work..
// alert("Try this");
// Wait for HTML..
setTimeout("completeEdit()", 1000);
function completeEdit() {
// Since the object was updated, get the object again..
var methodElement = element("FilterMethod_" + f);
for (x = 0; x < methodElement.options.length; x++) {
if (methodElement.options[x].text == savedFilterMethodValue) {
methodElement.options[x].selected = true;
break;
}
else {
methodElement.options[x].selected = false;
}
}
// Since the object was updated, get the object again..
var choicesElement = element("FilterChoices_" + f);
for (x = 0; x < choicesElement.options.length; x++) {
if (choicesElement.options[x].text == savedFitlerValues) {
choicesElement.options[x].selected = true;
break;
}
else {
choicesElement.options[x].selected = false;
}
}
// Only display next row if f = 2..
// If only one row was used, no reason display the next row..
if (f == 2) {
displayNextFilter(f - 1); // display it
}
}
clearTimeout(timeOut);
}
}
}


Do I have to pass the object (the form, the elements) to the completeEdit() function in the setTimeout() statement?

I could use some help...

Thanks!
Dan

Trinithis
12-17-2007, 05:12 PM
It's hard to tell what you are doing because the code has a bunch of functions that are not standard. Perhaps this will work, but if it doesn't, please show the JS code that defines functions like element(), updateFilters(), the variable timeOut, and others if needed. (I can't test incomplete code.) Preferably the entire page if you have a link to it.



function editQuery() {
var f;
var x;
var myForm = document.forms[0];
for(f = 1; f < 16; f++) {
var filter = myForm["FilterList_" + f];
if(filter.selectedIndex > 0) {
var methodElement = element("FilterMethod_" + f);
var methodIndex = methodElement.selectedIndex;
var savedFilterMethodValue = methodElement.options[methodIndex].text;
var choicesElement = element("FilterChoices_" + f);
var choicesIndex = choicesElement.selectedIndex;
if(isNaN(choicesIndex))
var savedFitlerValues = choicesElement.value;
else
var savedFitlerValues = choicesElement.options[choicesIndex].text;
updateFilters(filter);
setTimeout((function(f, methodElement, choicesElement) {
return function() {
completeEdit(f, methodElement, choicesElement);
};
})(f, methodElement, choicesElement), 1000);
arguments.callee.completeEdit(f, methodElement, choicesElement);
clearTimeout(timeOut);
}
}
}

editQuery.completeEdit = function completeEdit(f, methodElement, choicesElement) {
var methodElement = element("FilterMethod_" + f);
for(x = 0; x < methodElement.options.length; x++)
if(methodElement.options[x].text == savedFilterMethodValue)
methodElement.options[x].selected = true;
break;
else
methodElement.options[x].selected = false;
var choicesElement = element("FilterChoices_" + f);
for(x = 0; x < choicesElement.options.length; x++)
if(choicesElement.options[x].text == savedFitlerValues) {
choicesElement.options[x].selected = true;
break;
}
else
choicesElement.options[x].selected = false;
if(f == 2)
displayNextFilter(f - 1);
}

arcanerain
12-17-2007, 06:16 PM
Here are the other functions:


function updateFilters(filterObj){
var fName = filterObj.name
var fNumber = fName.substr(fName.indexOf("_")+1)
var fVal = filterObj[filterObj.selectedIndex].text
if (fVal == "- Select -"){
return
}else{
// display next row
// alert("filterRow" + fNumber + fName)
/*
obj = element("filterRow" + (parseInt(fNumber) + 1))
if (obj != null){
obj.style.display = "inline"
}
*/
}
getLookupValues(filterObj)
}
function getLookupValues(filterObj){
// need to have some check if it's a lookup doc
// probably just create a list/array of filters that require lookup
// something like if (filterLookups(filterObj.value)) then....
// if it is then go get the lookup values via xml
var lookupValue = false;
var fName = filterObj.name;
var fNumber = fName.substr(fName.indexOf("_")+1);
currentFilterNumber = fNumber;
var fVal = filterObj[filterObj.selectedIndex].text;
if(isFilterChoice(fVal) == true) {
lookupValue = true
}
// Get the lookupType...
lookupType = getLookupType(fVal);
if (lookupValue){
// go get it
url = "/py/p2p_query.nsf/lookupvalues?readform&lukey=" + businessEntity + "*&criterialabel=" + fVal + "*"
httpReq = getXMLHTTP();
if(httpReq){
httpReq.open("GET", url, true);
httpReq.onreadystatechange = function() {
if (httpReq.readyState==4 && httpReq.status==200 ) {
eval(httpReq.responseText);
updateLookupValues();
}
}
httpReq.send(null);
}
}
}
function getLookupType(filterName) {
for (x in filterObjects) {
if(x == filterName) {
return filterObjects[x];
}
};
}
function updateLookupValues(){
filterField = element("FilterChoices_" + currentFilterNumber);
td = element("filterChoicesSpan" + currentFilterNumber);

if (filterField != null){ // remove it first so we can recreate the object
td.removeChild(filterField)
}
// Set-up...
obj = element("filterRangeSpan" + currentFilterNumber);
if (obj != null){
obj.style.display = "none";
}
// Set the lookup methods -- Equals, Contains, etc.
var filterMethod = element("FilterMethod_" + currentFilterNumber);
var filterTDMethod = element("filterRowMethods" + currentFilterNumber)
if (filterMethod != null){ // remove it first so we can recreate the object
filterTDMethod.removeChild(filterMethod);
}
var newInput = document.createElement("<Select>");
newInput.name = "FilterMethod_" + currentFilterNumber;
newInput.setAttribute("id","FilterMethod_" + currentFilterNumber);
newInput.options.length = 0;
newInput.options.length = lookupMethods.length;
newInput.multiple = false;
if(lookupType == "Date") {
newInput.onchange = showRanges
}
else {
newInput.onchange = "";
}
for (x=0;x < lookupMethods.length;x++){
newInput.options[x] = new Option(lookupMethods[x],lookupMethods[x],false,false);
}
filterTDMethod.appendChild(newInput);
// Need to determine what type of field to show...
// <Text>
// <Radio>
// <Checkbox>
// Get the lookupType...
switch (lookupType) {
case "Text":
var newInput = document.createElement("<input>");
newInput.name = "FilterChoices_" + currentFilterNumber;
newInput.setAttribute("id","FilterChoices_" + currentFilterNumber);
td.appendChild(newInput);
break

case "Date":
// Date range FROM/TO...
// Just hide the choices and display the range fields...

break

case "Dialog List (one value)":
var newInput = document.createElement("<Select>")
newInput.name = "FilterChoices_" + currentFilterNumber
newInput.setAttribute("id","FilterChoices_" + currentFilterNumber)
newInput.options.length = 0
newInput.options.length = lookupValues.length
newInput.multiple = false
for (x=0;x < lookupValues.length;x++){
newInput.options[x] = new Option(lookupValues[x],lookupValues[x],false,false)
};
td.appendChild(newInput);
break

case "Dialog List (multi value)":
var newInput = document.createElement("<Select>")
newInput.name = "FilterChoices_" + currentFilterNumber
newInput.setAttribute("id","FilterChoices_" + currentFilterNumber)
newInput.options.length = 0
newInput.options.length = lookupValues.length
newInput.multiple = true
for (x=0;x < lookupValues.length;x++){
newInput.options[x] = new Option(lookupValues[x],lookupValues[x],false,false)
};
// Size the field to only show X at a time...
newInput.size = selectMultipleLines;
td.appendChild(newInput);
break;

case "Number Range":
var newInput = document.createElement("<input>");
newInput.name = "FilterChoices_" + currentFilterNumber;
newInput.setAttribute("id","filterChoices_" + currentFilterNumber);
td.appendChild(newInput);
break

case "Custom" :

break

default :

}
}
function element(id){
if (document.getElementById != null){ // nn 6+ ie 5+
return document.getElementById(id)

}
if (document.all != null){ //ie 4
return document.all[id]
}
if (document.layers != null){ // n4
return document.layers[id]
}
return null // not supported
}
function getXMLHTTP() {
// function to create an XmlHttp object
var xmlHttp = null;

try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch(oc) {
xmlHttp = null;
}
}

if(!xmlHttp && typeof XMLHttpRequest != "undefined") {
xmlHttp = new XMLHttpRequest();
}

return xmlHttp;
}

Thanks!

Zefris
12-17-2007, 07:33 PM
My guess is that when you're making a request to the server in "getLookupValues()" with, 'httpReq.open("GET", url, true);', you're not waiting for the server for the server's response and went ahead on accessing the elements you assumed to have been created. Adding an "alert()" gives some time needed for the server to respond and execute the function that'll create the HTML element on-the-fly. Just my guess, I haven't tested the code yet...

arcanerain
12-17-2007, 07:54 PM
I agree --- that's where I thought the setTimeout() statement would come in handy, however, after it runs, I can't get a handle on the elements I need to...

Any other ideas would be great -- thanks for your response!

Zefris
12-18-2007, 05:49 PM
Not sure what other problems I could think of without getting my hands on the program... global variables maybe...? :S



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum