Inline Table Row Insert, Update, and Delete using PHP and jQuery Tutorial
In this tutorial, you wil learn how to create an Inline Table Row Insert, Update, and Delete using PHP/OOP, MySQL Database,and JavaScript (jQuery adn Ajax). Our main goal for this tutorial is to display data from database to HTML table that can add, editm remove table row dynamically. The table cells in the table will be editable if the user add or edit a row. The source code must have a field validator for required fields and field text types.
Getting Started
I'll be using Bootstrap and jQuery plugins/libraries on this tutorial. And to run my PHP Script, I will use XAMPP version 3.3.0 which has a PHP version 8.0.7.
Before we continue, please make sure that your XAMPP/WAMP's Apache and MySQL are already started. To do this, open your XAMPP/WAMP's Control Panel and start the mentioned web and database server.
Creating the Database
Open the PHPMyAdmin in a browser i.e. http://localhost/phpmyadmin
and create new dayabase naming inline_db
. After that, navigate the page to the SQL Tab and copy/paste
the sql script below.
Creating the Database Connection
Create a new PHP File and save it as database.php
. Then, copy/paste
the folling PHP script below.
- <?php
- class DBConnection{
- private $host = 'localhost';
- private $username = 'root';
- private $password = '';
- private $database = 'inline_db';
- public $conn;
- public function __construct(){
- $this->conn = new mysqli($this->host, $this->username, $this->password, $this->database);
- if (!$this->conn) {
- echo 'Cannot connect to database server';
- exit;
- }
- }
- }
- public function __destruct(){
- $this->conn->close();
- }
- }
- ?>
Creating Our Interface
The script below is the code for the index file of the web application. Save the following script as index.php
.
- <?php
- //Including the Database Connection Class
- require_once('database.php');
- $db = new DBConnection();
- $conn = $db->conn;
- ?>
- <!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>Inline Table Form</title>
- <link rel="stylesheet" href="./assets/css/bootstrap.css">
- <style>
- .editable{
- display:none;
- }
- </style>
- </head>
- <body>
- <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
- <div class="container-fluid">
- <a class="navbar-brand" href="https://sourcecodester.com">SourceCodester</a>
- </div>
- </nav>
- <div class="container py-3">
- <h2 class="border-bottom border-dark">Table Inline Form</h2>
- <span>Inline Table row cells adding and editing data using PHP and jQuery</span>
- <div class="row">
- <div class="col-12">
- <h3 class="text-center">Member List</h3>
- </div>
- <hr>
- <div class="col-12">
- <!-- Table Form start -->
- <form action="" id="form-data">
- <input type="hidden" name="id" value="">
- <table class='table table-hovered table-stripped table-bordered' id="form-tbl">
- <colgroup>
- <col width="20%">
- <col width="25%">
- <col width="15%">
- <col width="25%">
- <col width="15%">
- </colgroup>
- <thead>
- <tr>
- <th class="text-center p-1">Name</th>
- <th class="text-center p-1">Email</th>
- <th class="text-center p-1">Contact</th>
- <th class="text-center p-1">Address</th>
- <th class="text-center p-1">Action</th>
- </tr>
- </thead>
- <tbody>
- <?php
- $query = $conn->query("SELECT * FROM `members` order by id asc");
- while($row = $query->fetch_assoc()):
- ?>
- <tr data-id='<?php echo $row['id'] ?>'>
- <td name="name"><?php echo $row['name'] ?></td>
- <td name="email"><?php echo $row['email'] ?></td>
- <td name="contact"><?php echo $row['contact'] ?></td>
- <td name="address"><?php echo $row['address'] ?></td>
- <td class="text-center">
- <button class="btn btn-primary btn-sm rounded-0 py-0 edit_data noneditable" type="button">Edit</button>
- <button class="btn btn-danger btn-sm rounded-0 py-0 delete_data noneditable" type="button">Delete</button>
- <button class="btn btn-sm btn-primary btn-flat rounded-0 px-2 py-0 editable">Save</button>
- <button class="btn btn-sm btn-dark btn-flat rounded-0 px-2 py-0 editable" onclick="cancel_button($(this))" type="button">Cancel</button></td>
- </td>
- </tr>
- <?php endwhile; ?>
- </tbody>
- </table>
- </form>
- <!-- Table Form end -->
- </div>
- <div class="w-100 d-flex pposition-relative justify-content-center">
- <button class="btn btn-flat btn-primary" id="add_member" type="button">Add New Member</button>
- </div>
- </div>
- </div>
- </body>
- <script type="text/javascript" src="./assets/js/jquery-3.6.0.js"></script>
- <script type="text/javascript" src="./assets/js/bootstrap.js"></script>
- <!-- This is the javascript file that contains the actions scripts of the table -->
- <script type="text/javascript" src="./assets/js/script.js"></script>
- </html>
Creating the JavaScript File
In this script, it contains the functionalities of the buttons and the Ajax Request scripts for the form submission. Save the following script as script.js
- $(function() {
- // Create New Row
- $('#add_member').click(function() {
- if ($('tr[data-id=""]').length > 0) {
- $('tr[data-id=""]').find('[name="name"]').focus()
- return false;
- }
- var tr = $('<tr>')
- $('input[name="id"]').val('')
- tr.addClass('py-1 px-2');
- tr.attr('data-id', '');
- tr.append('<td contenteditable name="name"></td>')
- tr.append('<td contenteditable name="email"></td>')
- tr.append('<td contenteditable name="contact"></td>')
- tr.append('<td contenteditable name="address"></td>')
- tr.append('<td class="text-center"><button class="btn btn-sm btn-primary btn-flat rounded-0 px-2 py-0">Save</button><button class="btn btn-sm btn-dark btn-flat rounded-0 px-2 py-0" onclick="cancel_button($(this))" type="button">Cancel</button></td>')
- $('#form-tbl').append(tr)
- tr.find('[name="name"]').focus()
- })
- // Edit Row
- $('.edit_data').click(function() {
- var id = $(this).closest('tr').attr('data-id')
- $('input[name="id"]').val(id)
- var count_column = $(this).closest('tr').find('td').length
- $(this).closest('tr').find('td').each(function() {
- if ($(this).index() != (count_column - 1))
- $(this).attr('contenteditable', true)
- })
- $(this).closest('tr').find('[name="name"]').focus()
- $(this).closest('tr').find('.editable').show('fast')
- $(this).closest('tr').find('.noneditable').hide('fast')
- })
- // Delete Row
- $('.delete_data').click(function() {
- var id = $(this).closest('tr').attr('data-id')
- var name = $(this).closest('tr').find("[name='name']").text()
- var _conf = confirm("Are you sure to delete \"" + name + "\" from the list?")
- if (_conf == true) {
- $.ajax({
- url: 'api.php?action=delete',
- method: 'POST',
- data: { id: id },
- dataType: 'json',
- error: err => {
- alert("An error occured while saving the data")
- console.log(err)
- },
- success: function(resp) {
- if (resp.status == 'success') {
- alert(name + ' is successfully deleted from the list.')
- location.reload()
- } else {
- alert(resp.msg)
- console.log(err)
- }
- }
- })
- }
- })
- $('#form-data').submit(function(e) {
- e.preventDefault();
- var id = $('input[name="id"]').val()
- var data = {};
- // check fields promise
- var check_fields = new Promise(function(resolve, reject) {
- data['id'] = id;
- $('td[contenteditable]').each(function() {
- data[$(this).attr('name')] = $(this).text()
- if (data[$(this).attr('name')] == '') {
- alert("All fields are required.");
- resolve(false);
- return false;
- }
- })
- resolve(true);
- })
- // continue only if all fields are filled
- check_fields.then(function(resp) {
- if (!resp)
- return false;
- // validate email
- if (!IsEmail(data['email'])) {
- alert("Invalid Email.");
- $('[name="email"][contenteditable]').addClass('bg-danger text-light bg-opacity-50').focus();
- return false;
- } else {
- $('[name="email"][contenteditable]').removeClass('bg-danger text-light bg-opacity-50')
- }
- // validate contact #
- if (!isContact(data['contact'])) {
- alert("Invalid Contact Number.");
- $('[name="contact"][contenteditable]').addClass('bg-danger text-light bg-opacity-50').focus();
- return false;
- } else {
- $('[name="contact"][contenteditable]').removeClass('bg-danger text-light bg-opacity-50')
- }
- $.ajax({
- url: "./api.php?action=save",
- method: 'POST',
- data: data,
- dataType: 'json',
- error: err => {
- alert('An error occured while saving the data');
- console.log(err)
- },
- success: function(resp) {
- if (!!resp.status && resp.status == 'success') {
- alert(resp.msg);
- location.reload()
- } else {
- alert(resp.msg);
- }
- }
- })
- })
- })
- })
- //Email Validation Function
- window.IsEmail = function(email) {
- var regex = /^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
- if (!regex.test(email)) {
- return false;
- } else {
- return true;
- }
- }
- //Contact Number Validation Function
- window.isContact = function(contact) {
- return ($.isNumeric(contact) && contact.length == 11 && contact.substr(0, 2) == '09');
- }
- // removing table row when cancel button triggered clicked
- window.cancel_button = function(_this) {
- if (_this.closest('tr').attr('data-id') == '') {
- _this.closest('tr').remove()
- } else {
- $('input[name="id"]').val('')
- _this.closest('tr').find('td').each(function() {
- $(this).removeAttr('contenteditable')
- })
- _this.closest('tr').find('.editable').hide('fast')
- _this.closest('tr').find('.noneditable').show('fast')
- }
- }
Creating Our PHP API
Lastly, we will create the PHP File that contains our API Queries for Insertinh, Updating, and Deleting the data in the database. Save the file as api.php
.
- <?php
- require_once('database.php');
- Class API extends DBConnection{
- public function __construct(){
- parent::__construct();
- }
- public function __destruct(){
- parent::__destruct();
- }
- function save_member(){
- $data = "";
- $id = $_POST['id'];
- foreach($_POST as $k => $v){
- // excluding id
- // add comma if data variable is not empty
- $data .= " `{$k}` = '{$v}' ";
- }
- }
- // Insert New Member
- $sql = "INSERT INTO `members` set {$data}";
- }else{
- // Update Member's Details
- $sql = "UPDATE `members` set {$data} where id = '{$id}'";
- }
- $save = $this->conn->query($sql);
- if($save && !$this->conn->error){
- $resp['status'] = 'success';
- $resp['msg'] = 'New Member successfully added';
- else
- $resp['msg'] = 'Member\'s Details successfully updated';
- }else{
- $resp['status'] = 'failed';
- $resp['msg'] = 'There\'s an error occured while saving the data';
- $resp['error'] = $this->conn->error;
- }
- }
- function delete_member(){
- $id = $_POST['id'];
- // Delete Query
- $delete = $this->conn->query("DELETE FROM `members` where id = '{$id}'");
- if($delete){
- $resp['status'] = 'success';
- }else{
- $resp['status'] = 'failed';
- $resp['msg'] = 'There\'s an error occured while deleting the data';
- $resp['error'] = $this->conn->error;
- }
- }
- }
- $api = new API();
- switch ($action){
- case('save'):
- echo $api->save_member();
- break;
- case('delete'):
- echo $api->delete_member();
- break;
- default:
- break;
- }
- ?>
DEMO
There you go! You can now test your work at your end and if an error occurred please review the scripts above. You can also download the working source code that I have created for this tutorial. Just simply click the Download Button below to download the provided source code zip file.
I hope this tutorial will help you with what you are looking for and you'll find this useful for your future web app projects using PHP and jQuery. Explore more on this website for more Free Source Codes and Tutorials.
Happy Coding :)
Comments
Uncaught reference error
Found the mistake in script.js
Second Form Table and databases tables
Add new comment
- Add new comment
- 6640 views