views:

1002

answers:

2

I'm trying to learn jQuery and it occurred to me that existing JS in some of my sites could be replaced with just a few lines of jQuery code. In the following code, I'm trying to set the value of a custom validator by making an AJAX call. The first block of code does not work as it should, whereas the second block works fine. The whole "if it ain't broke don't fix it" answer isn't helpful, I really want to learn jQuery. For the record, I've placed alerts in the code and they both return the exact same result, just one is setting the args and the other is not for some reason.

Why does this code NOT work:

    function CheckForUserName(sender, args)
{
    args.IsValid = true;

    var url = "/somepage.aspx";

    MakeCall(url, function(txt) {
    if (txt == "false") {
        args.IsValid = false;
    }
    });
}

function MakeCall(url,callback) { 
    $.ajax({
        url: url,
        dataType: "text",
        success: callback
    });
}

This code DOES work:

    function CheckForUserName(sender, args)
{
     args.IsValid = true;

     var call = MakeCall();
     if (call == "false")
     {
      args.IsValid = false;
     }

}

function MakeCall()
{ 
    var xmlHttp;
    var validation=true;

    xmlHttp=GetXmlHttpObject();
    if (xmlHttp==null)
    {
     alert ("Your browser does not support AJAX!");
     return;
    } 

    var url="/somepage.aspx";
    xmlHttp.onreadystatechange=function () 
    {
     if (xmlHttp.readyState==4)
     { 
      if (xmlHttp.status==200)
      {
       return xmlHttp.responseText;
      }
      else
      {
       alert(xmlHttp.status);
      }
     }
    };
    xmlHttp.open("GET",url,false);
    xmlHttp.send(null);
    return xmlHttp.responseText;
}

function GetXmlHttpObject()
{
var xmlHttp=null;
try
  {
  // Firefox, Opera 8.0+, Safari
  xmlHttp=new XMLHttpRequest();
  }
catch (e)
  {
  // Internet Explorer
  try
    {
    xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
    }
  catch (e)
    {
    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
return xmlHttp;
}
+2  A: 

In order to make it work, you need to specify the async option as false:

function MakeCall(url,callback) { 
    $.ajax({
        async: false,
        url: url,
        dataType: "text",
        success: callback
    });
}
Jose Basilio
typically a synch xhr call is bad news. It locks the browser up. A better bet is to return false immediately and then trigger functionality from within the ajax success callback.
redsquare
@redsquare - I agree with you. Why don't you post an answer that incorporates that and works under the scenario described by the OP.
Jose Basilio
yes please! thank you!
Jason
i've tried to use the .textResponse on the .ajax() call but it gives me a "data not available yet" error... maybe someone can build on that?
Jason
@redsquare/jose... you guys got anything?
Jason
@Jason - the code in your example that uses the XMLHttpRequest object directly is using "async=false". Using jQuery in this case only buys "having less code", but not much else in terms of functionality. In order to make this work in an asynchronous manner you need to get away from the ASP.NET custom validator which is not designed to be used asynchronously. It either works with a quick response on the client-side or a postback(full or partial).
Jose Basilio
A: 

This works fyi.. ignore my custom javascript namespace functions, but you should get the concept.

<script type="text/javascript">
        function VerifyCustomerNumber(s, a) {
            var r = ProcessCustomerNumber(a.Value);
            a.IsValid = r;
        }
        function ProcessCustomerNumber(n) {
            var u = '/Services/WebServices/Customer.asmx/CountByCustomerNumber';
            var d = '{"Number": "' + n + '"}';
            $j.ajax({
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: u,
                cache: false,
                async: false,
                data: d,
                dataType: "json",
                success: function(r) {
                    var v = Data.JS.Ajax.ParseJSON(r);
                    return v;
                }
            });
        }
    </script>
Marc M