Display information from an array in a modal - javascript

I have 3 boxes, each box contains different information, this box also has a "View rewards" button, I need that when I click for example on box 3, a modal receives the information listed in my rewards array, it contains 3 lines of objects with ID, Title and Description information, each box contains its id I need the information of each one specifically to appear in the modal when clicking on the button of one of the modals.
Boxs print
Output modal print <- I need this result
const rewards = [
{
id: 1,
desc:
`
teste
`
},
{
id: 2,
desc:
`
teste 2
`
},
{
id: 3,
desc:
`
teste3
`
},
{
id: 4,
desc:
`
teste 4
`
}
]
const box =
[
{
id: 1,
titulo: "dfgdstd",
imagem: "src/images/item.png",
desc:
`+ 160 Gcoins,
+ 1 Mastery Box (Standard),
`,
link: "#",
recompensa: ``
},
{
id: 2,
titulo: "MasteryBox",
imagem: "src/images/item.png",
desc: `+ 160 Gcoins,
+ 1 Mastery Box (Minor),
`,
link: "#",
recompensa: ``
},
{
id: 3,
titulo: "MasteryBox",
imagem: "src/images/item.png",
desc: `+ 160 Gcoins,
+ 1 Mastery Box (Minor),
+ 1 Mastery Box (Standard),
`,
link: "#",
recompensa: ``
},
]
const section_1 = add => {
const boxes = $("#boxes");
/*/ Boxes benefícios/*/
boxes.append
(`
<div class="box" style="background: url(https://i.imgur.com/TgM0mIc.png); width: 270px; height: 350px; color:#fff;">
<div class="box-title">${add.titulo}</div>
<div class="box-body">
<img class="d-block mx-auto"src="${add.imagem}" style="margin-top: 70px;">
<div class="box-desc text-center mt-3">${add.desc.split(",").join("<br/>")}</div>
</div>
<div class="box-footer">
<a id="box-button" style="width:193px; height: 37px;" class="mx-auto d-block box_button" href="${add.link}">
<img src="https://i.imgur.com/CiWhLm6.png"></a>
</div>
</div>
`);
}
const p_modal = add => {
const modals = $("#promoModal");
modals.append
(`
<div class="promo_modal_wrap col-lg-5 mx-auto">
<span id="promo-close">x</span>
<div class="promo_modal_content">
<div class="promo_modal_title">
${add.titulo}
</div>
${add.desc}
</div>
</div>
`)
}
box.forEach(add => section_1(add));
rewards.forEach(add => p_modal(add));
<html>
<head>
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.1/dist/css/bootstrap.min.css">
</head>
<body>
<div class="promo_modal_wrap col-lg-5 mx-auto"></div>
<div class="row">
<div id="boxes" class="d-flex align-items-center"></div>
</div>
</body>
</html>

Related

How can I render two object in div?

