Home > Software design >  Clicking on array element (object) shows wrong menu
Clicking on array element (object) shows wrong menu

Time:01-25

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>

  • Related