将选中的复选框复制到另一个div中

时间:2016-01-12 13:04:15

标签: javascript html

http://jsfiddle.net/pxzt8kvp/

此代码用于表单,用户可以选择各种内容并显示其当前选择。我希望它显示实际的元素而不是元素的文本,因为最终它将是一个图像缩略图。

我发现代码类似于我需要的代码,尽管它只将文本值放入另一个div中。我需要实际的输入元素,而不仅仅是纯文本。我试过从javasript中删除.text()但是没有将任何内容复制到div。

HTML:

<div id="ctl00_ContentPlaceHolder1_divServices" style="width:450px; height:250px; overflow-y:scroll;">
    <input id="1" type="checkbox" name="1"/><label for="1"><div id="thing">One</div></label>
    <input id="2" type="checkbox" name="2"/><label for="2"><div id="thing">Two</div></label>
    <input id="3" type="checkbox" name="3"/><label for="3"><div id="thing">Three</div></label>
    <input id="4" type="checkbox" name="4"/><label for="4"><div id="thing">Four</div></label>
</div>
<div id="selectedServices">
    <p>Result:<div id="myDiv"></div></p>
</div>

JavaScript的:

$(function() {
  $(":checkbox").change(function() {
    var arr = $(":checkbox:checked").map(function() { return $(this).next().text(); }).get();
    $("#myDiv").text(arr.join(', '));
  });
});

function ToggleBGColour(item) {
    var td = $(item).parent();      
    if (td.is('.rowSelected'))      
        td.removeClass("rowSelected");      
    else        
        td.addClass("rowSelected");     
}

5 个答案:

答案 0 :(得分:2)

虽然你已经接受了答案,但我想建议采用以下方法,第一种使用jQuery:

// caching the element (of id='myDiv') in which
// the output should be displayed:
var results = $('#myDiv'),

// because we'll be using this collection at least twice,
// the first to bind the event-handlers and the second
// to find the checked elements, we cache it here to
// reduce DOM queries:
    checks = $('#ctl00_ContentPlaceHolder1_divServices input[type=checkbox]');

// binding the anonymous function of the on() method
// as the event-handler of the 'change' event:
checks.on('change', function() {

  // caching the checked check-box <input> elements
  // and their next-sibling (the associated <label>):
  var clones = checks
    // filtering the cached list of check-box <input>
    // elements to retain only those that are checked:
    .filter(':checked')
    // finding the next-sibling element
    .next()
    // adding back the previous collection, that of the
    // checked check-box elements:
    .addBack()
    // cloning those elements
    .clone()
    // iterating over each element of the collection:
    .each(function() {
      // if the element has an id, and has a type and that
      // type is exactly equal to 'checkbox':
      if (this.id && this.type && this.type === 'checkbox') {
        // we remove the id attribute (a duplicate id
        // renders the document invalid); we leave the
        // 'for' attribute of the <label> alone because
        // that way it still triggers the 'change' event
        // of the cloned/'original' checkbox, which maintains
        // desired functionality:
        this.removeAttribute('id');
      }
    });

  // here we remove the current/previously-set contents
  // of the results element (cached above):
  results.empty()
    // and append the just-found cloned elements:
    .append(clones);
});

var results = $('#myDiv'),
  checks = $('#ctl00_ContentPlaceHolder1_divServices input[type=checkbox]');

checks.on('change', function() {
  var clones = checks.filter(':checked').next().addBack().clone().each(function() {
    if (this.id && this.type && this.type === 'checkbox') {
      this.removeAttribute('id');
    }
  });
  results.empty().append(clones);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ctl00_ContentPlaceHolder1_divServices" style="width:450px; height:250px; overflow-y:scroll;">
  <input id="1" type="checkbox" name="1" />
  <label for="1">
    <div id="thing">One</div>
  </label>
  <input id="2" type="checkbox" name="2" />
  <label for="2">
    <div id="thing">Two</div>
  </label>
  <input id="3" type="checkbox" name="3" />
  <label for="3">
    <div id="thing">Three</div>
  </label>
  <input id="4" type="checkbox" name="4" />
  <label for="4">
    <div id="thing">Four</div>
  </label>
</div>
<div id="selectedServices">
  <p>Result:<span id="myDiv"></span>
  </p>
</div>

JS Fiddle demo

但是,使用纯JavaScript,上面的内容可以重写为:

// caching the repeatedly accessed elements for
// efficiency:
var results = document.getElementById('myDiv'),
  checks = document.querySelectorAll('#ctl00_ContentPlaceHolder1_divServices input[type=checkbox]'),

// using Array.from() to turn the array-like NodeList 
// returned by document.querySelectorAll into an array:
  checksArray = Array.from(checks);

// iterating over that array of check-boxes:
checksArray.forEach(function(check) {
  // the first, and here only, argument ('check')
  // is the current array-element of the array
  // over which we're iterating.

  // here we add an event-listener for the 'change'
  // event, which will trigger the anonymous function:
  check.addEventListener('change', function() {

    // filtering the checksArray array of check-boxes,
    // retaining only those that are checked; here we
    // use an Arrow function which uses the named
    // function parameter ('el'), which is the first
    // parameter of the Array.prototype.filter() method
    // (as above the first parameter is the array-element
    // of the array over which we're iterating). Here if
    // the return value of 'el.checked' is true the element
    // is retained, otherwise it's discarded:
    var checked = checksArray.filter(el => el.checked),

    // an empty array-literal for use subsequently:
      clones = [],

    // a document fragment to allow all elements to be
    // appended in one call, rather than appending multiple
    // times causing the document to be drawn and re-drawn:
      frag = document.createDocumentFragment();

    // iterating over the array of checked check-boxes:
    checked.forEach(function(el) {

      // pushing the cloned checkbox, and its next sibling
      // the <label>, into the initialised array:
      clones.push(el.cloneNode(), el.nextElementSibling.cloneNode(true));
    });

    // using Array.prototype.map() to return a new array
    // of elements, after removing the 'id' from the
    // elements with an id and a type and that type is
    // exactly equal to 'checkbox'
    // (Array.prototype.forEach() could be used instead,
    // but it's slightly easier using map()):
    clones.map(function(el) {
      if (el.id && el.type && el.type === 'checkbox') {
        el.removeAttribute('id');
      }
      return el;

    // iterating over the array returned by map()
    // and appending the elements ('el') to the
    // created document.fragment:
    }).forEach(el => frag.appendChild(el));

    // emptying the results element, using a while
    // loop; while the element has a firstChild we
    // remove that firstChild:
    while (results.firstChild) {
      results.removeChild(results.firstChild);
    }

    // appending the document fragment to the
    // results element:
    results.appendChild(frag);
  });
});

var results = document.getElementById('myDiv'),
  checks = document.querySelectorAll('#ctl00_ContentPlaceHolder1_divServices input[type=checkbox]'),
  checksArray = Array.from(checks);

checksArray.forEach(function(check) {
  check.addEventListener('change', function() {
    var checked = checksArray.filter(el => el.checked),
      clones = [],
      frag = document.createDocumentFragment();

    checked.forEach(function(el) {
      clones.push(el.cloneNode(), el.nextElementSibling.cloneNode(true));
    });

    clones.map(function(el) {
      if (el.id && el.type && el.type === 'checkbox') {
        el.removeAttribute('id');
      }
      return el;
    }).forEach(el => frag.appendChild(el));
    while (results.firstChild) {
      results.removeChild(results.firstChild);
    }
    results.appendChild(frag);
  });
});
<div id="ctl00_ContentPlaceHolder1_divServices" style="width:450px; height:250px; overflow-y:scroll;">
  <input id="1" type="checkbox" name="1" />
  <label for="1">
    <div id="thing">One</div>
  </label>
  <input id="2" type="checkbox" name="2" />
  <label for="2">
    <div id="thing">Two</div>
  </label>
  <input id="3" type="checkbox" name="3" />
  <label for="3">
    <div id="thing">Three</div>
  </label>
  <input id="4" type="checkbox" name="4" />
  <label for="4">
    <div id="thing">Four</div>
  </label>
</div>
<div id="selectedServices">
  <p>Result:<span id="myDiv"></span>
  </p>
</div>

JS Fiddle demo

请注意,在上面的演示中,我稍微修改了您的HTML以交换:

<div id="selectedServices">
  <p>Result:<div id="myDiv"></div></p>
</div>

使用:

<div id="selectedServices">
  <p>Result:<span id="myDiv"></span></p>
</div>

这纯粹是因为<div>元素不能包含在<p>元素中。但是,在<p>元素的开始标记之前简单地关闭<div>元素可能更容易。但是,根据您的使用情况,这是您的电话。

其他,当前存在的答案的问题,或者:为什么我发布这个答案来回答已经接受答案的问题

  1. Roozbeh hz's answer

    • 您最终会在页面中至少有两个共享id的元素,这会立即导致您的HTML无效;如果您需要对重复元素进行操作,也会导致JavaScript / jQuery出现问题。
    • 如果你的陈述“我需要实际的输入元素”是真的,那么你自己的代码和Roozbeh的地址都不需要,并且只复制<label>的文本内容。我不知道这个是否是一个问题,但无论哪种方式,它都表明你应该澄清你的问题。但是,我从字面上理解了该语句并保留了要复制到'output'元素的<input>元素和<label>元素。
  2. dajo's answer没有提供所提供代码的解释,因此虽然它可能 - 或可能不会 - 但任何人都很难从该答案中学到任何东西。

  3. John C.'s answer被简要解释并且没有未记录的代码,只提供一个jQuery解决方案(就像写这个答案时所有当前的答案一样),这可能是一个常见的问题,值得一个简单的问题JavaScript答案;并且还使用稍微低效的:checkbox选择器参见引用,它必须在jQuery / Sizzle中实现,而不是input[type=checkbox]选择器,它可以传递给本地{{1 }} 参见reference 方法,并且速度更快,效率更高;正如jQuery API本身所说:

  4.   

    由于document.querySelectorAll()是jQuery扩展而不是CSS规范的一部分,因此使用:checkbox的查询无法利用本机DOM :checkbox方法提供的性能提升。为了在现代浏览器中获得更好的性能,请改用querySelectorAll()

    值得肯定的是,这是微观优化,几乎完全是个人偏好。

    1. Venugopal's answer再次被简要解释,尽管他的代码也没有记录,无法解释如何实现解决方案。
    2. 参考文献:

答案 1 :(得分:1)

而不是text()使用html(),用于获取和设置

http://jsfiddle.net/pxzt8kvp/1/

$(function() {
  $(":checkbox").change(function() {
    var arr = $(":checkbox:checked").map(function() { return $(this).next().html(); }).get();
    $("#myDiv").html(arr.join(', '));
  });
});

答案 2 :(得分:0)

试试这个:

 $(function() {
  $(":checkbox").change(function() {
    var arr = $(":checkbox:checked").map(function() { return $(this).attr('id'); }).get();
    $("#myDiv").text(arr.join(', '));
  });
});

答案 3 :(得分:0)

克隆label并添加到目标div #myDiv

$(function() {
    $(":checkbox").change(function() {
        var arr = $(":checkbox:checked").map(function() {
            return $(this).next();
        }).get();
        $("#myDiv").html('');
        arr.forEach(function(a) {
            $("#myDiv").append($(a).clone());
        });
    });
});

答案 4 :(得分:0)

首先,不是从map函数返回一个字符串,而是返回已检查input的克隆,并且它在label之后。然后,您只需将元素数组附加到div即可。请参阅下文(我保留的代码与您提供的代码大致相同,只是为实现目标而进行必要的更改) -

$(function() {
    $(":checkbox").change(function() {
      // Clear the contents of #myDiv
      $("#myDiv").empty();
      var arr = $(":checkbox:checked").map(function() {
        // This will select the current element, add the following
        // item to the selection and return cloned versions of the 
        // selection
        return $(this).add($(this).next()).clone();
      }).get();
      // Add the items to #myDiv
      $("#myDiv").append(arr);
    });
  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ctl00_ContentPlaceHolder1_divServices" style="width:450px; height:250px; overflow-y:scroll;">
  <input id="1" type="checkbox" name="1" />
  <label for="1">
    <div id="thing">One</div>
  </label>
  <input id="2" type="checkbox" name="2" />
  <label for="2">
    <div id="thing">Two</div>
  </label>
  <input id="3" type="checkbox" name="3" />
  <label for="3">
    <div id="thing">Three</div>
  </label>
  <input id="4" type="checkbox" name="4" />
  <label for="4">
    <div id="thing">Four</div>
  </label>
</div>
<div id="selectedServices">
  Result:
  <div id="myDiv"></div>
</div>