jQuery Dynamic Table - How to Add, Remove and Modify Html Table Rows Dynamically with jQuery

jQuery Dynamic Table - How to Add, Remove and Modify Html Table Rows Dynamically with jQuery

07 Jun 2022

Dynamic Table is a feature in and it is different from a standard table in UI that allows a table's number of rows to add, modify and delete depending on inputs in the Launch Form.

1. Basic Setup with Required Plugins

Let us start by defining the basic HTML structure of the web page.

  • Create an Html, Css and JavaScript files.
  • Include required plugins such as Audiowide Font & jQuery Plugins
  • Create Html Form to accept the input from the user. Input fields like Text Box, Date Picker, File Browse Button.
  • Make input fileds are mandatory by adding attribute required to html input elements.
  • Create an Html Table with all input fields as columns. Initially add a row with "No Records Found" text.

The basic project structure as follows.

Html
Copy
    <!DOCTYPE html>
	<html lang="en">
	<head>
	    <meta charset="UTF-8">
	    <meta http-equiv="X-UA-Compatible" content="IE=edge">
	    <meta name="viewport" content="width=device-width, initial-scale=1.0">
	    <title>Advanced Table Manipulation using Jquery</title>
	    <link rel="stylesheet" href="Table.css">
	    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Audiowide">
	    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
	    
	</head>
	<body>
	    <div class="nav-bar">
	        <ul class="nav-bar-left">
	            <li>
	                <h1>Full Stack Web Technology</h1>
	            </li>
	        </ul>
	    </div>
	    <div class="save-btn">
	        <button id="" class="select-btn" onclick="loadJson()">Load Json File</button>
	        <button id="" class="select-btn" onclick="saveJson()">Save Json File</button>
	    </div>

	    <div class="form-container">
	        <form action="javascript:formSubmit();" class="form">
	            <div class="row">
	                <div class="form-input">
	                    <label for="">Employee ID</label>
	                    <input type="text" name="empId" id="empId" class="input-field" required>
	                </div>
	                <div class="form-input">
	                    <label for="">Employee Name</label>
	                    <input type="text" name="empName" id="empName" class="input-field" required autocomplete="off">
	                </div>
	                <div class="form-input">
	                    <label for="">Employee DOB</label>
	                    <input type="date" name="empDob" id="empDob" class="input-field" required>
	                </div>
	                <div class="form-input profile-file">
	                    <label for="">Profile Photo</label>
	                    <img src="img/img.jpg" class="img" id="preview">
	                    <input type="file" name="empPhoto" id="empPhoto" class="input-field" accept=".jpg, .jpeg, .png" required>
	                </div>
	                <div class="form-input">
	                    <button id="submit">Submit</button>
	                </div>
	            </div>
	        </form>
	    </div>

	<div class="table-container">
	    <table class="table">
	        <thead>
	            <tr>
	                <th>Employee ID</th>
	                <th>Employee Name</th>
	                <th>Employee DOB</th>
	                <th>Status</th>
	                <th>Profile Photo</th>
	                <th>Action</th>
	            </tr>
	        </thead>
	        <tbody>
	            <tr>
	                <td colspan="6" class="noRecord">No Records Found.</td>
	            </tr>
	        </tbody>
	    </table>
	</div>

	<script src="Table.js"></script>

	</body>
	</html>
CSS
Copy
    *{
	    margin: 0;
	    padding: 0;
	}

	body{
	    width: 100%;
	    height: 100vh;
	    background: #f2f2f2;
	}

	.nav-bar{
	    position: relative;
	    width: 100%;
	    min-height: 70px;
	    background-color: white;
	    color: black;
	    box-shadow: 0 0 10px 1px rgba(0, 0, 0, 0.5);
	}

	.nav-bar-left{
	    position: absolute;
	    list-style: none;
	    left: 0;
	    padding: 12px;
	    font-family: "Audiowide", "Cursive";
	}

	.form-container{
	    display: flex;
	    align-items: center;
	    justify-content: space-around;
	    margin-top: 50px;
	}

	.form{
	    box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
	    background-color: white;
	    width: 80%;
	}

	.row{
	    display: flex;
	    align-items: center;
	    justify-content: space-around;
	    padding: 18px;
	}

	label{
	    font-size: 19px;
	    font-weight: 600;
	    display: block;
	    margin-bottom: 3px;
	}

	.input-field{
	    width: 190px;
	    height: 25px;
	    font-size: 15px;
	    padding: 2px 5px;
	}

	.input-field:focus{
	    outline-color: #008cba;
	}

	.profile-file{
	    display: flex;
	    justify-content: center;
	    align-items: center;
	    flex-direction: column;
	}

	.img{
	    width: 70px;
	    height: 70px;
	    border: 1px solid black;
	}

	.profile-file label, .profile-file img{
	    margin-bottom: 10px;
	}

	#empPhoto{
	    width: 95px;
	}

	#submit, .select-btn{
	    width: 150px;
	    height: 35px;
	    border: none;
	    font-size: 17px;
	    background: #008cba;
	    color: white;
	    cursor: pointer;
	    box-shadow: 0 0 5px rgb(0 0 0 / 50%);
	}

	.table-container{
	    margin-top: 50px;
	    display: flex;
	    align-items: center;
	    justify-content: space-around;
	}

	.table{
	    width: 80%;
	    border-spacing: 0;
	    box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
	    background-color: white;
	    margin-bottom: 50px;
	}

	.table th, .table td{
	    padding: 10px;
	    text-align: left;
	    font-size: 18px;
	    font-style: 'Cursive';
	}

	.table thead{
	    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
	    width: 100%;
	}

	.table th{
	    font-size: 20px;
	}

	.table tbody{
	    margin-top: 15px;
	}

	.table tbody tr:nth-child(even){
	    background-color: #528c9914;
	}

	.table tbody tr td:nth-child(1){
	    color: blue;
	}

	span.Active{
	    color: green;
	    font-weight: 600;
	    padding: 5px 15px 5px 15px;
	    background-color: #62cd4f4f;
	    border-radius: 4px;
	}

	.noRecord{
	    text-align: center !important;
	    color: red !important;
	    font-weight: 600;
	}

	.action-btn{
	    height: 28px;
	    box-shadow: 0 0 5px rgba(0,0,0,0.5);
	    padding: 0 6px;
	    border: none;
	    outline: none;
	    font-size: 16px;
	    background-color: #008cba;
	    cursor: pointer;
	    color: white;
	    margin-right: 5px;
	}
	button.status{
	    background-color: #ba0067;
	}

	.save-btn{
	    margin: 40px 0px -20px 170px;
	}
