Simon S.
Simon S.

Reputation: 25

jQuery: Clone input fields on click work, but select box values cannot be changed

I would like to add a new row which consists of an input field and a select box when you click the "ADD PHONE" button. The problem i'm facing, is that when I clone the elements, they seem to clone fine, however, the select-box doesn't seem to work. I cannot change it to a different value. Also, if the values are filled out, before the "add" button is clicked, the newly added fields will have contain the same values. Another issue is that if I have 2 sets of fields, when I click the "ADD PHONE" button, it will close both, and append both.

So here are my questions:
1) How can I get the cloned select box to work
2) How can I make sure that the cloned fields are empty
3) How can I clone just 1 at a time

I would greatly appreciate the help.

HTML

<button id="add-phone-button">Add Phone</button>
<div class="phone-details">
    <div id="phone-number" class="col-xs-8">
        <label for="phone" class="invisible">Phone</label>
        <input type="text" id="phone" class="phone" placeholder="Phone"/>
    </div>
    <div id="phone-type" class="col-xs-4">
        <label for="usage" class="invisible">Usage</label>
        <select id="usage" />
            <option selected="selected">Option 1</option>
            <option>Option 2</option>
            <option>Option 3</option>
        </select>
    </div>
</div>

jQuery

$('#add-phone-button').click(function() {
    $('.phone-details #phone-number, .phone-details #phone-type').clone().appendTo('.phone-details:last-child');
});

DEMO http://jsfiddle.net/abLun3fp/1/

Upvotes: 1

Views: 2377

Answers (1)

Regent
Regent

Reputation: 5178

  1. The problem occurs because jQuery Mobile wraps <select> with additional HTML tags and adds event listeners to them. The trick is to replace wrapped HTML with original <select> and to trigger initialization on it after appending to page:

    clone.find('.ui-select').html(function() { return $(this).find('select')[0].outerHTML });
    clone.appendTo('.phone-details');
    clone.find('select').parent().enhanceWithin();
    
  2. You can empty all <input>s values in clone before adding its to page:

    clone.find('input[type="text"]').val('');
    
  3. It can be achieved using :first:

     $('.phone-info:first')
    

or with your original HTML:

     $('.phone-details #phone-number:first, .phone-details #phone-type:first')

Since using multiple elements with same ID is strongly discouraged, I changed them to classes.

Fiddle

HTML:

<button id="add-phone-button">Add Phone</button>
<div class="phone-details">
    <div class="phone-info">
        <div class="phone-number col-xs-8">
            <label for="phone" class="invisible">Phone</label>
            <input type="text" name="phone" class="phone" placeholder="Phone"/>
        </div>
        <div class="phone-type col-xs-4">
            <label for="usage" class="invisible">Usage</label>
            <select name="usage">
                <option selected="selected">Option 1</option>
                <option>Option 2</option>
                <option>Option 3</option>
            </select>
        </div>
    </div>
</div>

JS:

$('#add-phone-button').click(function()
{
    var clone = $('.phone-info:first').clone();
    clone.find('.ui-select').html(function() { return $(this).find('select')[0].outerHTML });
    clone.find('input[type="text"]').val('');
    clone.appendTo('.phone-details');
    clone.find('select').parent().enhanceWithin();
});

If you somewhy want to stay with your original HTML, here is fiddle with fixed JS and original HTML.

Update. Thanks to @Omar for pointing out an error with <input> and for .enhanceWithin().

Upvotes: 3

Related Questions