1

Explain what is wrong here. First, the run function and its ajax request must be executed. But for some reason the function is executed, and the ajax request is not. It runs right at the very end of the script - after all the functions ... Why is this happening and how to fix it?..

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="id_product_create_form" method="post" enctype="multipart/form-data"></form>

<div class="media_preview_wrap">
  <div class="addPhoto">
    <div class="addPhotoHeader">
      <button type="button" class="button product_images_button">Add</button>
      <button id="id_submit" type="button">Submit</button>
    </div>
  </div>
</div>
<input type="file" name="image" style="display: none" required="" class="product_images" id="">

<script>
var files = [];

  $('.product_images_button').click(function() {
    $('.product_images').click();
  });

  $('.product_images').change(function() {
    handleFiles(this);
  });

  $('.media_preview_wrap').on('click', '.thumb', function() {
    removeFile($(this).data('id'));
  });

  $('#id_submit').click(function() {
    event.preventDefault();

     var $form = $('form'),
         formdata = new FormData($form[0]),
         $button = $('#id_submit');
     formdata.append('content', CKEDITOR.instances.id_content.getData());
     function run() {
       var product_id = null;
     $.ajax($form.attr('action'),{
       type: 'POST',
       data: formdata,
       processData: false,
       contentType: false,
       success: function(data) {
         product_id = data.product_id;
       }, error: function(error) {
          console.log(error)
      }
    });
     return product_id}
     product_id = run();
    files.forEach(function(file, index) {
      var data = new FormData();
      data.append('name', file.name);
      data.append('gallery_image', file.file);
      uploadFile(event.target.action, data)
        .done(function(response) {
          removeFile(file.id);
        })
        .fail(function(error) {
          console.log(error);
        });
    });
  });


  function handleFiles(input) {
    var URL = window.URL || window.webkitURL;

    var uniqueId = (new Date()).getTime()
    for (var i = 0; i < input.files.length; i++) {
      var file = input.files[i];

      if (file && file.type.startsWith('image/')) {
        uniqueId++;

        files.push({
          id: uniqueId,
          file: file,
          name: file.name // задел для возможности переименования файла.
        });

        var img = $('<img src="'+ URL.createObjectURL(file) +'" class="thumb" data-id="'+ uniqueId +'">');
        $('.media_preview_wrap').append(img);

        img.on('load', function() {
          URL.revokeObjectURL(this.src);
        });
      }
    }

    $(input).val('');
  }

  function removeFile(id) {
    files = files.filter(function(file) {
      return id !== file.id;
    })

    $('img[data-id="'+ id +'"]').remove();
  }

  function uploadFile(url, data) {
    return $.ajax({
      headers: {'X-CSRFToken': '{{ csrf_token }}' },
      type: 'POST',
      url: url,
      data: data,
      processData: false,
      contentType: false,
      cache: false
     });
  }
</script>

<style>
    .thumb {
      width: 150px;
      height: auto;
      opacity: 0.9;
      cursor: pointer;
    }
    .thumb:hover {
      opacity: 1;
    }
    .product_images {
      display: none;
    }
</style>
charlietfl
  • 170,828
  • 13
  • 121
  • 150

1 Answers1

3

The initial problem is likely due to some browsers having a global event object while others don't.

You are likely getting an error that event is undefined and that would prevent the remaining code to run

Use the argument of the event handler function which always passes in an event object:

$('#id_submit').click(function(event) {
                              // ^^^
    event.preventDefault();

Once that issue is solved... you need to realize that $.ajax is asynchronous and you can't use the new value of product_id until first request completes in the success callback

See How do I return the response from an asynchronous call?

charlietfl
  • 170,828
  • 13
  • 121
  • 150