I have 2 objects with data and I need to restruct the rendering in html.
This is what I get:
but this is what I need to obtain:
Black box is the *ngFor of articles object, respectively red one is *ngFor of adsContainer object
<div *ngFor="let article of articles; let i = index;">
<mat-card class="card">
<div>
<a class="title">
{{article.title}}
</a>
<a>
<p>{{article.content}}</p>
</a>
</div>
</mat-card>
<div class="container" *ngIf="(i % 7) === 6">
<div *ngFor="let data of adsContainer">
<div>
<h1>{{data.value}}</h1>
</div>
</div>
</div>
</div>
public adsContainer: any = [
{ id: '1', value: 'text value here' },
{ id: '2', value: 'text value here' },
{ id: '3', value: 'text value here' }
]
public articles: any = [
{ id: '1', title: 'title value here', content: 'content here' },
{ id: '2', title: 'title value here', content: 'content here' },
{ id: '3', title: 'title value here', content: 'content here' },
........
{ id: '20', title: 'title value here', content: 'content here' },
]
Your issue is that you add your ads containers in a loop
<div class="container" *ngIf="(i % 7) === 6">
<!-- this loop here -->
<div *ngFor="let data of adsContainer">
<div>
<h1>{{data.value}}</h1>
</div>
</div>
</div>
what you want is to add only one ad container at a time, in order to do that, you have to rmove the loop
In order to have the three ads show, you'll have to do some math to get the ad index from the article index
something like this :
<div class="container" *ngIf="(i % 7) === 6">
<div>
<h1>{{adsContainer[mathFloor(i / 7)].value}}</h1>
</div>
</div>
note that Math is not available in angular templates, you'll have to redefine floor as a component method
function mathFloor(val) {return Math.floor(val)}
Try to use directly the array , also when you call
adsContainer[(parseInt(i / 6)-1)% adsContainer.length, it will always restart the index:
<div *ngFor="let article of articles; let i = index;">
<mat-card class="card">
<div>
<a class="title">
{{article.title}}
</a>
<a>
<p>{{article.content}}</p>
</a>
</div>
</mat-card>
<div class="container" *ngIf="(i % 7) === 6">
<div>
<div>
<h1>{{adsContainer[(parseInt(i / 6)-1)%adsContainer.length].value}}</h1>
</div>
</div>
</div>
</div>

Clear Filter Functionality Not Working Vue

I'm working on a filtering feature in a Vue application. I'm new to Vue, and I have the filter semi-working. It successfully allows me to select an asset type from the dropdown, and will filter the results accordingly. But what's not working is the clearFilters method.
My goal is to reset the assetType to an empty string and the filterResults array to empty, and my thought was that since checking the length of filterResults, when I clear it it would return to displaying the entire un-filtered array.
What am I doing wrong? Any information would be greatly appreciated.
<template>
<div ref="content">
<div class="container pt-3 text-center">
<div class="filter-container">
<div class="btn-group">
<button
v-ripple="'rgba(255, 255, 255, .2)'"
#click="showAssetType = !showAssetType"
class="btn btn-secondary dropdown-toggle"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
style="max-height: 40px;">
{{assetType ? assetType : 'Asset Type'}}
</button>
<div class="dropdown-menu" :style="'display:' + (showAssetType ? 'block' : 'none') + ';'">
<a class="dropdown-item" #click.prevent="setAssetFilter('all')" href="#!">All Assets</a>
<a class="dropdown-item" #click.prevent="setAssetFilter('USD'); filterByAssetType()" href="#!">USD</a>
<a class="dropdown-item" #click.prevent="setAssetFilter('GBP'); filterByAssetType()" href="#!">GBP</a>
<a class="dropdown-item" #click.prevent="setAssetFilter('CAD'); filterByAssetType()" href="#!">CAD</a>
</div>
</div>
</div>
</div>
<div id="data-table" v-if="filterResults.length > 0">
<div v-for="(transaction, index) in filterResults" :key="index">
<global-history-item>
<template v-slot:header>
<h1 class="date">{{formatDate(transaction.date)}}</h1>
<div class="transaction-header-wrapper">
<p class="transaction-text">{{formatString(transaction.tx_type)}} Transaction</p>
<p class="transaction-text" style="text-align: right">{{transaction.coin_type}}</p>
</div>
</template>
<template v-slot:content>
<global-transaction :transaction='transaction' #updateClassType="updateClassType" />
</template>
</global-history-item>
</div>
</div>
<div id="data-table">
<div v-for="(item, index) in totalHistory" :key="index">
<div v-if="item.tx_type">
<global-history-item>
<template v-slot:header>
<h1 class="date">{{formatDate(item.date)}}</h1>
<div class="transaction-header-wrapper">
<p class="transaction-text">{{formatString(item.tx_type)}} Transaction</p>
</div>
</template>
<template v-slot:content>
<global-transaction :transaction='item' #updateClassType="updateClassType" />
</template>
</global-history-item>
</div>
<div v-else-if="item.invoice_id">
<global-history-item>
<template v-slot:header>
<h1 class="date">{{formatDate(item.date)}}</h1>
<div class="invoice-header-wrapper">
<p class="invoice-text">Invoice Created</p>
<p class="invoice-text">Invoice #{{item.invoice_id}}</p>
</div>
</template>
<template v-slot:content>
<global-invoice :invoice='item' />
</template>
</global-history-item>
</div>
<div v-else>
<global-history-item>
<template v-slot:header>
<h1 class="date">{{formatDate(item.date)}}</h1>
<div class="invoice-header-wrapper">
<p class="invoice-text">Login Event</p>
<br />
</div>
</template>
<template v-slot:content>
<global-account-activity :message='"A successful login to your account was made"' />
</template>
</global-history-item>
</div>
</div>
</div>
</div>
</template>
<script>
... imports removed for brevity
export default {
name: 'Global',
components: { },
props: ['totalHistory', 'printFormat'],
mixins: ['formatDate', 'formatMenuLabel'],
data () {
return {
showAssetType: false,
showClassType: false,
activityType: '',
assetType: '',
filterResults: [],
printMode: false
}
},
methods: {
setAssetFilter (value) {
this.showAssetType = false
this.assetType = value
},
formatString (str) {
const firstLetter = str.charAt(0)
const remainder = str.slice(1)
return firstLetter.toUpperCase() + remainder
},
updateClassType (transactionRecord) {
this.$store.dispatch('updateTransactionType', transactionRecord)
},
updateTransaction (transactionRecord) {
console.log('in updateTransaction', transactionRecord)
this.$store.dispatch('updateTransactionNote', transactionRecord)
},
filterByAssetType () {
const selectedCurrency = this.assetType
if (this.assetType === 'all') {
this.clearFilters()
} else {
this.filterResults = this.totalHistory.filter(function (trans) {
return trans.currency === selectedCurrency
})
}
},
clearFilters () {
return (this.assetType = '') && (this.filterResults = [])
}
}
}
</script>
So if I am not mistaking, you only want the method clearFilters, to work? If so, try:
clearFilters () {
this.assetType = ''
this.filterResults = []
}
The logical AND operator (&&) is not to chain expressions. It’s to do an expression if the first expression is truthy.
First expression && second expression, example
const questionAnswered = true
console.log(questionAnswered && "Hooray!")
// will log "Hooray!" (Expression 2)
If you set questionAnswered to false, it will log false (expression 1)
I agree with Jens rewrite of clearFilters(). The original looked odd to me.
I had started creating a sample component to demonstrate possibly simplifying the filtering process when there were no answers. Since I have finished it and it works, I am posting it.
ClearFilters.vue
<template>
<div class="clear-filters">
<div class="row">
<div class="col-md-6">
<table class="table table-bordered">
<thead>
<tr>
<th>NAME</th>
<th>CURRENCY</th>
</tr>
</thead>
<tbody>
<tr v-for="asset in filteredAssets" :key="asset.id">
<td>{{ asset.name }}</td>
<td>{{ asset.currency }}</td>
</tr>
</tbody>
</table>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="criteria-label">FILTER CRITERIA:</label>
<select class="form-control" v-model="currentCriteria">
<option v-for="(criteria, index) in criteriaOptions" :key="index" :value="criteria">{{ criteria }}</option>
</select>
</div>
<button type="button" class="btn btn-secondary" #click="resetFilter">Reset</button>
</div>
</div>
</div>
</template>
<script>
import assets from './clear-filters-data.js';
export default {
data() {
return {
assets: assets,
criteriaOptions: [
'ALL', 'USD', 'GBP', 'CAD'
],
currentCriteria: 'ALL'
}
},
computed: {
filteredAssets() {
if (this.currentCriteria === 'ALL') {
return this.assets;
}
else {
return this.assets.filter( asset => asset.currency === this.currentCriteria);
}
}
},
methods: {
resetFilter() {
this.currentCriteria = 'ALL';
}
}
}
</script>
<style scoped>
.criteria-label {
font-weight: bold;
}
</style>
Test data:
const assets = [
{
id: 1,
name: 'asset1',
currency: 'USD'
},
{
id: 2,
name: 'asset2',
currency: 'USD'
},
{
id: 3,
name: 'asset3',
currency: 'USD'
},
{
id: 4,
name: 'asset4',
currency: 'GBP'
},
{
id: 5,
name: 'asset5',
currency: 'GBP'
},
{
id: 6,
name: 'asset6',
currency: 'GBP'
},
{
id: 7,
name: 'asset7',
currency: 'CAD'
},
{
id: 8,
name: 'asset8',
currency: 'CAD'
},
{
id: 9,
name: 'asset9',
currency: 'CAD'
},
]
export default assets;

CDK Drag&Drop nested lists

I have two objects, Users and Info.
I intend to present users in different columns (individualize them) and within each User I intend to put the respective information where the User ID is the same as the IDUser in the info object. Basically, I intend to present the Obejto Info information within the list of each user, respectively.
At the moment I have two lists (users and info) I want to drag and drop between placing them vertically and horizontally, but without success.
Someone can help me solve this problem in order to pass the cards from one column to another (from user to user).
Example: In the column named Name1 I intend to place the card with the text Expand in the column named Name2.
Thank you
DEMO
html
<div style="width:100%; height:100%; display:flex; justify-content:center">
<div *ngFor="let usr of Users" style="width: 20%;">
<div class="card">
<div class="card-header" style="display: flex; align-items: center; justify-content: center;">
<span>{{usr.name}}</span>
</div>
<div class="card-body" style="height:100%" cdkDropList
cdkDropListOrientation="vertical" [cdkDropListData]="Info"
(cdkDropListDropped)="drop($event)">
<div *ngFor="let item of Info">
<div *ngIf="usr.id == item.idUser" cdkDrag>
<div class="card">
<div class="card-header" style="padding: 0px;">
<span>{{item.text}}</span>
</div>
<div class="card-body" style="padding: 0px;position: relative;">
<span>{{item.text}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
.ts
Users = [
{ id: 1, name: "Name1" },
{ id: 2, name: "Name2" },
{ id: 3, name: "Name3" }
];
Info = [
{ idUser: 1, text: "Expand1" },
{ idUser: 1, text: "Expand11" },
{ idUser: 2, text: "Expand2" },
{ idUser: 2, text: "Expand22" },
{ idUser: 3, text: "Expand33" },
{ idUser: 3, text: "Expand33" }
];
drop(event: CdkDragDrop<string[]>) {
console.log("TO", event.previousContainer.data[event.previousIndex]);
console.log("FROM", event.previousContainer.data[event.currentIndex]);
if (event.previousContainer === event.container) {
moveItemInArray(
event.container.data,
event.previousIndex,
event.currentIndex
);
} else {
transferArrayItem(
event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex
);
}
}
You can do multiple changes to your approach to solve this issue:
You technically just have a single data source for data and that will not work so transform your data structure so that each user will have an array to UserInfo items.
Use cdkDropListGroup on container element which contains all cdkDropList
and that's all!
import {
Component
} from "#angular/core";
import {
CdkDragDrop,
moveItemInArray,
transferArrayItem
} from "#angular/cdk/drag-drop";
#Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
Users = [{
id: 1,
name: "Name1",
items: [{
idUser: 1,
text: "Expand1"
}, {
idUser: 1,
text: "Expand11"
}]
},
{
id: 2,
name: "Name2",
items: [{
idUser: 2,
text: "Expand2"
}, {
idUser: 2,
text: "Expand22"
}]
},
{
id: 3,
name: "Name3",
items: [{
idUser: 3,
text: "Expand33"
}, {
idUser: 3,
text: "Expand33"
}]
}
];
drop(event: CdkDragDrop < string[] > ) {
if (event.previousContainer === event.container) {
moveItemInArray(
event.container.data,
event.previousIndex,
event.currentIndex
);
} else {
transferArrayItem(
event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex
);
}
}
}
<div style="width:100%; height:100%; display:flex; justify-content:center" cdkDropListGroup>
<div *ngFor="let usr of Users" style="width: 20%;">
<div class="card">
<div class="card-header" style="display: flex; align-items: center; justify-content: center;">
<span>{{usr.name}}</span>
</div>
<div class="card-body" style="height:100%" cdkDropList id="{{usr.id}}" cdkDropListOrientation="vertical" [cdkDropListData]="usr.items" (cdkDropListDropped)="drop($event)">
<div *ngFor="let item of usr.items">
<div cdkDrag>
<div class="card">
<div class="card-header" style="padding: 0px;">
<span>{{item.text}}</span>
</div>
<div class="card-body" style="padding: 0px;position: relative;">
<span>{{item.text}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Take a look at this stackblitz forked from yours.

Not able to nest divs elemnets using JQUERY

In the starred code is the nested div elements, I have read XML file which has news articles. I want to read and add those to this nested format using jquery.
<div id="for-you-feed" class="container" style="justify-content: center;">
<div class="row view-group " id="rowview">
**
<div class="item grid-group-item col-xs-4 col-lg-4 col-md-6 col-sm-12">
<div class=" thumbnail card border-light" style="width: 20rem; ">
<div class="img-event ">
<img class="group list-group-image img-fluid " src="https://timesofindia.indiatimes.com/photo/74745223.cms " alt=" " />
</div>
<div class="caption card-body ">
<h4 class="group card-title inner list-group-item-heading ">
Hyderabad: Buses with same number plates seized</h4>
<p class="group inner list-group-item-text ">
The transport authorities, under the guidance of deputy transport commissioner Papa Rao, seized four buses that belo</p>
<div class="row ">
<div id="footer1" class="col-xs-12 col-md-6 ">
<p class="lead ">
$21.000</p>
</div>
<div id="footer2" class="col-xs-12 col-md-6 ">
<a class="btn btn-success " href="http://www.jquery2dotnet.com ">Add to cart</a>
</div>
</div>
</div>
</div>
</div>
**
</div>
My code of jquery is below
$(document).ready(function() {
$.get("https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Ftimesofindia.indiatimes.com%2Frssfeeds%2F-2128816011.cms&api_key=mkzfaqsb5gtninv1pddoke81vwmjlyfiissiitvd", function(data, status) {
//$("#rowview").empty();
for (i in data.items) {
console.log(data.items[i].thumbnail);
console.log(data.items[i].title);
console.log(data.items[i].link);
console.log(data.items[i].description);
console.log(data.items[i].description.slice(pos + 4));
var pos = data.items[i].description.indexOf("</a>"),
$divitem = $("</div>").attr('class', 'item grid-group-item col-xs-4 col-lg-4 col-md-6 col-sm-12');
var $divthumb = $("</div>").attr({ "class": 'thumbnail card border-light', style: 'width: 20rem' }),
$divimg = $("</div>").attr('class', 'img-event '),
$imggrp = $("</img>").attr({ "class": 'group list-group-image img-fluid ', src: data.items[i].thumbnail }),
$divcaption = $("</div>").attr('class', 'caption card-body'),
$headcard = $("</h4>").text(data.items[i].title).attr('class', 'group card-title inner list-group-item-heading'),
$paracard = $("</p>").attr('class', 'group inner list-group-item-text').text(data.items[i].description.slice(pos + 4)),
$divrow = $("</div>").attr('class', 'row'),
$divfooter1 = $("</div>").attr({ "class": 'col-xs-12 col-md-6', id: 'footer1' }),
$lead = $("</p>").attr('class', 'lead').text('$21.000'),
$divfooter2 = $("</div>").attr({ "class": 'col-xs-12 col-md-6', id: 'footer2' }),
$atag = $("</a>").attr({ class: 'btn btn-success', href: 'http://www.jquery2dotnet.com' }).text("Add to cart");
$("#rowview").append($divitem.append($divthumb.append([$divimg.append($imggrp), $divcaption.append([$headcard, $paracard, $divrow.append([$divfooter1.append($lead), $divfooter2.append($atag)])])])));
// $($divthumb).append([$divimg, $divcaption]);
//$($divimg).append($imggrp);
// $(divthumb).append(divcaption);
//$($divcaption).append([$headcard, $paracard, $divrow]);
// $(divcaption).append(paracard);
//$(divcaption).append(divrow);
//$($divrow).append([$divfooter1, $divfooter2]);
//$($divfooter1).append($lead);
//$(divrow).append(divfooter2);
// $($divfooter2).append($atag);
// $(".view-group").append($divitem);
}
});
});
I'm not getting the response on my website. I even tried the code in the comments, but didn't work.
Update code and it is working. Hope it helps.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Sidebar demo</title>
<script
src="https://code.jquery.com/jquery-3.5.0.min.js"
integrity="sha256-xNzN2a4ltkB44Mc/Jz3pT4iU1cmeR0FkXs4pru/JxaQ="
crossorigin="anonymous"></script>
</head>
<body>
<div id="rowview"> </div>
<script>
$(document).ready(function() {
$.get("https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Ftimesofindia.indiatimes.com%2Frssfeeds%2F-2128816011.cms&api_key=mkzfaqsb5gtninv1pddoke81vwmjlyfiissiitvd", function(data, status) {
for (i in data.items) {
console.log(data.items[i].thumbnail);
console.log(data.items[i].title);
console.log(data.items[i].link);
console.log(data.items[i].description);
console.log(data.items[i].description.slice(pos + 4));
var pos = data.items[i].description.indexOf("</a>"),
$divitem = $("<div>").attr('class', 'item grid-group-item col-xs-4 col-lg-4 col-md-6 col-sm-12');
var $divthumb = $("<div>").attr({ "class": 'thumbnail card border-light', style: 'width: 20rem' }),
$divimg = $("<div>").attr('class', 'img-event '),
$imggrp = $("<img>").attr({ "class": 'group list-group-image img-fluid ', src: data.items[i].thumbnail }),
$divcaption = $("<div>").attr('class', 'caption card-body'),
$headcard = $("<h4>").text(data.items[i].title).attr('class', 'group card-title inner list-group-item-heading'),
$paracard = $("<p>").attr('class', 'group inner list-group-item-text').text(data.items[i].description.slice(pos + 4)),
$divrow = $("<div>").attr('class', 'row'),
$divfooter1 = $("<div>").attr({ "class": 'col-xs-12 col-md-6', id: 'footer1' }),
$lead = $("<p>").attr('class', 'lead').text('$21.000'),
$divfooter2 = $("<div>").attr({ "class": 'col-xs-12 col-md-6', id: 'footer2' }),
$atag = $("<a>").attr({ class: 'btn btn-success', href: 'http://www.jquery2dotnet.com' }).text("Add to cart");
$("#rowview").append($divitem.append($divthumb.append([$divimg.append($imggrp), $divcaption.append([$headcard, $paracard, $divrow.append([$divfooter1.append($lead), $divfooter2.append($atag)])])])));
// $($divthumb).append([$divimg, $divcaption]);
//$($divimg).append($imggrp);
// $(divthumb).append(divcaption);
//$($divcaption).append([$headcard, $paracard, $divrow]);
// $(divcaption).append(paracard);
//$(divcaption).append(divrow);
//$($divrow).append([$divfooter1, $divfooter2]);
//$($divfooter1).append($lead);
//$(divrow).append(divfooter2);
// $($divfooter2).append($atag);
// $(".view-group").append($divitem);
}
});
});
</script>
</body>
</html>

How to filter posts in Vue with components and v-bind:class

I'm trying to make an example based on this pen I got from here:
https://codepen.io/conradolandia/pen/YzyPmrv
But I want to use vue-router, I've tried this: (pen: https://codepen.io/conradolandia/pen/vYNERPW)
HTML:
<main class="wrap">
<div id="app">
<router-view></router-view>
</div>
</main>
<template id="post-list-template">
<div class="container">
<div class="row">
<h4>Filter by album:</h4>
<div class="filters">
<button class="btn" v-bind:class="{ active: currentFilter === 'ALL' }" v-on:click="setFilter('ALL')">all</button>
<button class="btn" v-bind:class="{ active: currentFilter === 'art' }" v-on:click="setFilter('art')">art</button>
<button class="btn" v-bind:class="{ active: currentFilter === 'doodles' }" v-on:click="setFilter('doodles')">doodles</button>
<button class="btn" v-bind:class="{ active: currentFilter === 'workshops' }" v-on:click="setFilter('workshops')">workshops</button>
</div>
</div>
<div class="columns is-multiline">
<div class="column is-3" v-if="currentFilter === post.category || currentFilter === 'ALL'" v-bind:key="post.title" v-for="post in posts">
<div class="card post">
<img class="card-img-top" v-bind:src="post.image">
<div class="card-body">
<div class="card-title">{{ post.title }}</div>
<small class="tags">{{ post.category }}</small>
</div>
</div> <!-- .post -->
</div> <!-- .col-md-4 -->
</div> <!-- .row -->
</div> <!-- .container -->
</template>
CSS:
body{
background-color: #ccc;
box-sizing:border-box;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
}
.post {
margin-bottom: 20px;
}
.post img{ width: 100%;}
.tags {background-color: #ccc; padding: 3px 5px;}
.filters {
margin-bottom: 20px;
}
JS:
var postList = Vue.extend({
template: "#post-list-template",
data: function(){
return {
currentFilter:'ALL',
posts: [
{title: "Artwork", image: "https://picsum.photos/g/200?image=122", category: 'art'},
{title: "Charcoal", image: "https://picsum.photos/g/200?image=116", category: 'art'},
{title: "Sketching", image: "https://picsum.photos/g/200?image=121", category: 'doodles'},
{title: "Acrillic", image: "https://picsum.photos/g/200?image=133", category: 'workshops'},
{title: "Pencil", image: "https://picsum.photos/g/200?image=134", category: 'doodles'},
{title: "Pen", image: "https://picsum.photos/g/200?image=115", category: 'art'},
{title: "Inking", image: "https://picsum.photos/g/200", category: 'workshops'},
{title: "Artwork", image: "https://picsum.photos/g/200?image=121", category: 'art'},
{title: "Charcoal", image: "https://picsum.photos/g/200?image=115", category: 'art'},
{title: "Sketching", image: "https://picsum.photos/g/200?image=124", category: 'doodles'},
{title: "Acrillic", image: "https://picsum.photos/g/200?image=13", category: 'workshops'},
{title: "Pencil", image: "https://picsum.photos/g/200?image=14", category: 'doodles'},
]
}
},
methods: {
setFilter: function(filter) {
this.currentFilter = filter;
}
},
})
// Start a new instance of router (instead of router.map)
var router = new VueRouter({
routes: [
{ path: '/', component: postList }
]
})
// Start a new instance of the Application required (instead of router.start)
new Vue({
el: '#app',
router: router,
})
So far, no luck. The filter kind of works, the first click I make activates a filtering option, but then all filters stop working, and firefox complains with "TypeError: "e is undefined"".
Can somebody point me in the right direction, please? I don't understand why the first codepen link works but the second doesn't.
Clarifying: When I click any filter, filters kind of work, but if I click the "ALL" filter, everything stops working.
Try using a computed function
computed:{
filteredPosts:function(){
if(this.currentFilter==='ALL'){
return this.posts;
}
return this.posts.filter(post=>{
return post.category === this.currentFilter;
})
}
}
You can use filteredPosts instead of posts while looping
<div class="columns is-multiline">
<div class="column is-3" :key="post.title" v-for="post in filteredPosts">
<div class="card post">
<img class="card-img-top" :src="post.image">
<div class="card-body">
<div class="card-title">{{ post.title }}</div>
<small class="tags">{{ post.category }}</small>
</div>
</div> <!-- .post -->
</div> <!-- .col-md-4 -->
</div> <!-- .row -->
You don't need to use any condition while looping, since the computed function will do the job.

Categories

Resources