Chad E.
Chad E.

Reputation: 1226

Vue JS select with logic

I'm writing an application that uses dropdown menus to map input fields from a CSV file. I would like to implement logic like this: "If the header row reads 'First name' or 'Given Name', then select this option." This code fails with "Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead."

<option value="first name" selected="{{ (field == 'First Name' || field == 'Given Name') ? true : false }}">First name</option>

The reason I don't use :value="field" or v-model="field" is two-fold. First, I have several synonyms I'd like to match, eg. "Date of Birth, DOB, Birth date" Second, many of the header rows won't match any field, in which case I want to revert to a catch-all option "Not Mapped"

I've tried:

<option value="first name" :selected="true : field == 'First Name' || field == 'Given Name'">First Name</option>

But this always seems to select the option no matter what. Even when field == "Date of Birth"

Any suggestions?

EDIT:

MY best workaround so far was to create a function to compute the option value:

<select class="form-select" name="f{index}" :value="mapFieldName(field)">

mapFieldName: function (colName) {

    // Default return value
    var fieldName = "not mapped";

    // Convert to lowercase for case-insensitive matching
    colName = colName.toLowerCase();

    // Match first name field
    if (colName == "first name" || colName == "given name" || colName == "first" || colName == "fn")
        fieldName = "first name";

    // Return computed option value
    return fieldName;           
}

Unless a more elegant solution is proposed, I'll go with this.

Upvotes: 1

Views: 244

Answers (2)

caulfield
caulfield

Reputation: 56

This is a perfect use-case for using v-bind with a method.

Previous answers have driven (somewhat) along similar lines, but I think both v-bind and a method would achieve exactly what you are looking for.

This is a brief example, but hopefully this gives you an idea of what I'm referring to:

<template>
  <div>
    <select class="form-select" :value="selectedFieldName">
      <option v-for="(item, index) in csvCollection" :key="index" :selected="isOptionSelected" @click="selectedFieldName = item.fieldName">{{ item.fieldName }}</option>
    </select>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        selectedFieldName: '',
        csvCollection: []
      }
    },
    methods: {
      isOptionSelected(item) {
        if (item.fieldName.toLower() === "first name" || "given name") {
          return true;
        }
        item.fieldName = "Not Mapped";
        return false;
      }
    }
  }
</script>

Upvotes: 1

fachrilinggo
fachrilinggo

Reputation: 283

you can use v-bind

<option value="first name" v-bind="getSelected('first name','given name')">First name</option> 

then in your script

methods:{
 getSelected(v1, v2){
  if(v1==this.field || v2==this.field){
   return {
    selected:true
   }
 }
}

Upvotes: 0

Related Questions