2017-02-21 23 views
0

私はユーザーがイベントを投稿できるようにするアプリを開発中です。 NodeJS、Express、Mongoを使用しています。フォームの編集時にアップロードされた画像が削除されないようにするにはどうすればよいですか?

イベントの詳細を入力してイベントに関連する画像をアップロードするためのフォームを作成しました。また、ユーザーがイベントの詳細を編集できるフォームを作成しました。

次のように形が見えます:

enter image description here

問題:

  1. ユーザーは、イベントの詳細をフォームに記入し、写真を添付し​​ます。
  2. ユーザーはフォーム
  3. ユーザーは、彼がイベントのタイトルを変更したいことを決定、しかし、他に何も
  4. ユーザーが編集イベントをクリックし、タイトルを変更し、
  5. 問題を提出提出:ユーザーが」didnのにもかかわらずイベントに関連付けられた画像を削除すると、画像はもはや存在しません。ここで

(あくまでも参考のためにここにこれを追加する新しいイベントを掲載するため、)私のnew.ejsファイルの一部である

<script type="text/javascript" src="/js/eventform.js"></script> 
<form action="/events" 
     method="POST" 
     enctype="multipart/form-data" 
     onSubmit="return(validate(this));" // validating user input 
     novalidate > 

    .... 
    .... 
    <input name="image" type="file" id="image" accept="image/*" style="display:none" onchange="handleFiles(this.files)"> 
    <div id="imageBorder" > 
     <div id="imageContainer"> 
      <div id="dropbox"> 
       <i class="fa fa-picture-o" aria-hidden="true"></i> 
       <p> Drop image here or click to upload</p> 
      </div> 
      <div id="preview" class="hidden"> 
      </div> 
      <button id="fileSelect" class="...">Upload Image</button> 
      <button id="fileRemove" class="...">Remove Image</button> 
     </div> 
    </div> 
    .... 
    .... 
</form> 

私は隠し入力フィールドを使用しています注意してください。また、私は2つのdiv、プレビュー(最初に隠された)とdropboxを持っています。画像がアップロードされると、「非表示」のクラスがプレビューから削除され、dropboxに追加されます。ここで

は、JSファイルの一部であり、ここで

