如何使用 jQuery 在每次单击按钮后调用 Dropzone 的 init 函数?

问题描述 投票:0回答:1

我有一个使用

<div>
循环创建的类似
for
元素的列表。对于每个
<div>
元素,我都有一个用于编辑信息的按钮。每次单击此编辑按钮时,都会打开一个弹出窗口,其中包含 Dropzone 框(使用 Dropzone 库)。现在,要加载与每个
<div>
相关的图像,我使用 jQuery 更改与图像 ID 关联的输入值。

但是,我需要从输入中读取更改后的 ID 并在 Dropzone 的

init
函数中使用它。问题在于 Dropzone 是在更改输入值之前创建的,并且在初始页面加载期间,它具有空值。我想在每次单击编辑按钮后以与前一个相同的配置重新运行 Dropzone
init
函数。

我现在将发布代码片段以供参考。

HTML 文件:

@foreach($steps as $step)
    <div class="row card p-3 mb-3 d-flex justify-content-center">
        <div class="col-12 row justify-content-between align-self-center mb-2">
            
            <div class="col-6 p-0">

                <button type="button" class="btn update_step" title="update"
                        data-toggle="modal" data-target="#update_step_modal"
                        step_number="{{$step->number}}"
                        route="{{route('panel.contents.clusters.steps.update', [$content->id, 
                        $cluster->id, $step->id])}}">

                    <span class="mdi mdi-18px mdi-square-edit-outline"></span>
                </button>
              </div>
         </div>

         <div class="col-12 row justify-content-center align-self-center mb-2">
             <p class="col-12 step_description_p">{{$step->description}}</p>

             <div class="col-6 justify-content-center pt-4">
                 <input class="step_cover_id" value="{{$step->cover_id}}" hidden>
                 <img src="{{$step->cover_image}}">
              </div>

         </div>
    </div>      
@endforeach

模态 HTML 文件:

<div class="modal fade" id="update_step_modal" tabindex="-1" role="dialog" aria- 
      labelledby="update_step_modal" aria-hidden="true" data-keyboard="false" data- 
      backdrop="static">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>

            <div class="modal-body">
                <div class="col-12 row justify-content-center align-self-center">
                    <form action="" method="POST" id="update_step_form">
                        @method('PATCH')
                        @csrf

                        <textarea name="description" id="update_step_description"></textarea>
                        <input name="cover_id" id="update_step_cover_id" hidden>
                        <input name="video_id" id="update_step_video_id" hidden>

                    </form>
                </div>

                <div class="col-12 row justify-content-center align-self-center mb-2">

                    <div class="col-6" id="update_step_cover_div">
                        <form action="{{url('panel/upload')}}" method="POST" 
                               class="dropzone" id="update_step_cover_form">
                            @csrf
                            <input name="type" value="step_cover" hidden />
                            <input name="content_id" value="{{$content->id}}" hidden />
                            <input name="cluster_id" value="{{$cluster->id}}" hidden />
                            <div class="dz-message" data-dz-message>
                                <span class="m-dropzone__msg-desc">some messages</span>
                            </div>
                        </form>
                    </div>
                </div>

                <div class="d-flex justify-content-center">
                    <button type="button" class="btn" id="step_update_button">
                        <span class="ladda-label">update</span>
                        <span class="ladda-spinner"></span>
                    </button>
                </div>

            </div>
        </div>
    </div>
</div>

JavaScript 文件:

$('.update_step').on('click', function () {
   let step_number = $(this).attr('step_number')
   let route = $(this).attr('route')

   $('#edited_step_number').text(step_number)
   $('#update_step_form').attr('action', route)

   let parent = $(this).parent().parent().parent();
   let description = parent.find('.step_description_p').text();
   let cover_id = parent.find('.step_cover_id').val();
   let video_id = parent.find('.step_video_id').val();

   $('#update_step_description').val(description).change();
   $('#update_step_cover_id').val(cover_id).change();
   $('#update_step_video_id').val(video_id).change();
});

