src/Eccube/Resource/template/admin/Product/_parts/js_product_feature.twig line 1

Open in your IDE?
  1. <script>
  2.     $(function() {
  3.         const itemClass = '.product_feature_row';
  4.         const $body = $('#product_feature_body');
  5.         let index = $body.find(itemClass).length;
  6.         function addForm() {
  7.             const prototype = $body.data('prototype');
  8.             const newForm = prototype.replace(/__name__/g, index);
  9.             $body.append(newForm);
  10.             index++;
  11.         }
  12.         $('#add_product_feature').on('click',addForm);
  13.         $(document).on('click','#remove_product_feature',function() {
  14.             if(!confirm('削除しますか?')) {
  15.                 return false;
  16.             }
  17.             const deleteIndex = $(this).data('index');
  18.             $(document).find('#product_feature_row'+deleteIndex).remove();
  19.         });
  20.     });
  21.     $(function() {
  22.         const featureBodyElem = document.getElementById('product_feature_body');
  23.         var observer = new MutationObserver(function () {
  24.             // 子要素が変化したときの処理
  25.             initFeatureFilePond();
  26.         });
  27.         observer.observe(featureBodyElem, {
  28.             attributes: true,
  29.             childList: true,
  30.             characterData: true,
  31.         });
  32.         initFeatureFilePond();
  33.     });
  34.     function initFeatureFilePond() {
  35.         $("[id^=product_feature_row]").each(function(index) {
  36.             // ファイルアップロード
  37.             // see https://pqina.nl/filepond/
  38.             var productFeatureFileId = `admin_product_ProductFeatures_${index}_file_name`;
  39.             var inputFileElement = document.querySelector(`input[id="${productFeatureFileId}"]`);
  40.             var files = inputFileElement && inputFileElement.value ? [
  41.                 {
  42.                     source: inputFileElement.value,
  43.                     options: {
  44.                         type: 'local'
  45.                     }
  46.                 }
  47.             ] : [];
  48.             var pond = FilePond.create(inputFileElement, {
  49.                 allowFileTypeValidation: true,
  50.                 acceptedFileTypes: [
  51.                     'image/gif',
  52.                     'image/png',
  53.                     'image/jpeg'
  54.                 ],
  55.                 allowFileSizeValidation: true,
  56.                 maxFileSize: 10000000,
  57.                 maxFiles: 1,
  58.                 allowBrowse: true,
  59.                 labelIdle: '<i class="fa fa-cloud-upload fa-3x text-ec-lightGray mx-3 align-middle" aria-hidden="true" style="font-size: 40px"></i>{{ 'admin.common.drag_and_drop_image_description'|trans }}<span class="filepond--label-action">{{ 'admin.common.file_select'|trans }}</span>',
  60.                 // 保存されている画像のロード
  61.                 files: files,
  62.                 server: {
  63.                     process: {
  64.                         url: '{{ path('admin_product_image_process_entity_key', { entity_name: "ProductFeatures", key_name: "file_name" }) }}',
  65.                         headers: {
  66.                             'ECCUBE-CSRF-TOKEN': $('meta[name="eccube-csrf-token"]').attr('content'),
  67.                             'X-Requested-With': 'XMLHttpRequest'
  68.                         }
  69.                     },
  70.                     load: {
  71.                         url: '{{ path('admin_product_image_load') }}?source=',
  72.                         headers: {
  73.                             'X-Requested-With': 'XMLHttpRequest'
  74.                         }
  75.                     },
  76.                     revert: {
  77.                         url: '{{ path('admin_product_image_revert') }}',
  78.                         headers: {
  79.                             'ECCUBE-CSRF-TOKEN': $('meta[name="eccube-csrf-token"]').attr('content'),
  80.                             'X-Requested-With': 'XMLHttpRequest'
  81.                         }
  82.                     }
  83.                 }
  84.             });
  85.             pond.on('initfile', function() {
  86.                 $(`#product_feature_image_error${index}`).hide();
  87.             });
  88.             pond.on('error', function(error, file) {
  89.                 var message = '{{ 'admin.common.upload_error'|trans }}';
  90.                 if (error.main !== undefined) {
  91.                     message = `${error.main}: ${error.sub}`;
  92.                 }
  93.                 $(`#product_feature_image_error${index}`)
  94.                     .show()
  95.                     .find('.form-error-message').text(message);
  96.                 // エラーメッセージが表示されてからプレビューエリアのエラーメッセージを非表示にする
  97.                 setTimeout(function() {
  98.                     $('.filepond--file-status').hide();
  99.                 }, 300);
  100.             });
  101.             // 画像が追加されたら payment_image にファイル名を追加する
  102.             pond.on('processfile', function(error, file) {
  103.                 if (error) {
  104.                     console.log(error);
  105.                 } else {
  106.                     $(`#${productFeatureFileId}`).val(file.serverId);
  107.                 }
  108.             });
  109.             // 画像が削除されたら payment_image のファイル名を削除する
  110.             pond.on('removefile', function(error, file) {
  111.                 if (error) {
  112.                     console.log(error);
  113.                 } else {
  114.                     $(`#${productFeatureFileId}`).val('');
  115.                 }
  116.             });
  117.         });
  118.     }
  119. </script>