v-for prop value not getting updated with bootstrap modal

1.3k views Asked by At

I have the following code snippet

<div class="list-group-item media" v-for="evt in event">

    <eventmodal :currentevent = "evt"></eventmodal>

</div>

The problem that I am facing is that in the prop, I am always getting the first value. Can you please let me know what I am doing wrong here? I am using vuejs 2.0

Also, I am wondering if I can set the props of a child component programmatically?

This is how my child component looks

    <template>
    <div class="card content">
        <h4 class="modal-title">
            <span v-if="currentevent">{{currentevent.title}}</span>
            <span v-else>New Event</span>
        </h4>

        <div class="form-group">
            <input type="text" placeholder="enter event title here" class="form-control" v-model="title">
            <i class="form-group__bar"></i>
        </div>
        <textarea class="note-view__body" id="eventDescription" v-model="description" placeholder="enter event description"></textarea>
        <div class="form-group">
            <input type="text" placeholder="enter organizer name here" class="form-control" v-model="organizer">
            <i class="form-group__bar"></i>
        </div>
        <div class="form-group">
            <input type="text" placeholder="start date" class="form-control" v-model="startdate">
            <i class="form-group__bar"></i>
        </div>
        <div class="form-group">
            <input type="text" placeholder="end date" class="form-control" v-model="enddate">
            <i class="form-group__bar"></i>
        </div>
        <div class="form-group">
            <input type="text" placeholder="email" class="form-control" v-model="email">
            <i class="form-group__bar"></i>
        </div>
        <div class="form-group">
            <input type="text" placeholder="phone" class="form-control" v-model="phone">
            <i class="form-group__bar"></i>
        </div>

        <div class="card-footer">
            <button type="button" v-on:click="clear()" class="btn btn-link" data-dismiss="modal">Close</button>
            <button type="button" v-on:click="performSave()" class="btn btn-link">Save</button>
        </div>

    </div>

</template>
<script>
export default {
    props:['currentevent'],
    data() {
            return {
                title: '',
                description: '',
                organizer: '',
                startdate: '',
                enddate: '',
                email: '',
                phone: ''
            }
        },
        mounted() {
            this.makeTextBoxReady();

        },
        methods: {
            makeTextBoxReady: function() {
                $(document).ready(function() {
                    if (!$('html').is('.ie9')) {
                        if ($('.note-view__body')[0]) {
                            $('.note-view__body').trumbowyg({
                                autogrow: true,
                                btns: [
                                    'btnGrp-semantic', ['formatting'],
                                    'btnGrp-justify',
                                    'btnGrp-lists', ['removeformat']
                                ]
                            });
                        }
                    }
                });
            },
            performSave : function() {
                let description = $('#eventDescription').trumbowyg('html');

                let formData = new FormData();
                formData.append('title',this.title);
                formData.append('desciption',description);
                formData.append('startdate',this.startdate);
                formData.append('enddate',this.enddate);
                formData.append('organizer',this.organizer);
                formData.append('email',this.email);
                formData.append('phone',this.phone);
                // formData.append('X-CSRF-TOKEN',document.querySelector('#_token').getAttribute('content'));
                console.log("going to save event information");
                this.$http.post('/admin/event/create', formData).then(response => {
                    console.log(response);
                    if(response.data.status==200) {
                        alert(response.data.message);
                        this.$emit('get_events');
                    }
                })
            },

            clear: function() {
                this.title = '';
                this.description = '';
                this.organizer = '';
                this.startdate = '';
                this.enddate = '';
                this.email = '';
                this.phone = '';
            }
        }
}
</script>

Events (which are being iterated) ...

An event (in context of my application) is a thing that happens, much like Google Events. The user will create events and they will be rendered on a calendar control.

There are currently 3 events in the system. All of them are listed here. I can also vouch for the fact that they do get loaded up properly in the "events" in the v-for. Its just the prop value is always the first one. In VueJs 1.0 i could easily do sync and it would sync the prop with the correct value that was being iterated , but I beleive that they have been taken away.

[
  {
    "id": 2,
    "title": "15-17",
    "desciption": "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi, deserunt.",
    "eventscategory_id": 1,
    "startdate": "2016-10-11 03:09:15",
    "enddate": "2016-10-17 19:12:15",
    "organizer": "another user",
    "street": null,
    "street2": null,
    "city": null,
    "province": null,
    "country": null,
    "phone": null,
    "email": "[email protected]",
    "fax": null,
    "created_at": "2015-09-21 19:12:15",
    "updated_at": "2016-12-11 10:51:53",
    "deleted_at": null
  },
  {
    "id": 19,
    "title": "latest event",
    "desciption": "",
    "eventscategory_id": 1,
    "startdate": "2017-01-01 00:00:00",
    "enddate": "2017-01-03 00:00:00",
    "organizer": "a user",
    "street": null,
    "street2": null,
    "city": null,
    "province": null,
    "country": null,
    "phone": "5197293401",
    "email": "[email protected]",
    "fax": null,
    "created_at": "2016-12-16 06:32:53",
    "updated_at": "2016-12-16 06:32:53",
    "deleted_at": null
  },
  {
    "id": 23,
    "title": "check for description",
    "desciption": "",
    "eventscategory_id": 1,
    "startdate": "2017-10-10 00:00:00",
    "enddate": "2017-10-10 00:00:00",
    "organizer": "test organizer",
    "street": null,
    "street2": null,
    "city": null,
    "province": null,
    "country": null,
    "phone": "12345",
    "email": "[email protected]",
    "fax": null,
    "created_at": "2016-12-16 06:43:04",
    "updated_at": "2016-12-16 06:43:32",
    "deleted_at": null
  }
]

Can you please let me know what I am doing wrong here?

1

There are 1 answers

1
Saurabh On BEST ANSWER

You may need to add key in v-for

<div class="list-group-item media" v-for="evt in event" :key="evt.id">
    <eventmodal :currentevent="evt"></eventmodal>
</div>

For the improvement of performance, v-for uses an “in-place patch” strategy and list rendering will not change on child component state or temporary DOM state changes. To track these changes you need to add key attribute with v-for.

I hope spaces are just typo in <eventmodal :currentevent = "evt"></eventmodal>, remove spaces from :currentevent = "evt".


Edited

You are showing same modal everytime, props are being passed correctly, but you are loading the same modal each time.

You should have dynamic id for each modal like following:

<eventmodal :id="evt.id" :currentevent="evt"></eventmodal>

and when you are showing this, you should use this dynamic id as following:

$("#" + event.id).modal()