Search code examples
phplaravelvue.jsvuejs3vue-component

Vue3-carousal plugin not showing the data in Vue component Laravel?


I have a Laravel 10(php 8.1) project in which i have install vue 3 for making a dynamic component.

Component Detail: I have created a component for showing team members of a company with a category bar where they can be categorize(this all functionality is working fine before implementing vue3-carousel).

Trying to achieve: the issue i'm getting is where I try to implement dynamic pagination for members.

I tried to implement multiple plugins of vue (vue-awesome-paginate, vue3-pagination,v-pagination-3 ) but they all don't work out. Now i tried to implement vue3-carousel it is working but the problem is that the data is not showing in it.team members and it's category bar image.

Project dependencies: Laravel 10.10 Vue ^3.2.36 vue3-carousel ^0.3.1

This below is my whole code

TeamMember.vue:

<template>
    <div>
        <!-- Category Section -->
        <div class="isotop_nav" id="categories-container">
            <ul>
                <li>
                    <!-- Use Vue data properties and methods -->
                    <a href="#" :class="{ 'active': selectedCategory === null }"
                        @click.prevent="handleCategoryClick(null)">
                        All
                    </a>
                </li>
                <!-- Loop through categories and generate links -->
                <li v-for="category in categories" :key="category.id">
                    <!-- Use Vue data properties and methods -->
                    <a href="#" :class="{ 'active': selectedCategory === category.name }"
                        @click.prevent="handleCategoryClick(category.name)">
                        {{ category . name }}
                    </a>
                </li>
            </ul>
        </div>

        <!-- Team Section -->
        <div class="leadership_list onTeam_sec">
            <carousel :items-to-show="3">
                <div class="row justify-content-center" id="filtered-team-members">
                    <!-- Use Vue data properties and methods -->
                    <slide v-for="member in members" :key="member.id" class="col-xxl-3 col-xl-3 col-lg-4 col-md-4 category-item">
                        <div :data-category="member.category ? member.category.name : ''">
                            <div class="leadership_list_info">
                                <span>
                                    <!-- Use Vue data properties -->
                                    <img :src="`/uploads/${member.profile_picture}`" alt="leadership profile" />
                                </span>
                                <a href="#"><strong>{{ member . name }}</strong></a>
                                <p>{{ member . role }}</p>
                                <div class="contactSocial_infoList">
                                    <ul>
                                        <!-- Use Vue data properties -->
                                        <li v-if="member.twitter_link">
                                            <a :href="member.twitter_link" target="_blank" class="s_tw">
                                                <i class="fa-brands fa-twitter"></i>
                                            </a>
                                        </li>
                                        <li v-if="member.salesforce_link">
                                            <a :href="member.salesforce_link" target="_blank" class="s_inst">
                                                <i class="fa-brands fa-salesforce"></i>
                                            </a>
                                        </li>
                                        <li v-if="member.linkedIn_link">
                                            <a :href="member.linkedIn_link" target="_blank" class="s_link">
                                                <i class="fa-brands fa-linkedin"></i>
                                            </a>
                                        </li>
                                    </ul>
                                </div>
                            </div>
                        </div>
                    </slide>
                </div>
                <!-- <Page :total="pageInfo" :current="pageInfo.current_page"  :page-size="parseInt(pageInfo.total)" v-if="pageInfo"/> -->
                <p v-if="members.length === 0">No team members found.</p>
                <template #addons>
                    <navigation />
                    <pagination />
                </template>
            </carousel>
        </div>
    </div>
</template>


