0

This code is not working:

$("ul.lst li").hover(function (event) {   
    $('#span').text($(this).index());
});

When use the same code and hard coded html, mouse-over works smooth and give the hovered li index. What am I missing?

var records = [];
var selectedIndex = null;
var selectedRecord = null;
var fRecords = [];
var autocomplete = function (event, el) {   
    var search = el.value;

    if (event.key === "ArrowDown") {
       
        if(records == null) return;  // if no result

        if (records.length > 0 && selectedIndex == null) {
            selectedIndex = 0;           
        }
        else if (records.length > 0 && selectedIndex < records.length - 1) {
            selectedIndex++;
        }
        changeClass(selectedIndex);
    }
    else if (event.key === "ArrowUp") {
        if (records == null) return;  // if no result

        if (records.length > 0 && selectedIndex == null) {
            selectedIndex = 0;
        }
        else if (records.length > 0 && selectedIndex > 0) {
            selectedIndex--;
        }
        changeClass(selectedIndex);
    }
    else if (event.key === "Enter") {

    }
    else {
        selectedIndex = null;
        selectedRecord = null;

        if (records.length === 0) {
            $.get('https://jsonplaceholder.typicode.com/comments')
                .done(function (data) {
                   
                    records = data;
                    // sort by name
                    sort(records);

                    showAutoComplete(records, search);
                });
        }
        else {
            showAutoComplete(records, search);
        }
    }
}

var showAutoComplete = function (data, search) {
    search = search.toUpperCase();
    fRecords = [];
    $.each(data, function (k, v) {
        if (v.name.toUpperCase().startsWith(search)) {
            fRecords.push(v);
            if (fRecords.length > 9)
                return false;
        }
    });

    $("ul.lst").empty();
    if (fRecords.length > 0)
        $("ul.lst").addClass("suggest");
    else
        $("ul.lst").removeClass("suggest");
    $.each(fRecords, function (key, value) {
        $("ul.lst").append('<li>' + value.name + '</li>');
    });
}

var sort = function (records) {
    records.sort(function (a, b) {
        var nameA = a.name.toUpperCase(); // ignore upper and lowercase
        var nameB = b.name.toUpperCase(); // ignore upper and lowercase
        if (nameA < nameB) {   return -1; }
        if (nameA > nameB) { return 1; }
        // names must be equal
        return 0;
    });   
}

var changeClass = function (index) {

    selectedRecord = records[selectedIndex];
    $("ul.lst>li.active").removeClass("active");
    if (selectedIndex != null) {
        $($("ul.lst>li")[selectedIndex]).addClass("active");
        $('#company').val($($("ul.lst>li")[selectedIndex]).text());
    }
}

$('#company').keyup(function () { autocomplete(event, this); });

$('#company').blur(function(){
    $("ul.lst").removeClass("suggest");
})

//$("ul.autocomplete li").hover(function (event) {
//        debugger;
//        selectedIndex = $(this).index();
//        changeClass(selectedIndex);
//        console.log(selectedIndex);
    
//});


$("ul.lst li").hover(function (event) {
   
    $('#span').text($(this).index());

});
ul.lst {
    display: none;
}
ul.lst.suggest {
        display:block;
       
    }
    ul.lst li {
        list-style: none;
        padding: 7px 12px;
        border: 1px solid #bbb;
        white-space: nowrap;
        overflow: hidden;
    }
     ul.lst > li.active {
        background-color: #ffcc66;
        color: #000;
       z-index:1000;
    }
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<div class='col-sm-10 offset-col-1 mt-4'>
  <strong>Type something for auto complete</strong>
  <span id='span'></span>
  <input type='text' id='company' class='form-control'>
  <ul class='lst'></ul>

</div>
Ali Adravi
  • 21,707
  • 9
  • 87
  • 85

2 Answers2

1

$("ul.lst li").hover adds the hover event handler only to the elements existing at the time when it’s called.

To make it apply to all the elements, even the ones added later, use on, like this:

$("ul.lst").on('mouseover', 'li', function (event) { {   
    $('#span').text($(this).index());
});

In the selector, you specify the parent element that exists at the moment of the script call (here, it’s ul.lst), and later, as the second parameter, you specify additional selector inside it (li). It will work on any li added inside ul.lst at any time.

Ali Adravi
  • 21,707
  • 9
  • 87
  • 85
  • 1
    Actually you can't bind `hover` event like this. You have to use `mouseenter` or `mouseover`. Reason is mentioned here: https://stackoverflow.com/questions/12260235/jquery-on-hover-not-working – NiK648 Feb 13 '18 at 18:11
0

Probably is because the event is been called before the elements are loaded. You should wait for the document to load before adding the event, like so:

$(function() {
  $("ul.lst li").hover(function (event) {   
     $('#span').text($(this).index());
  });
});
JPeter
  • 219
  • 1
  • 14