Как добавить новые поля формы с помощью jQuery и $ form helper? - PullRequest
4 голосов
/ 26 февраля 2010

Я пытаюсь позволить пользователю сделать ссылку «Нажмите здесь, чтобы добавить дополнительную информацию». Я пытаюсь сделать это с полями ввода, чтобы идентификатор поля увеличивался.

Я бы хотел, чтобы jQuery добавлял это при каждом клике, где $ i - это число каждого увеличенного поля:

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

Вот мой код jQuery:

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

Одно из решений, которое я придумал, - просто вручную создать поля ввода внутри javascript и назначить их newField. Я думаю, что должен быть способ, которым я могу создать первый рабочий набор, а затем использовать jQuery для копирования этого первого содержимого, а затем просто увеличить счетчик для новых полей.

Спасибо!

Ответы [ 3 ]

3 голосов
/ 26 февраля 2010

Идея состоит в том, чтобы подсчитать все существующие поля и кэшировать это число.

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

Теперь вы добавляете другое текстовое поле и присваиваете ему имя на основе того количества полей, которое вы рассчитали выше.

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

Presto!

Наконец, вместо добавления полей в виде строк, вы можете клонировать () поле html, а затем просто заменить его атрибут name на только что вычисленный.

1 голос
/ 27 февраля 2010

Спасибо Андрею за то, что он указал мне правильное направление. Мне удалось клонировать форму и даже добавить ссылку для удаления последних клонированных входов. Это решение не потребует от меня создания формы в javascript, поэтому все форматы по-прежнему не повреждены и требуют меньше кода для записи.

Я знаю, что это испортит компоненты Auth, и моя форма будет заблокирована, поскольку хэш будет неправильным. Я должен буду вручную почистить его в бэкэнде позже. В основном я заменяю первое поле с идентификатором от 1 до текущего приращения. Три места, которые, как я вижу, нуждаются в уникальном имени и идентификаторе, - это метка, имя ввода и идентификатор ввода. Я не знаю, есть ли у кого-нибудь лучшее решение для замены этих значений HTML, но я должен преобразовать его туда и обратно, чтобы заменить его.

Вот мое решение:

// 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 код:

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
0 голосов
/ 29 мая 2016

Это примечание для любого, кто найдет этот вопрос при поиске (точно так же, как я).

Чтобы сделать входные имена «клонируемыми», вам не нужно поддерживать приращение и выполнять эту уродливую конкатенацию.CakePHP распознает пустое значение и преобразует его в [], что более элегантно, поскольку браузер и сервер выполнят за вас работу по перечислению.

Вот пример того, о чем я говорю:

echo $form->input("User..first_name"); 
echo $form->input("User.first_name."); 

Это даст вам соответственно:

<input name="data[User][][first_name]">
<input name="data[User][first_name][]">

Затем вы можете использовать Javascript для клонирования, очистки и добавления узла.Вот упрощенный пример:

var container=document.getElementById('info');
var element=wrapper.getElementsByTagName('input')[0];
var clone=element.cloneNode(true);
var clone_inputs=clone.getElementsByTagName('input');
for (var i=0; i<clone_inputs.length; i++) {
    clone_inputs[i].value='';
}
var result=container.appendChild(clone);

Нет необходимости делать .replace() или data[User]['+currentFields+'][first_name], это гораздо более гибкое и в то же время менее уродливое решение.

ОБНОВЛЕНИЕ Также, если вы используете Компонент безопасности с включенным предотвращением несанкционированного доступа к форме , возможно, вы захотите разблокировать эти входы, чтобы запретить отправку сообщения стать черным отверстием:

$this->Form->unlockField('User.first_name'); // no trailing dot
echo $this->Form->input("User.first_name."); 

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...