tags:

views:

521

answers:

2

Hi all,

I'm trying to let a user to do a 'Click here to add more info' link. I'm trying to do this with input fields so that the id of the field have to increment.

I would like for jQuery to add this on every click where $i is the number of each field incremented:

<div id="info"></div>
<?php echo $form->input("User.$i.first_name"); ?>
<a href = 'add/' id='addInfo'>Add info</a>

Here is my jQuery code so far:

var current = 1;
$('#addInfo').click(function(){            
    var newField = '<h4>Info#' + current + '</h4>';
    $('#info').append(newField)
    current++;
    return false;
});

One of the solution I came up with is just manually create the input fields inside the javascript and assign it to the newField. I think there should be a way where I can create a first working set and then use jQuery to copy that first content and then just increment the count for new fields.

Thanks!

+2  A: 

The idea is to count all existing fields and cache that number.

currentFields = $('#yourFormname input').size(); // caches

Now you append another text field and assign it a name based on that field count you had calculated above.

$('#addInfo').click(function(){            
    $('#info').append('<input type="text" name="data[User]['+currentFields+'][first_name]"');
    currentFields++;
    return false;
});

Presto!

Finally, instead of appending fields as strings, you could clone() a field html and then just replace its name attribute with newly calculated.

Andrew Kolesnikov
Hi cruxst, thanks for your quick respond. I was looking for how to create the input element using the $form helper. Can you show me how can I clone the first input created using $form helper? Thanks.
KienPham.com
You cannot use a form helper on front end. If you wanted to use form helper to create a skeleton - forget it since it will spit out html equal to all previous input fields. Cloning the first field using jQuery and injecting it into DOM will do the trick.
Andrew Kolesnikov
A: 

Thanks to Andrew for pointing me in the right direction. I was able to clone the form, and even add a link to remove the last cloned inputs. This solution won't require me to generate the form within the javascript so all the format are still intact and less code to write.

I know this will mess up the Auth components and my form will be blackholed since the hash will be wrong. I'll have to manually clean it at the backend later. Basically I replace the first field with id of 1 to the current increment. The three places that I see it need unique name and id is the label for, input name, and input id. I don't know if anyone has a better solution of replacing these html value but I have to convert it back and forth to replace it.

Here is my solution:

// HTML 
    <div id="user">
                <div class="users">
                    <h4>User #1</h4>
                    <?php
                    echo $form->input("User.1.first_name", array(
                    'label' => 'First Name',
                    'error' => 'Please enter a valid first name.'
                    ));?>

                <?php
                echo $form->input("User.1.last_name", array(
                'label' => 'First Name',
                'error' => 'Please enter a valid last name.'
                ));?>
            </div>
</div>

<div id="moreUsers"></div>

// Javascript code: var currentUserCount = 1;

$('#addUser').click(function(){
            currentUserCount = cloning('#user', '#moreUser', currentUserCount);
            return false;
        });

$('#removeUser').click(function(){
                $('.users:last').remove();
                currentUserCount--;
            }
            return false;
        });

    function cloning(from, to, counter) {
                var clone = $(from).clone();
                counter++;

                // Replace the input attributes:
                clone.find(':input').each(function() {
                    var name = $(this).attr('name').replace(1,counter);
                    var id = $(this).attr('id').replace(1,counter);
                    $(this).attr({'name': name, 'id': id}).val('');
                });

                // Replace the label for attribute:
                clone.find('label').each(function() {
                    var newFor = $(this).attr('for').replace(1,counter);
                    $(this).attr('for', newFor);
                });

                // Replace the text between html tags:
                clone = clone.html().replace(1,counter);
                $(to).before(clone);
                return counter;
            } // end cloning
KienPham.com