JavaScript
Copy
    var empPhoto = document.getElementById('empPhoto');
    var preview = document.getElementById('preview');
    var filePath = 'C:/Users/Admin/Documents/img/';

    empPhoto.onchange = () =>{
        imagePreview(preview);
    }
    function imagePreview(imgPrev){
        imgPrev.src = getImageUrl(empPhoto);
    }
    function getImageUrl(photoFile){
        const [file] = photoFile.files;
        if(file){
           return filePath+file.name;
        }else{
            return filePath+'no image.jpg';
        }
    }

The basic web page as follows.


How to Add, Remove and Modify Html Table Rows Dynamically with jQuery

2. Add Row to the Table

To add new row to the table, you can use the jQuery .append() method. This can be used in both Static and Dynamic web pages where the user may need to add more rows dynamically.

Here are the steps to add table row:

  • Handle jquery click() event when click on "Add New Row" button.
  • Read all the input fields value from the Html Form and make it as an object.
  • Construct the Row Markup with adding form input values assign it to a variable.
  • Push the constructed object to an array which holds all input entries as list of objects.
  • Add the Row Markup to the table by passing it to jQuery event called append();
  • Once the record added to the table, clear all form fields using jquery.

Implementation of Add Row logic as follows.

JavaScript
Copy
    /* Handle Form data to Table */
    function formSubmit(){
        if(formAction == 'ADD'){
            addFormData();
        }else{
            updateFormData();
        }
    }

    function getFormObj(){
        var empId = $("#empId").val();
        var empName = $("#empName").val();
        var empDob = $("#empDob").val();
        var profileUrl = getImageUrl(empPhoto);
        var empStatus = 'Active';

        var emp = {'empId':empId, 'empName':empName, 'empDob':empDob, 'profileUrl':profileUrl, 'empStatus':empStatus};
        return emp;
    }

    function addFormData(){
        console.log('add: == '+empList)
        var emp = getFormObj();
        if(empList.length == 0){
            $('.table tbody tr').remove();
        }
        addDataToTable(emp);
        empList.push(emp);
        clearForm();
        console.log('emp: == '+emp)
    }


    function addDataToTable(emp){
        var statusTemp = emp['empStatus'];
        statusTemp = (statusTemp == 'Active') ? 'In Active' : 'Active' ;
        var tr = '<tr id="'+emp['empId']+'">'+
                    '<td>'+emp['empId']+'</td>'+
                    '<td>'+emp['empName']+'</td>'+
                    '<td>'+emp['empDob']+'</td>'+
                    '<td> <span class="'+emp['empStatus']+'"> '+emp['empStatus']+' </span> </td>'+
                    '<td> <img src="'+emp['profileUrl']+'" class="img"> </td>'+
                    '<td> <button class="action-btn edit-row" index="'+emp['empId']+'"> Edit </button>'+
                        '<button class="action-btn delete-row" index="'+emp['empId']+'"> Delete </button>'+
                        '<button class="action-btn status '+statusTemp+'" index="'+emp['empId']+'"> '+statusTemp+' </button>'+
                    '</td>'+
                '</tr>';
        $('.table tbody').append(tr);
    }
    
    function clearForm(){
        $("#empId").val('');
        $("#empName").val('');
        $("#empDob").val('');
        $("#empPhoto").val('');
        $("#preview").attr('src', filePath+'img.jpg');

        $("#empId").attr('readonly', false);
        $("#empPhoto").attr('required', true);

        formAction = 'ADD';
    }

    

The web page after implementing the Add Row logic as follows.


