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"></but开发者_运维知识库ton>');
} );
$(".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>');
} );
精彩评论