0

I have a php function which returns JSON in response to a ajax request for delivery charges. Here is the php function:

public function getDeliveryOptions($weight, $postcode)
{

    if($weight == 0)
    {

        return array(array("name" => "Non-Deliverable", "value" => "0.00"));

    }

    $this->db->where('dmc_lower_boundary <=', $weight);
    $this->db->where('dmc_upper_boundary >=', $weight);

    if(preg_match("([aA][bB](3[1-8]|4[1-5]|5[1-6])\s?[1-9][a-zA-Z]{2}|[fF][kK](19|20|21)\s?[1-9][a-zA-Z]{2}|[hH][sS][1-9]\s?[1-9][a-zA-Z]{2}|[iI][vV][1-9]{1,2}\s?[1-9][a-zA-Z]{2}|[kK][aA](27|28)\s?[1-9][a-zA-Z]{2}|[kK][wW][1-9]{1,2}?\s?[1-9][a-zA-Z]{2}|[pP][aA][2-8][0-9]\s?[1-9][a-zA-Z]{2}|[pP][hH]([156789]|1[056789]|[2-5][0-9]){1,2}\s?[1-9][a-zA-Z]{2}|[zZ][eE][1-9]\s?[1-9][a-zA-Z]{2})", $postcode))
    {

        $this->db->where("dm_id = ", 1);
        $this->db->or_where("dm_id =", 3);

    }
    elseif(preg_match("/([bB][tT][1-9]{1,2}\s?[1-9][a-zA-Z]{2}|[iI][mM][1-9]{1,2}\s?[1-9][a-zA-Z]{2}|[tT][rR](21|22|23|24|25)\s?[1-9][a-zA-Z]{2})/", $postcode))
    {

        $this->db->where("dm_id =", 1);
        $this->db->or_where("dm_id =", 4);

    }
    elseif(preg_match("/([gG][yY][1-9]\s?[1-9][a-zA-Z]{2}|[jJ][eE][1-4]\s?[1-9][a-zA-Z]{2})/", $postcode))
    {

        $this->db->where("dm_id =", 1);
        $this->db->or_where("dm_id =", 5);

    }
    else
    {

        $this->db->where("dm_id =", 1);
        $this->db->or_where("dm_id =", 2);

    }

    $this->db->group_by("dm_id");
    $query = $this->db->get("delivery_method_option_views");
    //print_r($query->result());
    //print_r(json_encode($query->result()));
    return(json_encode($query->result()));
}

Here is my javascript (using prototype) to send the results to the server and use the response to create radio buttons:

function updateDelivery()
{
if($('deliveryUpdate') == null)
{

    return false;

}

// This 'observes' our form submit - sort of like onsubmit
$('deliveryUpdate').observe('submit', function(evt) {

    // Stop the actual event from happening
    evt.stop();

    // This is the url we submit to - change it as needed
    var url = '/checkout/updateDelivery';

    //This will be the form and div we update
    var containerForm = $('deliveryUpdate');
    var optionsDisplay = $('deliveryOptions');

    // Grab all the info in the form
    var form_data = containerForm.serialize();
    var form = containerForm.innerHTML;

    // Here we make the request
    new Ajax.Request(url, {
        method: 'post',
        parameters: form_data,
        onCreate: function() {
            form = containerForm.innerHTML;
            containerForm.update(form+'<img src="/images/loader.gif" alt="loading..." class="loader" />');
        },
        onSuccess: function(transport) {
            containerForm.update(form);
            NVPResponse = transport.responseText;

            if(NVPResponse !== '[object Array]')
            {

                NVPResponse = new Array(NVPResponse);

            }
            alert(NVPResponse);
            options = "";
            for(i=0; i<NVPResponse.length; ++i)

            {

                options += '<label for="delivery">'+NVPResponse[i].dm_name+'</label><input type="radio" name="delivery" value="'+NVPResponse[i].dmc_price+'" />';

            }

            //optionsDisplay.update(NVPResponse);
            optionsDisplay.update(options);
        }

    });

});

}

If I just update with the JSON results (for postcode ab31 2as), I get the following:

Calculate Delivery Costs[{"dm_id":"1","dm_name":"Royal Mail","dm_admin_name":"Royal Mail","dmc_lower_boundary":"101","dmc_upper_boundary":"250","dmc_price":"3.65"},{"dm_id":"3","dm_name":"Courier","dm_admin_name":"Fed Ex Zone 4","dmc_lower_boundary":"101","dmc_upper_boundary":"250","dmc_price":"4.50"}]

However, if I update with the options var, I get "undefined" where the label text and and radio button values go. This is built in the for loop in the onSuccess function. Any ideas?

Edit

I added the following code in before the for loop because I was trying to use JSON strings as objects instead of objects:

NVPResponse = JSON.parse(NVPResponse);

1 Answer 1

1

I am no big expert on prototype, but it seems to me that your NVPResponse is a string, not translated to a javascript object. (see prototype documentation for AJAX (specifically Evaluating a JavaScript response) and JSON).

Also there seem to be some other problems with your code.

In the PHP code:

if($weight == 0)
    {

        return array(array("name" => "Non-Deliverable", "value" => "0.00"));

    }

you return an array without JSONing it, is that intentional?

In addition, there seems to be a logical error:

$this->db->or_where("dm_id =", 3);

Queries for dm_id = 3 regardless of any previous "where" that you set, so that

$this->db->where('dmc_lower_boundary <=', $weight);
$this->db->where('dmc_upper_boundary >=', $weight);

will be disregarded if dm_id = 3 (or any of the other or_where of course). The solution can be something like this:

$this->db->where_in("dm_id", array(1,3));

edit:

In this case the query you wrote works perfectly well, but you should notice that Codeigniter does not put parentheses around OR arguments in its queries, therefore combining OR and AND in the same query can be buggy. the way you wrote the code the query will look something like this (which works fine):

SELECT * FROM (`t_name`) 
WHERE `dmc_lower_boundary` <= $weight AND `dm_id` = 1 OR `dm_id` = 3

writing the same query in a different order (or sometimes when writing complex queries) can give you a very different result:

SELECT * FROM (`t_name`) 
WHERE `dm_id` = 1 OR `dm_id` = 3 AND `dmc_lower_boundary` <= $weight

after a few serious bugs I learned to be careful with "or_where" :)

Sign up to request clarification or add additional context in comments.

2 Comments

But my database queries are pulling the correct results? :S Thanks for the first array though :)
My bad. CI doesn't put parenthesis around OR statements therefore they tend to be buggy. I edited the answer to reflect this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.