user15282016
user15282016

Reputation:

v-select with groups from data via api

I get from my API this data:

[
   {
      "id":69,
      "name":"Baupraxis",
      "upper_id":7
   },
   {
      "id":42,
      "name":"bautipps.de",
      "upper_id":4
   },
   {
      "id":16,
      "name":"Bellevue",
      "upper_id":7
   },
   {
      "id":18,
      "name":"besser Bauen",
      "upper_id":7
   },
   {
      "id":2,
      "name":"Besuch auf Betriebsgel\u00e4nde",
      "upper_id":0
   },
   {
      "id":7,
      "name":"billiger Bauen",
      "upper_id":0
   }
]

I use it to fill a v-select like this:

<v-select
 label="Anfrageart"
 dense
 :items="itemsRequestTypes"
 item-text="name"
 item-value="id"
 v-model="requestType"
>
</v-select>

So here's what I'd like to solve, the upper_id is greater than zero if it is a subgroup of an item with the matching id. Means in upper_id is the id of the main group.

How can I group this in a v-select now? I try to add a header in the object, but this didn't help.

Upvotes: 3

Views: 2275

Answers (1)

Harshal Patil
Harshal Patil

Reputation: 21030

You need to transform your data from the API before passing it to the template. Also, v-select supports nested option group using items where header type represents the group header which is non-selectable item.

const data = [
  {
    "id": 69,
    "name": "Baupraxis",
    "upper_id": 7
  },
  {
    "id": 42,
    "name": "bautipps.de",
    "upper_id": 4
  },
  {
    "id": 16,
    "name": "Bellevue",
    "upper_id": 7
  },
  {
    "id": 18,
    "name": "besser Bauen",
    "upper_id": 7
  },
  {
    "id": 2,
    "name": "Besuch auf Betriebsgel\u00e4nde",
    "upper_id": 0
  },
  {
    "id": 7,
    "name": "billiger Bauen",
    "upper_id": 0
  }
];

// Create an intermediate object to hold categories.
const groups = {};

// Create array for each group to main subgroup list.
data.forEach((x) => {
  // create empty object if it doesn't exists.
  groups[x.upper_id] = groups[x.upper_id] || { name: x.name, list: [] };
  
  groups[x.upper_id].list.push(x);
});

// The flattened list of items that holds items as well as unique headers
const flattened = [];

// Iterate over all the unique categories and
// then flatten into a list that v-select needs.
Object.keys(groups).forEach((categoryId) => {
  const catgory = groups[categoryId];
  const categoryName = category.name;

  // Create a group 
  flattened.push({ header: categoryName });

  // Add all the items followed by category header
  flattened.push(...category.list);
});

Upvotes: 2

Related Questions