<script>
    import axios from "axios";
    import 'vue3-carousel/dist/carousel.css'
    import { Carousel, Slide, Pagination, Navigation } from 'vue3-carousel'
    // import ViewUIPlus from 'view-ui-plus'
    // import 'view-ui-plus/dist/styles/viewuiplus.css'


    export default {
        data() {
            return {
                members: [],
                categories: [],
                selectedCategory: null,
                // currentPage: 1,
                // itemsPerPage: 3,  // Adjust as needed
                // totalItems: 0,
                // total: 3,
                // pageInfo: null,
            };
        },
        components: {
            // VueAwesomePagination,
            Carousel,
            Slide,
            Pagination,
            Navigation,
            // ViewUIPlus
        },
        mounted() {
            // Fetch initial team members (all members)
            //
            this.fetchCategories();
            // this.filterTeamMembers();
        },
        methods: {

            // function to fetch categories
            fetchCategories() {
                // axios.get(`/our-team/categories`)
                axios.get(`/our-team/categories`)
                    .then(response => {
                        console.log('API Response for categories:', response.data);
                        this.categories = response.data.categories;
                        // this.members = response.data.members;
                        this.members = Object.entries(response.data.members).map(([key, value]) => value);
                        console.log(this.members);
                        // this.pageInfo = response.data.members;
                        // console.log(this.pageInfo);
                        this.selectedCategory = null;
                    })
                    .catch(error => {
                        console.error('Error fetching categories:', error);
                    });
            },

            // Function to fetch and display filtered team members
            filterTeamMembers(member) {
                axios.get(`/our-team/${member || 'all'}`)
                    .then(response => {
                        console.log('API Response:', response.data);
                        // this.members = response.data.members;
                        this.members = Object.values(response.data.members);
                        this.totalItems = response.data.total;
                    })
                    .catch(error => {
                        console.error('Error fetching team members:', error);
                    });
            },

            handleCategoryClick(category) {
                // Set the selected category
                this.selectedCategory = category;
                this.currentPage = 1;
                // Filter team members based on the selected category
                this.filterTeamMembers(category);
            },

                // handlePaginationChange(newPage) {
                // this.currentPage = newPage;
                // this.filterTeamMembers(this.selectedCategory);
                // },


        // handlePaginationChange(newPage) {
        //     this.currentPage = newPage;
        //     this.filterTeamMembers(this.selectedCategory);
        //     console.log(this.filterTeamMembers(this.selectedCategory));
        // },

        // nextPage() {
        //     if (this.currentPage * this.itemsPerPage < this.totalItems) {
        //         this.currentPage++;
        //         this.filterTeamMembers(this.selectedCategory);
        //     }
        // },

        // prevPage() {
        //     if (this.currentPage > 1) {
        //         this.currentPage--;
        //         this.filterTeamMembers(this.selectedCategory);
        //     }
        // },

        },

    }
</script>

Routes:

Route::get('/our-team/categories', [TeamMemberContentController::class, 'getTeam'])->name('team');
Route::get('/our-team/{member?}', [TeamMemberContentController::class, 'filterByCategory'])->name('team-members.filter');

TeamMemberContentController.php

<?php

namespace App\Http\Controllers;

use Log;
use App\Models\Category;
use App\Models\TeamMember;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\TeamCategory;
use Illuminate\Support\Facades\View;

class TeamMemberContentController extends Controller
{
    public function index(Request $request, $category = null)
    {
        // $members = TeamMember::all();
        $members = TeamMember::where('status', 'opened')->orderBy('order_column')->get();
        $categories = TeamCategory::all();
        $selectedCategory = null;

        // $categories = TeamCategory::all();
        // $selectedCategory = null;

        if ($category && $category !== 'all') {
            $selectedCategory = TeamCategory::where('name', 'like', $category)->first();
            if ($selectedCategory) {
                $members = $selectedCategory->teamMembers()->where('status', 'opened')->orderBy('order_column')->get();
            } else {
                $members = TeamMember::where('status', 'opened')->orderBy('order_column')->get();
            }
        }


        if ($request->ajax()) {
            try {
                $view = View::make('components.team-members', compact('members', 'categories', 'selectedCategory'))->render();
                return response()->json(['html' => $view]);
            } catch (\Exception $e) {
                return response()->json(['error' => $e->getMessage()], 500);
            }
        }

        return view('our-team.our-team', compact(
            'members',
            'categories',
            'selectedCategory'
        ));
    }


    public function filterByCategory(Request $request, $category)
    {
        // Log::info('Received category:', ['category' => $category]);
        if ($category === 'all') {
            // If the category is 'all', return all team members
            $members = TeamMember::where('status', 'opened')->orderBy('order_column')->paginate(3);
        } else {
            // If it's a specific category, filter by that category
            $categoryModel = TeamCategory::where('name', 'like', $category)->first();

            if (!$categoryModel) {
                // Handle the case when the category is not found
                return response()->json([
                    'members' => []
                ]);
            }

            // $members = $categoryModel->teamMembers;
            $members = $categoryModel->teamMembers()->where('status', 'opened')->orderBy('order_column')->get();
        }

        if ($request->ajax()) {
            return response()->json([
                'members' => $members,
                // 'categories' => $categories,
                // 'selectedCategory' => $selectedCategory,
            ]);
        }

        return view('our-team.our-team', compact('members', 'categories'));
    }


