1

我有一长串带有特定标签的复选框,如下所示:

<input type='checkbox' name='check[]' id='159' value='159' />
<label for='159'>Person 1</label>

<input type='checkbox' name='check[]' id='160' value='160' />
<label for='160'>Person 2</label>

在这个表格下面我有六个像这样的div:

<div id="member1"></div>
<div id="member2"></div>
<div id="member3"></div>
<div id="member4"></div>
<div id="member5"></div>
<div id="member6"></div>

我有这个 JS 函数,所以当我点击一个复选框时,它的标签被插入到第一个 div 中。这是它的样子:

$(function(){
    $('input:checkbox').click(function(){
        var id = $(this).attr('id');
        if($(this).is(':checked')){
            $('#member1').text($('label[for="'+ id +'"]').text());
        }
        else{
            $('#member1').text('');   
        }
    });
});

所以一个问题是该函数当前必须指定将其放入哪个 div (#member1)。当第一个 div 为“已满”时,下一个复选框将其标签插入到第二个 div 中,当该复选框已满时,第三个复选框将其标签插入第三个 div 等。

另一个问题是,如果复选框未选中,则应将其标签从其 div 中删除,并且其下方 div 中的标签应向上移动。有谁知道这是否可能?我会接受任何一个问题的帮助!

4

6 回答 6

2

警告:我会以完全不同的方式做这件事。

但使用您当前的结构:Live copy | 来源(使用有效id的 s)

$(function(){
    $('input:checkbox').click(function(){
        var $cb = $(this),
            id  = this.id, // No need for `attr`
            member,
            prev;
        if(this.checked){  // No need for `attr`
            $("div[id^=member]").each(function() {
                if (!this.firstChild) {
                    // It's empty, use it
                    $(this).text($('label[for="'+ id +'"]').text()).attr("data-contents", id);
                    return false; // Done
                }
            });
        }
        else {
            member = $('div[data-contents="' + id + '"]');
            if (member[0]) {
                member.empty().removeAttr('data-contents');
                prev = member[0];
                member.nextAll().each(function() {
                   if (!this.firstChild) {
                       return false; // Done
                   }
                   prev.appendChild(this.firstChild);
                   prev = this;
                });
            }
        }
    });
});

我会做的最小改变:

  • #memberXdiv 放入容器中,这样我们就不必进行id^=搜索了。
  • 根本不要在div 上使用id值。#memberX
  • 如果你不是绝对,肯定需要它们,就不要有空#member的 div。这将显着简化代码。
  • 如果您确实需要它们,请在清除时删除 div 并在末尾附加一个新的空的。

示例:Live Copy | 来源

HTML:

只需将#membersXdiv替换为<div id="members"></div>".

JavaScript:

$(function(){
    $('input:checkbox').click(function(){
        var $cb = $(this),
            id  = this.id; // No need for `attr`

        if(this.checked){  // No need for `attr`
            $("<div>")
                .text($('label[for="'+ id +'"]').text())
                .attr("data-contents", id)
                .appendTo("#members");
        }
        else {
            $('div[data-contents="' + id + '"]').remove();
        }
    });
});

您可以通过移动复选框输入s来进一步简化label(这也意味着您可以取消该for属性):Live copy | 来源

HTML:

<label><input type='checkbox' name='check[]' id="x159" value='159' />
  Person 1</label>
<label><input type='checkbox' name='check[]' id="x160" value='160' />
  Person 2</label>
<div id="members"></div>

JavaScript:

$(function(){
    $('input:checkbox').click(function(){
        var id  = this.id; // No need for `attr`

        if(this.checked){  // No need for `attr`
            $("<div>")
                .text($(this.parentNode).text())
                .attr("data-contents", id)
                .appendTo("#members");
        }
        else {
            $('div[data-contents="' + id + '"]').remove();
        }
    });
});
于 2012-06-20T15:37:28.640 回答
1

如果我正确理解了您的问题,那么您有 X 数量的可用名额,而您只能填补那么多。如果是这种情况,我认为这就是您要寻找的:jsFiddle。如果没有,其他一些解决方案可能会更好......

var $selections = $('ul.selections');
$('input:checkbox').click(function() {
    var id = $(this).val();
    if($(this).is(':checked')) {
        var $label = $(this).next('label');
        var $spot = $selections.find('li:not(.full)');
        if($spot.length == 0) {
            alert('no more spots open!');
            return false;
        }
        $spot.eq(0).addClass('full').html($label.clone());
    } else {
        var $label = $selections.find('label[for=' + id + ']');
        $label.closest('li').remove();
        $selections.append($('<li/>').html('&nbsp;'));        
    }
});

使用此 HTML:

<p>Options</p>

<ul>
    <li><input type='checkbox' name='check[]' id='159' value='159' /> <label for='159'>Person 1</label></li>
    <li><input type='checkbox' name='check[]' id='160' value='160' /> <label for='160'>Person 2</label></li>
    ....
</ul>

<p>Selections</p>

<!-- spots available = as many list items initially in HTML -->

<ul class='selections'>
    <li>&nbsp;</li>
    <li>&nbsp;</li>
    <li>&nbsp;</li>
    <li>&nbsp;</li>
    <li>&nbsp;</li>
    <li>&nbsp;</li>
</ul>

我列出了它们,因为它们实际上是这样的,但是如果这是您想要的,那么代码将与 DIV 相同。由于标签被克隆,单击选择列表上的标签将删除它。

于 2012-06-20T15:48:44.407 回答
1

试试这个:jsFiddle 示例

jQuery

$('input:checkbox').click(function() {
    if ($(this).is(':checked')) {
        $('div:empty:first').html($(this).next('label').html());
    }
    else {
        var foo = $(this);
        $('div').each(function() {
            if ($(this).html() == foo.next('label').html()) {
                $(this).html($(this).next('div').html());
                $(this).nextAll('div').each(function() {
                    $(this).html($(this).next('div').html());
                });
            }
        });
    }
});​
于 2012-06-20T15:49:06.700 回答
1

基于您的代码的简单方法在这里http://jsfiddle.net/joevallender/rTQMe/

$(document).ready(function(){

  $('input:checkbox').click(function(){

      var $checked = $('#checked');
      $checked.html('');

      $('input:checkbox').each(function(index){
          if($(this).is(':checked')) {
            $checked.append('<div>' + $('label[for="'+ $(this).attr('id') +'"]').text() + '</div>');   
          }
      });      

  });

});
于 2012-06-20T16:08:13.113 回答
0

有一些方法可以提高效率,但这应该适合您的目的:

  $(function(){

    var numberOfDivs = 6;

    $('input:checkbox').click(function(){

        var id = $(this).attr('id');

        if($(this).is(':checked')){

             for(i = 1; i < numberOfDivs - 1; i++)
             {
                 var div = $('#member' + i);

                 if(div.text() !== ''){
                     div.text( ($('label[for="'+ id +'"]').text() );                         
                 }
             }
        }
        else{

             var searchText = $('label[for="'+ id +'"]').text();

             for(i = 1; i < numberOfDivs - 1; i++)
             {
                 var div = $('#member' + i);

                 if(div.text() === searchText){
                     div.text('');                         
                 }
             }

        }
    });

});
于 2012-06-20T15:36:02.140 回答
0

这是我的做法:

$(function(){
    $('input:checkbox').click(function(){
        var id = this.id;
        if(this.checked){
            var member = $('#member1');
            var i = 1;
            while(member.data('num') == 1)
            {
                member = $('#member'+(++i));
            }
            member.text($('label[for="'+ id +'"]').text()).data('num',1);
        }
        else{
            var removed = false;
            $('div').each(function(){
                $(this).children('label').each(function(){
                    if(!removed && id == $(this).attr('for'))
                    {
                        removed = true;
                        $(this).parent().remove('label[for="'+$(this).attr('for')+'"]');
                    }
                }
                if(removed) //bubble the labels up into the next highest div.
                {
                    if($(this).data('num') == 1)
                    var lastObject = $(this).children('label');
                   $(this).prev().append(lastObject);
                }
            }
        }
    });
});
于 2012-06-20T15:56:25.747 回答