使用jQuery .each()从数据库中读取JSON到组合框中

问题描述:

I need to be able to select a country in a selectbox, and then get all the states from that country.

I'm trying to do something like this: how-to-display-json-data-in-a-select-box-using-jquery

This is my controller:

foreach($this->settings_model->get_state_list() as $state)
{
   echo json_encode(array($state->CODSTA, $state->STANAM));
}

and my javascript:

 $.ajax({
    url: 'settings/express_locale',
    type: 'POST',
    data: { code: location, type: typeLoc },
    success: function (data) {
        console.log(data);
    }
});

console.log shows me something like this:

["71","SomeState0"]["72","SomeState"]["73","SomeState2"]["74","SomeState3"]

So, what i need is to append all states in a new selectbox.

But I'm trying to read this array doing this in the success callback:

$.each(data, function(key,val){
   console.log(val);
});

In the result, each line is a word, like this:

[
 "
 7
 1
 "
 ,
 "
 s
 ....
 ]

Why does that happen, and what am I missing?

我需要能够在选择框中选择一个国家/地区,然后获取该国家/地区的所有州。

我正在尝试这样做: how-to-display-json-data-in-a-select-box-using-jquery p>

这是我的控制器 : p>

  foreach($ this-> settings_model-> get_state_list()as $ state)
 {
 echo json_encode(array($ state-> CODSTA,  $ state-> STANAM)); 
} 
  code>  pre> 
 
 

和我的javascript: p>

  $ .ajax  ({
 url:'settings / express_locale',
 type:'POST',
 data:{code:location,type:typeLoc},
 success:function(data){
 console.log(data  ); 
} 
}); 
  code>  pre> 
 
 

console.log向我显示如下内容: p>

   [ “71”, “SomeState0”] [ “72”, “SomeState”] [ “73”, “SomeState2”] [ “74”, “SomeState3”] 
上代码>  PRE> 
 
  

所以,我需要的是上诉 nd新选择框中的所有状态。 p>

但是我试图在成功回调中读取此数组: p>

  $  .each(data,function(key,val){
 console.log(val); 
}); 
  code>  pre> 
 
 

在结果中,每一行都是 一句话,如下: p>

  [
“
 7 
 1 
”
,
“
s 
 .... 
]  
  code>  pre> 
 
 

为什么会发生这种情况,我缺少什么? p> div>

JSON is not made of independent blocks. So this will never do:

foreach($this->settings_model->get_state_list() as $state)
{
    echo json_encode(array($state->CODSTA, $state->STANAM));
}

The output will be treated as text, and the iterator will loop the object's elements... which are the single characters.

You need to declare a list, or a dictionary. I have included some examples, depending on how you use the data in the jQuery callback. Note: PHP-side, you may also need to output the proper MIME type for JSON:

$states = array();
foreach($this->settings_model->get_state_list() as $state)
{
    // Option 1: { "71": "SomeState0", "72": "Somestate2", ... }
    // Simple dictionary, and the easiest way IMHO
    $states[$state->CODSTA] = $state->STANAM;

    // Option 2: [ [ "71", "SomeState0" ], [ "72", "SomeState2" ], ... ]
    // List of tuples (well, actually 2-lists)
    // $states[] = array($state->CODSTA, $state->STANAM);

    // Option 3: [ { "71": "SomeState0" }, { "72": "SomeState2" }, ... ]
    // List of dictionaries
    // $states[] = array($state->CODSTA => $state->STANAM);
}

Header('Content-Type: application/json');
// "die" to be sure we're not outputting anything afterwards
die(json_encode($states));

In the jQuery callback, you specify the datatype and content type with charset (this will come in handy as soon as you encounter a state such as the Åland Islands, where a server sending data in ISO-8859-15 and a browser running a page in UTF8 can lead to a painful WTF moment):

        $.ajax({
            url: 'settings/express_locale',
            type: 'POST',
            data: { code: location, type: typeLoc },
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (data) {
                $("#comboId").get(0).options.length = 0;
                $("#comboId").get(0).options[0] = new Option("-- State --", "");
                // This expects data in "option 1" format, a dictionary.
                $.each(data, function (codsta, stanam){
                   n = $("#comboId").get(0).options.length;
                   $("#comboId").get(0).options[n] = new Option(codsta, stanam);
             });
           },
           error: function () {
                alert("Something went wrong");
           }

have you tried using $.map() instead?

http://api.jquery.com/jQuery.map/

$.map(data, function(index, item) {
console.log(item)
})

You should use GET not POST since you are not actually creating anything new serverside. Read a bit about REST and why using GET is the proper noun here.

I've added a JSFiddle example that you can run straight away. http://jsfiddle.net/KJMae/26/

If this is the JSON that the PHP service returns:

{
    "success":true,
    "states":[
        {
            "id":71,
            "name":"California"
        },
        {
            "id":72,
            "name":"Oregon"
        }
    ]
}

This is our HTML code:

<select id="country">
    <option value="">No country selected</option>
    <option value="1">USA</option>
</select>

<select id="states">
</select>​

This is what the code to add that to the select could look like:

// Bind change function to the select
jQuery(document).ready(function() {
    jQuery("#country").change(onCountryChange);
});

function onCountryChange()
{
    var countryId = jQuery(this).val();    

     $.ajax({
        url: '/echo/json/',
        type: 'get',
        data: {
            countryId: countryId
        },
        success: onStatesRecieveSuccess,
        error: onStatesRecieveError
    });
}

function onStatesRecieveSuccess(data)
{
    // Target select that we add the states to
    var jSelect = jQuery("#states");

    // Clear old states
    jSelect.children().remove();

    // Add new states
    jQuery(data.states).each(function(){        
        jSelect.append('<option value="'+this.id+'">'+this.name+'</option>');
    });
}

function onStatesRecieveError(data)
{
    alert("Could not get states. Select the country again.");
}​

As for the PHP, here's a simple example that should give the same result as JSON used in example above. (Haven't tested it, from top of my head, no php here.)

$result = new stdClass;
$result->states = array();

foreach($this->settings_model->get_state_list() as $state)
{
    $stateDto = new stdClass();
    $stateDto->id = $state->CODSTA;
    $stateDto->name = $state->STANAM;

    $result->states[] = $stateDto;
}

$result->success = true;

die(json_encode($result));