Understanding how to properly add pagination with Bootstrap vue - vue.js

I'm using Vue and Vue Bootsrap. I wrote the following code:
<b-card border-variant="primary" header="Results:" header-bg-variant="primary" header-text-variant="white" align="center">
<div v-if="loading">
<img width="50px" height="50px" src="/assets/img/loading.gif" />
</div>
<div v-else-if="tools.length">
<div id="app" class="container">
<div class="grid">
<article v-for="tool in tools">
<div class="title">
<h3>{{capitalizeFirstLetter(tool.name)}}</h3>
</div>
<div class="description">
{{tool.description}}
</div>
</article>
</div>
</div>
</div>
</b-card>
I want to add pagination. Each page should contain up to 9 cards. In the docs it was suggested to add:
<div class="overflow-auto">
<b-pagination
v-model="currentPage"
:total-rows="rows"
:per-page="perPage"
first-text="First"
prev-text="Prev"
next-text="Next"
last-text="Last"
></b-pagination>
</div>
But how should I wrap the cards and show only 9?

<article v-for="tool in tools.slice((currentPage-1)*perPage,(currentPage-1)*perPage+perPage)" :key=tool>
just slice your array according to the current page
you can check out the fiddle here
https://jsfiddle.net/allanbanis/La8b0k23/21/
PS: I'm not using 9 as perpage value because I copied and pasted only 9 unique entries[Silly me], so each page would look the same if i used 9

Related

Render image data from directus

[UPDATE: SOLVED]
I am new to directus, I have problem in rendering image data from directus cloud api to my vue project.
How can I render UUID directus image? This is the json image
json image
and this is my vue app code
<script setup>
import Button from './Button.vue'
const { story } = defineProps(['story'])
//console.log(story.img)
</script>
<template>
<div class="card-wrapper shadow-lg shadow-slate-400 m-2 p-2 w-40 md:w-60 rounded-md flex flex-col justify-between">
<div class="content text-white">
<h2 class="text-2xl font-bold">{{ story.title }}</h2>
<!-- <h4 class="headline1 text-md font-semibold">{{ story.headline }}</h4> -->
<p>{{ story.article_body }}</p>
</div>
<div class="cat-ava flex justify-center items-center">
<img :src="`//https://my.directus-api.app/assets/${story.img}`" :alt="`${story.title} image`">
</div>
<div class="btn-wrapper flex justify-center">
<Button name="Read More..." />
</div>
</div>
</template>
this is the result:
result
the title and article body is working but not for the image.
this is what I expected:
expected result
UPDATE
this is how I solved:
the code from vue before:
<img :src="`//https://my.directus-api.app/assets/${story.img}`" :alt="`${story.title} image`">
this is after I fixed it:
<img :src="`https://my.directus-api.app/assets/${story.img}?some_random_token`" :alt="`${story.title} image`">

Vue JS: How to make two Vue Instances to work together on the same page?

I created a recipe website, you can find it here https://hungry-vegetarian.com/.
The tab on the index page is a vue instance. I'm trying to create a search bar that is also a vue instance.
The problem occurs when I try to display searched recipes on the index page. It just shows the search result on top of the search bar.
Ideally, only searched recipes should appear on the tab just like they are now but without any indications on top of the tab like Breakfast, Salad, Bakery, etc.
I don't know how to make two objects work together. For now, they work separately without communicating with each other.
SEARCH
<div id="search">
<div class="main-search">
<h1 class="search-question">What are you in the mood for?</h1>
<div class="search-box">
<input type="text" v-model="searchQuery" class="input-search" placeholder="Bread">
<button class="btn-search"><i class="fa fa-search"></i></button>
</div>
</div>
<div class="container">
<div class="recipe" v-for="post in filteredList">
<div v-if="searchQuery">
<a v-bind:href="post.url" class="recipe-card__card-link" target="_blank">
<img v-bind:src="post.image" alt="" class="recipe-card__image"/>
<div class="recipe-card__text-wrapper">
<h2 class="recipe-card__title">{{post.name}}</h2>
<div class="recipe-card__details-wrapper">
<p class="recipe-card__excerpt">{{post.body}}</p>
<a v-bind:href="post.url" class="recipe-card__read-more">Read more <i class="fa fa-arrow-right"></i></a>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
tab
<main id="tab">
<header>
<nav>
<ul>
<div id="arrow">
<span></span>
<span></span>
<span></span>
</div>
<li v-for="(tab, tabName) in tabs" :key="tabName">
<button class="tab" #click="setTabActive(tabName)" :class="{'active': tabName === activeTab}">
<span class="tab-copy">{{ tabName }}</span>
<span class="tab-background">
</span>
</button>
</li>
</ul>
</nav>
</header>
<article>
<div class="container">
<transition name="fade" mode="out-in" appear :duration="500">
<tab-content v-for="(tabContent, t) in tabs" :data="tabContent" :key="'content'+t" v-if="t === activeTab" inline-template>
<div class="content-wrapper">
<div class="recipes" v-for="(recipe, i) in data.recipes" :key="i">
<a v-bind:href="recipe.url" class="recipe-card__card-link"></a>
<img :src="recipe.image" alt="" class="recipe-card__image">
<div class="recipe-card__text-wrapper">
<h2 class="recipe-card__title">{{recipe.name}}</h2>
<div class="recipe-card__details-wrapper">
<p class="recipe-card__excerpt">{{recipe.body}}</p>
<a v-bind:href="recipe.url" class="recipe-card__read-more">Read more <i class="fa fa-arrow-right"></i></a>
</div>
</div>
</div>
</div>
</tab-content>
</transition>
</div>
</article>
</main>
I tried to combine instances search and tab into just one instance tab, but it always gives me a Vue warning:
[Vue warn]: Property or method "searchQuery" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
Also, I feel like I can have just the wrong approach to this problem I am trying to solve. Please, any suggestions are welcome. I am stuck.

