javascript - 使用vue折叠表格中的单元格

标签 javascript html vue.js

我尝试使用 vue.js 渲染时间表。在行中我有一些事件(在本示例中仅存在一个硬编码)。在科尔斯我有时间段。在单元格中 - 用户名称(如果用户安排在此时)。

enter image description here

您可以看到,Audrey 安排在 09:00 和 09:30。我的 vue.js 组件代码在这里:

<template>
    <div>
        <table>
            <thead>
            <tr>
                <th rowspan="2">Object</th>
                <th :colspan="intervals.length">
                    Intervals
                </th>
            </tr>
            <tr>
                <th v-for="(interval, id) in intervals" :key="id">
                    {{interval.name}}
                </th>
            </tr>
            </thead>
            <tbody>
            <tr>
                <td>Something</td>
                <td v-for="(interval, index) in intervals" :key="index">
                    {{getCell(interval.id).user_name}}
                </td>
            </tr>
            </tbody>
        </table>
    </div>
</template>

<script>
    export default {
        name: 'Test',
        data () {
            return {
                intervals: [
                    {
                        "id": 1,
                        "name": "09:00:00",
                    },
                    {
                        "id": 2,
                        "name": "09:30:00",
                    },
                    {
                        "id": 3,
                        "name": "10:00:00",
                    },
                    {
                        "id": 4,
                        "name": "10:30:00",
                    },
                    {
                        "id": 5,
                        "name": "11:00:00",
                    },
                    {
                        "id": 6,
                        "name": "11:30:00",
                    },
                    {
                        "id": 7,
                        "name": "12:00:00",
                    },
                ],
                schedule: [
                    {
                        "id": 1,
                        "interval_id": 1,
                        "user_name": "Audrey",
                    },
                    {
                        "id": 2,
                        "interval_id": 2,
                        "user_name": "Audrey",
                    },
                    {
                        "id": 3,
                        "interval_id": 4,
                        "user_name": "Ann",
                    },
                    {
                        "id": 4,
                        "interval_id": 5,
                        "user_name": "Ann",
                    },
                    {
                        "id": 5,
                        "interval_id": 7,
                        "user_name": "Chad",
                    },
                ],
            }
        },
        methods: {
            getCell(interval_id) {
                return this.schedule.find(row => row.interval_id === interval_id) || {};
            },
        }
    }
</script>

<style scoped>
    table, table td, table th {
        border: 1px solid black;
        border-collapse: collapse;
    }    
</style>

Intervals 数据和Schedule 数据来自 API。但我想折叠 Aundrey 单元格,以免显示他的(以及 Ann 的)user_name 两次。

enter image description here

我怎样才能做到这一点?

最佳答案

更新:这应该适用于多个用例:

