katie hudson
katie hudson

Reputation: 2893

VueJs Ensure two selects have different options

I have removed a lot of unrelated code, so let me quickly explain the process I am currently trying to deal with. Someone uploads a CSV file, this file could be huge. To avoid sending something so big to the server, I want to process it on the client, as I know which columns I need to keep.

So when the CSV is uploaded, I quickly parse the first row to get the column names. I then assign this to fileHeaders

Once this happens, the following displays

<div v-if="fileHeaders !== ''">
    <div class="form-group">
        <label for="selectId">Select ID Column</label>
        <select class="form-control" id="selectId" v-model="selectedIdCol">
            <option v-for="fileHeader in fileHeaders" :value="fileHeader">{{fileHeader}}
            </option>
        </select>
    </div>
    <div class="form-group">
        <label for="selectDate">Select Date Column</label>
        <select class="form-control" id="selectDate" v-model="selectedDateCol">
            <option v-for="fileHeader in fileHeaders" :value="fileHeader">{{fileHeader}}
            </option>
        </select>
    </div>
</div>

So it is 2 select options, each displaying all fileHeaders. All I need is for the user to let me know what header represents the ID column, and what header represents the Date column.

Within the script, I am currently binding the selected inputs to data

<script>
    export default {
        data: function () {
            return {
                fileHeaders: '',
                selectedIdCol: '',
                selectedDateCol: ''
            }
        },
        methods: {

        }
    }
</script>

Now I wanted to either do one of two things, whatever makes more sense. Firstly, if one option is selected, then I need to make sure this option does not appear in the second select. However, I may need to hide the second select in this case until the first option is selected?

Or, I produce some real time validation, whereby the are unable to select the same option twice?

What would make more sense, and how would I go about doing this? I have seen things like using mounted, but not sure if this a good option?

Thanks

Upvotes: 1

Views: 217

Answers (2)

Kamil Kiełczewski
Kamil Kiełczewski

Reputation: 92427

Try to check selected columns before sending data to server and show proper warrning to user

new Vue({
  el: "#app",
  data: { 
    selectedIdCol: null,
    selectedDateCol: null,
    fileHeaders: ['id', 'column1', 'columnData', 'column3', 'column...']
    
  },
  methods: {
  
    send: function(event) {
    
      if(this.selectedIdCol == this.selectedDateCol) alert('Choose two different columns!')
    },
    
   
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-if="fileHeaders !== ''">
    <div class="form-group">
        <label for="selectId">Select ID Column</label>
        <select class="form-control" id="selectId" v-model="selectedIdCol">
            <option v-for="fileHeader in fileHeaders" :value="fileHeader">{{fileHeader}}
            </option>
        </select>
    </div>
    <div class="form-group">
        <label for="selectDate">Select Date Column</label>
        <select class="form-control" id="selectDate" v-model="selectedDateCol">
            <option v-for="fileHeader in fileHeaders" :value="fileHeader">{{fileHeader}}
            </option>
        </select>
    </div>
    <button @click="send">SEND</button>
</div>
</div>

Upvotes: 0

Stephen Thomas
Stephen Thomas

Reputation: 14053

I would recommend using computed properties to populate both select elements:

<option v-for="fileHeader in idHeaders" :value="fileHeader">
    {{fileHeader}}
</option>

...

<option v-for="fileHeader in dateHeaders" :value="fileHeader">
    {{fileHeader}}
</option>

...

computed: {
    idHeaders() {
        return this.fileHeaders.filter(hdr => hdr !== this.selectedDateCol);
    },
    dateHeaders() {
        return this.fileHeaders.filter(hdr => hdr !== this.selectedIdCol);
    },

Upvotes: 2

Related Questions