174

I am using the jQuery DataTables plugin. I would like to move the search box (.dataTables_filter) and number of records to display dropdown (.dataTables_length) from their parent element (.dataTables_wrapper) to another div on my page without losing any registered javascript behavior. For instance the search box has a function attached to the 'keyup' event and I want to keep that intact.

The DOM looks like this:

<body>
<div id="parent1">
  <div class="dataTables_wrapper" id="table1_wrapper">
    <div class="dataTables_length" id="table1_length">
      <select size="1" name="table1_length">
        <option value="10">10</option>
        <option value="25">25</option>
        <option value="50">50</option>
        <option value="100">100</option>
      </select>
    </div>
    <div class="dataTables_filter" id="table1_filter">
      <input type="text" class="search">
    </div>
    <table id="table1">
    ...
    </table>
  </div>
</div>
<div id="parent2">
  <ul>
    <li><a href="#">Link A</a></li>
    <li><a href="#">Link B</a></li>
    <li><a href="#">Link C</a></li>
  </ul>
</div>
</body>

This is what I would like the DOM to look like after the move:

<body>
<div id="parent1">
  <div class="dataTables_wrapper" id="table1_wrapper">
    <table id="table1">
    ...
    </table>
  </div>
</div>
<div id="parent2">
  <div class="dataTables_filter" id="table1_filter">
    <input type="text" class="search">
  </div>
  <div class="dataTables_length" id="table1_length">
    <select size="1" name="table1_length">
      <option value="10">10</option>
      <option value="25">25</option>
      <option value="50">50</option>
      <option value="100">100</option>
    </select>
  </div>
  <ul>
    <li><a href="#">Link A</a></li>
    <li><a href="#">Link B</a></li>
    <li><a href="#">Link C</a></li>
  </ul>
</div>
</body>

I've been looking at the .append(), .appendTo(), .prepend() and .prependTo() functions but haven't had any luck with these in practice. I've also looked at the .parent() and .parents() functions, but can't seem to code a workable solution. I have also considered changing the CSS so that the elements are absolutely positioned - but to be frank the page is setup with fluid elements all over, and I really want these elements to be floated in their new parents.

Any help with this is much appreciated.

Dom
  • 3,173
  • 4
  • 30
  • 39
  • All the DOM manipulation functions you have listed should work just fine. Appending a DOM element to a different parent moves it to the new position keeping all the events intact. What exactly is not working for you? Is there an error? – Anurag Apr 08 '10 at 00:43

4 Answers4

376

As Jage's answer removes the element completely, including event handlers and data, I'm adding a simple solution that doesn't do that, thanks to the detach function.

var element = $('#childNode').detach();
$('#parentNode').append(element);

Edit:

Igor Mukhin suggested an even shorter version in the comments below:

$("#childNode").detach().appendTo("#parentNode");
Muhammad Zohaib
  • 307
  • 1
  • 5
  • 15
eric.itzhak
  • 15,752
  • 26
  • 89
  • 142
  • 8
    this is the best solution, because the detach()+append() won't clone the element but will move that to the new location. The events and the assocciated data won't get lost this way – Denes Papp Jan 17 '13 at 06:20
  • 3
    this should be marked as answer. – Daniel Jan 28 '13 at 21:39
  • 69
    Even shorter `$("#childNode").detach().appendTo("#parentNode");` – Igor Mukhin Jun 13 '13 at 09:11
  • I use iimuhin's answer all the time. Simple. clean. – jchwebdev Nov 12 '13 at 19:18
  • 8
    Except that you don't need detach. See my answer below. – JackArbiter Dec 04 '13 at 16:42
  • 2
    @JackArbiter - `detach` was useful for me because I need to temporarily remove the children from the parent for processing, then put them back with their original parent (CPS-style), so while not useful in the question's instance (parent to adoptive parent) it did solve my problem ;) – Campbeln May 19 '14 at 23:53
173

Detach is unnecessary.

The answer (as of 2013) is simple:

$('#parentNode').append($('#childNode'));

According to http://api.jquery.com/append/

You can also select an element on the page and insert it into another:

$('.container').append($('h2'));

If an element selected this way is inserted into a single location elsewhere in the DOM, it will be moved into the target (not cloned).

Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
JackArbiter
  • 5,705
  • 2
  • 27
  • 34
  • 4
    I found that detach gave me a different behavior in older browsers like IE (and even Edge). For example, Bootstraps DateTimePicker wouldn't work if the parent element was detached and appended, however simply using the append() to move my elements kept the DateTimePicker happy. – geekinit Jan 17 '19 at 15:05
47

$('#parent2').prepend($('#table1_length')).prepend($('#table1_filter'));

doesn't work for you? I think it should...

Alex Lawford
  • 669
  • 6
  • 3
  • It was a naming problem. My example above works fine. The actual id's of the fields had multiple -'s and _'s in it, and I was not selecting the element because the id wasn't matching. Thank you. – Dom Apr 08 '10 at 02:40
36

Based on the answers provided, I decided to make a quick plugin to do this:

(function($){
    $.fn.moveTo = function(selector){
        return this.each(function(){
            var cl = $(this).clone();
            $(cl).appendTo(selector);
            $(this).remove();
        });
    };
})(jQuery);

Usage:

$('#nodeToMove').moveTo('#newParent');
Ufuk Hacıoğulları
  • 37,978
  • 12
  • 114
  • 156
Jage
  • 7,990
  • 3
  • 32
  • 31
  • 8
    This method clone the elements don't move them. specifically if you have store in a variable $('#nodeToMove') before the moveTo call it won't work anymore – Roberto Feb 21 '13 at 14:11
  • @Jage why not use the JQuery syntax? $('#nodeToMove').appendTo('#newParent'); http://api.jquery.com/appendto/ – Randall Flagg Oct 19 '15 at 09:28