SitePoint Sponsor

User Tag List

Results 1 to 3 of 3
  1. #1
    SitePoint Member
    Join Date
    Jun 2007
    Posts
    9
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Exclamation trouble developing a custom AJAX function

    Hello geniuses,

    I'm working to develop a custom AJAX function that will allow me to submit a server call and get a response within a single line.

    The method of executing the AJAX would be pretty straightforward. A function would be called that would process data submitted by the user in one form or another. We would then build a custom query to a PHP page that would do all of the data processing work and return something. We would then specify a DIV to dump the returned value into and finally we would make the call to our AJAX processing function. That method would look something like this:

    Code:
    function createNewAssignment() {
    	
    	//GET ALL DATA FROM FORM
    		
    	//COMPOSE THE URL FOR OUR AJAX QUERY
    	var ajaxQuery = "ajax.php?Action=CreateAssignment" + othervalues;
    	
    	//NAME THE DIV THAT WILL HAVE CONTENT DUMPED INTO IT
    	var dumpDIV = "ResponseContainer";
    	
    	//DO THE AJAX
    	submitAJAX(ajaxQuery, dumpDIV);
    	
    }
    Now, this code is fine, no trouble at all. I can even create the xmlhttp request just fine. The trouble comes with specifying the div that will receive the response. The rest of the code looks like this:

    Code:
    var http_request = false;
    
    function submitAJAX(ajaxQuery, dumpDIV) {
    	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) {
    		alrt('Cannot create XMLHTTP instance');
    		return false;
    	}
    			
    	http_request.onreadystatechange = getResponse(dumpDIV);
    			  
    	http_request.open('GET', ajaxQuery, true);
    	http_request.send(null);
    }
    		
    		
    function getResponse(dumpDIV) {
    	if (http_request.readyState == 4) {
    		if (http_request.status == 200) {
    			result = http_request.responseText;
    			
    			if (result == '') {						
    				alert('Houston, we have a problem!')
    			} else {
    				document.getElementById(dumpDIV).innerHTML = result; 
    			}			           
    					
    		} else {
    			alert('There was a problem with the request.');
    		}
    	}
    }

    Everything is cool until the function "getResponse." Even this function will work just fine, if I don't want to get the name of DIV sent to the function (if I were to take out "(dumpDIV)" from the function call and the function name and plug in the literal name of the DIV rather than a variable, it works.

    So, my question is - why might the script not be working? Why can't I get variables into the "getResponse" function?

    Thank you everybody, hope this is an easy one!

    Mike

  2. #2
    SitePoint Enthusiast lkagan's Avatar
    Join Date
    Sep 2007
    Location
    Boca Raton, Florida
    Posts
    90
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Your suspicion is correct, you can't pass parameters into the callback. You would either need to use a global variable (as a PHP dev, you know this is bad) or look into closures. To be honest, the concept of closures is not easy to grasp since PHP doesn't have them and I've never come across them in C++ or Java. The XHR method could be encapsulated within an object and the callback could also be encapsulated along with any member variables (like the ID of the div) of that object. The the callback could refer to this.divID. Or you could just use a class that I wrote that does this for you. Please note that I have not tested the POST functionality of the class yet. Hope this helps.

    Code JavaScript:
    /**
    * Class for handling AJAX related tasks.
    *
    * @author Larry Kagan
    */
     
     
    /**
    * Class constructor
    *
    * @param string url
    * @param object The function object to set as a callback
    * @param object requestParams An object of key/value pairs that should be sent
    *       with the request. (Optional)
    * @param object callbackParams An object of key/value pairs that will
    *       be available to the callback function through the use of
    *       this.callbackParams within the callback function supplied. (Optional)
    * @param string method Either 'GET' or 'POST' (Optional, default 'GET')
    * @param bool async Flag for whether the request will be synchronous or not
    *       (Optional, default true)
    */
    AJAX = function(url, callback, requestParams, callbackParams, method, async)
    {
        this.req = null;
        this.url = url;
        this.callback = callback;
        this.requestParams = (requestParams) ? requestParams : null;
        this.callbackParams = (callbackParams) ? callbackParams : null;
        this.method = (method) ? method : 'GET';
        this.async = (async) ? async : true;
        this.errors = new Array();
        this._loadResponse();
    }
     
    AJAX.prototype =
    {
        /**
        * Build a query string based on any supplied request parameters.
        *
        * @access protected
        * @return string
        */
        _getQueryString:function()
        {
            var queryString = '';
     
            for(var param in this.requestParams) {
                queryString += param + '=' + escape(this.requestParams[param]) + '&';
            }
     
            if(queryString != '') {
                queryString = '?' + queryString;
            }
     
            return queryString;
        },
     
        /**
        * Perform the request
        *
        * @return bool True on success, false otherwise.
        * @access protected
        */
        _loadResponse:function()
        {
            // Build the XMLHttpRequest Object
            try {
                if(window.XMLHttpRequest) {
                    this.req = new XMLHttpRequest();
                } else if(typeof ActiveXObject != 'undefined') {
                    this.req = new ActiveXObject('Microsoft.XMLHTTP');
                }
            } catch(e) {
                this.errors.push(e);
                return false;
            }
     
            // Set the callback method.
            if(this.req) {
                try {
                    var thisCopy = this;
                    this.req.onreadystatechange = function()
                    {
                        thisCopy._stateChange.call(thisCopy);
                    }
                } catch(e) {
                    this.errors.push(e);
                    return false;
                }
     
            }
     
            // Prepare the request
            var queryString = this._getQueryString()
     
            if(this.method == 'get' || this.method == 'GET') {
                this.url += queryString;
            } else {
                this.body = queryString;
            }
     
            // Send the request
            try {
                this.req.open(this.method, this.url, this.async);
                this.req.send(this.body);
            } catch(e) {
                this.errors.push(e);
            }
        },
     
        /**
        * Initiate the user's callback function.
        *
        * @access protected
        */
        _stateChange:function()
        {
            if(this.req.readyState == 4 && this.req.status == 200) {
                this.callback.call(this);
            }
        }
    }
    Larry Kagan
    Lead Web Application Developer
    Superiocity, Inc.

  3. #3
    SitePoint Member
    Join Date
    Jun 2007
    Posts
    9
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you very much for your feedback! I'm definitely going to give your method a try, it seems for more robust than mine. In the meantime, I managed to get mine working with a bit of monkeying around:

    Code:
    http_request.onreadystatechange = function() { getResponse(dumpDIV); };
    Thanks again, I really appreciate it!


Bookmarks

Posting Permissions

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