Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Javascript array assignment issue

Status
Not open for further replies.

Bastien

Programmer
May 29, 2000
1,683
CA
Inherited some legacy code and am attempting to do a little caching with it. The query is doing some drop down filtering with an AJAX call to get some XML data. The plan is to intercept the AJAX calls if the element has been requested before by checking the xfilter array for the objCurrent item or allow the AJAX request if it has not and then store the returned XML to the xfilter array.

I am having some issues getting the data to get loaded into the array and back out again once its in been in the array. Can someone point me in the correct direction?

objCurrent is the element ID.
objParent is the parent select item
tmpValue is the value of the selected item in the parent

Code:
var xfilter = new Array();

// Filter a dropdown based on the tmpValue of the Parent
function RequestFilter(objCurrent, objParent, tmpValue){
  var url, theField, theListItem;
  var objCurrentRealName = '';  
  // this will store the current selections, prior to the control being redrawn
  var arrCurrentSelections = new Array();

  // don't attempt on empty field name
  if (objCurrent != '') theField = document.getElementById(objCurrent);
  
  // if the field does not exist, then exit.
  if (theField == null) return 0;
  
  // save selected values
  for (theListItem=0; theListItem < theField.options.length; theListItem ++) {
    if (theField.options[theListItem].selected == true) {
      arrCurrentSelections[theField.options[theListItem].value] = theField.options[theListItem].text;
    };
  };
  
  // Remove old list
  while (theField.options.length > 0) theField.options[0] = null;

  //get the real field name without the silly number
	pattern = /(\d)+$/;
	objCurrentRealName = objCurrent.replace(pattern,"");
  if(xfilter[objCurrentRealName]){
      //load the text string into an xml object
      theXML = xfilter[objCurrentRealName];
  }else{
	    // do the ajax query
 	    // prepare the XML call
		  url = "../../includes/apiscontrols2_filter.asp?" 
		  url = url + "xml_field_id=" + objCurrent + "&"
		  url = url + "xml_filter_id=" + objParent + "&"
		  url = url + "xml_filter_using=" + tmpValue + "&" + Math.random();
		  
		  
		  // Set xml_request as the XMLHttpRequest object based on type of browser
		  
		  // prompt('aa', url);
		  
		  if(window.XMLHttpRequest) {
		    xml_request = new XMLHttpRequest(); 
		  } else {
		      if (window.ActiveXObject)  xml_request = new ActiveXObject('Microsoft.XMLHTTP');
		  };
		
		  if (xml_request == null) {
		    return 0;
		  };
		  
		  // make the call for filtering synchronous
		  xml_request.open("POST", url, false);
		  xml_request.send(null);  // send null to end send
		
		
		  // if the response status is 200, it worked, otherwise alert with error.
		  if(xml_request.status == 200) {
		    var theXML, theList, sortlist;
		    
		    // fetch the xml response
		    theXML = xml_request.responseXML.selectSingleNode('/CONTROL');
		    //alert(objCurrentRealName+'||'+xfilter[objCurrentRealName]);
		    if (!xfilter[objCurrentRealName]){    //=="undefined"){
           xfilter[objCurrentRealName] = theXML;
           //alert("saving  xfilter[" + objCurrentRealName+"]");
        }
		  } else {
		    alert(xml_request.status + ' : ' + xml_request.statusText);
      }//end if(xml_request.status == 200) 

  }//end if(parent.common_area.filter[objCurrent.name]){
  

    if (theXML) {
      sortlist = theXML.getAttribute("SORT_LIST");
      // remove old values and remember selected ones
      theList = theXML.selectNodes("//OPTION");

      for (theListItem=0; theListItem < theList.length; theListItem ++) {
        // add the option from the response
        theField.options[theField.options.length] = new Option(theList[theListItem].getAttribute('VALUE'), theList[theListItem].getAttribute('ID'), false, false)

        // if the option was previously selected, then re-select it.
        if (arrCurrentSelections[theList[theListItem].getAttribute('ID')]) {
          theField.options[theField.options.length-1].selected = true
          arrCurrentSelections[theList[theListItem].getAttribute('ID')] = null;
        }
      };
      
      // add in any remaining previous selections with the leading asterisk
      for (theListItem in arrCurrentSelections) {
        if (arrCurrentSelections[theListItem]){
          if (arrCurrentSelections[theListItem].indexOf("* ") == -1) arrCurrentSelections[theListItem] = "* " + arrCurrentSelections[theListItem]
          
          theField.options[theField.options.length] = new Option(arrCurrentSelections[theListItem], theListItem, true, true)
        };
      }

      // if the result identified the dropdown to be sorted, call the sort_dropdown routine.
      if (sortlist.toLowerCase() == 'true') {
        Sort_DropDown(theField.id);
      }
    }


}

Bastien

I wish my computer would do what I want it to do,
instead of what I tell it to do...
 
Hi

Bastien said:
I am having some issues getting the data to get loaded into the array and back out again once its in been in the array.
Could you please give us details about those issues ? So far I found no evident bug in your code. Just some minor coding strangeness I prefer to avoid :
[ul]
[li]You are making a POST request but sending [tt]null[/tt] as content. In POST request the data should be send as content, not in the URL. But while you not set neither the necessary HTTP headers, this may pass through the web server.[/li]
[li]You are declaring variables in an [tt]if[/tt] block then using then outside of it. But in JavaScript variables can be local only to the [tt]function[/tt], so this will not cause problem.[/li]
[li]You are declaring xfilter as [tt]Array[/tt], but using it just as [tt]Object[/tt]. See a related discussion in thread216-1571560.[/li]
[/ul]


