1

I have a parent component name is StudentComponent and in this, I have a modal which creates student and update also, It's work fine when modal in the parent component, but when I separate the modal component it's own, and call it in the parent it's not working and when I click edit button it's open but data not manipulate in modal, here is my code below...

StudentComponent (Parent)

<template>
  <div id="student">

     <span style="position: absolute; right: 1rem; top: .5rem;">
        <button type="button" class="btn btn-success" @click="create()">
          Add New <i class="fa fa-plus"></i>
        </button>
     </span>

    <div class="table-responsive">
      <table class="table table-bordered table-hover">
         <tbody>
            <tr class="text-center" v-show="students.length" v-for="(student, index) in students" 
              :key="student.id">

              <td>{{ index+1 }}</td>
              <td>{{ student.name }}</td>
              <td>{{ student.email }}</td>
              <td>{{ student.phone }}</td>
              <td>{{ student.address }}</td>
              <td>
                  <button @click="edit(student)" type="button" class="btn btn-success btn-sm">
                     <i class="fa fa-edit"></i>
                  </button>
               </td>
             </tr>
           </tbody>
         </table>

      </div>

    <!--my modal--> 

      <student-modal
        :edit="editMode"
      />


   </div>
 </template>



<script>
  import ModalComponent from './partial/ModalComponent';

  export default {

    components:{

        "student-modal" : ModalComponent,
    },

    data() {
        return {
            editMode : false,

            form: new Form({
                id: '',
                name: '',
                email: '',
                phone: '',
                address: '',
            })
        }
    },

    mounted() {
        this.getStudents();
    },

    methods : {
        getStudents() {

            this.$Progress.start();

            axios
                .get('/api/students?page=' + this.pagination.current_page)
                .then(response => {
                    this.students = response.data.data;
                    this.pagination = response.data.meta;

                    this.$Progress.finish();
                })
                .catch(e => {
                    console.log(e);

                    this.$Progress.fail();
                })
        },

        create() {
            this.editMode = false;
            $('#createStudent').modal('show');
            this.clearForm();
        },

        store() {
            this.$Progress.start();
            this.form.busy = true;
            this.form.post('/api/students')
                .then(response => {
                    this.getStudents();
                    //$('#createStudent').modal('hide');

                    if (this.form.successful) {
                        this.clearForm();
                        this.$Progress.finish();
                        this.$snotify.success('Student create successfully', 'Success')
                    } else {
                        this.$Progress.fail();
                        this.$snotify.error('Something wrong, try again.!', 'Error')
                    }
                })
                .catch(e => {
                    this.$Progress.fail();
                    console.log(e)
                })
        },

        edit(student) {
            this.editMode = true;
            this.clearForm();
            this.form.fill(student);
            $('#createStudent').modal('show');
        },

        update() {
            this.$Progress.start();
            this.form.busy = true;
            this.form.patch('/api/students/' + this.form.id)
                .then(response => {
                    this.getStudents();
                    $('#createStudent').modal('hide');

                    if (this.form.successful) {
                        this.clearForm();
                        this.$Progress.finish();
                        this.$snotify.success('Student update successfully', 'Success')
                    } else {
                        this.$Progress.fail();
                        this.$snotify.error('Something wrong, try again.!', 'Error')
                    }
                })
                .catch(e => {
                    this.$Progress.fail();
                    console.log(e)
                })
        },

     }
   }
 </script>

ModalComponent (Child) I'm using this same modal for creating and update