$(document).ready(function() { 
    .... 
    eventImageSetup(); 
    .... 
} 
.... 
function eventImageSetup() { 
    var dropbox = document.getElementById("dropbox"), 
     fileElem = document.getElementById("image"), 
     fileSelect = document.getElementById("fileSelect"), 
     fileRemove = document.getElementById("fileRemove"); 
    $(dropbox).height($('#imageBorder').height()); 
    fileSelect.addEventListener("click", function(e) { 
     if (fileElem) { 
      fileElem.click(); 
      e.preventDefault(); // to prevent submit 
     } 
    }, false); 
    fileRemove.addEventListener("click", function(e) { 
     e.preventDefault(); // prevent submit 
     if(!$('#preview').hasClass('hidden')) { // if there is an image 
      $('#preview').empty(); 
      $('#dropbox').removeClass('hidden'); 
      $('#preview').addClass('hidden'); 
      $('#fileSelect').text('Upload Image'); 
      $('#image').wrap('<form>').closest('form').get(0).reset(); 
      $('#image').unwrap(); 
     }  
     removeError($('#imageError'), $('#image')); 
    }); 
    dropbox.addEventListener("dragenter", dragenter, false); 
    dropbox.addEventListener("dragover", dragover, false); 
    dropbox.addEventListener("drop", drop, false); 
} 

function handleFiles(files) { 
    var file = files[0]; 
    .... // some error checking 

    var img = document.createElement("img"); 
    img.id = "uploadedImage"; 
    img.file = file; 
    img.onload = function() { 
      adjustImageSize(img); 
    }; 
    $('#dropbox').addClass('hidden'); 
    $('#preview').removeClass('hidden'); 
    $('#preview').empty(); 
    $('#preview').append(img); 
    $('#fileSelect').text('Replace Image'); 

    var reader = new FileReader(); 
      reader.onload = (function(aImg) { 
       return function(e) { 
       aImg.src = e.target.result; 
      }; 
    })(img); 
    reader.readAsDataURL(file); 
}  

をnewevent.js私edit.ejsの一部である

<form action="/events/<%=event._id%>?_method=PUT" 
     method="POST" 
     enctype="multipart/form-data" 
     onSubmit="return(validate(this));" 
     novalidate > 

    <input name="image" type="file" id="image" accept="image/*" style="display:none" onchange="handleFiles(this.files)"> 

    <div id="imageBorder" > 
     <div id="imageContainer"> 
       <div id="dropbox" class="hidden"> 
        <i class="fa fa-picture-o" aria-hidden="true"></i> 
        <p> Drop image here or click to upload</p> 
       </div> 
       <div id="preview"> 
        <script> 
         var imageExists = '<%=event.image%>'; 
         if(imageExists) { 
          var myImg = document.createElement("IMG"); 
          var source = "../../<%= event.image %>"; 
          myImg.src = source; 
          adjustImageSize(myImg); 
          $('#preview').append(myImg); 
         } 
         </script> 
       </div> 
       <button id="fileSelect" class="...">Upload Image</button> 
       <button id="fileRemove" class="...">Remove Image</button> 
      </div> 
    </div> <!-- END OF imageBorder --> 
    .... 
</form> 

を提出正常に上記のスクリプトは、イメージがに表示されます編集ページを開きます。

enter image description here

しかし、Submitをクリックすると、画像が表示されません。

ここにnodejsルートファイルがあります。私は編集フォームでそのまま画像を残す場合は、基本的にここに

// UPDATE SPECIFIC EVENT IN DATABASE 
router.put("/:id", upload.single('image'), middleware.checkEventOwnership, function(req, res) { 

    var filepath = undefined; 
    if(req.file) { 
     filepath = req.file.path.substr(7); // Substr to remove "/public" 
    } 

    req.body.image = filepath; 

    Event.findByIdAndUpdate(req.params.id, req.body, function(err, foundEvent) { 
     if(err) { 
      console.log(err); 
      req.flash("error", err); 
     } else { 
      req.flash("success", "Successfully edited your event"); 
     } 
     res.redirect("/events/" + req.params.id); 
    }); 
}); 

問題を見ることができ、req.fileは存在しません。したがって、req.body.image = undefinedとなります。そして、イメージはもはやイベントに関連付けられていません。

常識はこの

if(req.file) { 
     filepath = req.file.path.substr(7); 
     req.body.image = filepath; 
    } 

を行うと言うでしょう。しかし、あなたがそれを行うならば、あなたは新しい問題を紹介:ユーザーがイベントを編集した画像を削除した場合(つまり、彼は、画像が関連付けられて望んでいないことを決定しますこのイベントでは、画像は決して削除されません。

どのようにこの問題を解決するには?私はedit.ejsスクリプトで何かをしなければならないことを知っています...もっと具体的には、私は画像ファイルを作成する必要があります...しかし、私はこれに近づける方法がわかりません

答えて

0

だから私は私は本当に好きではないハックを介して。私はedit.ejsと画像を扱う、より良い、よりクリーンな、標準的な方法があると確信しています。言い換えれば、より良い解決策を見つけるのを助けてください!ここ

edit.ejs

<form action="/events/<%=event._id%>?_method=PUT" 
     method="POST" 
     enctype="multipart/form-data" 
     onSubmit="return validate(this) & editPageImageProcessing(this);" 
     novalidate > 
    .... 
    .... 
     <div id="preview"> 
      <script> 
        var imageExists = '<%=event.image%>'; 
        if(imageExists) { 
         var myImg = document.createElement("IMG"); 
         var source = "../../<%= event.image %>"; 
         myImg.src = source; 
         myImg.name = "previewImage"; 
         myImg.id = "previewImage"; 
         adjustImageSize(myImg); 
         $('#preview').append(myImg); 
        } 
      </script> 
     </div> 

の変化は基本的に、私はラインを

      myImg.name = "previewImage"; 
         myImg.id = "previewImage"; 

を加え、機能editPageImageProcessing添加します。

この機能の機能:ユーザーが新しい画像をアップロードせずに画像を削除しなかった場合は、隠し入力フィールド「hiddenImage」を作成し、その値を元の画像のソースにします。以下を参照してください。今

// This function deals with edit image 
function editPageImageProcessing(form) { 
    // If the user didn't change the image 
      // preview would be NOT hidden 
      // there would not be a req.file (document.getElementById('image').val == '') 
      // we want a hiddenimage input field 
    var aFile = document.getElementById('image').value; 
    console.log("File: ", aFile); 
    var preview = document.getElementById('preview'); 
    console.log("Preview has hidden class: " + $(preview).hasClass('hidden')); 
    if(aFile == '' && !$(preview).hasClass('hidden')) { 
     var input = document.createElement('input'); 
     $(input).attr("name", "hiddenImage"); 
     $(input).attr("id", "hiddenImage"); 
     $(input).attr("type", "hidden"); 
     var myImage = document.getElementById('previewImage'); 
     $(input).attr("value", myImage.src); 
     $('form').append(input); 
    } 
    return true; 
} 

、編集ルートで、私はこれに

// UPDATE SPECIFIC EVENT IN DATABASE 
router.put("/:id", upload.single('image'), middleware.checkEventOwnership, function(req, res) { 
    var filepath = undefined; 
    if(req.file) { // If user uploaded a new image 
     filepath = req.file.path.substr(7); // Substr to remove "/public" 
     console.log(filepath); 
    } else if(req.body.hiddenImage) { // If user kept the same image 
     var index = req.body.hiddenImage.lastIndexOf("/uploads"); 
     filepath = req.body.hiddenImage.substr(index); 
     // req.body.hiddenImage WILL ONLY EXIST if user left image unchanged 
    } 

    req.body.image = filepath; // If user deleted image, this will be undefined, which is what we want 

    Event.findByIdAndUpdate(req.params.id, req.body, function(err, foundEvent) { 
     if(err) { 
      console.log(err); 
      req.flash("error", err); 
     } else { 
      req.flash("success", "Successfully edited your event"); 
     } 
     res.redirect("/events/" + req.params.id); 
    }); 
}); 

わかりましたので、その乱雑をしました。

さらに良い解決策があります。

関連する問題