Dropzone.options.updateStepCoverForm = {
    paramName: "file", 
    uploadMultiple: false,
    acceptedFiles: "image/*,",
    maxFiles: 1,
    headers: {
        'X-CSRF-Token': $('input[name="_token"]').val(),
        'Accept': 'application/json'
    },
    addRemoveLinks: true,
    init: function() {
        let coverDropzone = this;
        let id = $('#update_step_cover_id').val()

        if(id !== ''){
            $.ajax({
                url: '/panel/fetch_file/' + id,
                type: 'get',
                dataType: 'json',
                success: function (response) {
                    var mockFile = {name: response.data.file_name, size: response.data.size};

                    coverDropzone.emit("addedfile", mockFile);
                    coverDropzone.emit("thumbnail", mockFile, response.data.file_path);
                    coverDropzone.emit("complete", mockFile);
                    coverDropzone.options.maxFiles = 0;
                }
            });
        }

        this.on("removedfile", file => {
            let id = $('#update_step_cover_id').val()
            remove_file_function(id, "update_cover")
        });
    },
    accept: function(file, done) {
        done();
    },
    success: function (file, response) {
        $('#update_step_cover_id').val(response.data.id).change();
    },
    error: function (file, response) {
        error_function(file, response)
    }
};
javascript jquery laravel laravel-blade dropzone.js
1个回答
1
投票

重新初始化 Dropzone 以反映新的输入值

您正在处理修改

cover_id
输入值后更新 Dropzone 组件的挑战。这里的问题是 Dropzone 组件仅在其初始设置期间读取输入字段值。如果您稍后更改输入值,例如单击
update_step
按钮时,Dropzone 将无法识别此更改,除非您重新初始化它。

  • 动态创建 Dropzone 组件: 您可以选择根据需要动态制作和拆除 Dropzone 组件,而不是通过

    Dropzone.options.updateStepCoverForm
    坚持 Dropzone 的声明性设置。

  • 单击按钮时重新初始化 Dropzone: 配置输入值后,每次按

    update_step
    按钮时,您都会继续删除之前的 Dropzone(如果有),然后继续生成新的 Dropzone。这种方法可确保新创建的 Dropzone 的
    init
    函数能够识别更新的输入值。

更新代码:

// Remove this static configuration
// Dropzone.options.updateStepCoverForm = { ... };

// Variable of the current Dropzone instance
let coverDropzone;

$('.update_step').on('click', function() {
  // TODO: [your previous code here]

  // After setting the new input values reinitialize Dropzone
  initializeDropzone();
});

function initializeDropzone() {
  // If there is already an existing Dropzone instance it gets destroyed
  if (coverDropzone) {
    coverDropzone.destroy();
  }

  // Creates a new Dropzone instance
  coverDropzone = new Dropzone("#update_step_cover_form", {
    paramName: "file",
    uploadMultiple: false,
    acceptedFiles: "image/*,",
    maxFiles: 1,
    headers: {
      'X-CSRF-Token': $('input[name="_token"]').val(),
      'Accept': 'application/json'
    },
    addRemoveLinks: true,
    init: function() {
      // TODO: [put your existing init function code here]
    },
    accept: function(file, done) {
      done();
    },
    success: function(file, response) {
      $('#update_step_cover_id').val(response.data.id).change();
    },
    error: function(file, response) {
      error_function(file, response);
    }
  });
}

initializeDropzone();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

更新:

很可能会出现您提到的问题,因为即使您已经销毁并重新初始化了 Dropzone 实例,由前一个实例创建的 DOM 元素(即之前获取的文件预览)可能仍然存在。

要解决此问题,您可以在销毁 Dropzone 实例时手动消除预览。

下面是代码的更改版本,应处理预览的清除:

您修改后的代码:

$('.update_step').on('click', function () {
    ...
    ... // Your previous code stays here

    // Destroys previous Dropzone instance
    if (Dropzone.instances.length > 0) {
        const dropzoneInstance = Dropzone.forElement("#update_step_cover_form");
        
        // Clears the previews
        dropzoneInstance.removeAllFiles(true);
        
        dropzoneInstance.destroy();
    }

    // Reinitializes the Dropzone with updated configurations
    new Dropzone("#update_step_cover_form", {
        ...
        ... // The rest of your Dropzone configurations stay here
    });
});
© www.soinside.com 2019 - 2024. All rights reserved.