Search code examples
javascriptjqueryhtmlmaterialize

JSON live search. Result items onclick events not firing. Why?


The code below works up to the point where I want the user to click on the link list item. For some reason my on click event handler is not catching it at all.

What am I missing? Really frustrated...

I have the following json file data.json with the following structure.

I search this json of key value pairs and create a ul with links in it as the result matches.

Each result inside ul is a link with an href.

I already generate these dynamically.

I would like to capture this click, do a e.preventDefault() on it, then get the href attribute value and windows.location to it. This keeps a native html5 safari ap from opening in a new window as I request a different page.

Here's the LIVE DEMO

[
  {
    "name":"Sarah Connor",
    "client_id":"111"
  },
  {
    "name":"John Travolta",
    "client_id":"222"
  },
  {
    "name":"Tom Cruise",
    "client_id":"333"
  }
]
<!DOCTYPE html>
<html>
<head>
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!--Import materialize.css-->
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>

</head>

<body>

<div class="container">

<div class="row">
<div class="input-field col s12">
<input id="search" type="text" class="validate" placeholder="at least 1 character...">
<label for="search">Search</label>
<div id="results" style="position: absolute; top:48px; background: white;"></div>
</div>

</div>

</div>
<!--JavaScript at end of body for optimized loading-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>

<script>

$( ".collection-item" ).on("click", "a", function(e) {
console.log('test click event fired.');

});


$(document).ready(function() {


$('#search').keyup(function(){

// the search input
var searchField = $('#search').val();

// if at least one char is typed...
if (searchField.length > 0) {

// A. Empty results div.
$('#results').empty();

// "i" = ignore case
var regex = new RegExp(searchField, 'i');

var output = '<ul class=\"collection\">';

// get JSON from PHP...
$.getJSON('data.json', function(data) {

// loop through JSON array of key/value pairs...
$.each(data, function(key, val){

// Returns a Number, representing the position of the first occurrence 
// of the specified searchvalue, or -1 if no match is found

// Here we search and compare against the -1 condition.
// Example... val.name.search(regex) different than NOT FOUND...

// If we got a match on name OR client_id....
if ((val.name.search(regex) != -1)) {

output += '<a href=\"#random\" class=\"collection-item\">';
output += val.name;
output += '<span class=\"badge\">' + val.client_id + '</span>';
output += '</a>';
console.log('match!');

}
// end if

});
// end each

output += '</ul>';
// close ul tag

// output to results div
$('#results').html(output);

}); 


} else {

// clear results div
$('#results').empty();

}

});
});

</script>

</body>
</html>


Solution

  • You are attempting to apply the event listener before the elements exist

    move your event listener assignment to after you iterate over your results, and the elements are added to the dom.

    Also, I believe your event assignment syntax is incorrect. you need to select the element in the $(..) part (ie include your a here) and then apply the handler. You seem to have an extra incorrect parameter ("a") in that part, which I've moved into the selection part.

    ie :

    $('#results').html(output);
    
    ...
    
    $( "a.collection-item" ).on("click", function(e) {
    console.log('test click event fired.');
    
    });