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; | |
} |