0

I am new to laravel and vue.js.

In a blade view, I have a bootstrap-vue modal which includes a vue.js component for a full-text search and sends a post request to the backend when clicking a button.

So I want to hide this modal after clicking the same button after performing the request.

I have tried to access modal using ref attribute and then call the hide() method as stated in the documentation here, but it doesn't work, I don't know what I am missing.

Here is my code:

index.blade.php:


@extends('layouts.app', ['navId' => 'teams'])
@section('title', 'Teams')
@section('content')
    <div class="container-fluid mt-5 pt-5 col-10">
        <div class="row">
            <div class="col-3 offset-6">
                <b-button v-b-modal="'myModal'">Add Users</b-button>
                <!-- The modal -->
                <b-modal id="myModal" class="" size="s" centered :hide-footer="true" :hide-header="true">
                    <div class="row justify-content-center">
                        <h4 class="">Add new Participant</h4>
                    </div>
                    <user-search />
                </b-modal>
            </div>
        </div>
    </div>

@endsection

UserSearch.vue:

<template>
    <div class="" ref="myModalRef">
        <div class="card">
            <input type="text" placeholder="Search ..." v-model="keywords" v-on:keyup="autoComplete" 
                    class="form-control bg-light border-0">
            <div class="panel-footer mt-2" v-if="results.length">
                <ul class="list-unstyled">
                    <div class="result-item my-3">
                        <li class="media mx-2 my-3" v-for="result in results" :key="result.id" @mouseover="hover = true"
                                                        @mouseleave="hover = false"
                                                        :class="{ active: hover }">
                            <img :src="result.avatar_path ? result.avatar_path : '/img/dashboard/user-placeholder.png'" 
                                    class="rounded-circle align-self-center mr-3" width="40" height="40"/>
                            <h5 v-text="result.name" class="mt-3"></h5>
                            <div class="media-body d-flex justify-content-end mt-3">
                                <b-form-checkbox :id="'selected-user' + result.id" v-model="usersToAdd" :value="result" class="" />
                            </div>
                        </li>
                    </div>
                </ul>
            </div>
        </div>

        <div v-if="usersToAdd.length" class="col-3 my-5 mx-auto">
            <b-button type="submit" @click="sendInviteToUsers">Done</b-button>
        </div>

    </div>

</template>
<script>
import bForm from 'bootstrap-vue/es/components/form/form';
import bFormGroup from 'bootstrap-vue/es/components/form-group/form-group';
import bFormInput from 'bootstrap-vue/es/components/form-input/form-input';

export default {
    name: 'UserSearch',
    data() {
        return {
            keywords: '',
            results: [],
            hover: false,
            usersToAdd: [],
        };
    },

    methods: {
        autoComplete() {
            this.results = [];
            if(this.keywords.length > 2 ){
                this.$axios.get('/api/users/search', { params: { keywords: this.keywords } })
                .then(response => {
                    this.results = response.data;
                })
                .catch(() => {
                        this.loading = false;
                        this.showErrorToast('An error occurred while Fetching Users. Please try again later');
                });

                // .catch(error => {});
            }

        },

        sendInviteToUsers() {
            if(this.usersToAdd.length) {
                this.$axios.post('/api/teams/invite-with-email/', this.usersToAdd);
            }
        }
    }
}
</script>
<style scoped>

</style>


1 Answer 1

1

The problem with your code is bootstrap-vue was not able to find the modal reference correctly.Try something like this,

Remove modal from your index.blade.php and include it in UserSearch.vue with the ref attribute

index.blade.php

@extends('layouts.app', ['navId' => 'teams'])
@section('title', 'Teams')
@section('content')
    <div class="container-fluid mt-5 pt-5 col-10">
        <div class="row">
            <div class="col-3 offset-6">
                <b-button v-b-modal="'myModal'">Add Users</b-button>

                <!--Removed modal tag from here and included it in UserSearch.vue-->
                <user-search />

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

@endsection

UserSearch.vue

<template>
    <!--Add b-modal tag and ref attribute here-->
    <b-modal id="myModal" class="" size="s" centered :hide-footer="true" :hide-header="true" ref="myModalRef">
    <div class="row justify-content-center">
        <h4 class="">Add new Participant</h4>
    </div>
    <div class="card">
        <input type="text" placeholder="Search ..." v-model="keywords" v-on:keyup="autoComplete"
               class="form-control bg-light border-0">
        <div class="panel-footer mt-2" v-if="results.length">
            <ul class="list-unstyled">
                <div class="result-item my-3">
                    <li class="media mx-2 my-3" v-for="result in results" :key="result.id" @mouseover="hover = true"
                        @mouseleave="hover = false"
                        :class="{ active: hover }">
                        <img :src="result.avatar_path ? result.avatar_path : '/img/dashboard/user-placeholder.png'"
                             class="rounded-circle align-self-center mr-3" width="40" height="40"/>
                        <h5 v-text="result.name" class="mt-3"></h5>
                        <div class="media-body d-flex justify-content-end mt-3">
                            <b-form-checkbox :id="'selected-user' + result.id" v-model="usersToAdd" :value="result" class="" />
                        </div>
                    </li>
                </div>
            </ul>
        </div>
    </div>

    <div class="col-3 my-5 mx-auto">
        <b-button type="submit" @click="sendInviteToUsers">Done</b-button>
    </div>

</b-modal>

</template>
<script>
import bForm from 'bootstrap-vue/es/components/form/form';
import bFormGroup from 'bootstrap-vue/es/components/form-group/form-group';
import bFormInput from 'bootstrap-vue/es/components/form-input/form-input';

export default {
    name: 'UserSearch',
    data() {
        return {
            keywords: '',
            results: [],
            hover: false,
            usersToAdd: [],
        };
    },

    methods: {
        autoComplete() {
            this.results = [];
            if(this.keywords.length > 2 ){
                this.$axios.get('/api/users/search', { params: { keywords: this.keywords } })
                .then(response => {
                    this.results = response.data;
                })
                .catch(() => {
                        this.loading = false;
                        this.showErrorToast('An error occurred while Fetching Users. Please try again later');
                });

                // .catch(error => {});
            }

        },

        sendInviteToUsers() {
            if(this.usersToAdd.length) {
                this.$axios.post('/api/teams/invite-with-email/', this.usersToAdd).then(response => {
                    //Do something you want
                    this.$refs.myModalRef.hide();
                }).catch(error => {
                    //Handle the errors
                    this.$refs.myModalRef.hide();
                })
            }

        }
    }
}
</script>
<style scoped>

</style>

Inside your "sendInviteToUsers" function edit the function as above. In here the modal will close after you receive the api response from the server.

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

Comments

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.