Feherke.
 
[1] One of the main problem is your using of selectNodes() and selectSingleNode() which will stop it to work cross-browser. Use the simpler getElementsByTagName() would do. But, it makes more assumptions on the xml structure and less "exact" than the full use of xpath - that's understood with more friendly responseXML known a priori.

[2] Care about the need of url encoding in case, or make sure the original options do not contain unsafe characters.

[3] If you want to use somehow loosely hungarian, at least try not to mislead yourself. For instance, objCurrent or objCurrentRealName are strings, rather than "object"...

[4] There are other details that might improve somewhat the logic, as I see it; but, it is not mandatory.
[tt]
var xfilter = new Array();

// Filter a dropdown based on the tmpValue of the Parent
function RequestFilter(objCurrent, objParent, tmpValue){
var url, theField, theListItem;
var objCurrentRealName = '';
// this will store the current selections, prior to the control being redrawn
[red]//[/red]var arrCurrentSelections = new Array();
[blue]var arrCurrentSelections = new Object();[/blue]

// don't attempt on empty field name
if (objCurrent != '') theField = document.getElementById(objCurrent);

// if the field does not exist, then exit.
if (theField == null) return 0;

// save selected values
for (theListItem=0; theListItem < theField.options.length; theListItem ++) {
if (theField.options[theListItem].selected == true) {
arrCurrentSelections[theField.options[theListItem].value] = theField.options[theListItem].text;
};
};

// Remove old list
[red]//[/red]while (theField.options.length > 0) theField.options[0] = null;
[blue]//can be simply this
theField.length=0;[/blue]

//get the real field name without the silly number
pattern = /(\d)+$/;
objCurrentRealName = objCurrent.replace(pattern,"");
if(xfilter[objCurrentRealName]){
//load the text string into an xml object
theXML = xfilter[objCurrentRealName];
}else{
// do the ajax query
// prepare the XML call
[blue]//take care of url encoding in care[/blue]
url = "../../includes/apiscontrols2_filter.asp?"
url = url + "xml_field_id=" + objCurrent + "&"
url = url + "xml_filter_id=" + objParent + "&"
url = url + "xml_filter_using=" + tmpValue + "&" + Math.random();


// Set xml_request as the XMLHttpRequest object based on type of browser

// prompt('aa', url);

if(window.XMLHttpRequest) {
xml_request = new XMLHttpRequest();
} else {
if (window.ActiveXObject) xml_request = new ActiveXObject('Microsoft.XMLHTTP');
};

if (xml_request == null) {
return 0;
};

// make the call for filtering synchronous
[red]//[/red]xml_request.open("POST", url, false);
[blue]xml_request.open("GET", url, false);[/blue]
xml_request.send(null); // send null to end send


// if the response status is 200, it worked, otherwise alert with error.
if(xml_request.status == 200) {
var theXML, theList, sortlist;

// fetch the xml response
[red]//[/red]theXML = xml_request.responseXML.selectSingleNode('/CONTROL');
[blue]theXML = xml_request.responseXML.getElementsByTagName('CONTROL')[0];[/blue]
//alert(objCurrentRealName+'||'+xfilter[objCurrentRealName]);
if (!xfilter[objCurrentRealName]){ //=="undefined"){
xfilter[objCurrentRealName] = theXML;
//alert("saving xfilter[" + objCurrentRealName+"]");
}
} else {
alert(xml_request.status + ' : ' + xml_request.statusText);
}//end if(xml_request.status == 200)

}//end if(parent.common_area.filter[objCurrent.name]){


if (theXML) {
sortlist = theXML.getAttribute("SORT_LIST");
// remove old values and remember selected ones
[red]//[/red]theList = theXML.selectNodes("//OPTION");
[blue]theList = theXML.getElementsByTagName("OPTION");[/blue]

for (theListItem=0; theListItem < theList.length; theListItem ++) {
// add the option from the response
theField.options[theField.options.length] = new Option(theList[theListItem].getAttribute('VALUE'), theList[theListItem].getAttribute('ID'), false, false)

// if the option was previously selected, then re-select it.
if (arrCurrentSelections[theList[theListItem].getAttribute('ID')]) {
theField.options[theField.options.length-1].selected = true
[red]//[/red]arrCurrentSelections[theList[theListItem].getAttribute('ID')] = null;
[blue]//if the line is meant to remove the entry, do this instead to be proper
delete arrCurrentSelections[theList[theListItem].getAttribute('ID')];[/blue]
}
};

// add in any remaining previous selections with the leading asterisk
for (theListItem in arrCurrentSelections) {
if (arrCurrentSelections[theListItem]){
if (arrCurrentSelections[theListItem].indexOf("* ") == -1) arrCurrentSelections[theListItem] = "* " + arrCurrentSelections[theListItem]

theField.options[theField.options.length] = new Option(arrCurrentSelections[theListItem], theListItem, true, true)
};
}

// if the result identified the dropdown to be sorted, call the sort_dropdown routine.
if (sortlist.toLowerCase() == 'true') {
Sort_DropDown(theField.id);
}
}


}
[/tt]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top