I want to have a menu open after I click a person. Somehow, it does work, however, for Jane it shows Joe's records. How to solve it? Here's the link: https://jsfiddle.net/4uhafm2s/#&togetherjs=vQepAdHg2q
And the code:
function toggle(id) {
var elt = document.getElementById(id);
elt.style.display = elt.style.display == 'block' ? 'none' : 'block';
}
function groupBy(array, key) {
const result = {}
array.forEach(item => {
if (!result[item[key]]) {
result[item[key]] = []
}
result[item[key]].push(item)
})
return result
}
new Vue({
el: "#app",
data: {
persons: [{
'name': "Joe",
"a": "1",
"b": "2",
"c": "3"
}, {
'name': "Jane",
"a": "4",
"b": "5",
"c": "6"
}, {
'name': "Joe",
"a": "7",
"b": "8",
"c": "9"
}]
},
computed: {
filtered() {
var result = this.persons;
return groupBy(result, 'name');
}
}
});
<style>tr.hi {
background-color: #ffd6600a
}
tr.cr {
background-color: #ff60600a
}
.dropbtn {
background-color: #04AA6D;
color: black;
padding: 16px;
font-size: 16px;
border: 2px solid #ccc;
width: 100%;
height: 3em;
}
.btncritical {
background-color: #fc0303;
color: black;
padding: 16px;
font-size: 16px;
border: 2px solid #ccc;
height: 3em;
}
.btnheigh {
background-color: #fc7703;
color: black;
padding: 16px;
font-size: 16px;
border: 2px solid #ccc;
height: 3em;
}
button {
height: 100%;
}
td {
height: 10px;
padding: 2px;
}
dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
position: absolute;
left: 0;
display: none;
background-color: #f9f9f9;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
}
.submenu {
display: none;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
white-space: nowrap;
}
</style>
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<table id="bigtable">
<tr v-for="person in filtered">
<td><button onclick="toggle('submenu-1')"> {{person[0].name}}</button>
<div id="submenu-1">
<table style="width:100%">
<tr>
<th>a</th>
<th>b</th>
<th>c</th>
<tr>
<tr v-for="item in person">
<td>{{ item.a }}</td>
<td>{{ item.b }}</td>
<td>{{ item.c }}</td>
<td>{{ item.cve }}</td>
</tr>
</table>
</div>
</td>
</tr>
</table>
<script src="src/index.js"></script>
</body>
</html>
CodePudding user response:
Keep it all inside Vue. Use Vue to manage the state of the DOM, not IDs and CSS.
new Vue({
el: "#app",
data: () => ({
selected: '',
persons: [{
'name': "Joe",
"a": "1",
"b": "2",
"c": "3"
}, {
'name': "Jane",
"a": "4",
"b": "5",
"c": "6"
}, {
'name': "Joe",
"a": "7",
"b": "8",
"c": "9"
}]
}),
computed: {
filtered() {
return this.groupBy(this.persons, 'name');
}
},
methods: {
toggle(index) {
this.selected = index === this.selected ? '' : index
},
groupBy(array, key) {
const result = {}
array.forEach(item => {
if (!result[item[key]]) {
result[item[key]] = []
}
result[item[key]].push(item)
})
return result
}
}
});
.dropbtn {
background-color: #04AA6D;
color: black;
padding: 16px;
font-size: 16px;
border: 2px solid #ccc;
width: 100%;
height: 3em;
}
td {
height: 10px;
padding: 2px;
}
dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
position: absolute;
left: 0;
background-color: #f9f9f9;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<table id="bigtable">
<tr v-for="(person, index) in filtered">
<td>
<button @click="toggle(index)"> {{person[0].name}}</button>
<div v-if="index === selected">
<table style="width:100%">
<tr>
<th>a</th>
<th>b</th>
<th>c</th>
</tr>
<tr v-for="item in person">
<td>{{ item.a }}</td>
<td>{{ item.b }}</td>
<td>{{ item.c }}</td>
<td>{{ item.cve }}</td>
</tr>
</table>
</div>
</td>
</tr>
</table>
</div>