In this article, we will demonstrate how to create a sortable and filtrable table using JavaScript. This custom table will have the functionality of editing or removing individual items along with sorting and filtering items according to different fields. Also, a form is attached so that the user can easily edit as well as add more items to the table using that input form. It will consist of 3 namely the Name of the item, the category of the item and the year it was released.
On completion, this custom table will look like this:
Prerequisites:
Project Structure:
The structure of the project representing containing files is:
Approach:
- First create a table structure using HTML tags table, tr, th, tr, with class names, id, and event listeners. Also, add an input form using input components, buttons, etc.
- Add style to the web pages using class names and ids to give background color, margin, padding, box-shadow, display to hide and show buttons, hover and transition to show zoom effect, and other properties.
- In JavaScript create an array of objects to store info and properties of the dataset. and create a function addItem() to insert data into the table.
- Use event listeners to sort the data array when clicking on the respective title in ascending or descending order.
- Access the form items using HTML DOM methods to get the inputs and push items in the data array.
- Link event listener to manage i.e. delete or edit the data from the respective icons and update button to apply the changes to the respective data item.
Example: In this example, we will create a sample HTML table with the above-mentioned approach.
<!-- index.html --> <!DOCTYPE html> < html >
< head >
< meta name = "viewport" content=" width = device -width,
initial-scale = 1 " />
< link href = "style.css" rel = "stylesheet" />
</ head >
< body >
< div class = "root" >
< h1 >Custom Table</ h1 >
< div class = "form" >
< div >
< h2 id = "formTitle" >Add item</ h2 >
</ div >
< input type = "text" id = "nameInput" placeholder = "Enter Name"
title = "Type in a name" value = "" />
< input type = "text" id = "catInput" value = "" placeholder = "Enter Category" title = "Type in a name" />
< input type = "Number" id = "yearInput" value = "" placeholder = "Enter year"
title = "Type in a name" />
< button id = "submitItem" type = "button"
onclick = "submitItem()" >
Add Item
</ button >
< button id = "editItem" style = "display: none" onclick = "editItem()" >
Update
</ button >
</ div >
< h2 >Search for Item...</ h2 >
< input type = "text" id = "searchInput" onkeyup = "searchItems()" placeholder = "Search for names.."
title = "Type in a name" />
< table id = "table" >
< tr class = "titles" >
< th style = "width: 5%" >S.no</ th >
< th style = "width: 30%" id = "name" onclick = "sortItems('name')" >
Name
</ th >
< th style = "width: 30%" onclick = "sortItems('category')" >
Category
</ th >
< th style = "width: 10%" onclick = "sortItems('year')" >
Year
</ th >
< th style = "width: 2%" >Edit Entry</ th >
< th style = "width: 2%" >Delete Entry</ th >
</ tr >
</ table >
< script src = "script.js" ></ script >
</ div >
</ body >
</ html >
|
/* style.css */ * { box-sizing: border-box;
} body { display : flex;
flex- direction : column;
align-items: center ;
} .root { display : "block" ;
width : 50 rem;
} #searchInput { background-repeat : no-repeat ;
width : 100% ;
font-size : 16px ;
padding : 12px 20px 12px 40px ;
border : 1px solid #ddd ;
margin-bottom : 12px ;
} .form { box-shadow: 0 0 5px rgba( 0 , 0 , 0 , 0.2 );
display : flexbox;
margin : 0 1 rem;
padding : 1 rem;
width : 98% ;
font-size : 16px ;
background-color : rgb ( 247 , 246 , 246 );
} .form>div { width : 100% ;
} .form>button { background-color : rgb ( 46 , 171 , 46 );
padding : 1% ;
border-radius: 5px ;
width : 10% ;
color : black ;
border : 1px solid #ddd ;
} .form>input { width : 25% ;
margin : 2% ;
font-size : 16px ;
padding : 1% ;
border : 1px solid #ddd ;
} #table { border-collapse : collapse ;
width : 100% ;
border : 1px solid #ddd ;
font-size : 18px ;
} #table th, #table td { text-align : left ;
padding : 12px ;
} #table tr { border-bottom : 1px solid #ddd ;
} #table tr.titles { background-color : lightgreen;
} .zoom { text-align : center ;
} .zoom:hover { transform: scale( 1.5 );
color : rgb ( 255 , 0 , 0 );
} |
// script.js // For edit item let index = -1; const table = document.getElementById( "table" );
// For sorting ascending or descending const flag = { Name: false , Cat: false , Year: false };
let data = [ { Name: "HTML" , Cat: "Web" , Year: "1993" },
{
Name: "Java" ,
Cat: "Programming" ,
Year: "1995" ,
},
{ Name: "JavaScript" , Cat: "Web" , Year: "1995" },
{ Name: "MongoDB" , Cat: "Database" , Year: "2007" },
{ Name: "Python" , Cat: "Programming" , Year: "1991" },
]; // To switch update or add form const switchEdit = () => { document.getElementById( "submitItem" ).style.display =
"none" ;
document.getElementById( "editItem" ).style.display = "" ;
}; const switchAdd = () => { document.getElementById( "submitItem" ).style.display =
"" ;
document.getElementById( "editItem" ).style.display =
"none" ;
}; // To create table function addItem(e, i) {
row = table.insertRow(i + 1);
let c0 = row.insertCell(0);
let c1 = row.insertCell(1);
let c2 = row.insertCell(2);
let c3 = row.insertCell(3);
c4 = row.insertCell(4);
let c5 = row.insertCell(5);
c0.innerText = i + 1;
c1.innerText = e.Name;
c2.innerText = e.Cat;
c3.innerText = e.Year;
c4.innerHTML = "✍" ;
c5.innerHTML = "☒" ;
c4.classList.add( "zoom" );
c5.classList.add( "zoom" );
c4.addEventListener( "click" , () => edit(c4, i));
c5.addEventListener( "click" , () => del(e));
} // Traverse and insert items to table data.map((e, i) => addItem(e, i)); // For sorting in different cases function sortItems(title) {
remove();
switch (title) {
case "name" :
sortName();
break ;
case "category" :
sortCat();
break ;
case "year" :
sortYear();
break ;
default :
console.log( "Default" );
}
data.map((e, i) => addItem(e, i));
} // Clear the table before updation function remove() {
console.log( "removed" );
while (table.rows.length > 1) table.deleteRow(-1);
} // Sort with names function sortName() {
data.sort((a, b) => {
let fa = a.Name.toLowerCase(),
fb = b.Name.toLowerCase();
console.log(fa, fb);
if (fa < fb) {
return -1;
}
if (fa > fb) {
return 1;
}
return 0;
});
if (flag.Name) data.reverse();
flag.Name = !flag.Name;
} // Sort with categories function sortCat() {
data.sort((a, b) => {
let fa = a.Cat.toLowerCase(),
fb = b.Cat.toLowerCase();
console.log(fa, fb);
if (fa < fb) {
return -1;
}
if (fa > fb) {
return 1;
}
return 0;
});
if (flag.Cat) data.reverse();
flag.Cat = !flag.Cat;
} // Sort with year function sortYear() {
data.sort((a, b) => a.Year - b.Year);
if (flag.Year) data.reverse();
flag.Year = !flag.Year;
} // To search and filter items function searchItems() {
let input = document
.getElementById( "searchInput" )
.value.toLowerCase();
let filterItems = data.filter((e) => {
return (
e.Name.toLowerCase().includes(input) ||
e.Cat.toLowerCase().includes(input) ||
e.Year.includes(input)
);
});
remove();
filterItems.map((e, i) => addItem(e, i));
} // Initiate edit form function edit(c, i) {
console.log(c.classList.value);
if (c.classList.value === "zoom" ) {
c.classList.add( "open" );
el = data[i];
switchEdit();
let nameInput =
document.getElementById( "nameInput" );
let catInput = document.getElementById( "catInput" );
let yearInput =
document.getElementById( "yearInput" );
nameInput.value = el.Name;
catInput.value = el.Cat;
yearInput.value = el.Year;
index = i;
} else {
c.classList.value = "zoom" ;
switchAdd();
document.getElementById( "nameInput" ).value = "" ;
document.getElementById( "catInput" ).value = "" ;
document.getElementById( "yearInput" ).value = "" ;
index = -1;
}
} // Submit edit data function editItem() {
console.log( "edit" );
nameInput = document.getElementById( "nameInput" );
catInput = document.getElementById( "catInput" );
yearInput = document.getElementById( "yearInput" );
data[index] = {
Name: nameInput.value,
Cat: catInput.value,
Year: yearInput.value,
};
remove();
data.map((e, i) => addItem(e, i));
nameInput.value = "" ;
catInput.value = "" ;
yearInput.value = "" ;
switchAdd();
} // Add new data function submitItem() {
console.log( "submit clicked" );
nameInput = document.getElementById( "nameInput" ).value;
catInput = document.getElementById( "catInput" ).value;
yearInput = document.getElementById( "yearInput" ).value;
if (
nameInput === "" ||
catInput === "" ||
yearInput === ""
) {
window.alert( "incomplete input data" );
return ;
}
data.push({
Name: nameInput,
Cat: catInput,
Year: yearInput,
});
document.getElementById( "nameInput" ).value = "" ;
document.getElementById( "catInput" ).value = "" ;
document.getElementById( "yearInput" ).value = "" ;
remove();
data.map((e, i) => addItem(e, i));
console.log(data);
} // Delete specific field function del(el) {
console.log( "del clicked" , el);
remove();
data = data.filter((e) => e.Name !== el.Name);
data.map((e, i) => addItem(e, i));
} |
Output: