1

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.

22
  • Is the above Javascript the actual code you are using? Have you looked at the console? What code is in connect.php? Commented Apr 19, 2021 at 6:36
  • yes this is what i am using . and sorry what do you mean by looking at the console ? i have added the connect.php above in the desc. Commented Apr 19, 2021 at 6:39
  • There is a stray "\" in there immediately before $.post("http://localhost/MiniProject/Update.php" which is causing an error. The console is part of the Browser Developer Tools ~ most modern browsers have such. What Browser have you got? Commented Apr 19, 2021 at 6:41
  • got that thanks . yes i now get what console is and i have looked at it . and i am using chrome browser Commented Apr 19, 2021 at 6:44
  • 1
    Why have you got mysqli and PDO code running here in various places - such as update.php or ` connect.php? Also worth noting - class Users extends DatabaseClass` ~ is the user a database? NO. Extending a class makes sense when of same/similar types of objects... in this case you could pass the db connection as a parameter to the user class.... but, if it works don't sweat it but it is not great from a design point of view Commented Apr 19, 2021 at 8:49

2 Answers 2

1

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>
Sign up to request clarification or add additional context in comments.

Comments

1

You say that you want to make an AJAX request (submit), but I don't see where are you doing it.

Also, it seems that you're submitting twice your form.

You should have something like this:

        $.ajax({
        data: $(this).serialize(),
        type: "POST",
        url: "http://localhost/MiniProject/connect.php",
        success: function(data) {
            //if it's successful, put all your code here to change names etc.
        }

$(this).serialize() will work only if you change your button to a submit input:

<input type="submit" id="submitBtn" class="btn btn-primary">Submit</input>

you can also use a "button" but then you'll have to specify what data you're submitting, it's easier to use a submit input, if you ask me.

Also, if you already have an ID for name and email, it's a lot easier to change them using it's respective ID's, instead of trying to re-write the whole div element.

Anyway, I hope it helps

1 Comment

thanks a lot . i will try to implement your ideas in my code .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.