1

I have a table with two columns(Location and Users). The location is static information but the users is a multi-select using Vue-Select. I need to shows users currently selected for a location on page load. I grab that information from a database. I also need to be able to change the selected users of a location by using a multi-select that shows all users. Example Mock

Vue Outline

<table>
    <thead>
    <tr>
        <th class="col-xs-2">Locations</th>
        <th class="col-xs-8">Users</th>
    </tr>
    </thead>
    <tbody>
        <tr v-for="(row, index) in rows" v-bind:key="index">
            <td>
              <span>{{ row.location }}</span>
            </td>
            <td>
                <v-select multiple v-model="row.users">
                <option v-for="user in allUsers" :key="user.id" :value="user.id">{{ user.name }}</option>
                </v-select>
            </td>
        </tr>
    </tbody>
</table>

Vue

var app = new Vue({
    el: '#el',
    data() {
        return {
          errors: [],
          loading: false,
          rows: this.assignments,
          allUsers: this.users
        }
    },
   props: {
     assignments: Array,
     users: Array
   },
})

Example of how rows are returned from database

    [{
    "locations":[
      { "id":1,
        "name":"SomePlace, CA",
        "users": [
          {"id":1, "name":"Person One"},
          {"id":2, "name":"Person Two"}
        ]
      },
      { "id":2,
        "name":"AnotherPlace, CA",
        "users": [
          {"id":3, "name":"Person Three"}
        ]
      }
    ]
  },
  {
    "locations":[
      { "id":1,
        "name":"SomePlace, CA",
        "users": [
          {"id":1, "name":"Person One"},
          {"id":2, "name":"Person Two"}
        ]
      },
      { "id":2,
        "name":"AnotherPlace, CA",
        "users": [
          {"id":3, "name":"Person Three"}
        ]
      }
    ]
  }]

Example of how all users are returned from database

[
    ["id":1, "name":"Person One"],
    ["id":2, "name":"Person Two"],
    ["id":3,"name":"Person Three"],
]
11
  • please clarify more your use case Commented Oct 29, 2018 at 18:51
  • 1
    @BoussadjraBrahim I have a table that shows a location and the users that are associated with that location. All the users that are associated to a location can be selected in the V-Select. A user is defined as an object with an id and name property. The issue is the Vue cannot support v model binding of objects. I need a workaround to be able to still use the id of user object but display the name Commented Oct 29, 2018 at 20:33
  • i can't figure out your use case, could you edit this pen to give me a start point to help you Commented Oct 29, 2018 at 20:38
  • 1
    Check this pen Commented Oct 29, 2018 at 20:55
  • @MohamedEl-Refaie You should post that as an answer with an explanation Commented Oct 29, 2018 at 21:05

2 Answers 2

1

I had moved the data coming via props directly to data object, since your rows property has one item which contains locations array, i looped through the first item rows[0] and i put row as the select options :options="row" and for the second column i looped through the user of the selectedLocation :

Vue.component('v-select', VueSelect.VueSelect)

var app = new Vue({
  el: '#app',
  data() {
    return {
      errors: [],
      loading: false,
      rows: [{
          "locations": [{
              "id": 1,
              "name": "SomePlace, CA",
              "users": [{
                  "id": 1,
                  "name": "Person One"
                },
                {
                  "id": 2,
                  "name": "Person Two"
                }
              ]
            },
            {
              "id": 2,
              "name": "AnotherPlace, CA",
              "users": [{
                "id": 3,
                "name": "Person Three"
              }]
            }
          ]
        },
        {
          "locations": [{
              "id": 1,
              "name": "SomePlace, CA",
              "users": [{
                  "id": 1,
                  "name": "Person One"
                },
                {
                  "id": 2,
                  "name": "Person Two"
                }
              ]
            },
            {
              "id": 2,
              "name": "AnotherPlace, CA",
              "users": [{
                "id": 3,
                "name": "Person Three"
              }]
            }
          ]
        }
      ],
      allUsers: this.users
    }
  },
  props: {
    assignments: Array,
    users: Array
  },
})
<table>
  <thead>
    <tr>
      <th class="col-xs-2">Locations</th>
      <th class="col-xs-8">Users</th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="(row, index) in rows[0].locations" v-bind:key="index">
      <td class="lead-locations">
        {{row.name}}
      </td>
      <td class="lead-users">
        <v-select multiple v-model="row.users" label="name">
        </v-select>
      </td>
    </tr>
  </tbody>
