1

I have search the forums here, but still could not find the right answer. I see solutions with jQuery which I am not familiar with. I am looking for vanilla JavaScript solution please. In short, I create elements dynamically with Ajax and I need to add event listeners to them once they are created. The js here privides suggestions when a user starts typing in input boxes. The code works fine if the input is static, but does not with dynamic. I know DOM gets constructed on load and those elements do not exist yet at the time of loading.

Main page:

<head>

  <script src="../js/autocomplete-type.js"></script>

   <script>
     window.addEventListener("load", function(){
       suggest.attach({
         target : "NCustType",
         url : "../private/searchdbtype.php",
         data : { type: "CustType" }
       });
     })
  </script>
</head>

autocomplete-type.js is pretty long, so not sure if I should post it here.

body on load:

<table id='CustDetails'></table>

Ajax fills this table with the following innerHTML (posting here just one element):

<tr>
  <td>Customer Type</td>
  <td><input type='text' id='NCustType'></td>
</tr>

So I need to add an event listener with function "suggest" with attachments {} to input box with id='NCustType'. I will appreciate help with JavaScript suggestions! I am not a pro with coding but this issue drives me crazy. And I would like to avoid jQuery please.

This part of the code (in automcomplete-type.js) adds a listener:

suggest.instance[opt.target].input.addEventListener("keyup", function (evt) { // Clear old timer if (suggest.instance[opt.target].timer != null) { window.clearTimeout(suggest.instance[opt.target].timer); } However, the file is generic and is used for different fields

So how do I call that js file AND function in 'head' (with parameters) after Ajax fires?

MaxCB
  • 59
  • 6
  • 1
    Does this answer your question? [Event binding on dynamically created elements?](https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – teshnizi Apr 22 '20 at 14:44
  • So what adds the table? Call a function that binds the autosuggest when that completes. – epascarello Apr 22 '20 at 14:54
  • Epascarello, multiple rows/columns are added to the table with multiple input fields. This table is dynamic. Ajax sends request to another php page which constructs that table and fills out inputs. However, then lets say I need to edit the field but my suggestion function does not work – MaxCB Apr 22 '20 at 18:59
  • Teshnizi, the above mentioned link suggests jQuery and I am looking for vanilla js solution – MaxCB Apr 22 '20 at 18:59
  • The question linked has answers which do not use jQuery; [this one, for instance](https://stackoverflow.com/a/27373951/215552). – Heretic Monkey Apr 22 '20 at 19:27
  • Heretic, it is based on classes, I have dozens of fields so I need to use ids plus that post does not explain much in details – MaxCB Apr 22 '20 at 19:36
  • I tried to wrap all autocomplete js code in one function in js file, then use AppendChild method step by step. Inserted this code after Ajax inserted html. Still not working: `` – MaxCB Apr 22 '20 at 21:20
  • FYI, to reply to someone, put an @ symbol in front of their name, like @MaxCB. – Heretic Monkey Apr 23 '20 at 15:36

2 Answers2

0

If you want to add event listener to elements, which do not exist yet, there is a trick: you attach event listener to the document and then rely on event "bubbling" up from the element through the DOM tree.

In code that would look like

// Attach event listener to the document
document.addEventListener('change', (event) => {
    // Make sure, that you're receiving event from a correct element
    if (event.target.id === 'NCustType') {
        // Do what you want to do here
    }
});

Hope that helps!

0

If I understand the issue correctly, the html elements do not exist before doing the ajax request, which means that you can only do the event bindings afterwards. So after doing the ajax call, you need to iterate every result and create a listener for each id input that you're creating.

fetch('my/api').then(r => {
   r.map(item => {
    document.querySelector(`#${item.id}-input`).addEventListener('keyup', yourfunction);
   })
})