How to Add, Remove and Modify Html Table Rows Dynamically with jQuery

2. Modify Existing Record of the Table

Dynamic table provides the feature to Update the Existing Record. When click on edit button all vallues will be displayed in the respective fields and allow user to modify it.

Here are the steps to update table row:

  • Handle jquery click() event when click on "Edit" button.
  • Get the index value from the index attribute of the button using jQuery attr() method.
  • Get the object from the selected index of the array.
  • Display the values for the respective fields.
  • Handle click() even when click on Update button and construct an object of the form input fields.
  • Replace the object in array as well as table body.

Implementation of Modify Row logic as follows.

JavaScript
Copy
    /** Edit form data */
    $('body').on('click', '.edit-row', function(){
        var empId = $(this).attr('index');
        var objIndex = empList.findIndex(x => x.empId == empId);
        var empobj = empList[objIndex];

        $("#empId").val(empobj['empId']);
        $("#empId").attr('readonly', true);
        $("#empName").val(empobj['empName']);
        $("#empDob").val(empobj['empDob']);
        $("#empPhoto").attr('required', false);
        $("#preview").attr('src', empobj['profileUrl']);
        formAction = 'UPDATE';
    })

    /** Update form data */
    function updateFormData(){
        var emp = getFormObj();
        var objIndex = empList.findIndex(x => x.empId == emp.empId);
        var empobj = empList[objIndex];

        // Replace existing Image URL
        if(emp.profileUrl == filePath+'no image.jpg'){
            emp['profileUrl'] = empobj.profileUrl;
        }

        empList[objIndex] = emp;
        updateTableData();
        clearForm();
    }

    /** Update table data */
    function updateTableData(){
        $('.table tbody tr').remove();
        addListToTable();
    }

    /** Append list elements to table */
    function addListToTable(){
        if(empList.length == 0){
            displayNoRecordsFound();
        }
        for(var i = 0; i< empList.length; i++){
            addDataToTable(empList[i]);
        }
    }

    /* Display no records found */
    function displayNoRecordsFound(){
        $("table tbody").append('<tr><td colspan="6" class="noRecord">No Records Found.</td></tr>')
    }

The web page after implementing the Modify Row logic as follows.


How to Add, Remove and Modify Html Table Rows Dynamically with jQuery

4. Delete Row of the Table

To remove selected row from the table dynamically, you can use the jQuery .remove() method.

Here are the steps to Delete Table row:

  • Handle jquery click() event when click on "Remove" button.
  • Display a confirm box saying that "Are you sure you would like to delete this record?".
  • if click on "OK" get the index value from the index attribute of the button using jQuery attr() method.
  • First remove the object from the selected index of the array.
  • Then refresh the table body by re iterating the array;

Implementation of Delete Row logic as follows.

JavaScript
Copy
    /* delete table row */
    $('body').on('click', '.delete-row', function(){
        var cfm = confirm("Are you sure you would like to delete this record?");
        if(cfm){
            var empId = $(this).attr('index');
            var empIndex = empList.findIndex(x => x.empId == empId); 
            empList.splice(empIndex, 1);
            updateTableData();
        }
    });

    

The web page after implementing the Delete Row logic as follows.

Screenshot 1


How to Add, Remove and Modify Html Table Rows Dynamically with jQuery


Screenshot 2





5. Save Data to Memory using JavaScript API

Save entire table body into external file as well as browser cache memory in once click.

Here are the steps to Save Table Records:

  • Declare fileHandler instance using window.showOpenFilePicker()().
  • A file selector window will opens, just slelect/create new json file. Ex: Table.json
  • Add records into the table.
  • Conver arry of objects into Json String.
  • Write the Json String into the selected file.
  • Put the array of objects into localStorage
  • Close the file streams.
  • When refresh the page, data will be retrieved from localStorage memory.
  • When select the Json file, data which are present in the Json file will be loaded into table body.

Implementation of Save Table Records logic as follows.

JavaScript
Copy
    /* Load table data from memory */
    var tempEmpList = localStorage.getItem("empList");
    if(tempEmpList != null && tempEmpList != ''){
        empList = JSON.parse(tempEmpList);
        updateTableData()
    }

    /* Load table data from file */
    let fileHandler;
    async function loadJson(){
        [fileHandler] = await window.showOpenFilePicker();
        var file = await fileHandler.getFile();
        if(file != null && file != ''){
            var fileData = await file.text();
            var tempFileList = (fileData != null && fileData != '') ?JSON.parse(fileData) : [];
            console.log('FILE: '+tempFileList);
            if(tempEmpList != null && tempEmpList != '' && tempEmpList.length != tempFileList.length && tempFileList.length != 0){
                empList = tempFileList;
                updateTableData();
            }
        }
        
    }

    /* SAVE data to memory */
    async function saveJson(){
        let stream = await fileHandler.createWritable();
        await stream.write(JSON.stringify(empList));
        await stream.close();
        localStorage.setItem("empList", JSON.stringify(empList))
    }


That's all!. You have successfully done "Advanced Dynamically Table".

Download Source Code

Comments