2017-01-06 3 views
2

Я хочу создать HTML-форму, в которой пользователь может редактировать набор элементов сразу. Пользователь должен уметь удалять элемент, редактировать элемент и добавлять новые элементы. Я использую PHP (Laravel) в качестве backend и jQuery для динамической формы.Каков самый чистый способ реализации динамической формы HTML?

Моя первоначальная идея была сделать в основном это:

<form id="bars"> 
    @foreach($foo as $bar) 
     <input type="text" name="name[]" value="{{$bar->name}}" required> 
     <input type="color" name="color[]" value="{{$bar->color}}" required> 
     <input type="checkbox" name="completed[]"{{$bar->completed ? ' checked' : ''}}> 
     <span class="deleteRow"></span> 
    @endforeach 
</form> 

<div id="template" style="display:none;"> 
     <input type="text" name="name[]" required> 
     <input type="color" name="color[]" required> 
     <input type="checkbox" name="completed[]"{{$bar->completed ? ' checked' : ''}}> 
     <span class="deleteRow"></span> 
</div> 

<script> 
    $(document).ready(function() { 
    // Remove rows 
     $('form').on('click', '.deleteRow', function() { 
      $(this).closest('tr').remove(); 
     }); 

     // Clone new rows from template 
     $('#addRow').click(function() { 
      $('#template tr') 
       .clone() 
       .appendTo('#bars'); 
     }); 
    }); 
</script> 

Это шаблон клинка, от которого я удалил все ненужные код и стиль. Этот подход использует следующие понятия:

  • [] в именах входных данных, чтобы данные POSTED были помещены в массив. При обработке я заканчиваю тремя массивами name, color и completed, которые будут содержать POSTED данные.
  • Существующие элементы визуализируются на стороне сервера в форме шаблоном Blade
  • Новые строки клонируются из «шаблона формы» и добавляются к форме, когда пользователь нажимает кнопку «новая строка».

Это довольно просто и работает в большинстве случаев (я использовал это раньше), но в этом случае это не работает из-за небольшой вещи: флажков. Непроверенные флажки не будут POSTED, что означает, что в массиве completed[] размер будет меньше по размеру, чем другие массивы, и у меня нет способа проверить, какие элементы имеют флажок.

Теперь я мог бы изменить свой JS таким образом, чтобы он отслеживал индексы и явно вставлял индекс в каждое имя ввода (так name[0], name[1] и т. Д.), Но этот подход осложняется тем, что форма должна быть предварительно заполненными данными и не запускаться пустым.

Я могу вместо заполнения данных с помощью шаблона Blade позволить JS обрабатывать это тоже (через JSON API), но это также становится сложным быстро, потому что JS теперь должен «разобрать» шаблон формы и заполнить все значения.

Какова наилучшая практика для этого в чистом виде?

+0

изменить '(document) .ready (...)' to '$ (document) .ready (...)' –

+0

А, конечно, я имел в виду это;) Это была просто ошибка при копировании в код. Я отредактировал вопрос. – Compizfox

+0

О, hahah: D Я просматриваю ваш код, и все кажется прекрасным:/вы уверены, что у вас есть ** все ** включено, что необходимо? –

ответ

0

То, что я закончил с следующий: (! Так что спасибо)

<form id="bars"> 
    @foreach($foo as $i => $bar) 
     <input type="hidden" name="id[{{$i}}]" value="{{$status->id}}"> 
     <input type="text" class="form-control" name="name[{{$i}}]" value="{{$status->name}}" required> 
     <input type="color" name="color[{{$i}}]" value="{{$bar->color}}" required> 
     <input type="checkbox" name="completed[{{$i}}]"{{$bar->completed ? ' checked' : ''}}> 
     <span class="deleteRow"></span> 
    @endforeach 
</form> 

<div id="template" style="display:none;"> 
     <input type="text" name="name[$i]" required> 
     <input type="color" name="color[$i]" required> 
     <input type="checkbox" name="completed[$i]"{{$bar->completed ? ' checked' : ''}}> 
     <span class="deleteRow"></span> 
</div> 

<script> 
    $(document).ready(function() { 
    // Remove rows 
     $('form').on('click', '.deleteRow', function() { 
      $(this).closest('tr').remove(); 
     }); 

     // Clone new rows from template 
     $('#addRow').click(function() { 
      $('#template tr') 
       .clone() 
       .html(function(i, oldHTML) { 
        return oldHTML.replace(/\$i/g, $('#bars tr').length); 
       }) 
       .appendTo('#bars'); 
     }); 
    }); 
</script> 

Это в основном то, что @MagnusEriksson посоветовал мне сделать, но решил в немного чистого пути, не имея сохранить счетчик, но просто используя количество строк внутри формы в качестве индекса для клонированных строк.

Смежные вопросы