0

I have a table of customers. Each customer has a first and a last name. The two text fields of the table are editable. So users can update the information when they press Save. The problem is that I cannot get the specific row information,I only get the first row results

I tried to match to the names with the input field but I had no success.

<?php foreach($customer as $each){ ?>
    <td class="first_name" id="first" contenteditable="true"><?php echo 
    $each['first_name']; ?></td>
    <td class="last_name" id="last"  contenteditable="true"><?php echo 
    $each['last_name']; ?></td>
    <td >   <button type="button" onclick="save('<?php echo $each['first_name'];? 
    >','<?php echo $each['last_name'];?>');" >Save</button></td>
    <? } ?>

<script type="text/javascript">
    function save(first,second) {
      <?php foreach($customer as $each){?>
        var first_name = "<?php echo $each['first_name']?>";
        var last_name = "<?php echo $each['last_name']?>";
        if (first_name==first && last_name == second){
          var fname = document.querySelectorAll(".first_name");
          console.log(fname[0]);
        }
        <?php } ?>

      }
 </script>
Spy
  • 153
  • 10
  • 1
    Possible duplicate of [What is the difference between client-side and server-side programming?](https://stackoverflow.com/questions/13840429/what-is-the-difference-between-client-side-and-server-side-programming) – Jonnix Jan 28 '19 at 11:19
  • That because when you doing `this.document.querySelector('#first_name'),` you always get the first name. You should look for / save the name you got in the argument of the function – dWinder Jan 28 '19 at 11:20
  • 4
    It is because you use IDs. IDs are unique, so you can only use them once in the document. You should use the class-attribute to achieve this. – Bernhard Jan 28 '19 at 11:21
  • 1
    Try using classes instead of id's `.first-name` `.last-name` – Andrejs Gubars Jan 28 '19 at 11:23
  • @AndrejsGubars I edited the code and added the classes plus added the querySelectorAl. Still, I am getting only the first row results – Spy Jan 28 '19 at 11:47
  • yes, because `this.document.querySelector('.className')` will return the first occurrence. use `this.document.querySelectorAll('.className')` will return you an array of all elements with that `className` – Andrejs Gubars Jan 28 '19 at 11:53

2 Answers2

1

You would have to use a different query selector. Assign a classname or an attribute to the elements you want to select (e.g name for querying with .name) then querySelectorAll method will return an array of the elements that matched your query.

Jay
  • 841
  • 1
  • 8
  • 19
  • I have edited my code. Still, with classes and querySelectorAll, I get only the first result – Spy Jan 28 '19 at 11:46
  • you specifically used the first one: `console.log(fname[0]);` if you need them all use a `for...in` loop or something similar – Jay Jan 28 '19 at 12:04
1

The main problem that I see is that you create unnecessary foreach loop inside a javascript function using php.

You can dynamically create your table and the contents inside it, that's fine. But the javascript does not care about that and you should not create javascript with php. So I would do it this way.

I wrap the td's in tr's cause i'm assuming you are putting that data in tr.

<?php foreach($customer as $each){ ?>
  <tr class="customer-row">
    <td class="first_name" contenteditable="true"><?php echo 
    $each['first_name']; ?></td>
    <td class="last_name" contenteditable="true"><?php echo 
    $each['last_name']; ?></td>
    <td><button type="button" class="save">Save</button></td>
  </tr>
<? } ?>

Then outside the php foreach loop i would create my script.

<script type="text/javascript">
var saveBtn = document.querySelectorAll(".save");

for(var i = 0; i < saveBtn.length; i++) {
  // attach click event to every button.
  saveBtn[i].addEventListener("click", function() {
    var _this = this;
    var _tr = _this.closest(".customer-row");
    var fname = _tr.querySelector(".first_name").innerText;
    var lname = _tr.querySelector(".last_name").innerText;
    console.log("Name: ", fname + " " + lname");
    // below you can implement your check name logic...
  }
}
</script>

I'm not 100% sure if my js will not throw errors, but it should give you an indication that you should separate your server-side from client-side logic.

Andrejs Gubars
  • 584
  • 7
  • 30