0

I'm (very slowly) making a website, and I'm creating a search engine for the database, which is essential to organize the dependencies during data entry.

Anyway, what I would like is to type a few keywords into a box, have a menu pop up with various search results, and have the box fill with the ID number of the selected entry when it's clicked.

Currently, I have a document called search.php which fills a div called search-output using xmlhttp.open() and the innerhtml property. Everything is working perfectly except for filling the original search box with the ID number when clicking.

My first attempt was to add an onclick event to each entry in the output from search.php. Unfortunately, I found that javascript inserted into innerhtml is not run for security reasons. I've been Googling for hours but haven't been able to find a solution.

How can I get the original search text box to fill with the correct ID when I click it? Is what I'm doing a good setup for the results I desire, or is there a better way to integrate search features into data entry?

3
  • 1
    So the ID comes back from the XHR query? Or was it in the popup the entire time? I don't understand where the problem is. May 27, 2014 at 6:43
  • The problem is that the javascript onclick event doesn't set the textbox value to the ID number because the code was inserted using innerhtml. When the link is clicked, nothing happens.
    – user144527
    May 27, 2014 at 6:52
  • See if my answer fits your needs. May 27, 2014 at 6:53

1 Answer 1

1

Assuming I got what you mean correctly, The solution would be to have a single event handler on the div which is getting populated with the results, and use the Event object passed to the event handler to determine exactly which object was hit:

<input type="text" id="search" name="search">
<div id="search-popup"></div> <!-- This will be populated with partial results -->

And in the JavaScript, this JavaScript is not inserted into the page, but is part of it:

var searchPopup = document.getElementById("search-popup");
searchPopup.onclick = function(event) {
    var actualClickedElement = event.target; //Magic is here
    //Handle your event, probably by changing searchInput.value
};

Now you can handle things with actualClickedElement inside the handler function. This also provides a nice performance boost when things get larger, since you only ever have one handler.

Read up on event delegation @ MDN.

12
  • So, you're saying that I can determine which element was clicked in javascript code outside the innerhtml of the div, even though this stuff was added later, using event.target?
    – user144527
    May 27, 2014 at 6:54
  • This is called event delegation. If you have a div with children, clicking on any of the children also counts as clicking on the parent. By setting a handler on the parent, and using .target to know which child was actually clicked, you can make a generic handler for all of the children at once. Read the attached link for more information. May 27, 2014 at 6:55
  • From what I understand, the problem is that what is added to innerhtml isn't added to the DOM.
    – user144527
    May 27, 2014 at 6:56
  • No, that's wrong. By the mere fact that you can see it on the page, means that it's added to the DOM. Rather, newly created elements need to be attached with the event handler anew. If you are attaching the event handler to an element that doesn't get removed and re-added (like the parent div), you don't have that problem. May 27, 2014 at 6:57
  • 1
    Sometimes event.target was returning the anchor, as expected, but sometimes it was returning an object for just the text inside the anchor. My fix was to cycle through the parents until either event.target.name was defined or the event handler object was found. Now it works every time.
    – user144527
    May 27, 2014 at 14:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.