0

I am creating a dynamically generated html <ul> in jquery which has some <li> elements in it. I want an active class be added to any of the <li> elements by hovering. I've tried some functions in jquery but it won't change <li> elements, it will only work if I try it on <ul> element. Here is my html code:

<div class="col-md-3 all_session_section" id="listRight">

  <ul class="meeting_lists" id="meeting_lists"></ul>

My Javascript code:

$.ajax({
        url: myURL,
        method: "GET",
        headers: { "Accept": "application/json; odata=verbose" },
        success: function (data) {
            if (data.d.results.length > 0) {
                AllTask = data.d.results;
                html = '';
            
                for (var i = 0; i < Number(AllTask.length); i++) {
                    html += '<li class="pass" data-tab="tab-1">';
                    html += '<div class="clear_border_active"></div>';
                    html += '<a href="#">';
                    html += '<div class="title">' + AllTask[i].Title + '</div>';
                    html += '<div class="details d-flex justify-content-end align-items-center"><span class="salon mr-3">' + AllTask[i].meeting_place + '</span><span class="date">' + JDate + '</span></div></a></li>';
                    
                }

document.getElementsByClassName('meeting_lists')[0].innerHTML = html;

and my jquery function:

$(".all_session_section  ul > li").hover(
  function () {
    $(this).addClass("active");
  },
  function () {
    $(this).removeClass("active");
  }
);

if anyone can help me with this, I would really appreciate that.

Morris
  • 11
  • 3

2 Answers2

0

right after this line:

document.getElementsByClassName('meeting_lists')[0].innerHTML = html;

which in jQuery could be simplified into this:

$('#meeting_lists').html(html)

Your listener could get created on that specific UL, with 2 callbacks, one for mouseenter, the other for mouseleave

$("#meeting_lists li").hover(
  function () {
    $(this).addClass("active");
  },

function () { $(this).removeClass("active"); } );

But why not just set up a css rule for the hover?

.all_session_section  ul > li:hover{
    /* whatever the active class had for styles */
}
Kinglish
  • 23,358
  • 3
  • 22
  • 43
  • Thank you for the response. Actually, I forgot to copy my last line of ajax code here in the beginning now I've added it. It is still not working and the class will be added only on elements which are static. About your second approach, the reason I can't use that is I'm editing another one's code and there are thousands complex lines of CSS code so I really don't know styles of active class. – Morris May 27 '21 at 08:58
  • I revised my answer. the hover event had 2 callbacks. – Kinglish May 27 '21 at 16:13
0

As @Mohicane told, delegated events are your savior in this case (my example will also use them).

However, IMHO, this will only make the code more complex and I, personally, would go with @Kinglish's solution and use CSS only. For any web work, you're gonna need to know CSS anyway. I strongly recommend you to delve into it.

Security concerns

When constructing HTML like this, the values from the data you receive must be sanitized beforehand. Otherwise this is susceptible to XSS (Cross Site Scripting) and Iframe Injection attacks. The easiest solution is to strip any HTML tags this data might have.

Solution

I tried to reuse your code as much as possible (I have generated the task list instead of an AJax query, so the example runs in this snippet -- click on the Run code snippet button below, to see it in action).

I have also added an active class style to demonstrate the behavior (when the list item will have the active class, it will become yellow).

// I used this to generate some data instead of the ajax request
function generateTasks() {
  const tasks = [];
  for (var i = 0; i < 9; i++) {
    tasks.push({
      Title: 'some task ' + i,
      meeting_place: 'some place ' + i
    });
  }
  
  return tasks;
}

const AllTask = generateTasks();
const JDate = ' 2021-05-07';

let html = '';

for (var i = 0; i < Number(AllTask.length); i++) {
  html += '<li class="pass" data-tab="tab-1">';
  html += '<div class="clear_border_active"></div>';
  html += '<a href="#">';
  html += '<div class="title">' + AllTask[i].Title + '</div>';
  html += '<div class="details d-flex justify-content-end align-items-center"><span class="salon mr-3">' + AllTask[i].meeting_place + '</span><span class="date">' + JDate + '</span></div></a></li>';

}

document.getElementsByClassName('meeting_lists')[0].innerHTML = html;

$(".all_session_section  ul > li").on('mouseenter', function() {
    $(this).addClass("active");
})
  
$(".all_session_section  ul > li").on('mouseleave', function() {
    $(this).removeClass("active");
});
.active {
   background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-md-3 all_session_section" id="listRight">

  <ul class="meeting_lists" id="meeting_lists"></ul>
</div>
beerwin
  • 9,813
  • 6
  • 42
  • 57