Jason Demitri
Jason Demitri

Reputation: 63

converting .live() to .on() or .click() functions jquery

I'm currently following a tutorial that uses an old version of jQuery to create an mvc with a built in todo list using ajax calls. The original code went as follows:

$(function() {
    $.get('dashboard/xhrGetListings', function(o) {
        for (var i = 0; i < o.length; i++)
        {
            $('#listInserts').append('<div>' + o[i].text + '<a class="del" rel="'+o[i].id+'" href="#">X</a></div>');
        }

        $('.del').live('click', function() {
            delItem = $(this);
            var id = $(this).attr('rel');
            $.post('dashboard/xhrDeleteListing', {'id': id}, function(o) {
                delItem.parent().remove();
            }, 'json');
            return false;
        });
    }, 'json');

    $('#randomInsert').submit(function() {
        var url = $(this).attr('action');
        var data = $(this).serialize();

        $.post(url, data, function(o) {
            $('#listInserts').append('<div>' + o.text + '<a class="del" rel="'+ o.id +'" href="#">X</a></div>');        
        }, 'json');
            return false;
    });
});

When I updated the jQuery version it threw a hissy fit and wouldn't work so I looked up the error and it didn't like up the .live() function and so a suggestion was to use .on()

And so I changed the .live into

$(document).on("click", ".del", function() 

Now the code does delete from the database but doesn't update until the page is refreshed . . . am I missing something?

Upvotes: 1

Views: 599

Answers (4)

Lorenzo
Lorenzo

Reputation: 13

this is my solution for this jquery script with the latest lib:

$(function() {

$('#listInserts').on('click', '.del', function() {
    var delItem = $(this);
    var id = $(this).attr('rel');
    $.post('dashboard/xhrDeleteListing', {'id': id}, function() {
        delItem.parent().remove();
    });
});

$.get('dashboard/xhrGetListings', function(o) {
    for (var i = 0; i < o.length; i++) {
        $('#listInserts').append('<div>' + o[i].text + ' <a class="del" rel="' + o[i].id + '" href="#">elimina</a></div>');
    }
}, 'json'); // JSON = JavaScript Object Notation

$('#randomInsert').submit(function() {
    var url = $(this).attr('action');
    var data = $(this).serialize();
    $.post(url, data, function(o) {
        $('#listInserts').append('<div>' + o.text + ' <a class="del" rel="' + o.id + '" href="#">elimina</a></div>');
    }, 'json');
    return false;
});});

Hope this help.

Upvotes: 0

Mark Schultheiss
Mark Schultheiss

Reputation: 34196

  • Move event handler for .del outside callback function
  • Change to reuse cached delItem
  • Remove delItem from global scope

Modified code:

$(document).ready(function () {
    $(document).on("click", ".del", function () {
        var delItem = $(this);
        var id = delItem.attr('rel');
        $.post('dashboard/xhrDeleteListing', {
            'id': id
        }, function (o) {
            delItem.parent().remove();
        }, 'json');
    });
    $.get('dashboard/xhrGetListings', function (o) {
        for (var i = 0; i < o.length; i++) {
            $('#listInserts').append('<div>' + o[i].text + '<a class="del" rel="' + o[i].id + '" href="#">X</a></div>');
        }
    }, 'json');
    $('#randomInsert').submit(function () {
        var url = $(this).attr('action');
        var data = $(this).serialize();
        $.post(url, data, function (o) {
            $('#listInserts').append('<div>' + o.text + '<a class="del" rel="' + o.id + '" href="#">X</a></div>');
        }, 'json');
        return false;
    });
});

EDIT Revised to only hit the DOM once on the insert, bind to the wrapper for the 'on() event handler:

$(document).ready(function () {
    $('#listInserts').on("click", ".del", function () {
        var delItem = $(this);
        var id = delItem.attr('rel');
        $.post('dashboard/xhrDeleteListing', {
            'id': id
        }, function (o) {
            delItem.parent().remove();
        }, 'json');
    });

    $.get('dashboard/xhrGetListings', function (o) {
        var newlinks = ''
        for (var i = 0; i < o.length; i++) {
            newlinks = newlinks + '<div>' + o[i].text + '<a class="del" rel="' + o[i].id + '" href="#">X</a></div>';
        }
        $('#listInserts').append(newlinks);
    }, 'json');

    $('#randomInsert').submit(function () {
        var url = $(this).attr('action');
        var data = $(this).serialize();
        $.post(url, data, function (o) {
            $('#listInserts').append('<div>' + o.text + '<a class="del" rel="' + o.id + '" href="#">X</a></div>');
        }, 'json');
        return false;
    });
});

Upvotes: 0

Justin Bicknell
Justin Bicknell

Reputation: 4808

You are binding the event to the document. So you do not need to do this more than once, and the elements in question do not need to be present when you bind the event. Move the on syntax outside of the ajax callback, inside the document ready.

$(function(){
    $('#listInserts').on("click", ".del", function() {

    });

})  

Other option is to leave it inside the callback, and modify your code to be:

$.get('dashboard/xhrGetListings', function(o) {
    $('.del').on('click',function(){
    });

});

NOTE: As suggested below in the comment, the first option would be more suitable in this case since the .del elements are added in the subtmit, unless you want to bind the click event from there as well.

Upvotes: 1

hradac
hradac

Reputation: 2491

Here's how I would re-write the sample code. I've commented where I changed things.

$(function() {
    var $listInserts = $('#listInserts'); // Store the element once so we don't have to do it again

    // Function for re-usability
    function addToList (text, id) {
        $listInserts.append('<div>' + text + '<a class="del" rel="'+id+'" href="#">X</a></div>');
    }

    // Here I'm assuming that $('#listInserts') is a container for all those .del elements.
    // If you use .on() on a containing element try to keep as close to those elements as you can.
    // Keeping it close keeps the events from having to bubble up through every parent element on the page.
    $listInserts.on('click', '.del', function(e) {
        var $delItem = $(this);

        e.preventDefault(); // Stops the normal link behavior. Sort of like 'return false;' would do.

        $.post('dashboard/xhrDeleteListing', {'id': this.id}, function(o) {
                $delItem.parent().remove();
            }, 'json');
    });

    $.get('dashboard/xhrGetListings', function(o) {

        for (var i = 0; i < o.length; i++)
        {
            addToList(o[i].text, o[i].id);
        }
    }, 'json');

    // Changed to .on()
    $('#randomInsert').on('submit', function(e) {
        var url = $(this).attr('action');
        var data = $(this).serialize();

        e.preventDefault();

        $.post(url, data, function(o) {
            addToList(o.text, o.id);
        }, 'json');

        return false;
    });

});

Upvotes: 0

Related Questions