I want to send an Ajax request when clicking a button but it seems my request is never executed. Here is my HTML code :
<!DOCTYPE html> <html lang="en"> <head> <title>User Form</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script> <script src = "./actions.js"></script> </head> <body> <div id="badFrm" class="container"> <h2><br>User Registration</h2> <form id="Form" method="post"> <div class="form-group"> <label for="name">Name:</label> <input type="name" class="form-control" id="name" placeholder="Enter Name" name="name"> </div> <div class="form-group"> <label for="email">Email:</label> <input type="email" class="form-control" id="email" placeholder="Enter Email" name="email"> </div> <button id="submitBtn" class="btn btn-primary">Submit</button> </form> </div> </body> </html>
i feel there is something wrong with my javascript code but i cant figure whats wrong ! i changed a lot of it based on the comments i got earlier . what i want is when i click on the update button it changes to ” submit again “ and i want to replace “list items” ( name and email ) with input fields and put whatever written in them to be saved in the database instead . and eventually return to the first page which is the register form. i need help in this part !! i know this part is buggy . i need to know how to reach each list item individually ( what attribute should i add/use ) and here is my javascript code :
$(document).ready(function() { var i ; $("#submitBtn").click(function (e) { e.preventDefault(); var name = $("#name").val(); var email = $("#email").val(); $.post("http://localhost/MiniProject/connect.php", { name: name, email: email }, function () { var element = document.getElementById("badFrm"); element.remove(); showTbl(); }); function showTbl() { $.post("http://localhost/MiniProject/Select.php", { name: name, email: email }, function (res) { // console.log(res); res = JSON.parse(res); var html = '<ul id="List">'; for (i = 0; i < res.length; i++) { var j = i +1 ; html += '<li class = "name" >' + res[i].name + '</li><li class = "email">' + res[i].email + '</li>'+ '<div>' + '<button onclick="removeUser(this)" class="btn btn-primary">Remove</button>' + '<button onclick="updateUser(this)" class="btn btn-primary">Update</button>' + '</div>'; } html += '</ul>'; document.body.innerHTML = html; }); } }); }); function removeUser(element){ var ID = element.id; var element2 = document.getElementById("List"); element2.remove(); $.post("http://localhost/MiniProject/Remove.php",{ id : ID }, function (res) { console.log(res); document.write(res); }); //alert(element.id); } function updateUser(element){ // code ... $.post("http://localhost/MiniProject/Update.php",{ id : ID2, }, function (res) { console.log(res); // document.write(res); }); }
here is connect.php :
<?php require 'Users.php'; $name = $_POST['name']; $email = $_POST['email']; $conn = new mysqli('localhost','root','','mydatabasename'); if($conn->connect_error){ die('Connection Failed : '.$conn->connect_error); }else { $user = new Users(); $user->Insert(['name' => $name, 'email' => $email]); echo "name is : ".$name." and email is : ".$email; }
this is Users.php :
<?php require 'newDB.php'; class Users extends DatabaseClass{ public $table = 'Users'; }
and this is where i handle the database commands :
<?php class DatabaseClass{ public $connection = null; public $table = null; // this function is called everytime this class is instantiated public function __construct( $dbhost = "localhost", $dbname = "myDatabaseName", $username = "root", $password = ""){ try{ // $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); $this->connection = new PDO("mysql:host=$dbhost;dbname=$dbname", $username, $password); $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $sql = "CREATE TABLE MyGuests ( id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, firstname VARCHAR(30) NOT NULL, lastname VARCHAR(30) NOT NULL, email VARCHAR(50), reg_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP )"; }catch(Exception $e){ throw new Exception($e->getMessage()); } } // Insert a row/s in a Database Table public function Insert($parameters = [] ){ try{ $fields = array_keys($parameters); $fields_string = '`' . implode('`,`', $fields) . '`'; $values_string = ':' . implode(',:', $fields); $sql = "INSERT INTO `{$this->table}`({$fields_string}) VALUES ( {$values_string} )"; $this->executeStatement( $sql , $parameters ); return $this->connection->lastInsertId(); }catch(Exception $e){ throw new Exception($e->getMessage()); } } // Select a row/s in a Database Table public function Select( $parameters = [] ){ try{ $fields = array_values($parameters); $fields_string=implode(' , ',$fields); $sql = "SELECT {$fields_string} FROM {$this->table}"; $stmt = $this->executeStatement( $sql , $parameters ); return $stmt->fetchAll(); }catch(Exception $e){ throw new Exception($e->getMessage()); } } // Update a row/s in a Database Table public function Update( $parameters = [] ){ try{ $fields = array_keys($parameters); $fields_string = 'id = '.implode($fields); $sql = "UPDATE {$this->table} SET {$fields_string} WHERE {$fields_string} "; echo $sql; exit ; $this->executeStatement( $sql , $parameters ); }catch(Exception $e){ throw new Exception($e->getMessage()); } } // Remove a row/s in a Database Table public function Remove( $parameters ){ try{ $fields_string = 'id = '.implode($parameters); $sql = "DELETE FROM {$this->table} WHERE {$fields_string}"; $this->executeStatement( $sql , $parameters ); }catch(Exception $e){ throw new Exception($e->getMessage()); } } // execute statement public function executeStatement( $statement = "" , $parameters = [] ){ try{ $stmt = $this->connection->prepare($statement); $stmt->execute($parameters); return $stmt; }catch(Exception $e){ throw new Exception($e->getMessage()); } } }
and this is Update.php :
<?php require 'Users.php'; $id = $_POST['id']; $conn = new mysqli('localhost','root','','mydatabasename'); if($conn->connect_error){ die('Connection Failed : '.$conn->connect_error); }else { $user = new Users(); $result = $user->Update(['id'=>$id]); // echo json_encode($result); } ?>
i dont want the question to have a lot of code so hope this makes it better to understand.
Advertisement
Answer
I mentioned posting something without jQuery – here is a demo which does what I understand your requirement to be. There are comments below to explain what is going on.
<?php error_reporting( E_ALL ); if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['action'] ) ){ ob_clean(); /* This emulates ALL of the PHP endpoints used in the original code -this is for demo purposes ONLY. The data returned is DEMO data and should be ignored. All AJAX functions should be pointed at their original endpoints... unless you adopt a similar approach in which case include your various PHP classes here. The ficticious sql in the below is for example only! Obviously you would use `prepared statements`... */ switch( $_POST['action'] ){ case 'insert': // do stuff... // send response... $data=sprintf('name is: %s and email is: %s',$_POST['name'],$_POST['email']); break; case 'remove': header('Content-Type: application/json'); $data=json_encode(array( 'action' => $_POST['action'], 'name' => $_POST['name'], 'email' => $_POST['email'], 'sql' => sprintf('delete from `TABLE` where `email`="%s"', $_POST['email'] ) )); break; case 'update': header('Content-Type: application/json'); $data=json_encode(array( 'action' => $_POST['action'], 'name' => $_POST['name'], 'email' => $_POST['email'], 'sql' => sprintf('update `TABLE` set `col`=? where `email`="%s"', $_POST['email'] ) )); break; } exit( $data ); } ?> <!DOCTYPE html> <html lang='en'> <head> <meta charset='utf-8' /> <title></title> <style> .hidden{display:none} </style> <script> document.addEventListener('DOMContentLoaded',()=>{ /* I can see no benefit to having multiple endpoints to process the different AJAX requests. You can structure a single script to process each request rather like the above PHP code but that is just an opinion. The following points ALL requests to the same page for this demo. The user's `email` address should be unique(?) so could be used as the key in whatever sql query??? */ const endpoints={ 'insert':location.href, // 'MiniProject/connect.php' 'select':location.href, // 'MiniProject/Select.php' 'remove':location.href, // 'MiniProject/Remove.php' 'update':location.href // 'MiniProject/Update.php' }; // Elements in the initial page/form let cont=document.querySelector('div.container'); let form=document.forms.register; let bttn=form.querySelector('button'); // the main callback - for the `Submit` button const bttnclickhandler=function(e){ e.preventDefault(); let valid=true; // check the form fields are not empty before continuing let col=form.elements; Array.from( col ).some( n => { if( n.tagName=='INPUT' && n.value=='' ){ alert( '"' + n.name + '" cannot be empty' ); valid=false; return true; } }) if( !valid )return false; // Prepare the Payload to be sent, via AJAX POST, to the backend script/endpoint. let fd=new FormData( form ); fd.append('action',this.dataset.action); // Send the AJAX request fetch( endpoints.insert, { method:'post', body:fd } ) .then( r=>r.text() ) .then( text=>{ // Hide the original form - do not remove it though... you want to reinstate this later form.classList.add('hidden'); /* create a clone of the template and then find the elements within assign new values and bind event listeners. */ let oTmpl=document.querySelector('template#list-item').content.firstElementChild.cloneNode( true ); oTmpl.querySelector('[data-id="name"]').textContent=fd.get('name'); oTmpl.querySelector('[data-id="email"]').textContent=fd.get('email'); oTmpl.querySelectorAll('button[data-action]').forEach( n=>{ n.addEventListener('click',function(e){ let action=this.dataset.action; let url=endpoints[ action ]; let fd=new FormData(); fd.append('action',action); fd.append('name',e.target.parentNode.parentNode.querySelector('span[data-id="name"]').textContent); fd.append('email',e.target.parentNode.parentNode.querySelector('span[data-id="email"]').textContent); // send a new AJAX request fetch( url, { method:'post', body:fd }) .then( r=>r.json() ) .then( json=>{ // the response... console.log( json ); // show the original form and remove the clone form.classList.remove('hidden'); cont.querySelector('ul#list').removeChild( oTmpl ); }) }); }); // Add the cloned template to the container cont.querySelector('ul#list').appendChild( oTmpl ) }) }; // bind the event handler to the button. bttn.addEventListener( 'click', bttnclickhandler ); }); </script> </head> <body> <!-- All buttons below have dataset attributes data-action='value' - this is used to decide which piece of PHP code to process. --> <div class='container'> <h2>User Registration</h2> <form name='register' method='post'> <div class='form-group'> <label> Name: <input type='text' name='name' class='form-control' placeholder='Enter Name' /> </label> </div> <div class='form-group'> <label> Email: <input type='email' name='email' class='form-control' placeholder='Enter Email' /> </label> </div> <button data-action='insert' class='btn btn-primary'>Submit</button> </form> <ul id='list'></ul> </div> <!-- The template will be called and populated by ajax callback when the above `Submit` button is clicked. This will NOT appear in the DOM until requested with Javascript. The inner contents of this template are cloned and inserted into the DOM. --> <template id='list-item'> <li> <span data-id='name'></span> <span data-id='email'></span> <div> <button data-action='remove' class="btn btn-primary">Remove</button> <button data-action='update' class="btn btn-primary">Update</button> </div> </li> </template> </body> </html>