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

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!

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);
});
2 Likes

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!!

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!!
1 Like

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
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();
}

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);
                })
            }

@camperextraordinaire, 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: