Triggering 'focusout' (or similar) for parent elements

793 Views Asked by At

I have an (obviously simplified) form structure like so:

 <form class = 'crud'>
  <div class = 'record' id='record_0'>
    <input id='testa_0' name='testa' class = 'crud-control'>
    <input id='testb_0' name='testb' class = 'crud-control'>
  </div>
  <div class = 'record' id='record_1'>
    <input id='testa_1' name='testa' class = 'crud-control'>
    <input id='testb_1' name='testb' class = 'crud-control'>
  </div>
  <div class = 'record' id='record_2'>
    <input id='testa_2' name='testa' class = 'crud-control'>
    <input id='testb_2' name='testb' class = 'crud-control'>
  </div>
</form>

I would like to trigger an event (for data submission), when the user moves from an input element within one record to another record (actually clicks/moves outside the current record), but not when the user moves from one input to another input that's a descendant of the same div.record.

I have tried to attach a .focusout() event handler to div.record, but that fires also, when moving from input to another input 'within' the same record -- I suppose that's normal behavior due to bubbling.

Any suggestions, on how to proceed?

2

There are 2 best solutions below

0
Harsh Saini On

You can bind the blur events to the input fields like this:

const testa_0 = document.getElementById('testa_0');
testa_0?.addEventListener('blur', function(event) {
  //check if the new target is in the same parent or not
  if (event.target.parentElement != event.relatedTarget?.parentElement) {
    //parent is changed
    //do whatever you like to do
  }
});

0
Louys Patrice Bessette On

I woould use both focus and blur events.
On blur, store the parent element in a variable.
On focus, if the parent is not the same, do something.

let inputs = document.querySelectorAll(".record input")
let parent

inputs.forEach(function(input) {
  input.addEventListener("blur", function(e) {
    parent = e.target.closest(".record")
  })

  input.addEventListener("focus", function(e) {
    if (parent && e.target.closest(".record") !== parent) {
      console.log("Do something here.")
    }
  })
})
<form class='crud'>
  <div class='record' id='record_0'>
    <input id='testa_0' name='testa' class='crud-control'>
    <input id='testb_0' name='testb' class='crud-control'>
  </div>
  <div class='record' id='record_1'>
    <input id='testa_1' name='testa' class='crud-control'>
    <input id='testb_1' name='testb' class='crud-control'>
  </div>
  <div class='record' id='record_2'>
    <input id='testa_2' name='testa' class='crud-control'>
    <input id='testb_2' name='testb' class='crud-control'>
  </div>
</form>