Как обработать форму, выводимую в цикле?

Добрый день, коллеги!
Делаю админку для сайта-витрины stroytara.ru. Там админятся, в числе прочего, категории товаров и сами товары. Они хранятся в базе данных MySQL, оттуда же выводятся на сайт и в админку. Естественно, выводятся в цикле.
Проблема в том, что ниже приведенные коды отлично работают для:
а) одного, отдельно взятого изображения;
б) для первого изображения группы, выведенной в цикле. Для остальных - не срабатывает даже input type="file".
Вот, максимально упрощенные коды для категорий:
<?php foreach($categories as $cat) { ?>
<div class="container">
  <!-- Аватар категории -->
  <?php
    $controller = new avatarController($captures[0], 'categories', 'category_avatar', $cat['category_avatar'], $cat['id']);
    $controller->render_avatar();
  ?>
  <div  class="container">
    <form>
    Здесь выводим характеристики категории: id, описание и прочее + кнопку для обновления БД
    </form>
  </div>
</div>
<?php } ?>

Нас интересует только момент с заменой аватара. Контроллер и метод контроллера для аватара:
class avatarController {
  protected $capture;
  protected $table;
  protected $field;
  protected $filename;
  protected $id;
  public function __construct($capture, $table, $field, $filename, $id=NULL) {
    $this->capture = $capture;
    $this->table = $table;
    $this->field = $field;
    $this->filename = $filename;
    $this->id = $id;
  }
  public function render_avatar() {
    ob_start();
    include("tmpl/change_avatar.tpl");
    echo ob_get_clean();
  }
}

Шаблон change_avatar:
<div class="container">
  <div><?=$this->capture?></div>
  <div><img id="preview" src="../images/<?=trim($this->filename);?>" /></div>
  <div>
    <form id="upload-image" name="upload-image" enctype="multipart/form-data">
      <div class="form-group">
        <div class="file-upload">
          <label><input type="file" name="image" id="image" data-id="<?=$this->id?>"><span>Выбрать другой файл</span></label>
        </div>
        <div class="file-save">
          <label><input id="save_logo" name="save_logo" type="submit"><span>Заменить и сохранить в медиабиблиотеке</span></label>
        </div>
        <input id="a_id" name="a_id" type="hidden" value="<?=$this->id?>" />
        <input id="a_field" name="a_field" type="hidden" value="<?=$this->field?>" />
        <input id="a_table" name="a_table" type="hidden" value="<?=$this->table?>" />
      </div>
    </form>
  </div>
</div>

По задумке, после выбора файла для замены аватара картинка в img id="preview" обновляется, а сохранение новой картинки в БД делается PHP. Вот код JavaScript/Ajax для обновления картинки и передачи данных формы вывода аватара в php handler:
$(document).ready(function () {
   $('#image').change(function(){
    readImage(this);
  });
  function readImage ( input ) {
    console.log('Reading image');
    if (input.files && input.files[0]) {
      var reader = new FileReader();
      reader.onload = function (e) {
        $('#preview').attr('src', e.target.result);
      }
      reader.readAsDataURL(input.files[0]);
    }
  }
   $('#upload-image').on('submit',(function(e) {
    e.preventDefault();
    var formData = new FormData(this);
    $.ajax({
      type:'POST',
      url: '.images.php',
      data: formData,
      cache:false,
      contentType: false,
      processData: false,
      success:function(data){
        console.log('success');
        window.location.reload();
      },
      error:function(data){
        console.log(data);
      }
    });
  }));
});

И простейший php-обработчик (я убрал из кода все проверки, генерацию имени и прочий мусор):
$full_img_name = $_FILES['image'];
$filePath  = $full_img_name['tmp_name'];
$errorCode = $full_img_name['error']; 
$id = $_POST['a_id'];
$field = $_POST['a_field'];
$table = $_POST['a_table'];
$new_avatar = новое сгенерированное имя файла;
if (move_uploaded_file($filePath, 'images' . $new_avatar)) {
    Database::setNewAvatar($new_avatar, $table, $field, $id);
}
else {
    die('При записи изображения на диск произошла ошибка.');
}
?>

В методе setNewAvatar просто срабатывает UPDATE с переданными параметрами, код приводить не буду, он тривиален.
  • Вопрос задан
  • 351 просмотр
Пригласить эксперта
Ответы на вопрос 2
coderisimo
@coderisimo Куратор тега JavaScript
Писать для вашего примера , пардон, не буду. Но постараюсь донести суть.
Вы можете создать одну функцию для обработки сколь угодно (непредсказуемо) большого числа инпутов. Просто при генерации инпутов вам нужно помещать в них атрибуты , которые помогут идентифицировать поле в базе данных, которое связано в данным инпутом.
Вот пример.


т.е вы вешаете обработчик на КЛАСС, а далее в этом обработчике выясняете с каким полем в БД этот инпут связан и делаете все что нужно применительно именно к этому полю.
Ответ написан
Комментировать
Stalker_RED
@Stalker_RED
$('#image').change ... // обработчик на первом попавшемся элементе с id="image"

При этом у вас их больше одного. А так делать нельзя. Но браузер от этого нарушения не взрывается, и даже ошибок не выдает, а просто обрабатывает первый попавшийся. А в делегирование и traversing вы еще не умеете.

Но в комментарии я эти темы раскрывать не буду, ибо они довольно объемные.
https://learn.javascript.ru/event-delegation
https://developer.mozilla.org/ru/docs/Web/API/Docu...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы