How to set value in select options from complex objects using knockout?

174 Views Asked by At

How to create two select box from the given object? I need to create two select option box with Country dropdown and State dropdown Selection.

const optionsList =  ko.observableArray ([
    {
        'AD':{'name':'Andora'},
        'AE':{'name':"United Arab Emirates"},
        'AG':{'name':"Antigua & Barbuda"},
        'ES':{'name':"Spain", 'regions':{
                "22": {
                    "code": "A Coruсa",
                    "name": "A Coruña"
                },
                "23": {
                    "code": "Alava",
                    "name": "Alava"
                },
                "24": {
                    "code": "Albacete",
                    "name": "Albacete"
                }
                "25": {
                    "code": "Zaragoza",
                    "name": "Zaragoza"
                }
            }},
        'AT':{'name':"Austria", 'regions':{
                "95": {
                    "code": "WI",
                    "name": "Wien"
                },
                "96": {
                    "code": "NO",
                    "name": "Niederösterreich"
                }
            }},
        'AU':{'name':"Australia", 'regions':{
                "569": {
                    "code": "ACT",
                    "name": "Australian Capital Territory"
                },
                "570": {
                    "code": "NSW",
                    "name": "New South Wales"
                },
                "571": {
                    "code": "VIC",
                    "name": "Victoria"
                },
                "572": {
                    "code": "QLD",
                    "name": "Queensland"
                }
            }}
    }
])

I want to create two dropdown using knockout JS.

  1. Country List
  2. Region list if object contains the region list in object. (like Spain, Austria and Australia)

I am not sure how to create two select box in knockout using the above given object.

Thank you for any useful information.

1

There are 1 best solutions below

2
user3297291 On BEST ANSWER

You can define a regions computed that looks at a selected country and only returns its regions:

const regions = ko.pureComputed(
  () => selectedCountry()?.regions ?? []
  //        can be null -^         ^^- if a country has no regions,
  //                                   return an empty list
);

The data you posted uses objects where I'd expect arrays, so it's slightly different. Here's a runnable example:

const countries = Object.values(getData());
const selectedCountry = ko.observable(null);

const regions = ko.pureComputed(
  () => Object.values(
    selectedCountry()?.regions ?? {}
  )
);
const selectedRegion = ko.observable(null);


ko.applyBindings({ countries, selectedCountry, regions, selectedRegion });

function getData() {
  return {
    'AD': {
      'name': 'Andora'
    },
    'AE': {
      'name': "United Arab Emirates"
    },
    'AG': {
      'name': "Antigua & Barbuda"
    },
    'ES': {
      'name': "Spain",
      'regions': {
        "22": {
          "code": "A Coruсa",
          "name": "A Coruña"
        },
        "23": {
          "code": "Alava",
          "name": "Alava"
        },
        "24": {
          "code": "Albacete",
          "name": "Albacete"
        },
        "25": {
          "code": "Zaragoza",
          "name": "Zaragoza"
        }
      }
    },
    'AT': {
      'name': "Austria",
      'regions': {
        "95": {
          "code": "WI",
          "name": "Wien"
        },
        "96": {
          "code": "NO",
          "name": "Niederösterreich"
        }
      }
    },
    'AU': {
      'name': "Australia",
      'regions': {
        "569": {
          "code": "ACT",
          "name": "Australian Capital Territory"
        },
        "570": {
          "code": "NSW",
          "name": "New South Wales"
        },
        "571": {
          "code": "VIC",
          "name": "Victoria"
        },
        "572": {
          "code": "QLD",
          "name": "Queensland"
        }
      }
    }
  }
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<select data-bind="
  options: countries, 
  value: selectedCountry,
  optionsText: 'name'
"></select>

<select data-bind="
  options: regions, 
  value: selectedRegion,
  optionsText: 'name',
  visible: regions().length
"></select>

<pre data-bind="text: JSON.stringify({ country: selectedCountry(), region: selectedRegion() }, null, 2)"></pre>