</table>

for demo check this code

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

2 Comments

I dont know if the demo link is the correct one you meant to share but it does not compile. The other link that you shared (codepen.io/anon/pen/VENNWg?editors=1010) is closer. But the location should not be changeable because each location should be shown in its on row. The users dropdown should show the saved users from 'Example of how rows are returned from database' in the question with the options of 'Example of how all users are returned from database'
This works perfectly! The updated pin does exactly as I needed. I was trying to bind the incorrect things to the model. Thanks for all your help @Boussadjra Brahim!
1

I believe that the sample data supplied to the "rows" variable are missing.

So, I will make an imaginary assumption here that you have some web servers distributed in multiple locations and you want to manage access of users.

The following is my imaginary data for "rows" variable which is close enough to your data:

[
{
    "serverID": 1,
    "serverName": "My Backend API Server",
    "locations": [
    {
        "id": 1,
        "name": "SomePlace, CA",
        "users": [
        { "id": 1, "name": "Person One" },
        { "id": 2, "name": "Person Two" }
        ]
    },
    {
        "id": 2,
        "name": "AnotherPlace, CA",
        "users": [{ "id": 3, "name": "Person Three" }]
    }
    ]
},
{
    "serverID": 1,
    "serverName": "My Frontend App Server",
    "locations": [
    {
        "id": 1,
        "name": "SomePlace, CA",
        "users": [
        { "id": 1, "name": "Person One" },
        { "id": 2, "name": "Person Two" }
        ]
    },
    {
        "id": 2,
        "name": "AnotherPlace, CA",
        "users": [{ "id": 3, "name": "Person Three" }]
    }
    ]
}
]

Now, we have to loop over the servers array first, then loop over the locations array to get some thing close to your mock as follows:

Check this pen for the implementation.

JS Code:

Vue.component('v-select', VueSelect.VueSelect)

let servers = [
    {
        "serverID": 1,
        "serverName": "My Backend API Server",
        "locations": [
        {
            "id": 1,
            "name": "SomePlace, CA",
            "users": [
            { "id": 1, "name": "Person One" },
            { "id": 2, "name": "Person Two" }
            ]
        },
        {
            "id": 2,
            "name": "AnotherPlace, CA",
            "users": [{ "id": 3, "name": "Person Three" }]
        }
        ]
    },
    {
        "serverID": 1,
        "serverName": "My Frontend App Server",
        "locations": [
        {
            "id": 1,
            "name": "SomePlace, CA",
            "users": [
            { "id": 1, "name": "Person One" },
            { "id": 2, "name": "Person Two" }
            ]
        },
        {
            "id": 2,
            "name": "AnotherPlace, CA",
            "users": [{ "id": 3, "name": "Person Three" }]
        }
        ]
    }
    ];

let users = [
    {"id":1, "name":"Person One"},
    {"id":2, "name":"Person Two"},
    {"id":3,"name":"Person Three"},
];

var app = new Vue({
    el: '#app',
    data() {
        return {
        errors: [],
        loading: false,
        selectedLocation: {},
        rows:  servers,
        allUsers: users
        }
    }
})

HTML Code:

<div id="app">
<table>
    <thead>
    <tr>
        <th class="col-xs-2">Locations</th>
        <th class="col-xs-8">Users</th>
    </tr>
    </thead>
    <tbody>
        <tr v-for="(row, index) in rows" v-bind:key="index">
            <td colspan="2">
            <b>{{ row.serverName }}</b>
            <table>
                <tr  v-for="(location, l_index) in row.locations" v-bind:key="l_index">
                    <td class="col-xs-2">{{ location.name }}</td>
                    <td class="col-xs-8">
                    <v-select multiple v-model="location.users" label="name" :options="allUsers">
                </v-select>
                    </td>
                </tr>
            </table>
            </td>

            <td class="lead-locations">
            {{ row.locations.name }}          
            </td>
            <td class="lead-users">

            </td>
        </tr>
    </tbody>
</table>
</div>

1 Comment

This is basically what I was trying to accomplish, but you can only select a user once. Boussadjra Brahim solution was very similar

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.