0

Edit: Similar but slightly different question can be found here: Vue.js : How to set a unique ID for each component instance?

I'm trying to create a table so that someone can check the people they want to add to a group. So far I've managed to retrieve them from the DB with PHP and display them with vue in HTML. Now I would like to assign each checkbox ID with the email of the student, so i can send the checked students back to PHP later. There may be (a lot) better ways to do this, but I'm very new to this.

This is my current output: My Output

My HTML:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <!-- Axios -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

    <div id="vue-app">
        <table>
            <thead>
                <tr>
                    <th>Select</th>
                    <th>Firstname</th>
                    <th>Lastname</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(student, index) in students">
                <input type="checkbox" id="{{student.email}}">
                <td>{{student.firstname}}</td>
                <td>{{student.lastname}}</td>
                </tr>
            </tbody>
        </table>
    </div>

 var app = new Vue({

            el: '#vue-app',
            data: {
                students: []
            },
            mounted: function () {
                axios.get('get_students_list.php')
                    .then(response => {
                        this.students = response.data;
                        console.log(students);
                    })
                    .catch(error => {
                        console.log(error);
                    });
            }
        })

get_students_list.php:

try {
include("db_connection.php");
$isteacher = false;

$query = "SELECT firstname, lastname, email FROM persons WHERE isteacher = :isteacher";
$statement = $conn->prepare($query);
$statement->bindParam(':isteacher', $isteacher);

$statement->execute();

//gets row as associative array
$users = $statement->fetchAll(PDO::FETCH_ASSOC);


$students = json_encode($users);
echo $students;

} catch (PDOException $error) {
echo $error;
}

I've tried the above id allocation and I also tried creating a checkbox with javascript with the following code (which didn't work either, because for one i can't acces the vue elements from there):

                var checkbox = document.createElement('input');
                checkbox.type = "checkbox";
                checkbox.id = {{student.email}};
                checkbox.checked = false; 

Additional tries:

<input type="checkbox" v-bind:id="student.email">

and

<input type="checkbox" :id="student.email">
5
  • As written in the answer below, you need to bind the id attribute using v-bind. Simply using id="{{...}}" does not interpolate the template variable but inserts it verbatim. Commented Dec 26, 2019 at 12:21
  • Yes but the mentioned code doesn't work either. I tried v-bind:id and just :id but both throw an error in my code. Commented Dec 26, 2019 at 12:47
  • Don't use {{...}} in the attribute, see link to the docs below. Commented Dec 26, 2019 at 12:50
  • Sorry i forgot to take that out of the post, i don't have that in my code anymore anyway. Commented Dec 26, 2019 at 12:51
  • Also, continuously editing the question makes it very hard for readers to see what is going on; rather add to your question what you already tried, so others can follow. Commented Dec 26, 2019 at 12:51

1 Answer 1

1

Note: This refers to the last snippet shown in the question, as the OP changed the question after this answer.

Assuming the server side code & fetching the data works, you don't need to create the input element by another script, you can simple create it like you do with the <td> elements in the v-for loop:

<tr v-for="(student, index) in students">
  <input type="checkbox" :id="student.email"
  <td>{{student.email}}</td>
  <td>{{student.lastname}}</td>
</tr>

Note the : (or v-bind: as the verbose option) before the id attribute, this is used to bind data to attributes. See https://v2.vuejs.org/v2/guide/syntax.html#Attributes

Edit: Added working example: https://codesandbox.io/s/stack-overflow-q-59488184-x8m0w

Edit: You also need to bind the result to the vue instance. this in .then does not point to your component. Use a closure for that:

 mounted() {
    let vm = this;
    axios
      .get("..."
      .then(response => {
        vm.students = response.data;
        console.log(vm.students);
      })
Sign up to request clarification or add additional context in comments.

2 Comments

When i try this code following error appears: "Vue warn]: Property or method "student" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property." and this "[Vue warn]: Error in render: "TypeError: Cannot read property 'email' of undefined"
Thank you so much! I don't quite understand it yet - with me it only works when pasting the code into the same file, but at least it works - so i have a good basis to work on. Thanks!

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.