Search code examples
jqueryclone

using jquery clone with other function


PS: There were two answer before, and I refresh this page, the answer disappeared, what's going on?

demo: demo in jsbin

html

<table>
<tr class='test_tr'>
  <td>
    <select class='test_select'>
      <option value=1>test1</option>
      <option value=2>test2</option>
      <option value=3>test3</option>
    </select>
  </td>
  <td><a href="#" class='test_clone'>clone</a></td>
</tr>

js

$(document).ready(function(){
  $('select.test_select').selectmenu();
  $('.test_clone').click(function(){
    var tp = $(this).parents('.test_tr');
    var new_tr = tp.clone(true);
    new_tr.insertAfter(tp);
    tr_func(new_tr);
  })
});
  function tr_func(new_tr){
     $('.test_select',new_tr).selectmenu();
  }

After click the clone button and click on the new select, it always affect to the first one. Any suggestion? Thanks!


Solution

  • This problem has a few interesting aspects:

    1. When a row is cloned, all items with an id attribute will be cloned as well, causing two elements with the same #ID; that's not good. It can be solved by creating a pristine sample row that gets cloned every time you click the button which you then have to "decorate" before it can be used (i.e. apply .selectmenu() and click handler).

    2. When a <select> is cloned, it doesn't retain the selected option. You have to save the selectedIndex property and apply it to the cloned version.

    Both problems solved looks like this:

      $(document).ready(function() {
        // keep reference to the sample row
        var sample = $('.test_tr.sample');
        // click handler for the clone button
        function cloneRow()
        {
          var parentRow = $(this).parents('.test_tr'),
              selectedOption = parentRow.find('.test_select').prop('selectedIndex');
    
          setupRow(newRow().insertAfter(parentRow), selectedOption);
        }
    
        // decorates the new row and sets the correct selected option before applying
        // selectmenu()
        function setupRow(row, selectedOption)
        {
          row
            .find('.test_select')
              .prop('selectedIndex', selectedOption || 0)
              .selectmenu()
              .end()
            .find('.test_clone')
              .click(cloneRow)
              .end()
        }
    
        // helper function that clones the sample and shows it before handing it over
        // to other code.
        function newRow()
        {
          return sample.clone().show();
        }
    
        // setup the first row
        setupRow(newRow().appendTo('table'));
      });
    

    Demo