0

I have a vue page that loads a bunch of actions from a database. It then creates a table with some data got from the action, using v-for.

Here is my problem: In one of the table rows I need a checkbox that is v-modeled to an attribute, action.weekly. Ideally, it will be a boolean. But there are a bunch of action entries in my database that don't have a weekly attribute. In those cases, I need the checkbox checked, as if it were true. Normally, I would use a computed property here, but you can't pass arguments to computed properties, so I don't know how to tell vue which action to look at at (I can't pass $event, ndx in to a computed property like I am doing below with handleEnableChanged() ).

Here is my code for the table:

<tbody>
            <tr v-for="(action, ndx) in actions" >
              <td class="pointer" @click='openModalCard(action, ndx)'>
                {{action.name}}
              </td>
                <input type="checkbox" v-model="action.weekly??" @change="handleEnableChanged($event, ndx)"/>
              </td>
                <input type="checkbox" v-model="action.enabled" @change="handleEnableChanged($event, ndx)">
              </td>
            </tr>
            </tbody>

In the cases where action does not have a weekly attribute, I want the checkbox checked as if it were true. How can I accomplish this?

If there is a better way to approach this, please let me know. I'm still a novice with vue.js.

2
  • 1
    Can you just v-if it? Commented Dec 16, 2019 at 18:32
  • 1
    As far as I understand it, v-if is only for optional rendering. I want the checkbox rendered either way, but I want it checked if the v-model attribute is true or undefined. Commented Dec 16, 2019 at 18:39

3 Answers 3

1

I think it would be easiest to use v-if and v-else for this.. With that being said, I have also provided an example of how to handle this without v-if and v-else..

Using v-if and v-else:

new Vue({
  el: "#root",
  data: {
    actions: [
        {
          name: "first",
          weekly: true,
          enabled: false
        },
        {
          name: "second",
          enabled: false
        },
        {
          name: "third",
          weekly: true,
          enabled: true
        },
        {
          name: "fourth",
          enabled: true
        }
      ]
  },
  template: `
<tbody>
  <tr v-for="(action, ndx) in actions" >
    <td class="pointer" @click='console.log(action, ndx)'>{{action.name}}</td>
    <input v-if="'weekly' in action" type="checkbox" v-model="action.weekly" @change="handleEnableChanged($event, ndx)"/>
    <input v-else type="checkbox" checked="true" @change="handleEnableChanged($event, ndx)"/>
    </td>
    <input type="checkbox" v-model="action.enabled" @change="handleEnableChanged($event, ndx)">
    </td>
  </tr>
</tbody>
  `,
  methods: {
    handleEnableChanged(evt, ndx) {
      console.log(evt, ndx);
    },
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<div id="root"></div>

Without v-if and v-else:

new Vue({
  el: "#root",
  data: {
    actions: ""
  },
  template: `
<tbody>
  <tr v-for="(action, ndx) in actions" >
    <td class="pointer" @click='console.log(action, ndx)'>{{action.name}}</td>
    <input type="checkbox" v-model="action.weekly" @change="handleEnableChanged($event, ndx)"/>
    </td>
    <input type="checkbox" v-model="action.enabled" @change="handleEnableChanged($event, ndx)">
    </td>
  </tr>
</tbody>
  `,
  methods: {
    handleEnableChanged(evt, ndx) {
      console.log(evt, ndx);
    },
    getActions() {
      let originalActions = [
        {
          name: "first",
          weekly: true,
          enabled: false
        },
        {
          name: "second",
          enabled: false
        },
        {
          name: "third",
          weekly: true,
          enabled: true
        },
        {
          name: "fourth",
          enabled: true
        }
      ];
      this.actions = originalActions.map(a => { 
        return {
          name: a.name,
          weekly: 'weekly' in a ? a.weekly : true,
          enabled: a.enabled
        }
      })
    }
  },
  created() {
    this.getActions();
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<div id="root"></div>

Sign up to request clarification or add additional context in comments.

Comments

0

You can just do this:

<input type="checkbox" :checked="!!action.weekly">

The !! operator will return true if the value is not undefined or empty

Comments

0

If you want all items in the array to have an action.weekly property, then update your data when it is initially retrieved. You can then just use v-model="action.weekly" for all items in the array.

this.newArray = this.oldArray.map(item => {
  if(!item.hasOwnProperty('weekly')){
    item.weekly = true;
  }
  return item
})

2 Comments

If item.weekly is false, wouldn't this just change it to true? I think a better way to check for the existence of the weekly key would be to do something like: if('weekly' in item){...}
Ah yes, my mistake. Yes you'd need to check it exists first before setting to true. I'll update the answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.