    public function getTeam(Request $request, $category = null)
    {
        $membersQuery = TeamMember::where('status', 'opened')->orderBy('order_column');
        $categories = TeamCategory::all();
        $selectedCategory = null;

        if ($category && $category !== 'all') {
            $selectedCategory = TeamCategory::where('name', 'like', $category)->first();
            if ($selectedCategory) {
                $membersQuery->where('team_category_id', $selectedCategory->id);
            }
        }

        $members = $membersQuery->get();

        if ($request->ajax()) {
            return response()->json(['members' => $members, 'categories' => $categories, 'selectedCategory' => $selectedCategory]);
        }

        return view('our-team.our-team', compact('members', 'categories', 'selectedCategory'));
    }
}

vite.congfig.js

import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
import vue from "@vitejs/plugin-vue";

export default defineConfig({
    plugins: [
        laravel({
            input: [
                "resources/sass/app.scss",
                "resources/js/app.js",
                "resources/css/app.css",
            ],
            // input: ["resources/js/app.js"],
            refresh: true,
        }),
        vue({
            compilerOptions: {
                isCustomElement: (tag) => tag.startsWith("carousel"),
            },
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
    resolve: {
        alias: {
            vue: "vue/dist/vue.esm-bundler.js",
        },
    },
});

and this below is the response data format image : response data image

Kindly let me know how to resolve the issue or there's alternative way(plugins) of achieving dynamic pagination.

Tried: I tried to achieve dynamic pagination for the component but it's not worked out.

Expect: I want to achieve dynamic pagination for the members which will work when i tried to filter through category bar it.


Solution

  • The vue3-carousel starts working when i moved or removed or moved the div tag between the carousel and slide tag it starts working fine. I don't know the exact reason, when i was trying different things it worked out.

    I think it may be due to fact that slide tag is it's direct child and it requirement for the plugin structure. Now the update code below

            <div class="leadership_list onTeam_sec">
            <div  id="filtered-team-members">
            <carousel :items-to-show="3" :items="members"  class="row justify-content-center">
                    <!-- Use Vue data properties and methods -->
                    <!-- console members data -->
    
    
                    <slide v-for="(member) in members" :key="member.id" class="col-xxl-3 col-xl-3 col-lg-4 col-md-4 category-item">
                        <div :data-category="member.category ? member.category.name : ''" >
                            <div class="leadership_list_info">
                                <span>
                                    <img :src="`/uploads/${member.profile_picture}`" alt="leadership profile" />
                                </span>
                                <a href="#"><strong>{{ member.name }}</strong></a>
                                <p>{{ member . role }}</p>
                                <div class="contactSocial_infoList">
                                    <ul>
                                        <!-- Use Vue data properties -->
                                        <li v-if="member.twitter_link">
                                            <a :href="member.twitter_link" target="_blank" class="s_tw">
                                                <i class="fa-brands fa-twitter"></i>
                                            </a>
                                        </li>
                                        <li v-if="member.salesforce_link">
                                            <a :href="member.salesforce_link" target="_blank" class="s_inst">
                                                <i class="fa-brands fa-salesforce"></i>
                                            </a>
                                        </li>
                                        <li v-if="member.linkedIn_link">
                                            <a :href="member.linkedIn_link" target="_blank" class="s_link">
                                                <i class="fa-brands fa-linkedin"></i>
                                            </a>
                                        </li>
                                    </ul>
                                </div>
                            </div>
                        </div>
                    </slide>
                    <!-- <Page :total="pageInfo" :current="pageInfo.current_page"  :page-size="parseInt(pageInfo.total)" v-if="pageInfo"/> -->
                    <!-- <p v-if="members.length === 0">No team members found.</p> -->
                    <template #addons>
                        <navigation />
                        <pagination />
                    </template>
                </carousel>
            </div>
    

    Let me know if anyone knows the reason. As far as for me it worked out.