3


I'm having issues with following code. I'm looking to validate an address(city,zip,state) and check it against what's in our database, which is called in the CFC. When I have the dataFilter setting for the Ajax, it goes into the error and display "parseerror", and I do not see the string javascript return. When I remove the dataFilter, in the console I see the javascript string return, but it always goes into the "else" for the success setting.
Anyone know what is going on? What am I doing wrong? The CFC does return correctly according to Fiddler (true/false).

$.ajax({
    type: "get",
    url: "/component/validateLenderAddress.cfc",
    data: {
        method: "validateZipCityState",
        returnFormat: "json",
        zip:$('input[name*="zip"]').val(), 
        city:$('input[name*="city"]').val(), 
        state:$('input[name*="state"]').val()
    },
    async: false,
    cache: false,
    dataFilter: function(data) {
        return $.parseJSON(data);
    },
    success:function(data) {
        if (data) {
            alert('Address Validated');
            return true;
        }
        else {
            alert('Address could not be validated');
            return false;
        }
    },
    error: function(xhr, ajaxOptions, thrownError) {
        alert(ajaxOptions);
    }
});

My CFC is

<cfcomponent output="false" extends="component.Database" hint="validates lender address lendermaint.inc">    
<cffunction name="validateZipCityState" output="false" returnType="struct" access="remote"> 
     <cfargument name="zip" type="string" required="true"> 
     <cfargument name="city" type="string" required="true"> 
     <cfargument name="state" type="string" required="true"> 

     <cfset var local = structNew()>

     <cfquery name="local.zipCodeList" datasource="#getDSN()#" username="#getUsername()#" password="#getPassword()#"> 
          SELECT TOP 1 1 
          FROM ZipCode 
          WHERE zipCode = <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(arguments.zip)#"> 
               AND city = <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(arguments.city)#"> 
               AND stateShort = <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(arguments.state)#"> 
     </cfquery> 

     <cfreturn local.zipCodeList.recordCount EQ 1> 
</cffunction>

Thanks!

ScrumMaster Guy
  • 267
  • 2
  • 6
  • 16
  • 1
    Can you share with us an example of the returned string from the cfc page? Is it actually json? – random_user_name Aug 27 '12 at 17:47
  • Thanks, that was it..it was including an onrequested script in our system...i needed to eliminate that when a cfc is being requested. SO now just includes the json:) – ScrumMaster Guy Aug 27 '12 at 18:30

2 Answers2

2

Instead of using a dataFilter just set { dataType : "json" } and you dont need to use the dataFilter. Also if you set the header on the response to Content-type: application/json jquery will automatically handle the response as json.

Also, consider removing async because you already have handlers to wait for the response and this could lock the browser and move your error and complete handlers to use the jqXHR .done() and .fail()

arhea
  • 454
  • 2
  • 5
2

I put the following into all my remote components:

<cfparam name="url.returnformat" default="json">
<cfparam name="url.queryformat" default="column">

Here's a plugin I wrote to help me do ajax:

!function($, window, undefined) {
    $.ajaxSetup ({
         cache: false // http://stackoverflow.com/questions/168963/stop-jquery-load-response-from-being-cached
    });
    $('#msg').ajaxStart(function() {
      $(this).empty().removeClass('alert alert-info');
    });
    $.fn.myAjax = function(myURL, mySettings) {
        var local = {};
        local.settings = {
            type: 'post',
            dataType: 'json',
            context:this[0]
        };
        local.settings = $.extend({}, local.settings, mySettings);
        local.XHR = $.ajax(myURL,local.settings);
        local.XHR.done(function(result) {
            if (result.MSG) {
                $('#msg').html(result.MSG).addClass('alert alert-error');
            }
        });
        local.XHR.fail(function(A,B,C) {
            $('#msg').html(C).addClass('alert alert-error');
        });
        return local.XHR;
    };
}(jQuery, window);

What it allows you to do is use 'this' when it returns:

!function($, window, undefined) {
    var settings = {}
    settings.data = {};
    settings.data.method = 'Save';

    $('input:checkbox').on('change',function() {
        $(this).removeAttr('checked');
        settings.data.xxxID = $(this).val();
        var myPromise = $(this).myAjax('xxx.cfc',settings);
        myPromise.done(function(result) {
            if (!result.MSG) {
                $(this).prop('checked',true); // OK, it's been inserted.
                local.qryxxx = result.qry.DATA;
                local.qryxxx.RecordCount = result.QRY.ROWCOUNT;
                local.qryxxx.ColumnList = result.QRY.COLUMNS;
            }
        });
    });
}(jQuery, window);
Phillip Senn
  • 46,771
  • 90
  • 257
  • 373