jQuery替换了复选框w/image,新的复选框';的AJAX函数不再工作


jQuery replaced checkbox w/ image, new checkbox's AJAX function no longer works?

我正在使用ScrewDefaultButtonsjQuery插件来替换带图像的复选框。该插件使用以下代码成功隐藏复选框,并将其替换为已检查/未检查的图像:

$('input:checkbox').screwDefaultButtons({ 
    image: "url(../../images/radio_check.png)",
    width:   14,
    height:  14
});

当我尝试将这些自定义复选框与使用复选框将项目标记为已完成的待办事项列表插件相结合时,我遇到了一个问题。当一个项目完成时,复选框被选中,该项目通过PHP和AJAX移动到"已完成项目"列表中。

上面的代码成功地用自定义图像替换了默认复选框,但当勾选新复选框时,除了"未选中"的图像变为"已选中"图像外,什么都不会发生。使用默认复选框时,会弹出一条警报,确认您是否要移动项目,如果确认,则会移动项目。

最大的问题是:如何让ScrewDefaultButtons复选框与我的待办事项列表的复选框功能一起工作?

这是复选框的代码:

默认复选框的输出:

<td id="checkbox_parent">
    <input id="ctdl-1852" class="todo-checkbox uncompleted" type="checkbox"></input>
    <input type="hidden" value="a193d8dc3a" name="cleverness_todo_complete_nonce"></input>
</td>

ScrewDefaultButton复选框的输出:

<td id="checkbox_parent">
    <div class="todo-checkbox uncompleted styledCheckbox" style="background-image: url("../../images/radio_check.png"); width: 14px; height: 14px"> … </div>
    <input type="hidden" value="a193d8dc3a" name="cleverness_todo_complete_nonce"></input>
</td>

PHP:

protected function show_checkbox( $id, $completed = NULL, $layout = 'table', $single = '' ) {
    $permission = CTDL_Lib::check_permission( 'todo', 'complete' );
    if ( $permission === true ) {
        if ( is_admin() || $layout == 'table' ) $this->list .= '<td id="checkbox_parent">';
        if ( $completed == 1 ) {
            $this->list .= sprintf( '<input type="checkbox" id="ctdl-%d" class="todo-checkbox completed'.$single.'" checked="checked" />', esc_attr( $id ) );
        } else {
            $this->list .= sprintf( '<input type="checkbox" id="ctdl-%d" class="todo-checkbox uncompleted'.$single.'" />', esc_attr( $id ) );
        }
        $cleverness_todo_complete_nonce = wp_create_nonce( 'todocomplete' );
        $this->list .= '<input type="hidden" name="cleverness_todo_complete_nonce" value="'.esc_attr( $cleverness_todo_complete_nonce ).'" />';
        if ( is_admin() || $layout == 'table' ) $this->list .= '</td>';
    }
}

jQuery:(注意:添加.bind("click", function () {并不能解决问题)

$( '.todo-checkbox' ).click( function () {
    var confirmed = confirm( ctdl.CONFIRMATION_CHECK );
            if ( confirmed == false ) return false;
    var status = 1;
    var id = $( this ).attr( 'id' ).substr( 5 );
    var todoid = '#todo-' + id;
    var single = $ ( this ).hasClass( 'single' );
    if ($( this ).prop( 'checked' ) == false ) status = 0;
    var data = {
        action: 'cleverness_todo_complete',
        cleverness_id: id,
        cleverness_status: status,
        _ajax_nonce: ctdl.NONCE
    };
    jQuery.post( ctdl.AJAX_URL, data, function( response ) {
        if ( single != true ) {
                    $( todoid ).fadeOut( function () {
                        $( this ).remove();
                    });
            $( '.todo-checkbox' ).prop( "checked", false );
        }
    } );
} );

编辑(07/28/13):输出Hauke的第一个代码:

<td id="checkbox_parent">
  <div class="todo-checkbox uncompleted styledCheckbox" style="background-image: url("../../images/radio_check.png"); width: 14px; height: 14px; cursor: pointer; background-position: 0px 0px;"> … </div>
  <input type="hidden" value="a81d045af8" name="cleverness_todo_complete_nonce"></input>
</td>

单击复选框时,输出中唯一的区别是背景位置的高度更改为-14px。

ScrewDefaultButtons在实际的input元素周围创建一个包装HTML元素。因此,在click事件处理程序中使用this元素时,不能将其视为必要的input元素。相反,您必须首先找到input元素。你可以这样做:
var inputElement;
if( $( this ).is( 'input' ) )
    inputElement = $( this );
else
    inputElement = $( this ).children().first();

找到inputElement后,您可以获得其id等。然后:

var id = inputElement.attr( 'id' ).substr( 5 );   
var todoid = '#todo-' + id;
var single = inputElement.hasClass( 'single' );
if (inputElement.prop( 'checked' ) == false ) status = 0;

为了测试这一点,我在这里创建了一个小的jsFiddle:http://jsfiddle.net/Q8s96/3/


编辑:在jsFiddle中,我没有处理这一行:

$( '.todo-checkbox' ).prop( "checked", false );

您必须将其替换为首先检测ScrewDefaultButtons是否应用于复选框的内容。如果应用了它,则必须更改其第一个子级的checked属性。如果未应用,则可以直接更改checked属性。

类似这样的东西:

$( '.todo-checkbox' ).each( function () {
    if( $( this ).is( "input" ) )
        $( this ).prop( "checked", false );
    else
        $( this ).children().first().prop( "checked", false );
});

尝试用$(document).on("click", '.todo-checkbox', function {替换$( '.todo-checkbox' ).click( function () {(假设您有jQuery 1.7+):

$(document).on('click', '.todo-checkbox', function {
    var confirmed = confirm( ctdl.CONFIRMATION_CHECK );
            if ( confirmed == false ) return false;
    var status = 1;
    var id = $( this ).attr( 'id' ).substr( 5 );
    var todoid = '#todo-' + id;
    var single = $ ( this ).hasClass( 'single' );
    if ($( this ).prop( 'checked' ) == false ) status = 0;
    var data = {
        action: 'cleverness_todo_complete',
        cleverness_id: id,
        cleverness_status: status,
        _ajax_nonce: ctdl.NONCE
    };
    jQuery.post( ctdl.AJAX_URL, data, function( response ) {
        if ( single != true ) {
                    $( todoid ).fadeOut( function () {
                        $( this ).remove();
                    });
            $( '.todo-checkbox' ).prop( "checked", false );
        }
    } );
} );