A table whose rows you can filter.
A Pen by James Hibbard on CodePen.
A table whose rows you can filter.
A Pen by James Hibbard on CodePen.
| <div id="app"> | |
| <table> | |
| <thead> | |
| <tr> | |
| <th>Department</th> | |
| <th>Employees</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr v-for="(row, index) in filteredRows" :key="`employee-${index}`"> | |
| <td v-html="highlightMatches(row.department)"></td> | |
| <td v-html="highlightMatches([...row.employees].sort().join(', '))"></td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <input type="text" placeholder="Filter by department or employee" v-model="filter" /> | |
| </div> |
| const app = new Vue({ | |
| el: "#app", | |
| data: { | |
| filter: "", | |
| rows: [ | |
| { department: "Accounting", employees: ["Bradley", "Jones", "Alvarado"] }, | |
| { | |
| department: "Human Resources", | |
| employees: ["Juarez", "Banks", "Smith"] | |
| }, | |
| { | |
| department: "Production", | |
| employees: ["Sweeney", "Bartlett", "Singh"] | |
| }, | |
| { | |
| department: "Research and Development", | |
| employees: ["Lambert", "Williamson", "Smith"] | |
| }, | |
| { | |
| department: "Sales and Marketing", | |
| employees: ["Prince", "Townsend", "Jones"] | |
| } | |
| ] | |
| }, | |
| methods: { | |
| highlightMatches(text) { | |
| const matchExists = text | |
| .toLowerCase() | |
| .includes(this.filter.toLowerCase()); | |
| if (!matchExists) return text; | |
| const re = new RegExp(this.filter, "ig"); | |
| return text.replace(re, matchedText => `<strong>${matchedText}</strong>`); | |
| } | |
| }, | |
| computed: { | |
| filteredRows() { | |
| return this.rows.filter(row => { | |
| const employees = row.employees.toString().toLowerCase(); | |
| const department = row.department.toLowerCase(); | |
| const searchTerm = this.filter.toLowerCase(); | |
| return ( | |
| department.includes(searchTerm) || employees.includes(searchTerm) | |
| ); | |
| }); | |
| } | |
| } | |
| }); |
| <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> |
| table { | |
| font-family: arial, sans-serif; | |
| border-collapse: collapse; | |
| width: 100%; | |
| } | |
| td, th { | |
| border: 1px solid #dddddd; | |
| text-align: left; | |
| padding: 8px; | |
| } | |
| th { | |
| background-color: #dddddd; | |
| } | |
| input[type=text], select { | |
| width: 100%; | |
| padding: 12px 20px; | |
| margin: 8px 0; | |
| display: inline-block; | |
| border: 1px solid #ccc; | |
| border-radius: 4px; | |
| box-sizing: border-box; | |
| margin-top: 25px; | |
| } |