0

I'm doing a project using Laravel 8 and Vue 3, and I have a Student Component. There is in it, a datalist to find the students that are already created, and I would like, when I select a student, that it fills my fields with the data that is in my database.

I already tried thigs with vueJs and v-model, but I only get the string that is in the input of the datalist. I also had some issues when I try to retrieve the data that I have [object Object] in my field or in the datalist input.

So there is my code :

//This is the data of my trainees which are my students
 data() {
        return {
            trainees: [],
          },
          //And this is the method that I use to retrieve the student from the database
  methods: {
     getTrainee() {
            axios.get(AXIOS + 'trainee')
                .then(response => this.trainees = response.data)
                .catch(error => console.log(error));
        },
  },
<!--This is a part of my student component, this is the datalist where I can find my students-->
 
 <div class="search_trainee">
            <input id="search" class="search_trainee_input" list="trainees" placeholder=" "
                   type="text">
            <label class="label_search" for="search">Search a trainee</label>
            <datalist  id="trainees">
                <option v-for="user in trainees" :key="user.id">
                    {{ user.firstname }} {{ user.lastname }}
                </option>
            </datalist>
        </div>
        
  <!--This is the other part in my Student component, this is the part where I want my input and filed to be fill with the data of the student I pick-->

        <div class="form_trainee">
            <h3 class=" title_form">Add a trainee</h3>
            <div class="row g-3">
                <div class="col-md-6">
                    <input id="lastname" ref="lastname" class="form-control" name="lastname" placeholder=" "
                           type="text" @blur.prevent="addTrainee();displayAudit()">
                    <label class="label_form" for="lastname">Lastname</label>
                </div>
                <div class="col-md-6">
                    <input id="firstname" ref="firstname" class="form-control" name="firstname" placeholder=" "
                           type="text" @blur.prevent="update">
                    <label class="label_form" for="firstname">Firstname</label>
                </div>
                <div class="col-md-6">
                    <input id="email" ref="email" class="form-control" name="email" placeholder=" " type="email"
                           @blur.prevent="update">
                    <label class="label_form" for="email">Email</label>

                </div>
                <div class="col-md-6">
                    <input id="company" ref="company" class="form-control" name="company" placeholder=" "
                           type="text"
                           @blur.prevent="update">
                    <label class="label_form" for="company">Company</label>

                </div>
                <div class="col-md-6">
                    <input id="vehicle" ref="vehicle" class="form-control" name="vehicle" placeholder=" "
                           type="text"
                           @blur.prevent="update">
                    <label class="label_form" for="vehicle">Vehicle</label>

                </div>
                <div class="col-md-6">
                    <input id="location" ref="location" class="form-control" name="location" placeholder=" "
                           type="text"
                           @blur.prevent="update">
                    <label class="label_form" for="location">Location</label>

                </div>
                <div class="col-md-6">
                    <select id="instructor_id" ref="instructor_id" v-model="instructor" class="form-control"
                            name="instructor_id"
                            @blur.prevent="update">
                        <option value="">--Choose an instructor--</option>
                        <option v-for="user in instructors" :key=user.id v-bind:value="{id:user.id}">{{
                                user.firstname
                            }}
                            {{ user.lastname }}
                        </option>
                    </select>
                </div>
                <div class="col-md-6">
                    <select id="acpCenter" ref="acp_center_id" v-model="acpCenter" class="form-control" name="acpCenter"
                            @blur.prevent="update">
                        <option value="">--Choose an Acp Center--</option>
                        <option v-for="center in acpCenters" :key="center.id" v-bind:value="{id:center.id}">
                            {{ center.city }} {{ center.postal_code }}
                        </option>
                    </select>
                </div>
            </div>
        </div>

Any help or advice or tip is welcome, I can provide more code if neccessary. Thanks for your time.

Bastien
  • 71
  • 1
  • 13
  • where are you calling getTrainee() method ? – Franco Mitoire Aug 18 '21 at 14:29
  • @FrancoMitoire Well, its on the created of vue js, then the data goes intot 'Trainees' then I use it – Bastien Aug 18 '21 at 14:29
  • Did u try define selectedUser var in your data option and then Click one and take a look at vue dev tools, what is in your selectedUser var – Franco Mitoire Aug 18 '21 at 14:33
  • Is trainees supposed to be an array? If so, you are missing the brackets ```[]```. – Tim Aug 18 '21 at 14:35
  • @Tim Oh yes that's true, it was like this at the begining I was just trying things, I edited my post – Bastien Aug 18 '21 at 14:37
  • @FrancoMitoire I can not use vue devtool, I dont know why, I installed it at the beginning of my project but he don't want to see that am using vue in my project – Bastien Aug 18 '21 at 14:39
  • Well, maybe you can try fix that first, and it would be much easier track errors – Franco Mitoire Aug 18 '21 at 14:41
  • @FrancoMitoire I already tried, but I remember that click are not working on Options, so I could not get that information back – Bastien Aug 18 '21 at 14:44
  • put a
    inside your option tag, and bind the click to the div. Maybe u can print {{selectedUser}} in template to debug
    – Franco Mitoire Aug 18 '21 at 14:47
  • @FrancoMitoire Not working I tried this way , but moreover div tag are not allowed there – Bastien Aug 18 '21 at 14:50

1 Answers1

1

Actually, the datalist don't have event handlers in vuejs. Hence it becomes difficult to achieve what you're trying to achieve. Why don't you give vue-select a try? it's pretty simple to use and it's very easy to handle the events.

Here's a demo for you:

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

new Vue({
  el: "#app",
  data() {
    return {
      selectedStudent: "",
      acpCenter: "",
      instructor: "",
      instructors: [
        { id: 10, firstname: "instructor1", lastname: "lastname" },
        { id: 11, firstname: "instructor2", lastname: "lastname" },
        { id: 12, firstname: "instructor3", lastname: "lastname" }
      ],
      acpCenters: [
        { id: 10, city: "city", postalCode: "postalCode" },
        { id: 11, city: "city2", postalCode: "postalCode" },
        { id: 12, city: "city3", postalCode: "postalCode" }
      ],
      trainees: []
    };
  },
  mounted() {
    this.getTrainee();
  },
  //And this is the method that I use to retrieve the student from the database
  methods: {
    getTrainee() {
      this.trainees = [
        {
          id: 10,
          firstname: "Ben",
          lastname: "Alphonso",
          company: "company",
          vehicle: "vehicle",
          location: "location",
          email: "something.1@email.com"
        },
        {
          id: 11,
          firstname: "Carry",
          lastname: "Menati",
          company: "company",
          vehicle: "vehicle",
          location: "location",
          email: "something.2@email.com"
        },
        {
          id: 13,
          firstname: "Bruce",
          lastname: "Wayne",
          company: "Wayne Enterprises",
          vehicle: "vehicle",
          location: "location",
          email: "something.2@email.com"
        }
      ];
    },

    onInput(val) {
      if (!val) if (!val) this.selectedStudent = { firstname: "" };
    },

    addTrainee() {
      return false;
    },
    displayAudit() {
      return false;
    },
    update() {
      return true;
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vue-select@latest"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-select@latest/dist/vue-select.css">

<div id="app">
  <template>
  <div class="container">
    <div class="search_trainee">
      <v-select
        v-model="selectedStudent"
        @input="onInput"
        label="firstname"
        :options="trainees"
      ></v-select>
    </div>

    <!--This is the other part in my Student component, this is the part where I want my input and filed to be fill with the data of the student I pick-->

    <div class="form_trainee">
      <h3 class="title_form">Add a trainee</h3>
      <div class="row g-3">
        <div class="col-md-6">
          <input
            id="lastname"
            ref="lastname"
            class="form-control"
            name="lastname"
            v-model="selectedStudent.lastname"
            placeholder=" "
            type="text"
          />
          <label class="label_form" for="lastname">Lastname</label>
        </div>
        <div class="col-md-6">
          <input
            id="firstname"
            ref="firstname"
            class="form-control"
            name="firstname"
            v-model="selectedStudent.firstname"
            placeholder=" "
            type="text"
            @blur.prevent="update"
          />
          <label class="label_form" for="firstname">Firstname</label>
        </div>
        <div class="col-md-6">
          <input
            id="email"
            ref="email"
            class="form-control"
            name="email"
            placeholder=" "
            v-model="selectedStudent.email"
            type="email"
            @blur.prevent="update"
          />
          <label class="label_form" for="email">Email</label>
        </div>
        <div class="col-md-6">
          <input
            id="company"
            ref="company"
            class="form-control"
            name="company"
            placeholder=" "
            v-model="selectedStudent.company"
            type="text"
            @blur.prevent="update"
          />
          <label class="label_form" for="company">Company</label>
        </div>
        <div class="col-md-6">
          <input
            id="vehicle"
            ref="vehicle"
            class="form-control"
            name="vehicle"
            placeholder=" "
            v-model="selectedStudent.vehicle"
            type="text"
            @blur.prevent="update"
          />
          <label class="label_form" for="vehicle">Vehicle</label>
        </div>
        <div class="col-md-6">
          <input
            id="location"
            ref="location"
            class="form-control"
            name="location"
            placeholder=" "
            v-model="selectedStudent.location"
            type="text"
            @blur.prevent="update"
          />
          <label class="label_form" for="location">Location</label>
        </div>
        <div class="col-md-6">
          <select
            id="instructor_id"
            ref="instructor_id"
            v-model="instructor"
            class="form-control"
            name="instructor_id"
            @blur.prevent="update"
          >
            <option value="">--Choose an instructor--</option>
            <option
              v-for="user in instructors"
              :key="user.id"
              v-bind:value="{ id: user.id }"
            >
              {{ user.firstname }}
              {{ user.lastname }}
            </option>
          </select>
        </div>
        <div class="col-md-6">
          <select
            id="acpCenter"
            ref="acp_center_id"
            v-model="acpCenter"
            class="form-control"
            name="acpCenter"
            @blur.prevent="update"
          >
            <option value="">--Choose an Acp Center--</option>
            <option
              v-for="center in acpCenters"
              :key="center.id"
              v-bind:value="{ id: center.id }"
            >
              {{ center.city }} {{ center.postalCode }}
            </option>
          </select>
        </div>
      </div>
    </div>
  </div>
</template>
</div>
Note, this is a browser version. The way you import this into your local nodejs project is:
  1. yarn add vue-select or npm install vue-select to install dependency
  2. import the vue-select component and css like so:
<script>
import Vue from "vue";
import vSelect from "vue-select";
import "vue-select/dist/vue-select.css";
Vue.component("v-select", vSelect);
</script>

Final code in your app.vue or something.vue file, will look like this:

<template>
  <div class="container">
    <div class="search_trainee">
      <v-select
        v-model="selectedStudent"
        @input="onInput"
        label="firstname"
        :options="trainees"
      ></v-select>
    </div>

    <!--This is the other part in my Student component, this is the part where I want my input and filed to be fill with the data of the student I pick-->

    <div class="form_trainee">
      <h3 class="title_form">Add a trainee</h3>
      <div class="row g-3">
        <div class="col-md-6">
          <input
            id="lastname"
            ref="lastname"
            class="form-control"
            name="lastname"
            v-model="selectedStudent.lastname"
            placeholder=" "
            type="text"
          />
          <label class="label_form" for="lastname">Lastname</label>
        </div>
        <div class="col-md-6">
          <input
            id="firstname"
            ref="firstname"
            class="form-control"
            name="firstname"
            v-model="selectedStudent.firstname"
            placeholder=" "
            type="text"
            @blur.prevent="update"
          />
          <label class="label_form" for="firstname">Firstname</label>
        </div>
        <div class="col-md-6">
          <input
            id="email"
            ref="email"
            class="form-control"
            name="email"
            placeholder=" "
            v-model="selectedStudent.email"
            type="email"
            @blur.prevent="update"
          />
          <label class="label_form" for="email">Email</label>
        </div>
        <div class="col-md-6">
          <input
            id="company"
            ref="company"
            class="form-control"
            name="company"
            placeholder=" "
            v-model="selectedStudent.company"
            type="text"
            @blur.prevent="update"
          />
          <label class="label_form" for="company">Company</label>
        </div>
        <div class="col-md-6">
          <input
            id="vehicle"
            ref="vehicle"
            class="form-control"
            name="vehicle"
            placeholder=" "
            v-model="selectedStudent.vehicle"
            type="text"
            @blur.prevent="update"
          />
          <label class="label_form" for="vehicle">Vehicle</label>
        </div>
        <div class="col-md-6">
          <input
            id="location"
            ref="location"
            class="form-control"
            name="location"
            placeholder=" "
            v-model="selectedStudent.location"
            type="text"
            @blur.prevent="update"
          />
          <label class="label_form" for="location">Location</label>
        </div>
        <div class="col-md-6">
          <select
            id="instructor_id"
            ref="instructor_id"
            v-model="instructor"
            class="form-control"
            name="instructor_id"
            @blur.prevent="update"
          >
            <option value="">--Choose an instructor--</option>
            <option
              v-for="user in instructors"
              :key="user.id"
              v-bind:value="{ id: user.id }"
            >
              {{ user.firstname }}
              {{ user.lastname }}
            </option>
          </select>
        </div>
        <div class="col-md-6">
          <select
            id="acpCenter"
            ref="acp_center_id"
            v-model="acpCenter"
            class="form-control"
            name="acpCenter"
            @blur.prevent="update"
          >
            <option value="">--Choose an Acp Center--</option>
            <option
              v-for="center in acpCenters"
              :key="center.id"
              v-bind:value="{ id: center.id }"
            >
              {{ center.city }} {{ center.postalCode }}
            </option>
          </select>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import Vue from "vue";
import vSelect from "vue-select";
import "vue-select/dist/vue-select.css";
Vue.component("v-select", vSelect);

export default {
  name: "TodoList",
  data() {
    return {
      selectedStudent: "",
      acpCenter: "",
      instructor: "",
      instructors: [
        { id: 10, firstname: "instructor1", lastname: "lastname" },
        { id: 11, firstname: "instructor2", lastname: "lastname" },
        { id: 12, firstname: "instructor3", lastname: "lastname" }
      ],
      acpCenters: [
        { id: 10, city: "city", postalCode: "postalCode" },
        { id: 11, city: "city2", postalCode: "postalCode" },
        { id: 12, city: "city3", postalCode: "postalCode" }
      ],
      trainees: []
    };
  },
  mounted() {
    this.getTrainee();
  },
  //And this is the method that I use to retrieve the student from the database
  methods: {
    getTrainee() {
      this.trainees = [
        {
          id: 10,
          firstname: "Ben",
          lastname: "Alphonso",
          company: "company",
          vehicle: "vehicle",
          location: "location",
          email: "something.1@email.com"
        },
        {
          id: 11,
          firstname: "Carry",
          lastname: "Menati",
          company: "company",
          vehicle: "vehicle",
          location: "location",
          email: "something.2@email.com"
        },
        {
          id: 13,
          firstname: "Bruce",
          lastname: "Wayne",
          company: "Wayne Enterprises",
          vehicle: "vehicle",
          location: "location",
          email: "something.2@email.com"
        }
      ];
    },

    onInput(val) {
      if (!val) this.selectedStudent = { firstname: "" };
    },

    addTrainee() {
      return false;
    },
    displayAudit() {
      return false;
    },
    update() {
      return true;
    }
  }
};
</script>
Salvino D'sa
  • 4,018
  • 1
  • 7
  • 19
  • When I do this, I can barely click on the dropdown of my datalist (I don't know why, it's like clipping when I put my mouse on it, and if I manage to click on it, the input of the datalist is filled with [Object object], And I have a warning in console : Unexpected token < in JSON at position 0 that I didnt have before – Bastien Aug 18 '21 at 16:25
  • So I follow the documentation of vue-select, and I now have this error : TypeError: this.$on is not a function, and the v-select tag are highlighted – Bastien Aug 19 '21 at 07:22
  • I do the import in the app.js, but actually I can't use Vue.component, but I use something else then, but still not working for me – Bastien Aug 19 '21 at 07:28
  • ah sorry, this is a browser version. when you run it in a node server you will need to put it a bit differently. Let me update the answer. – Salvino D'sa Aug 19 '21 at 07:41
  • 1
    @Bastien updated my answer, trying using the final code, it's a actual working file that I pasted. – Salvino D'sa Aug 19 '21 at 07:48
  • Yeah, that's what I used before, but same error here, the error : TypeError: this.$on is not a function is coming 6 times on console and the warnings: Unhandled error during execution of created hook at ... > and this one Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next at ... > at are also coming 6 times – Bastien Aug 19 '21 at 07:52
  • Please cross reference your file with the one I pasted last, Its a working code. I'm using `"vue": "^2.6.12"`. Which vue version are you on? – Salvino D'sa Aug 19 '21 at 07:55
  • Ah that might be the issue, am using "vue": "^3.1.5" – Bastien Aug 19 '21 at 07:56
  • 1
    yep, you're right. there's a solution for it. Check this [answer](https://stackoverflow.com/questions/68262456/vue-3-typescript-uncaught-in-promise-typeerror-this-on-is-not-a-function) and comments on it. You can use [this](https://iendeavor.github.io/vue-next-select/) library instead, which has similar implementation but is for vue 3 – Salvino D'sa Aug 19 '21 at 07:59
  • 1
    I took a look at it, I run npm install and everything But i still have : VueNextSelect is not defined, it's imported, its in my package.json, but it's underline in my app.js and even if I run npm install or things like that it's not working for the moment, but I'll take a deeper look at that, thanks for your time, I'am going to check your answer because it's working for people using vue 2 – Bastien Aug 19 '21 at 08:23
  • I don't know if you will read this, but when I install vue-next-select, the import is not working, I don't know if you ever had an issu like this ? – Bastien Aug 19 '21 at 09:14