This is a first version of a rough around the edges Vue.js component. I built it as fast as possible. I just used lodash
as a dependency.
<template> <div class="selector"> <button @click="onClickButton" class="main">{{getTotal}} selected</button> <div v-if="selectorOpen"> <button @click="selectAll">All</button> <button @click="selectNone">None</button> <ul> <li v-for="item in countries" @click="onClickList(item.country)"> <input type="checkbox" checked v-if="item.checked"> <input type="checkbox" v-else> {{item.country}} </li> </ul> </div> <div class="hello"> Hello, {{getCountryListString}}! </div> </div> </template> <script> import {map, size, filter} from 'lodash' export default { name: 'HelloWorld', data () { return { countries: [ { country: 'Russia', checked: true }, { country: 'US', checked: false }, { country: 'China', checked: false }, { country: 'Europe', checked: false }, { country: 'India', checked: false }, { country: 'Japan', checked: false } ], selectorOpen: false } }, computed: { getChecked () { return filter(this.countries, (item, idx) => { return item.checked === true }) }, getTotal () { return size(this.getChecked) }, getCountryListString () { const names = map(this.getChecked, (i) => { return i.country }) return size(names) > 0 ? names.join(', ') : 'everybody' } }, methods: { onClickButton () { this.selectorOpen = !this.selectorOpen }, onClickList (country) { this.countries = map(this.countries, (i, idx) => { if (i.country === country) { return {...i, checked: !i.checked} } return i }) }, selectAll () { this.countries = map(this.countries, (i, idx) => { return {...i, checked: true} }) }, selectNone () { this.countries = map(this.countries, (i, idx) => { return {...i, checked: false} }) } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> .selector { width: 400px; margin: 20px auto; padding: 10px; } button.main { width: 100%; margin-bottom: 2px; } ul { margin: 10px 0px; padding: 0; height: 90px; overflow: auto; text-align: left; background-color: #f1f1f1; border: 1px solid #ccc; } li { list-style: none; } </style>