eskiesirius's avatar

Problem with Table and toggle button

I just created a table with a dropdown menu in it but the problem is that when i click the dropdown it will open all the menu in the table. I just want to open the specific dropdown that i clicked.

<template>
    <div>
        <table class="table table-bordered">
            <thead>
                <tr>
                    <th>#</th>
                    <th>Title</th>
                    <th>Start Date</th>
                    <th>Price</th>
                    <th>Activity Type</th>
                    <th>Active</th>
                    <th>Action</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(tour,index) in tours">
                    <td>{{index+1}}</td>
                    <td><a :href="'/tours/' + tour.slug">{{tour.title}}</a></td>
                    <td>{{tour.start_date}}</td>
                    <td>{{tour.price}}</td>
                    <td>
                        <center>
                            <span v-if="tour.activity_type == 'exclusive'" class="label label-success">Exclusive</span>
                            <span v-else class="label label-info">Joiner</span>
                        </center>
                    </td>
                    <td>
                        <center>
                            <span v-if="tour.active" class="label label-success">Active</span>
                            <span v-else class="label label-danger">Not Active</span>
                        </center>
                    </td>
                    <td>
                        <div class="dropdown" :class="{'open':isOpen}" @click="isOpen = !isOpen">
                            <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Action
                                <span class="caret"></span>
                            </button>
                            <ul class="dropdown-menu">
                                <li><a href="#">HTML</a></li>
                                <li><a href="#">CSS</a></li>
                                <li><a href="#">JavaScript</a></li>
                            </ul>
                        </div> 
                    </td>
                </tr>
            </tbody>
        </table>
        <div class="row">
            <div class="col-md-12 center">
                <vue-pagination :pagination="pagination" @click.native="fetchTourList(pagination.current_page)" :offset="pagination.per_page"></vue-pagination>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        props: {
            url: {
                required: true
            }
        },
        created(){
            this.fetchTourList(this.pagination.current_page);
        },
        data () {
            return {
                tours: [],
                counter: 0,
                pagination: {
                    total: 0,
                    per_page: 2,
                    from: 1,
                    to: 0,
                    current_page: 1
                },
                offset: 4,
                isOpen: false
            };
        },
        methods: {
            fetchTourList(page){
                this.$http.get(this.url + '?page='+page).then((tours) => {
                    this.tours = tours.body.data;
                    this.pagination = tours.body;
                });
            },
        },
    };
</script>

<style lang="css" scoped>
</style>
0 likes
5 replies
WebKenth's avatar

You could do a few things

Firstly i would change your created() method to a beforeCreated() to get the data before you render the view, minor performance boost.

you could modify the data you get and add an isOpen : false attribute to each item in the array

or

you could create an array and fill it with expanded items and remove them when you click again

something along the lines of this:

// data
expanded_items : []


// methods
expand(item){
    if(this.isExpanded(item))
    {
        this.expanded_items = this.expanded_items.filter((expanded_item) => expanded_item.id != item.id)
    }else{
        this.select(item);
        this.expanded_items.push(item);
    }
},
isExpanded(item){
    return !! this.expanded_items.find((expanded_item) => expanded_item.id == item.id);
},

use the expand(item) as the @click method on the dropdown and use the isExpanded(item) to check wether to expand the dropdown or not

tomasz.r's avatar

@WebKenth I'm not sure that you can call methods from beforeCreated() though. I think they are initialized after that.

hendranucleo's avatar

You have double class declaration on dropdown div there. Better use vue class binding for multiple class declaration. <div :class="['dropdown', {open: isOpen}]" @click="isOpen = !isOpen">.

hendranucleo's avatar

@eskiesirius I agree with you, and its on the doc either. But my own preferences i like array class binding rather than set static class. But it depend on self preferences.

Second, would you create a fiddle so we can resolve your trouble with working code. Thanks.

Please or to participate in this conversation.