[AJAX & PHP] How to get specific Button Value if all of them have the same class

[AJAX & PHP] How to get specific Button Value if all of them have the same class
0

#1

Scenario:

Im going to make this question as clear as i can so that everyone will be able to understand what i exactly dont understand! Now I have a total of 3 buttons in my document which has the same name and class but each has different value according to its id in the database (The buttons' values are retrieved from a SQL database thats why one is significantly unique from all others)

<form method="GET">
    <button class='manipulate' name='manipulate' value='1' >Manipulate</button>
    <button class='manipulate' name='manipulate' value='2' >Manipulate</button>
    <button class='manipulate' name='manipulate' value='3' >Manipulate</button>
</form>

What I usually do using pure PHP :

if(isset($_GET['manipulate']){
    echo $_GET['manipulate'];
}

// The code above will actually display the specific value of a specific button from the form when its clicked

The Problem :

Im using AJAX to send request to the server asynchronously so that there will be no page refresh whenever I query to the database. Now, instead of using the pure PHP to retrieve the value of each button, I have to use javascript and pass the value of the selected button to an AJAX function called get()

let xhr = new XMLHttpRequest();
// xhr.open("The method", "The PHP Processor");

xhr.open("GET", "processor.php?idValue="+/*This is where the selected button's id should appear!*/);

I know i can use the ' .value ' property of the button and just append it to the comment above... But it seems like its hard for javascript to know what button was clicked since they have the same class and name, and by the way i select them using querySelector('.manipulate') function... I certainly dont know what to do! Please Help me!

Summary:

I want to get the value of a specific button from an array of buttons which has the same class and use it for the ajax get function!

#2

querySelector will only select the first element matching the class.

There are a couple different options to capture the correct value of the button clicked. If you will only have a few buttons (1-5), then you can use querySelectorAll which will return a NodeList which you will need iterate through and add click event listeners to each button.

If you only have the one form on the page, then you can write:

const buttons = document.querySelectorAll('.manipulate');
for (let i in buttons) {
  buttons[i].addEventListener('click', event => {
    event.preventDefault();
    console.log(event.target.value);
  });
};

A cleaner and more efficient way (especially if you have many buttons), is to wrap all the buttons in another element (like a div) and give that element a unique id. Then in your JavaScript, you add a single eventListener for that element by using getElementById.

HTML

<form method="GET">
  <div id="buttons">
    <button class='manipulate' name='manipulate' value='1' >Manipulate</button>
    <button class='manipulate' name='manipulate' value='2' >Manipulate</button>
    <button class='manipulate' name='manipulate' value='3' >Manipulate</button>
  </div>
</form>

JavaScript

buttons.addEventListener('click', event => {
  event.preventDefault();
  console.log(event.target.value);
});

#3

Thanks a lot for a clear and comprehensive reply! I really appreciated it!

I have 2 things to clarify :

Before I use these solutions to my project. I want to clarify these things.
1.) In my addEventListener Function I use an anonymous function as my second parameter :
x.addEventListener('click', function(){
   //Like so
})

However, I have noticed that you used something that I havent tried before, I feel that is in the ES6 but does that “event” represents the parameter i usually append whenever I declare an anonymous function?

2.) Does that target property represents what button was actually clicked from the node list?




And, by the way, I am using a form, which usually is the one that I submit like :

document.querySelector("myForm").addEventListener('click', function(evt){
evt.preventDefault()
})

// But i can see that you added that into the button… Anyways, I will try, Thanks a lot!!


#4

The addEventListener callback function receives the event object as it’s argument. My arrow function syntax does the same thing as below.

x.addEventListener('click', function(event){
   //Like so
})

The target property of the event object is the element that was clicked.


#5

I have got it!

I just found out the answers to my problem right when I tried it in my project!!! I learned that the event that was passed in the function was an object that includes the property of target which is as well an object that has a lot of properties that includes value... so to get the value, you can simply use event.target.class! just like document.querySelector() where the querySelector() is a method of the document object!!

Thanks sir Randell !

Now Im getting the correct value whenever I click a specific button! Thanks sir @randelldawson ! I never thought i could as well add the prevent default in the button that was actually submitting the form instead of the form itself!!

#6

My problem was fixed, just like ive declared above, but…
I have another problem, the document.querySelectorAll doesnt retrieve the buttons that came from a database…

Like this :

<div class='container'>
</div>

display_data(document.querySelector('.container')); 
// an external script function that displays the informations from the PHP From the database

console.log(document.querySelectorAll("button"));
// Instead of showing all possible buttons in the document it results to an empty nodeList

#7

I assume the display_data function uses AJAX to get the data? If so, it is probably an asynchronous function and other code after the call is allowed to keep executing. The console.log statement executes before the data is received. I would need to see your display_data function code to better instruct you on how to proceed.


#8
function display_data(container){
    let xhr = new XMLHttpRequest();
    xhr.open("GET", "php/display_data.php", true);

    xhr.onreadystatechange = function(){
        if(xhr.readyState === 4 && xhr.status === 200){
            let json = JSON.parse(xhr.responseText);
            let message = "";
            for (let i = 0; i < json.length ; i++) {
                message += "<p class='name'>"+json[i].name+"</p>";
                message += "<p class='email'>"+json[i].email+"</p>";
                message += "<button class='delete' name='delete' value='"+json[i].id+"'>DELETE</button>"
            }

            container.innerHTML = message;
        }
    };

    xhr.send();
}

#9

Anything you want to do with buttons created after the container.innerHTML = message line will need to be done after that line (inside the if(xhr.readyState === 4 && xhr.status === 200){ statement block).

function display_data(container){
    let xhr = new XMLHttpRequest();
    xhr.open("GET", "php/display_data.php", true);

    xhr.onreadystatechange = function(){
        if(xhr.readyState === 4 && xhr.status === 200){
            let json = JSON.parse(xhr.responseText);
            let message = "";
            for (let i = 0; i < json.length ; i++) {
                message += "<p class='name'>"+json[i].name+"</p>";
                message += "<p class='email'>"+json[i].email+"</p>";
                message += "<button class='delete' name='delete' value='"+json[i].id+"'>DELETE</button>"
            }
            container.innerHTML = message;
            console.log(document.querySelectorAll("button")); 
           // Only once the buttons have been created, can you do anything with them.
        }
    };

    xhr.send();
}

#10

I written these below the containe.innerHTML = message; but it doesnt seem to apply that preventDefault() function, the page still loads, whenever i make a form request

container.innerHTML = message;
            let buttons = document.querySelectorAll(".delete");
            for (let i = 0; i < buttons.length; i++) {
                buttons[i].addEventListener('click', function(e){
                    e.preventDefault();
                    console.log(e);
                })
            }

#11

I do not see a form anywhere in your latest code. Can you please put your code in Codepen, JSFiddle, or somewhere else, so we can both see the same code? It will make it easier.

Thank you.


#12

@RandellDawson, everything was actually fine, chrome just seems to be playing around and wont change the appearance and dynamics of the page, even if changed the code… However, I can see the result i chnaged when I view it with another browser… I fixed it by simply clearing history and cookies… Finally, i made a CRUD via Ajax :smile: Thanks! :heart::heart::heart: