Search code examples
javascripthtmlvue.jsvuejs2vue-component

How to create a show more/less button which applies to individual element with vue.js?


There is an option to display more text, or less, but the @click event applies for the all elements and the all elements display all text.

I understand, that I need to pass some value to identify individual element, that the value would not apply to all elements, but at the moment stuck and would appriciate help.

HTML:

        <tr v-for="script in scripts.slice(0, 5)">
            <td>{{script.key}}</td>
            <td v-if="!readMore">{{script.script_content.substring(0, 200) + ".."}}</td>
            <td v-if="readMore">{{script.script_content}}</td>
            <button @click="showMore" v-if="!readMore" class="btn btn-primary">Show more</button>
            <button @click="showLess" v-if="readMore" class="btn btn-primary">Show less</button>
        </tr>

Vue data and methods:

data: () => ({
       readMore: false,
    }),
    methods: {
        showMore() {
            this.readMore = true;
        },
        showLess() {
            this.readMore = false;
        },

Array values:

enter image description here

How could I make a method apply only for an individual element?

In this situation, there is no need to create a component, because this case will be used only on one page.


Solution

  • Create an object to hold a hash of readMore toggles, one for each item:

    data: () => ({
        readMore: {},
    }),
    

    The keys will be the item id. Test those in the template and also set them in the buttons by passing that id:

    <td v-if="!readMore[script.id]">{{script.script_content.substring(0, 200) + ".."}}</td>
    <td v-if="readMore[script.id]">{{script.script_content}}</td>
    <button @click="showMore(script.id)" v-if="!readMore[script.id]" class="btn btn-primary">Show more</button>
    <button @click="showLess(script.id)" v-if="readMore[script.id]" class="btn btn-primary">Show less</button>
    

    And set values in methods by passing the item id and toggling it:

    methods: {
        showMore(id) {
            this.$set(this.readMore, id, true);
        },
        showLess(id) {
            this.$set(this.readMore, id, false);
        },
    }