Reputation: 1269
I have an array of alphabets, I want to make it so that the user can select one of these letters, then when you click on the button named "All" with an alert, the name of the selected letter is displayed, this construction looks like this
You can also look at this project in codesandbox
<template>
<div>
<div class="alphabet-container">
<div
class="alphabet-row"
v-for="i in Math.ceil(alphabet.length / 6)"
:key="i.id"
>
<span
class="AlphabetLetters"
:class="item"
v-on:click="show(item)"
v-for="(item, index) in alphabet.slice((i - 1) * 6, i * 6)"
:key="index"
>
{{ item }} <br v-if="(index + 1) % 6 == 0" />
</span>
</div>
<div class="alphabet-btn">
<button>All</button>
</div>
</div>
</div>
</template>
<script>
import _ from "lodash";
export default {
data() {
return {
alphabet: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],
};
},
methods: {
computed: {
productChunks() {
return _.chunk(Object.values(this.products), 4);
},
},
show(item) {
alert(item);
},
},
};
</script>
<style scoped>
.B {
border: 1px solid #74c8c5;
border-radius: 5px;
}
</style>
Upvotes: 0
Views: 111
Reputation: 6996
You can have a state like selectedAlphabet
as @Melvynx suggested.
And you can move your click event from the alphabet to the button.
<template>
<div>
<div class="alphabet-container">
<div
class="alphabet-row"
v-for="i in Math.ceil(alphabet.length / 6)"
:key="i.id"
>
<span
class="AlphabetLetters"
:class="{ 'blue-border': item === selectedAlphabet }"
v-on:click="selectedAlphabet = item"
v-for="(item, index) in alphabet.slice((i - 1) * 6, i * 6)"
:key="index"
>
{{ item }} <br v-if="(index + 1) % 6 == 0" />
</span>
</div>
<div class="alphabet-btn">
<button :click="show()">All</button>
</div>
</div>
</div>
</template>
<script>
import _ from "lodash";
export default {
data() {
return {
selectedAlphabet: 'A',
alphabet: [
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
],
};
},
methods: {
computed: {
productChunks() {
return _.chunk(Object.values(this.products), 4);
},
},
show() {
alert(this.selectedAlphabet);
},
},
};
</script>
<style scoped>
.alphabet-container {
width: 200px;
margin: auto;
max-width: 100%;
}
.alphabet-row {
display: flex;
justify-content: space-between;
}
.AlphabetLetters {
font-family: "Second-Montserrat-Bold";
cursor: pointer;
font-style: normal;
font-weight: bold;
font-size: 12px;
line-height: 14px;
padding: 10px;
}
.Z {
display: flex;
justify-content: flex-start;
width: 100%;
}
.blue-border {
border: 1px solid #74c8c5;
border-radius: 5px;
}
.alphabet-btn {
position: relative;
}
.alphabet-btn button {
position: absolute;
cursor: pointer;
right: 0;
bottom: 0;
background: #74C8C5;
padding: 8px 40px;
border: none;
outline: none;
border-radius: 5px;
color: #ffffff;
}
</style>
Side note:
I think you can do away with the loop on the parent div (alphabet-row
) and also remove the slice
methods in the code, it should just work fine without it. If you're using it to control how many alphabets appear on a row, you can do that with only css.
Edit:
You've also put computed
inside methods
which is incorrect.
Upvotes: 1
Reputation: 1175
You can add a state like selectedAlphabet
which contains the selected letter.
Your function show
will set selectedAlphabet
to the item
.
In your HTML, you juste can add a conditionnal class that add a border if the selectedAplhabet === item
:
<span
class="AlphabetLetters"
:class="item"
v-bind:class="{ 'blue-border': item === selectedAlphabet }" <--
v-on:click="show(item)"
v-for="(item, index) in alphabet.slice((i - 1) * 6, i * 6)"
:key="index"
>
Upvotes: 1