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..
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 :
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.
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.