0

Basing on this How to render custom data in Bootstrap-Vue Table component? I created this code:

assignDocuments(id) {
        const documents = this.$store.state.documentList.filter(e => e.user.idUser === id);
        console.log(documents);
        let i;
        for(i=0; i < documents.length;i++) {
          return documents[i] ? `${documents[i].filename}` : 'loading...';
        }

      }

but it doesn't work like I need... I need to display the names(filename) of all objects(in this case I have 2 objects in documents array) in array but now only name of first object is displayed in b-table.

EDIT:

B-table code:

<b-table ref="table" small striped hover :items="$store.state.userList" :fields="fields" head-variant="dark">
     <template v-slot:cell(indexNumber)="row">
       {{ row.item.indexNumber}}
     </template>

     <template v-slot:cell(name)="row">
       {{ row.item.name}}
     </template>

     <template v-slot:cell(surname)="row">
       {{ row.item.surname}}
     </template>

     <template v-slot:cell(specialization.specName)="row">
       {{ row.item.specialization.specName}}
     </template>

     <template v-slot:cell(yearbook)="row">
       {{ row.item.yearBook.startYear }}<b>/</b>{{ row.item.yearBook.endYear }}
     </template>

     <template v-slot:cell(details)="row">
       <b-button size="sm" @click="row.toggleDetails" class="mr-2">
         {{row.detailsShowing ? 'Ukryj' : 'Pokaż'}} Szczegóły
       </b-button>
     </template>
</b-table>

Fields:

fields:[
            {
              key: 'indexNumber',
              label: 'Numer indeksu'
            },
            {
              key: 'name',
              label: 'Imię'
            },
            {
              key: 'surname',
              label: 'Nazwisko',
            },
            {
              key: 'specialization.specName',
              label: 'Kierunek',
            },
            {
              key: 'yearBook',
              label: 'Rocznik',
            },
            {
              key: 'idUser',
              label: 'Documents',
              formatter: 'assignDocuments'
            },
            {
              key: 'details',
              label: 'Szczegóły',
            },
          ],
1
  • It would be helpful if you could post the relevant HTML code and any other relevant JS Commented Mar 25, 2020 at 20:55

1 Answer 1

0

It's because in your function you are returning after the first iteration of your loop. You instead need to get all the file names, and then return:

In the example that you shared, they are only assigning one value; the first/ last name as a string. In your case, it appears that you have multiple documents that could be related to a single row in the table.

Try changing your code to return all the docs:

assignDocuments(id) {
  const documents = this.$store.state.documentList.filter(e => e.user.idUser === id);
  console.log(documents);

  let fileNames = [];

  // Get the file name for each doc and put into our array
  documents.forEach(elem => fileNames.push(elem.filename));

  // Return the file names as a concatenated string
  return filesNames.length > 0 ? fileNames.join() : 'loading...';

}

Edit:

Based on your comment, I have updated so that you can place this in buttons later on! What you could do is utilize the same function, and then dynamically create your buttons based on the docs that you have for that row.

<template>
  <div>
    <b-table :items="someTableItems" :fields="fields">
      <button v-for="(doc, index) in assignDocuments(someIdHere)" 
              :key="`docBtn-${index}`"
              :class="doc.cssClassObject">
         {{ doc.filename }}
      </button>
    </b-table>
  </div>
</template>

assignDocuments(id) {
  const documents = this.$store.state.documentList.filter(e => e.user.idUser === id);
  console.log(documents);

  let files= [];

  // Get the file name for each doc and put into our array
  documents.forEach(elem => {
    const isAccepted = elem.status === "accepted";

    files.push({
      status: elem.status, 
      filename: elem.filename, 
      cssClassObject : { accepted: isAccepted, rejected: !isAccepted }
    });
  });

  // Return the files as an array
  return files.length > 0 ? files : 'loading...';

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

6 Comments

Now it's working. Thanks! In the future i'm going to replace raw names to a buttons with name. Button will change color based on document status (accepted: button will be green, rejected: red) so I assume this example will stop working becouse i need return a button not a string?
In that case you could simply change fileNames.join() to fileNames. This would return the array of file names itself. You could then dynamically create your button components using a v-for directive and pass the file names to it :)... Edit: updating answer to reflect your new requirements
@DestiX I have finished updating my answer, I haven't tested that new stuff. But the concept is correct
You are really helpfull! Last question :P (I updated queestion, added some more code). So as you can see for documents i use formatter becouse documents contains only idUser(in database idUser is primary key in table Users and foreign key in table documents), so what should I do to display the buttons? I can't do it with your solution in easy way right?
You would definitely have to rework your approach a little bit. What you could do is create a new property to hold your docs for you, then bind you button component to iterate over, instead of calling the assignDocuments function, as I did in my example.
|

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.