javascript - Using jQuery to insert labels into divs - Stack Overflow

I have this long list of checkboxes with specific labels that look something like this:<input type=&

I have this long list of checkboxes with specific labels that look something like this:

<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>

And below this form I have six div's like so:

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

I have this JS function so that when I click on a checkbox, it's label is inserted into the first div. Here's what it looks like:

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

So one problem is the function currently has to specify which div to put it into (#member1). It's supposed to work that when the first div is "full", the next checkbox will insert its label into the second div, and when that one is full, the third checkbox will insert its label into the third div, etc.

The other issue is if a checkbox bees unchecked, its label should be removed from its div and the labels in the divs below it should move up. Anyone know if that's possible? I'll accept help for either problem!

I have this long list of checkboxes with specific labels that look something like this:

<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>

And below this form I have six div's like so:

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

I have this JS function so that when I click on a checkbox, it's label is inserted into the first div. Here's what it looks like:

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

So one problem is the function currently has to specify which div to put it into (#member1). It's supposed to work that when the first div is "full", the next checkbox will insert its label into the second div, and when that one is full, the third checkbox will insert its label into the third div, etc.

The other issue is if a checkbox bees unchecked, its label should be removed from its div and the labels in the divs below it should move up. Anyone know if that's possible? I'll accept help for either problem!

Share Improve this question asked Jun 20, 2012 at 15:24 aaduaadu 3,25410 gold badges42 silver badges65 bronze badges 12
  • why do you need all those divs to insert labels? – GnrlBzik Commented Jun 20, 2012 at 15:26
  • 3 First, IDs can not start with a number. Second, how do you determine a div is "full"? Third, you should probably put a data-attribute in each div to keep a count of its current labels, and when it hits that magic number, start on the next. If it goes below that, bubble the rest up. – gcochard Commented Jun 20, 2012 at 15:28
  • @j08691: In HTML5, yeah, but not in CSS -- so if using CSS selectors (as you do with jQuery), let's just say it's problematic. A standards-pliant browser will throw on document.querySelector("#123"). – T.J. Crowder Commented Jun 20, 2012 at 15:29
  • Why can't you append labels into one div? – GnrlBzik Commented Jun 20, 2012 at 15:30
  • I assume you could add up heights of the inserted labels and check that value against height of the parent container. And if height of the container filled up by the labels you can then insert them into next one. – GnrlBzik Commented Jun 20, 2012 at 15:31
 |  Show 7 more ments

6 Answers 6

Reset to default 2

Caveat: I would do this pletely differently.

But using your current structure: Live copy | source (using valid ids)

$(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;
                });
            }
        }
    });
});

Minimum changes I would make:

  • Put the #memberX divs in a container so we don't have to do the id^= search.
  • Don't use id values on the #memberX divs at all.
  • If you don't absolutely, positively need them, don't have empty #member divs at all. This would simplify the code markedly.
  • If you do need them, when clearing, remove the div and just append a new, empty one to the end.

Example: Live copy | source

HTML:

Just replace the #membersX divs with <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();
        }
    });
});

You can simplify even more by moving the checkbox input the labels (which also means you can do away with the for attribute): Live copy | source

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();
        }
    });
});

Try this: jsFiddle example.

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());
                });
            }
        });
    }
});​

If I understood your question correctly, you have X amount of spots available and you can only fill that many. If that is the case, I think this is what you are looking for: jsFiddle. If not, some of the other solutions might be better...

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;'));        
    }
});

With this 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>

I made them lists since that is what they really are, but the code would work the same with DIVs if that is what you want. Since the labels are cloned over, clicking on a label on the selection list will remove it.

Simple way based on your code here http://jsfiddle/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>');   
          }
      });      

  });

});

There are ways to make this more efficient, but this should work for your purposes:

  $(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('');                         
                 }
             }

        }
    });

});

Here's how I would do it:

$(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);
                }
            }
        }
    });
});

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744929286a4601632.html

相关推荐

  • javascript - Using jQuery to insert labels into divs - Stack Overflow

    I have this long list of checkboxes with specific labels that look something like this:<input type=&

    1天前
    50

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信