简体   繁体   中英

Jquery replacewith not working correctly

So I have a table that contains a column with a button. When this button is clicked, it toggles the class of the current table row and then replaces the button.

$(document).ready(function() {

    $(".checkOut").click(function() {
        var currentRow = $(this).closest("tr");
        $(currentRow).removeClass("checkedIn");
        $(currentRow).addClass("checkedOut");
        $(this).replaceWith('<button title="Check In" class="checkIn" value="true" name="check_in"><img alt="Check In" src="../images/check.png"></button>');
    } );

    $(".checkIn").click(function() {
        var currentRow = $(this).closest("tr");
        $(currentRow).removeClass("checkedOut");
        $(currentRow).addClass("checkedIn");
        $(this).replaceWith('<button title="Check Out" class="checkOut" value="true" name="check_out"><img alt="Check Out" src="../images/minus.png"></button>');
    } );

});

The initial click seems to work just fine. However when I click to change the state back to its orignal, it does not seem to work. I think it is a problem with replaceWith. Any help would be most appreciated!

Because you're adding the Check In button dynamically (when you click the Check Out button), your click event listener is not going to be attached to it. You could use live instead:

$(document).ready(function() {
    $(".checkOut").live("click", function() {
        //Your event handler code
    });

    $(".checkIn").live("click", function() {
        //Your event handler code
    });
}

You will need to use live for both, because after the first replacement, a new .checkOut element is dynamically added to the page.

$(document).ready(function() {
    $(".checkOut").live('click', function() {
        var $this = $(this),
            $currentRow = $this.closest("tr");
        $currentRow
            .removeClass("checkedIn")
            .addClass("checkedOut");
        $this.replaceWith('<button title="Check In" class="checkIn" value="true" name="check_in"><img alt="Check In" src="../images/check.png"></button>');
    });

    $(".checkIn").live('click', function() {
        var $this = $(this),
            $currentRow = $this.closest("tr");
        $currentRow
            .removeClass("checkedOut")
            .addClass("checkedIn");
        $this.replaceWith('<button title="Check Out" class="checkOut" value="true" name="check_out"><img alt="Check Out" src="../images/minus.png"></button>');
    });
});

1. You have to use .live() to attach a handler to the event for all elements which match the current selector, now and in the future.

2. You were doing an unnecessary re-constructing of the variable currentRow . I added a $ sign, so you know it's already a jQuery object, and not to re-construct it.

In addition, I added code to cache the $currentRow and $this objects, so you won't have to lookup the DOM every time you want to manipulate them.

Instead of replacing you can just change the attribute values which will preserve the event handlers you attached to buttons.

$(document).ready(function() {

    $(".checkOut").click(function() {
        $(this).closest("tr").removeClass("checkedIn").addClass("checkedOut");
        $(this)
         .attr({ title: "Check In", class: "checkIn", value: "true", name: "check_in" })
         .find("img").attr({ src: "../images/check.png", alt: "Check In" });
    } );

    $(".checkIn").click(function() {
        $(this).closest("tr").removeClass("checkedOut").addClass("checkedIn");
        $(this)
         .attr({ title: "Check Out", class: "checkOut", value: "true", name: "check_out" })
         .find("img").attr({ src: "../images/minus.png", alt: "Check Out" });
    } );

});

an alternative to existing answers would be one handler for both check in and check out:

$(".checkIn, .checkOut").live('click', function() {
        var $this = $(this),
            $currentRow = $this.closest("tr"),
            checking = $this.hasClass("checkIn"),
            classToAdd = ckecking ? "checkedOut" : "checkedIn",
            classToRemove = ckecking ? "checkedIn" : "checkedOut",
            buttonTitle = checking ? "Check Out" : "Check In",
            buttonName = checking ? "check_out" : "check_in",
            imgSrc = checking ? "minus" : "check";

        $currentRow.removeClass(classToRemove) .addClass(classToAdd);
        $this.replaceWith('<button title="'+buttonTitle+'" class="'+classToAdd+'" value="true" name="'+buttonName+'"><img alt="'+buttonTitle+'" src="../images/'+imgSrc+'.png"></button>');

    } );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM