JSFiddle - React, Tailwind, and code Playground

by Simon Herteby

HTML

<body>
  <div id="app">
    <h1>Geographic Permissions</h1>
    <input type="search" v-model="query" placeholder="filter by country name">
    <ul>
      <li v-for="subregion in continents">
        <input type="checkbox" :value="subregion.find(country => country.checked)"@input="checkParent(subregion)"> <label :for="subregion[0].subregion">{{ subregion[0].subregion }}</label>
        <ul>
          <li v-for="country of subregion">
              <input type="checkbox" v-model="country.checked" > <label :for="country.name">{{ country.name }} (+{{ country.callingCodes[0]}})</label>
          </li>
        </ul>
      </li>
    </ul>
  </div>
  <script src="https://unpkg.com/vue"></script>
  <script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
  <script src="./js/main.js"></script>  
</body>
</html>

CSS

ul {
  list-style-type: none;
}

JavaScript

var apiURL = "https://restcountries.eu/rest/v2/all";

var app = new Vue({
  el: '#app',

  data: {
    subregions: null,
    countries: null,
    query: '',
    countryList: [],
  },

  created: function () {
    this.fetchData();
  },

  computed: {
    continents() {
      const filtered = this.countryList.filter(({name}) => {
        return name.toLowerCase().includes(this.query.toLowerCase())
      });
      return _.groupBy(filtered, "subregion");
    },
  },

  methods: {
    fetchData: function() {
      var xhr = new XMLHttpRequest();
      var self = this;
      xhr.open('GET', apiURL);
      xhr.onload = function() {
        self.countryList = JSON.parse(xhr.responseText);
      };
      xhr.send();
    },
  },
});