Vue - Country Filter Editor

Made with two combo-widgets

by Ben Clayton

HTML

<script src="https://unpkg.com/vue"></script>
 === Vue JS - Array of Twin combo-widgets ====
<div id="interface">
</div>

<script id="vue-tmpl-country-filter-interface" type="text/x-template">
  <div>
    <country-filter-widget v-for="(row,index) in rows" :countrylist="countrylist" :key="index" :row="row" v-on:remove="remove(index)"></country-filter-widget>
    <button v-on:click="add">+</button>
    <br/>
    <br/>
    <br/> Current keywords: {{rows}}
    <br/>
    <br/> Lists for keyword combos: {{countrylist}}
    <br/>
  </div>
</script>


<script id="vue-tmpl-country-filter-widget" type="text/x-template">
  <div class="filter">

    <select v-if="showop" class="cfselect" v-model="row.operator">
      <option v-for="opt in operatorlist">{{opt}}</option>
    </select>
		<span class="dummyselect" v-if="invshowop"></span> 

    <select class="cfselect" v-model="row.country">
      <option v-for="opt in countrylist">{{opt}}</option>
    </select>
    <button v-on:click="remove">-</button>
  </div>
</script>

CSS

.combo-widget {
  display: inline-block;
}

.combo-widget .cwselect {
  position: relative;
  width: 140px;
  height: 26px;
}

.combo-widget .cwselectinput {
  position: absolute;
  z-index: 2;
  width: 110px;
  height: 22px;
  border-top-left-radius: 3px;
  border-bottom-left-radius: 3px;
  border: 1px solid #C0C0C0;
  border-right: 0;
  background-color: rgb(248, 248, 248);
}

input:focus,
select:focus {
  outline: none !important;
}
.dummyselect {
	width:74px;
	display:inline-block;
}

JavaScript

//---------------------------------------------------------
Vue.component('country-filter-widget', {
  template: "#vue-tmpl-country-filter-widget",
  props: ['row', 'countrylist'],
  data: function() {
    return {
      operatorlist: ["", "Include", "Exclude"]
    }
  },

  computed: {
    showop: function() {
      return this.row.country != '[ANY]'
    },
		invshowop: function() {
      return this.row.country == '[ANY]'
    }
  },
  methods: {
    remove() {
        this.$emit('remove');
      },
      newword(listnum) { // called when new word is entered not already in list. params={word,list no}
        //console.log("listnum",listnum,"row name", this.row.name,"row value", this.row.value);
        if (listnum == 1) { // need to add new word to correct array at second level of 'lists'
          this.lists[this.row.name].push(this.row.value); // push new word onto list
        } else { // listnum 0, need to add new key at top level of 'lists'
          Vue.set(this.lists, this.row.name, []);
        }

      }
  }
});

//---------------------------------------------------------
vm1 = new Vue({ // create a root Vue instance
  el: '#interface',
  template: '#vue-tmpl-country-filter-interface',
  data() {
    return {
      rows: [{
        operator: "",
        country: "[ANY]"
      },{
        operator: "Include",
        country: "IRELAND"
      }],
      countrylist: ["[ANY]", "IRELAND", "FRANCE"]
    }
  },
  methods: {
    add() {
        console.log("Add");
        this.rows.push({
          operator: "",
          country: ""
        });
      },
      remove(index) {
        this.rows.splice(index, 1);
      }
  }
});