Matt
Matt

Reputation: 2509

Cloning elements with hover events?

HTML:

<div id='task-header'>
</div>
<div id='tasks'>
    <a href="#" id ="add">Add</a>
  <ul>
    <li class ="editable">
      <form class='task'>
        <input class='textfield' type='text' />
      </form>
        <a href="#" class="delete">Delete this row</a>
    </li>
  </ul>
</div>
<div id='task-footer'></div>

jQuery:

var item = $("#tasks ul li:eq(0)").clone(true); // need to clone for new add
$('#add').click(function() {
    var taskItem = item.clone(true);
    $('#tasks ul').append(taskItem);
    taskItem.find(':input:text').val("");
    return false;
});

$('body').on('click', '.delete', function() {
    $(this).parent('li').remove();
    return false;
});

$(".editable").hover(function() {
    $(this).addClass("editHover");
}, function() {
    $(this).removeClass("editHover");
});​

JSFiddle: http://jsfiddle.net/t67yJ/

I set my clone(true) parameter, but I still cannot get my cloned <li>'s to have the hover effect. What should I do?

Thanks.

Upvotes: 2

Views: 1977

Answers (4)

VisioN
VisioN

Reputation: 145428

In order not to clone element twice, you can remove one extra clone in the first line and attach handlers in delegated-events approach:

var item = $("#tasks ul li:eq(0)");

$("body").on("hover", ".editable", function() {
    $(this).toggleClass("editHover");
}).on("click", "#add", function() {
    var taskItem = item.clone(true).removeClass("editHover");
    $("#tasks ul").append(taskItem);
    taskItem.find(":input:text").val("");
    return false;
}).on("click", ".delete", function() {
    $(this).parent("li").remove();
    return false;
});​

DEMO: http://jsfiddle.net/t67yJ/7/

Upvotes: 0

thecodeparadox
thecodeparadox

Reputation: 87073

Solution 1:

$(".editable").hover(function() {
    $(this).addClass("editHover");
}, function() {
    $(this).removeClass("editHover");
});
var item = $("#tasks ul li:eq(0)").clone(true); // just change the place 
                                                // of first clone statement
$('#add').click(function() {
    var taskItem = item.clone(true);
    $('#tasks ul').append(taskItem);
    taskItem.find(':input:text').val("");
    return false;
});
$('body').on('click', '.delete', function() {
    $(this).parent('li').remove();
    return false;
});

DEMO

Solution 2: (with event delegation)

var item = $("#tasks ul li:eq(0)"); // remove clone(true) from here
$('#add').click(function() {
    var taskItem = item.clone(true);
    $('#tasks ul').append(taskItem);
    taskItem.find(':input:text').val("");
    return false;
});
$('body').on('click', '.delete', function() {
    $(this).parent('li').remove();
    return false;
});
// use event delegation
$("#tasks").on('hover', '.editable', function(e) {
    if (e.type == 'mouseenter') $(this).addClass("editHover");
    else $(this).removeClass("editHover");
});

DEMO (with event delegation)

Upvotes: 2

Selvakumar Arumugam
Selvakumar Arumugam

Reputation: 79830

Simply move the clone call below the handler like below,

$(".editable").hover(function() {
    $(this).addClass("editHover");
}, function() {
    $(this).removeClass("editHover");
});

var item = $("#tasks ul li:eq(0)").clone(true); // need to clone for new add

DEMO

Upvotes: 2

Fabr&#237;cio Matt&#233;
Fabr&#237;cio Matt&#233;

Reputation: 70169

The event listeners aren't defined yet when you clone the element. Move var item = $("#tasks ul li:eq(0)").clone(true); to the end of your script.

Fiddle

Or use the .on/.live event delegation and you won't have to clone the listeners, as coder said.

Upvotes: 0

Related Questions