<template>
  <div id="studentModal">
    <div class="modal fade" id="createStudent" tabindex="-1" role="dialog" aria- 
       labelledby="studentModalTitle" aria-hidden="true">
        <div class="modal-dialog" role="document">

            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="studentModalTitle">{{ edit ? 'Update' : 'Create' }} 
                      Student</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <form @submit.prevent="edit ? update() : store()" @keydown="form.onKeydown($event)">

                    <div class="modal-body">

                        <alert-error :form="form"/>

                        <div class="form-group">
                            <label for="name" class="font-weight-bold">Name</label>
                            <input type="text" v-model="form.name" class="form-control" :class="{ 
                              'is-invalid': form.errors.has('name') }" id="name" name="name" 
                                placeholder="Your Name">
                            <has-error :form="form" field="name"></has-error>
                        </div>

                        <div class="form-group">
                            <label for="email" class="font-weight-bold">Email</label>
                            <input type="email" v-model="form.email" class="form-control" :class="{ 
                                'is-invalid': form.errors.has('email') }" name="email" id="email" 
                                  placeholder="Email hare">
                            <has-error :form="form" field="email"></has-error>
                        </div>

                        <div class="form-group">
                            <label for="phone" class="font-weight-bold">Phone</label>
                            <input type="tel" v-model="form.phone" class="form-control" :class="{ 
                              'is-invalid': form.errors.has('phone') }" name="phone" id="phone" 
                               placeholder="Phone number">
                            <has-error :form="form" field="phone"></has-error>
                        </div>

                        <div class="form-group">
                            <label for="address" class="font-weight-bold">Address</label>
                            <textarea class="form-control" v-model="form.address" :class="{ 'is- 
                             invalid': form.errors.has('address') }" name="address" id="address" 
                             placeholder="Your address"></textarea>
                            <has-error :form="form" field="address"></has-error>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data- 
                          dismiss="modal">Close</button>
                        <button :disabled="form.busy" type="submit" class="btn btn-primary">
                           {{ edit ? 'Update' : 'Create' }}
                        </button>
                    </div>

                </form>
            </div>

        </div>
    </div>
  </div>
</template>

<script>
  export default {
    name: "ModalComponent",

    props : {
        edit : Boolean,
    },

    data() {
        return {
            form: new Form({
                id: '',
                name: '',
                email: '',
                phone: '',
                address: '',
            })
        }
     }
  }
</script>

How can I create and update this data to parent ?

Shekh Saifuddin
  • 470
  • 2
  • 6
  • 27
  • 1
    Possible duplicate of [vuejs update parent data from child component](https://stackoverflow.com/questions/40915436/vuejs-update-parent-data-from-child-component) – Carol Skelly Nov 21 '19 at 12:01

1 Answers1

2

Use events.

In your child component, when your form is submitted emit a create event (or whatever you wish to name it), and add to the event the data you wish to send to the parent (I'll call it formData).

Example:

 <form @submit.prevent="$emit('create', formData)" @keydown="form.onKeydown($event)">

In your parent component, bind your custom event to the method you wish to execute (I'll call it createMethod).

Example:

<student-modal :edit="editMode" @create="createMethod"/>

Then all you have to do is make sure that the data you're passing via event is the data you need on the parent.

Here's a fiddle with a functional example: https://jsfiddle.net/wey5og6z/

Ayrton
  • 2,218
  • 1
  • 14
  • 25
  • @ShekhSaifuddin Are you getting any error messages? If you are, please add them to the question. I also recommend you to make a fiddle of your example. – Ayrton Nov 21 '19 at 16:01
  • Actually I'm a newbie in `vue.js` I don't understand what saying that errors, and I don't know how to make fiddle, if you can make a fiddle with a `ModalComponent` just simply create and update data, this will very helpful for me, I know this is not right to tell you like this but believe me, brother, I stack this situation last 4 days. I'm getting hopeless. – Shekh Saifuddin Nov 21 '19 at 16:47
  • @ShekhSaifuddin To see any errors just open dev tools (F12 on google chrome) and go to the console tab, any errors in your code will be displayed there. If your code isn't throwing any errors then I'll add a sample fiddle to my answer – Ayrton Nov 21 '19 at 16:50
  • I have done this like in ModalComponent `
    ` and in parent I call it like this ``and it shows me this error in consol `Property or method "formData" 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.`
    – Shekh Saifuddin Nov 21 '19 at 18:43
  • @ShekhSaifuddin that's because the arguments you pass to your event must be existing variables in your Vue instance. I used the variable `formData` as an example, but to implement you must declare it, then in your submit method you must populate it with the data you want to pass to the parent – Ayrton Nov 21 '19 at 19:20
  • @ShekhSaifuddin I added a functional fiddle to the question, check it out – Ayrton Nov 22 '19 at 11:36
  • many many thanks brother, I'm checking this and I'll feedback you, – Shekh Saifuddin Nov 22 '19 at 18:51