Basic Basic Basic! Passing parameter in AJAX callback, but I'm clueless

This is basic, basic, basic, but I don’t know where to begin.

I’ve got a small AJAX form, and the tiny forms are lite, they work great, and this specific one is for an “Email to a Friend” sort of thing. However, I want to put multiple “Email to a Friend” boxes on the page, under a page with multiple listings, for a real estate site.

So all I want to do is specify where the callback alert - e.g. “Success!” or “Error. You didn’t fill it out correctly” - is going to go. The code that I have now hardcodes it to a specific element Id called “c_form_target”. I’m going to have multiple “c_form_target” so I want to be able to pass that parameter of where the alert goes - e.g. “c_form_target1”, “c_form_target7”, etc.

So this is what I came up with to pass the “target_id”, using code I’ve already had and you can see that I’m trying to pass “target_id” as a param, first to makePOSTRequest and then further to alertContents. All I want to be able to do is call alertContents(target_id) with a param, but that won’t work:

function makePOSTRequest(url, parameters, target_id) 
{
  http_request = false;
  if (window.XMLHttpRequest) { // Mozilla, Safari,...
     http_request = new XMLHttpRequest();
     if (http_request.overrideMimeType) {
     	// set type accordingly to anticipated content type
        //http_request.overrideMimeType('text/xml');
        http_request.overrideMimeType('text/html');
     }
  } else if (window.ActiveXObject) { // IE
     try {
        http_request = new ActiveXObject("Msxml2.XMLHTTP");
     } catch (e) {
        try {
           http_request = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) {}
     }
  }
  if (!http_request) {
     alert('Cannot create XMLHTTP instance');
     return false;
  }
  
  if(target_id == undefined){ http_request.onreadystatechange = alertContents; } else { http_request.onreadystatechange = alertContents(target_id); } //THIS IS WHAT'S NOT WORKING!
  
  http_request.open('POST', url, true);
  http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  http_request.setRequestHeader("Content-length", parameters.length);
  http_request.setRequestHeader("Connection", "close");
  http_request.send(parameters);
}

function alertContents(target_id) {
  if (http_request.readyState == 4) {
     if (http_request.status == 200) {
        result = http_request.responseText;
        
        if(target_id == undefined) {target_id = "c_form_target";}
        
        document.getElementById(target_id).innerHTML = result; //THIS IS WHERE THE RESULT GETS SPIT OUT TO           
     } else {
        alert('There was a problem with the request.');
     }
  }
}

I appreciate the help fellas. I know it should be basic, but it’s tricky to me.

It is only a function that is assigned to the onreadystatechange event, so you need the function that is assigned to that event to retain knowledge of the target id. Something called closure is used to achieve that. This is where a returned function retains knowledge of variables from where that function is returned from.

A simple example is:


function outer(value) {
    function inner() {
        alert(value);
    }
    return inner;
}

You can also combine the function and the return in to one statement, with:


function outer(value) {
    return function () {
        alert(value);
    }
}

In both cases, the returned inner function retains knowledge of the value from its outer scope.

Paul, thanks for the definition of what I need. So would it make more sense for me to not use a function like this, and instead use a standard one without “closure”, because I’m not familiar w/closure and it seems complicated.

If you do it without closure, your function can not retain the information that you need about the target id. Its your call.