new Vue({
  el: '#app',

  filters: {
    /**
    * receives the first name of a group and if have prefix 'nobody' return ''
    */
    validateNames(name) {
      return name.split('_')[0] === 'nobody' ? '' : name
    }
  },

  data () {
    return {
      intervals: [
        {
          "id": 1, "name": "09:00:00",
        },
        {
          "id": 2, "name": "09:30:00",
        },
        {
          "id": 3, "name": "10:00:00",
        },
        {
          "id": 4, "name": "10:30:00",
        },
        {
          "id": 5, "name": "11:00:00",
        },
        {
          "id": 6, "name": "11:30:00",
        },
        {
          "id": 7, "name": "12:00:00",
        },
      ],
      scheduleOne: [
        {
          "id": 1, "interval_id": 1, "user_name": "Audrey",
        },
        {
          "id": 2, "interval_id": 2, "user_name": "Audrey",
        },
        {
          "id": 3, "interval_id": 4, "user_name": "Ann",
        },
        {
          "id": 4, "interval_id": 5, "user_name": "Ann",
        },
        {
          "id": 5, "interval_id": 7, "user_name": "Chad",
        }
      ],
      scheduleTwo: [
        {
          "id": 1, "interval_id": 1, "user_name": "Audrey",
        },
        {
          "id": 2, "interval_id": 2, "user_name": "Audrey",
        },
        {
          "id": 3, "interval_id": 3, "user_name": "Audrey",
        },
        {
          "id": 4, "interval_id": 5, "user_name": "Ann",
        },
        {
          "id": 5, "interval_id": 7, "user_name": "Chad",
        }
      ],
      scheduleThree: [
        {
          "id": 1, "interval_id": 1, "user_name": "Audrey",
        },
        {
          "id": 2, "interval_id": 2, "user_name": "Ann",
        },
        {
          "id": 3, "interval_id": 4, "user_name": "Ann",
        },
        {
          "id": 4, "interval_id": 6, "user_name": "Chad",
        },
        {
          "id": 5, "interval_id": 7, "user_name": "Chad",
        }
      ],
      scheduleFour: [
        {
          "id": 1, "interval_id": 1, "user_name": "Audrey",
        },
        {
          "id": 2, "interval_id": 3, "user_name": "Audrey",
        },
        {
          "id": 3, "interval_id": 5, "user_name": "Audrey",
        },
        {
          "id": 4, "interval_id": 6, "user_name": "Audrey",
        },
        {
          "id": 5, "interval_id": 7, "user_name": "Chad",
        }
      ],
      scheduleFive: [
        {
          "id": 1, "interval_id": 3, "user_name": "Chad",
        },
        {
          "id": 2, "interval_id": 4, "user_name": "Chad",
        },
        {
          "id": 3, "interval_id": 5, "user_name": "Chad",
        }
      ],
      scheduleSix: [
      ],
      scheduleSeven: [
        {
          "id": 1, "interval_id": 1, "user_name": "Audrey",
        },
        {
          "id": 2, "interval_id": 2, "user_name": "Audrey",
        },
        {
          "id": 3, "interval_id": 3, "user_name": "Audrey",
        },
        {
          "id": 4, "interval_id": 4, "user_name": "Audrey",
        },
        {
          "id": 5, "interval_id": 5, "user_name": "Audrey",
        },
        {
          "id": 6, "interval_id": 6, "user_name": "Audrey",
        },
        {
          "id": 7, "interval_id": 7, "user_name": "Audrey",
        },
      ]
    }
  },

  methods: {
    /**
    * assigning groups with same name for consecutives intervals
    * @param {Array<String>, Array<Array<String>>}
    */
    recursiveGroupsGenerator (intervalsNames, intervalsGroups) {
      // first name in intervalsNames[] && groupInterval[] to fill with consecutives names
      const currentUserName = intervalsNames[0], groupInterval = []

      // pushing only consecutives names in groupInterval[]
      for (const intervalName of intervalsNames) {
        if (currentUserName === intervalName) groupInterval.push(intervalName)
        else break;
      }
      // pushing in intervalsGroups[] the current groupInterval[]
      intervalsGroups.push(groupInterval)

      // splicing intervalsNames[] without the current groupInterval[]
      intervalsNames = intervalsNames.splice(groupInterval.length, intervalsNames.length - groupInterval.length)

      // calling to self as recursive while intervalsNames[] haves names
      // if intervalsNames[] is empty return intervalsGroups[]
      return intervalsNames.length > 0 ? this.recursiveGroupsGenerator(intervalsNames, intervalsGroups) : intervalsGroups          
    },

    resolveSchedule (schedule) {
      // getting array of names for each interval if not exists assign 'nobody_{index}'
      const assignedIntervalsNames = this.intervals.map((interval, index) => {
        const userAssigned = schedule.find(s => s.interval_id === interval.id)
        return userAssigned 
          ? userAssigned.user_name
          : `nobody_${index}`
      })
      // resolving groups with same name for consecutives intervals
      return this.recursiveGroupsGenerator(assignedIntervalsNames, [])
    }
  }
})
table, table td, table th {
  border: 1px solid black;
  border-collapse: collapse;
}

tr > td {
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>

<div id="app">
  <table>
    <thead>
      <tr>
        <th rowspan="2">Object</th>
        <th :colspan="intervals.length">
          Intervals
        </th>
      </tr>
      <tr>
        <th v-for="(interval, id) in intervals" :key="id">
          {{interval.name}}
        </th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>scheduleOne</td>
        <td v-for="(item, index) in resolveSchedule(scheduleOne)" :key="index" :colspan="item.length">
          {{ item[0] | validateNames }}
        </td>
      </tr>
      <tr>
        <td>scheduleTwo</td>
        <td v-for="(item, index) in resolveSchedule(scheduleTwo)" :key="index" :colspan="item.length">
          {{ item[0] | validateNames }}
        </td>
      </tr>
      <tr>
        <td>scheduleThree</td>
        <td v-for="(item, index) in resolveSchedule(scheduleThree)" :key="index" :colspan="item.length">
          {{ item[0] | validateNames }}
        </td>
      </tr>
      <tr>
        <td>scheduleFour</td>
        <td v-for="(item, index) in resolveSchedule(scheduleFour)" :key="index" :colspan="item.length">
          {{ item[0] | validateNames }}
        </td>
      </tr>
      <tr>
        <td>scheduleFive</td>
        <td v-for="(item, index) in resolveSchedule(scheduleFive)" :key="index" :colspan="item.length">
          {{ item[0] | validateNames }}
        </td>
      </tr>
      <tr>
        <td>scheduleSix</td>
        <td v-for="(item, index) in resolveSchedule(scheduleSix)" :key="index" :colspan="item.length">
          {{ item[0] | validateNames }}
        </td>
      </tr>
      <tr>
        <td>scheduleSeven</td>
        <td v-for="(item, index) in resolveSchedule(scheduleSeven)" :key="index" :colspan="item.length">
          {{ item[0] | validateNames }}
        </td>
      </tr>
    </tbody>
  </table>
</div>

关于javascript - 使用vue折叠表格中的单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59699106/

相关文章:

javascript - 使用 JavaScript 从表中删除行时遇到问题

php - 如何在多选框的选择框中添加复选框bo0x

vue.js - Vuejs 在方法内构建/渲染组件并输出到模板中

vue.js - 开 Jest 错误找不到模块....映射为:

javascript - jQuery JavaScript 函数顺序

javascript - 'focus' 上不存在属性 'Element' ?

javascript - 组合两个更改功能

html - CSS Firefox 与 Chrome 不一致的高度和位置输出

html - selectOneListBox 大小为 1 显示为下拉菜单

apache - Vue 使用 Apache 部署 : routes don't work in history mode