0

I have a rest call in my application (spring based) to update the User's Active (boolean) status using Fetch API like below:

async function activateUser(obj) {
    var fullURL = obj.getAttribute("href");
    
    let response = await fetch(fullURL, {
        method: 'POST'
    });
    let result = await response.json();
    if (response.ok) {
        alert(result.username + " Activated Successfully.. !!");
        obj.parentElement.parentElement.cells[6].innerHTML = "true";
        //getAllUsersApi(endpoint);
    } else {
        alert(response.status + "Error Occurred.. !!");
    }
}

All works well.

Now, I am trying to update just that cell of my html table to true whose Initial value was false. I am updating the html table's cell by hard-coding the column number using (as you can see above too) - obj.parentElement.parentElement.cells[6].innerHTML = "true";. I was wondering if there is some way we can find the false in that row for that particular user and update that cell only. Prior to this I was reloading the entire table (the commented line in the JS code above), which nobody will prefer. I tried to find the solution here and here. But couldn't find the stating point for my situation.

From my rest call I am returning the User object so I was just wondering if I could search the table (on client side) just for that particular user and update that just one corresponding cell. In the table Id, Username and email are unique if that helps to find and replace false to true..

Summarized question: How can I update just one cell of my html table by utilizing the response from my REST call?

Ajay Kumar
  • 2,906
  • 3
  • 23
  • 46
  • Why search the entire table? Isn't the link sitting in the row that relates to the user? And secondly, what is the *issue* with the current code? – trincot Mar 15 '21 at 20:56
  • Yes correct the link is there in the same row. I meant to say, I need to find that false and set it to true. I am open for any solution where I dont have to hard-code. Some clean way rather than the patch work I have done. ! :-) – Ajay Kumar Mar 15 '21 at 20:57
  • So should it not be enough to scan the *current* row? Is there a possibility it is not in cell 6? – trincot Mar 15 '21 at 20:59
  • Yes there is possibility that it might not be in cell[6]. Thats why I am looking for a cleaner way to achieve it. – Ajay Kumar Mar 15 '21 at 21:00
  • It looks like you're already using their `user.id` for other stuff on the page, you could use that for making finding the cells easier. E.g. each row would have an id like `user_{{ user id goes here }}`. Now each cell can have a class or data-attribute that identifies it's purpose. So to get the boolean cell, it could be `document.querySelector('#user_{{ user id goes here }} .is-user-active');`. – frankie Mar 15 '21 at 21:14
  • It would have been better if your question had some sample HTML included. Relevant information should not be behind a link – trincot Mar 15 '21 at 21:52

2 Answers2

1

There is not really much magic to do. Instead of targetting cell 6, you would check find out the column number by finding the column header that has the title "Enabled". Replace this:

obj.parentElement.parentElement.cells[6].innerHTML = "true";

With:

let row = obj.closest("tr");
let titles = row.closest("table").querySelectorAll("th");
for (let cellNo = 0; cellNo < titles.length; cellNo++) {
    if (titles[cellNo].textContent.includes("Enabled")) {
        row.cells[cellNo].textContent = "true";
    }
}    

This is based on the information you have given in the question (not behind links) and in comments/chat.

trincot
  • 317,000
  • 35
  • 244
  • 286
  • Yes, it will change all false to true (in that row only). If that is not what you want, then your question should explain how to identify the cell that needs updating. – trincot Mar 15 '21 at 21:28
  • As I mentioned, Id, Username and Email are unique for all users and can not be null or true or false if that helps. Thanks again. – Ajay Kumar Mar 15 '21 at 21:28
  • Yes, but I understood that the current row was the row of the user. I think you confirmed that, right? – trincot Mar 15 '21 at 21:29
  • Yes correct. So we need to focus only on one row. Yes right - as this code does. But I need to handle other "false" too, if any. – Ajay Kumar Mar 15 '21 at 21:30
  • As this code does... `obj` is the link, `obj.parentNode` is the cell that has the link, `obj.parentNode.parentNode` is the row that has the link, `obj.parentNode.parentNode.cells` are all the cells in the row that has the link. The loop looks for `false` among the cells in that row (only), and updates `false` to `true`. – trincot Mar 15 '21 at 21:30
  • *"but I need to handle other "false" too"*: where are they? In the same row? – trincot Mar 15 '21 at 21:33
1

Since each ID is unique, you can add that to each row as an id="user id goes here" attribute. Then each cell can be given a class to specify it's purpose.

For example:

<table>
  <tr id="user_{{ user ID }}">
    <td class="user-name">{{ user name }}</td>
    <td class="user-email">{{ user email address }}</td>
    <td class="is-user-active">{{ user active status }}</td>
  </tr>
</table>

Since the result is returning the username, I am guessing it can also return the ID, in which case your code would look like this:

if (response.ok) {
  let isUserActive = document.querySelector(`#user_${result.id} .is-user-active`);

  isUserActive.innerHTML = "true"
}
frankie
  • 201
  • 1
  • 6
  • This solution didn't work for me. As I am creating the tr's and td's using javascript. I was able to set the class as isuseractive for td - `${appuser.userenabled}` and tried the solution but didnt work. It always returns null for let isUserActive = document.querySelector(`isuseractive_${result.id}`); – Ajay Kumar Mar 15 '21 at 22:24
  • Your selector string should be `.isuseractive_${result.id}` the period lets `querySelector` know to look for an element with that class. Your current code is looking for an element with the tag name `isuseractive_${result.id}` – frankie Mar 15 '21 at 22:34
  • Man...! It worked.. I was doing a silly mistake by setting the class for another TD. The solution I was looking for, worked flawlessly - only with two lines of code. – Ajay Kumar Mar 16 '21 at 02:16
  • @AjayKumar Glad to hear it! – frankie Mar 16 '21 at 02:36