Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    New to the CF scene
    Join Date
    Dec 2007
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts

    alert() statement lets code work, remove it, code errors out

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

  • #2
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    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.

    Code:
    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);
    }
    Trinithis

  • #3
    New to the CF scene
    Join Date
    Dec 2007
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Here are the other functions:

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

  • #4
    New Coder
    Join Date
    Jun 2005
    Posts
    52
    Thanks
    0
    Thanked 4 Times in 4 Posts
    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...
    Last edited by Zefris; 12-18-2007 at 01:03 AM.

  • #5
    New to the CF scene
    Join Date
    Dec 2007
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts
    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!

  • #6
    New Coder
    Join Date
    Jun 2005
    Posts
    52
    Thanks
    0
    Thanked 4 Times in 4 Posts
    Not sure what other problems I could think of without getting my hands on the program... global variables maybe...? :S


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •