views:

307

answers:

2

I'm building a price estimator form, which uses jQuery to manipulate select menus. Basically, when a new quantity is chosen, the value of each option in every select menu is multiplied by a per-unit price, and a new price is shown to the user.

What I'm trying to do is pull the per-unit prices from a PHP file, which stores these prices in a series of arrays; e.g.:

<?php
    // prices.php
    $colorPrices = array(2.339,3.195,6.537,2.614,2.614,1.759);
    $json = json_encode($colorPrices);
    echo $json;
?>

Keeping the arrays separate will keep my jQuery cleaner and make it easier to update the pricing.

In my jQuery file, which calculates the total price, I'm reading in the JSON like this:

$.getJSON('prices.php',function(data) {
    var colorArray = data;
})

At this point, colorArray is an object, so it doesn't play nice with this bit of jQuery:

// whenever a new COLOR is chosen, step through colorArray and multiply by the currently selected QUANTITY
$('#colors option').each(function(i){
    $(this).attr('label',qty * colorArray[i]);
});

My thinking is that if I can convert colorArray to an array, I can loop through its contents. Right now, nothing happens when I choose a new color.

Am I close or clueless?

+5  A: 

colorArray will be an array of the form

[2.339, 3.195, 6.537, 2.614, 2.614, 1.759]

according to the php json_encode() documentation.

I've put together a Working Demo to demonstrate how to handle data returned in a JSON string as an array. add /edit to the URL to see the code.

Code from the demo

$(function() {

  $('button').click(function() {

    // the URL is just another page on jsbin.com that contains 
    // this string - ["2.339","3.195","6.537","2.614","2.614","1.759"]
    $.getJSON('http://jsbin.com/amibo', function(data) {

      $.each(data, function(i,v) {
        $('<div>').text(v).appendTo('body');
      });

    });

  });

});

Note that in your example, colorArray is declared locally inside the function that executes when the AJAX request has completed and therefore will not be available outside of that scope. You can either use a higher scoped variable to capture the returned data or perform your iteration inside of the callback function.

EDIT:

I've looked at your code here and you would need something like this

$('#quantity').change(function() {

  var qty = $('option:selected', this).val();

  switch (qty) {
    case '250':
      $.getJSON('scripts/jsondata.php',function(data) {

        // call the new updateOptionLabels function
        updateOptionLabels(qty, data);


        // I'm not sure if you needed this part as it seems to
        //  essentially duplicate the new updateOptionLabels function
        // I've commented out but I may misunderstand what you're doing
        /*
        $.each(data, function(i, value) {
          $('#colors option').eq(i).attr('label',qty * value);
        });
        */

      });    
      break;

    case '500':
      // ditto, but retrieving a different array
      break;

    // etc...
    default:
      alert("Default");
      break;
  }


  // I'd like to use that local "colorArray" variable here
  function updateOptionLabels(qty, arr) {
    $('#colors option').each(function(i) {
      $(this).attr('label',qty * arr[i]);
    });
  }


});

I've introduced a new function for updating option labels. This function is scoped to the function executed when the change event is raised on <select> with id quantity. The variable qty can be used inside of the callback function for the getJSON() command in each case statement as it is declared outside of the scope of the callback function. The data variable and the qty are both passed into the updateOptionLabels() function so that this code is not duplicated in each case statement. This could probably be refined earlier. I've commented out the $.each() for the moment as it looks as though what you were trying to do with that is now taken care of by the updateOptionLabels() function.

I would suggest taking a look at Doug Crockford's excellent Survey of the JavaScript Programming Language, particularly the section on Functions. Also take a look at Mozilla's excellent Core JavaScript 1.5 reference material. Here's the section on Functions and function scope

Russ Cam
Thanks Russ, that helped me understand what was going on. I think there *is* a variable scope issue, but I'm not sure how to resolve it. I've posted a sampling of my code here: www.3roadsmedia.com/samplejquery.phpAlso, I'm not sure how I'd go about retrieving a second or third array from the PHP file. Is this possible?
Ryan
I should also add that the sample code won't do anything; view source to check it out.
Ryan
Russ, rock on! Works great. Only one more question (I hope). Any idea how I'd read in more than one array from an external PHP file? I'd like a separate array for each quantity, and more beyond that. I posted my sample jsondata.php file at http://www.3roadsmedia.com/samplejson.html if you wouldn't mind taking a look (view source).
Ryan
I just had a thought that maybe this should be a separate question. Let me know if so and I'll re-post. I'm relatively new here...
Ryan
@Ryan- Following along the same lines as before, I'm no PHP person, but json_encode() should be allow you to send an array of arrays like`$a = array(array(1,2,3,4),array(2,3,4,5),array(4,5,6,7));`. What you would get on the client side would be like `[[1,2,3, 4],[2,3,4,5],[4,5,6,7]]`. You can verify if a string is valid JSON with http://www.jsonlint.com/ . If you need more details, please go ahead and post another question
Russ Cam
Thanks Russ -- that works great. I also found another question here that answers my question. I appreciate your help on this. Thanks.
Ryan
+1  A: 

It's not clear to me whether the $('#colors option') code block is inside the method that fetches the JSON data. You defined colorsArray as a local variable inside the JSON function. That means it won't be accessible outside. My guess is that's your problem.

In Javascript, if you omit the var in front of a variable declaration in a function, you make that variable global, hence accessible in other parts of your code. This is not generally recommendable, but it should do the trick for you here.

The data you fetch through JSON is already in the array format and you can reference object members through the array syntax, so that isn't the source of your problem.

Alex Ciminian
Alex, that is indeed the problem, and I'm not sure how to "promote" that variable so I can use it where I'd like. I provided some sample code here (http://www.3roadsmedia.com/samplejquery.php) that shows where the code blocks are in relation to each other, if you'd like to take a look.
Ryan
Check out my edit :). Cheers!
Alex Ciminian