0

I have a php script that returns timezones from the form country SELECT and populates the timezone SELECT.

'US' produces ...

PHP

Timezones Array
(
 [0] => America/Adak
 [1] => America/Anchorage
 [2] => America/Boise
 [3] => America/Chicago
...etc...
 [28] => Pacific/Honolulu
)

echo json_encode($timezones_array_above);

But I dont know how to handle the key/value data in javascript/jquery, so I had to create another loop in the php script to name the pair to use the javascript below.

PHP

// I WANT TO GET RID OF THIS EXTRA LOOP AND MOVE IT TO JAVASCRIPT PART BELOW!
foreach ($timezones as $key => $value) {
  $json[] = array(
    'id' => $value,
    'name' => $value
  );
}

echo json_encode($json);

HTML / JQUERY

$('#country').on('change', function (){
  $.post('{$constant->get('AJAXPAGE')}/timezonesbycountry.php', {country: $(this).val()}, function(data){

/*
// I WANT TO HANDLE THE RAW TIMEZONE ARRAY HERE!
// AND REPLACE THIS WITH KEY & VALUE VARS...
    var options = '';
    for (var x = 0; x < data.length; x++) {
      options += '<option value="' + data[x]['id'] + '">' + data[x]['name'] + '</option>';
    }
*/
    $('#timezone').html(options);
  }, 'json');
});

How do I do this in javascript?


Here is the replacement I came up with, which works, but is this correct?

$('#country').on('change', function (){
    $.post( "{$constant->get('AJAXPAGE')}/timezonesbycountry.php", {country: $(this).val()})
    .done(function( data ) {
    var result = JSON.parse(data);
    var options = '';
        $.each(result, function(k, v) {
            options += '<option value="' + v + '">' + v + '</option>';
        });
    $('#timezone').html(options);
    });
});
I Write Bugs
  • 21
  • 1
  • 7
  • Please check if you're sending header `Content-Type: application/json` in your PHP script: http://stackoverflow.com/a/20620606/3647441 – mario.van.zadel Sep 14 '15 at 05:58
  • for (var x = 0; x < data.length; x++) { options += ''; } Should do - you are receiving non associative array in the first case(json_encode) – Milen Georgiev Sep 14 '15 at 06:10
  • When I add the header header('Content-Type: application/json'); echo json_encode($timezones); it quits working and I get "Uncaught SyntaxError: Unexpected token A" – I Write Bugs Sep 14 '15 at 06:30
  • @IWriteBugs , what you made with the JSON.parse is actually the same as what jQuery does behind the scenes, when you specify JSON response type. You've changed the cycle though - prevuously you had the id for option value, now you have the text. – Milen Georgiev Sep 14 '15 at 12:49
  • @Milen Georgiev @mapek - Added the json header and removed `code`var result = JSON.parse(data);`code` - works perfect with 1 less line of code, thank you! – I Write Bugs Sep 14 '15 at 19:14

2 Answers2

0

The elements in your javascript object data are objects and not arrays. You can check it in your console by calling console.log(data);.

Please change

options += '<option value="' + data[x]['id'] + '">' + data[x]['name'] + '</option>';

to

options += '<option value="' + data[x].id + '">' + data[x].name + '</option>';
mario.van.zadel
  • 2,919
  • 14
  • 23
  • You can work with objects, just like with arrays, so having data[x]['id'] isn't much different from data[x].id – Milen Georgiev Sep 14 '15 at 05:48
  • 1
    Thank's a lot for the comment, @MilenGeorgiev :) I've just read something about accessing properties in JS in this answer: http://stackoverflow.com/a/922578/3647441 – mario.van.zadel Sep 14 '15 at 06:04
0

Here is what I came up with, stripped, leaving the basics..

PHP (timezonesbycountry.php)

if (empty($_POST['country'])) {
    $timezones = DateTimeZone::listIdentifiers(DateTimeZone::ALL);
}else{
    $timezones = DateTimeZone::listIdentifiers(DateTimeZone::PER_COUNTRY, $_POST['country']);
}

header('Content-Type: application/json');
echo json_encode($timezones);

JQUERY

$('#country').on('change', function (){
    $.post( 'timezonesbycountry.php', {country: $(this).val()})
    .done(function( data ) {
    var options = '';
        $.each(data, function(k, v) {
            options += '<option value="' + v + '">' + v + '</option>';
        });
    $('#timezone').html(options);
    });
});

HTML

<select class="form-control" id="country" name="country" required>
    <option value="">Select One</option>
    <option value="AF">Afghanistan</option>
    <option value="US">United States</option>
    ...etc...
</select>

<select class="form-control" id="timezone" name="timezone" required>
    <option value="">Select One</option>
    ...etc...
</select>

I use temp keys for all ajax requests, and sanitize the data in the php though...

$.post( '{$constant->get('AJAXPAGE')}/timezonesbycountry.php', {act: 'SOMETHING', ajaxkey: 'KEYHERE', country: $(this).val()})

I also pre-populate the country/timezone selects with php array's; you could pre-populate the timezones with the ajax instead though if your country select is static.

Thanks for the help, hopefully this help somebody else.

I Write Bugs
  • 21
  • 1
  • 7