Vue-formulate - Group item collapsible / toggle collapse

453 views Asked by At

Is there a possibility to make group item collapsible?

<FormulateInput type="group" name="employments" :repeatable="true" label="Employments"
    add-label="+ Add Employment" #default="groupProps">
    <!-- Clickable area -->
    <div class="group text-sm font-semibold py-2 cursor-pointer relative" @click="groupProps.showForm">
        ....
    </div>
    <!-- Nested form: must be collapsible accordion -->
    <div class="nested-form" v-show="groupProps.showForm">
        ....
    </div>
</FormulateInput>

I thought to add showForm property to the group context.

For this I need to do Custom input types or is there some other way?

If anyone has any other ideas?

Thanks

1

There are 1 answers

0
NKSM On BEST ANSWER

I figured it out with the gist of @jpschroeder.

CollapsableGroupItem.vue:

<template>
    <div class="group-item" :data-is-open="itemId === showIndex">
        <div class="group group-item-title text-sm font-semibold py-2 cursor-pointer relative hover:text-blue-400" @click="toggleBody">
            <slot name="title" v-bind="groupItem">#{{ context.index }}</slot>
        </div>
        <div class="group-item-body" v-show="itemId === showIndex">
            <slot name="body">
                <FormulateInput type="pelleditor" name="description" label="Description"/>
            </slot>
        </div>
    </div>
</template>

<script>
export default {
    name: "CollapsableGroupItem",
    props: {
        context: {
            type: Object,
            required: true,
        },
        showIndex: {
            type: [Number, String],
            required: true,
        },
        groupItem: {
            type: Object,
            required: true,
        },
    },
    data () {
        return {
            itemId: this.context.name + this.context.index
        }
    },
    created: function () {
        // show current item
        this.$emit("open", this.itemId);
    },
    methods: {
        toggleBody() {
            if (this.itemId === this.showIndex) {
                // dont show anything
                this.$emit("open", -1);
            } else {
                // show this one
                this.$emit("open", this.itemId);
            }
        },
    }
};

FormTemplate.vue:

<CollapsableGroupItem
    :context="context"
    :show-index="showIndex"
    :group-item="educations[context.index]"
    @open="showIndex = $event"
>   
    <template v-slot:title="education">
        <span v-if="education.institution || education.degree"
        >   
            {{ education.institution }}
            <span v-if="education.institution && education.degree">at</span>
            {{ education.degree }}
        </span>
        ...
    </template>
    <template v-slot:body>
        ...
    </template>
</CollapsableGroupItem>

Maybe it will help someone else or will be useful