Scroll to a specific element in Vue

How can i make this Scroll to a specific Element Using html in Vue when the ID and element i want to click on are in different component?
<template>
<div class="container">
<div class="section">
<Bio/> <--------------------- inside of this is the text i want to click on
</div>
<div class="section">
<About/>
</div>
<div class="section">
<Gallery/>
</div>
<div class="section">
<Counter/>
</div>
<div class="section">
<Services/> <----------------- Section i want to scroll in after click
</div>
<div class="section">
<Clients/>
</div>
<div class="section">
<Clientslogo/>
</div>
</div>
</template>
As explained here, this is how you can achieve such thing
<template>
<div class="container">
<router-link :to="{ hash: '#services' }">Scroll to Services</router-link>
<div class="section">
<Bio id="bio" /> <!-- inside of this is the text I want to click on -->
</div>
<div class="section">
<About/>
</div>
<div class="section">
<Gallery/>
</div>
<div class="section">
<Counter/>
</div>
<router-link :to="{ hash: '#bio' }">Scroll to Bio</router-link>
<div class="section">
<Services id="services" /> <!-- Section I want to scroll in after click -->
</div>
<div class="section">
<Clients/>
</div>
<div class="section">
<Clientslogo/>
</div>
</div>
</template>

Nuxt.js + BootstrapVue: How to place the form card in the center of the page?

I have a card with form/ I want to place in the center of the page.
Here my layout 'empty':
<template>
<nuxt />
</template>
<script>
export default {
name: 'Empty'
}
</script>
<style></style>
I have next page with form:
<template>
<b-card>
<b-form #submit.stop.prevent="onSubmit">
...
</b-form>
</b-card>
</template>
I get next result:
<body data-gr-c-s-loaded="true">
<div id="__nuxt">
<!---->
<!---->
<div id="__layout">
<div class="card">
<!---->
<!---->
<div class="card-body">
<!---->
<!---->
<form class="">
...
</form>
</div>
<!---->
<!---->
</div>
</div>
</div>
...
</body>
On the screen, it looks like:
But I want to it looks like:
I can't find how to do it. Can you help me?
You can use a combination of bootstrap v4.3 flex utility classes and position utility classes with a sprinkling of custom styling:
<div
class="fixed-top d-flex align-items-center justify-content-center"
style="bottom: 0; overflow-y: auto"
>
<b-card style="max-width: 400px;">
<form>
<b-form-input class="mb-2"></b-form-input>
<b-form-input class="mb-2"></b-form-input>
<b-form-input class="mb-2"></b-form-input>
<b-form-input class="mb-2"></b-form-input>
</form>
</b-card>
</div>
You may need to tweak the above styles a bit.

how to reset component properties in Vue js?

I am trying to make a product review page using Vue js. Please see the below code
App.Vue
<template>
<div class=" wrapper">
<div class="container shadow padding-left-none">
<div class="grid-100 padding-left-none">
<div class="grid-30 padding-left-none">
<product-list></product-list>
</div>
<div class="grid-70">
<reviewPage :reviews="reviews"></reviewPage>
</div>
</div>
</div>
</div>
</template>
review-page.vue
<template>
<div class="grid-100">
<div class="review-wrapper">
<h3>Rate this product</h3>
<div class="rating-section">
<div class="user-ratings">
<rating-star v-on:ratingProvided="ratingProvided"></rating-star>
</div>
<div class="rating-complement" v-if="isRatingProvied">
<span class="complement">{{ratingComplement}}</span>
</div>
<div class="rating-saved pull-right" v-if="isRatingSaved">
<span class="saved-status">Your rating has been saved</span>
</div>
</div>
<div class="reviews-container">
<div class="review" v-for="review in reviews" :key="review.id">
</div>
</div>
</div>
</div>
</template>
product-list is having product.vue components.
whenever i am selecting a produc, the properties of review-page components are not getting reset. I want to reset "isRatingProvied" property.so that a fresh review page will be rendered for every product selection.