0

So I am creating a table where I need to be able to delete a row when I focus on the input field inside a cell using a button outside the table

<div tabindex="0" class="remove_row" role="button" onclick="removeRow()">
  <span>Remove</span>
</div>
<table id="ListTab" role="grid">
  <thead tabindex="0">
    <tr role="row">
      <th title="Column 1" role="columnheader">
        <span>Column 1</span>
      </th>
      <th title="Column 2" role="columnheader">
        <span>Column 2</span>
      </th>
    </tr>
  </thead>
  <tbody tabindex="0">
    <tr class="UiListRow">
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off">
      </td>
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off">
      </td>
    </tr>
    <tr class="UiListRow">
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off">
      </td>
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off">
      </td>
    </tr>
    <tr class="UiListRow">
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off">
      </td>
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off">
      </td>
    </tr>
  </tbody>
</table>

I want when the user stand on one of the inputs and clicks remove it only removes that row.

2 Answers 2

1

Does this work for you?

var currentFocus = null;

document.querySelector('table').addEventListener("focusin", focusChanged);

function focusChanged(event) {
  currentFocus = event.target;
}

function removeRow() {
  if (currentFocus == null) {
    return;
  }
  var rowToRemove = currentFocus.closest('tr');
  if (rowToRemove.parentElement == null) {
    return;
  }
  rowToRemove.parentElement.removeChild(rowToRemove);
}
<div tabindex="0" class="remove_row" role="button" onclick="removeRow()">
  <span>Remove</span>
</div>
<table id="ListTab" role="grid">
  <thead tabindex="0">
    <tr role="row">
      <th title="Column 1" role="columnheader">
        <span>Column 1</span>
      </th>
      <th title="Column 2" role="columnheader">
        <span>Column 2</span>
      </th>
    </tr>
  </thead>
  <tbody tabindex="0">
    <tr class="UiListRow">
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off" placeholder="a">
      </td>
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off">
      </td>
    </tr>
    <tr class="UiListRow">
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off" placeholder="b">
      </td>
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off">
      </td>
    </tr>
    <tr class="UiListRow">
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off" placeholder="c">
      </td>
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off">
      </td>
    </tr>
  </tbody>
</table>

Sign up to request clarification or add additional context in comments.

3 Comments

I have an add row function and when a new row is added it doesn't detect if it is focused so it can't delete
I changed the "focus" listener on each input item to a "focusin" listener on the table. Does that work for you?
It is generally not a good idea to use inline event handlers.
1

Alternative: use event delegation to handle Adding/Removal of rows.

[`click`, `focusin`].forEach(et => document.addEventListener(et, handle));
const deactivateAllRows = () => document.querySelectorAll(`#ListTab td.active`)
  .forEach(td => td.classList.replace(`active`, `inactive`));

function handle(evt) {
  const origin = evt.target;

  if (evt.type === `click`) {
    if (origin.id === `addRow`) { return addRow(); }

    if (origin.closest(`td`) &&
      origin.closest(`td`).classList.contains(`active`)
    ) {   return origin.closest(`tr`).remove();  }
  }

  if (evt.type === `focusin` &&
    origin.type === `text` &&
    origin.closest(`tr`)) {
    deactivateAllRows();
    const shouldDeactivate = origin.closest(`tr`).querySelector(`td.inactive`);
    return shouldDeactivate &&
      shouldDeactivate.classList.replace(`inactive`, `active`);
  }

  return true;
}

function addRow() {
  deactivateAllRows();
  document.querySelector(`#ListTab tbody`)
    .insertAdjacentHTML(`beforeend`,
      document.querySelector(`#ListTab tbody tr`).outerHTML);
}
.inactive {
  color: #EEE;
}

.active {
  color: red;
  cursor: pointer;
}
<button id="addRow">Add row</button>

<table id="ListTab" role="grid">
  <thead tabindex="0">
    <tr role="row">
      <th title="Column 1" role="columnheader">
        <span>Column 1</span>
      </th>
      <th title="Column 2" role="columnheader">
        <span>Column 2</span>
      </th>
      <th title="remove" role="columnheader" id="removeHeader">
        <span>Remove row</span>
      </th>
    </tr>
  </thead>
  <tbody tabindex="0">
    <tr class="UiListRow">
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off">
      </td>
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off">
      </td>
      <td tabindex="-1" role="gridcell" class="inactive">
        Remove
      </td>
    </tr>
    <tr class="UiListRow">
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off">
      </td>
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off">
      </td>
      <td tabindex="-1" role="gridcell" class="inactive">
        Remove
      </td>
    </tr>
    <tr class="UiListRow">
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off">
      </td>
      <td tabindex="-1" role="gridcell">
        <input type="text" autocomplete="off">
      </td>
      <td tabindex="-1" role="gridcell" class="inactive">
        Remove
      </td>
    </tr>
  </tbody>
</table>

Comments

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.