2011-09-07 38 views
2

我使用MVC3,并且我有一个带有文件上传的表单。如果该文件已经存在于服务器上,我想提示用户确认他们要覆盖该文件。我已经在表单提交上添加了一个jQuery方法来处理我在线阅读的内容,但是似乎邮件在初始化之前可以显示确认对话框。如果文件已经存在,jQuery拦截并阻止表单提交

如果我在顶部调用e.preventDefault()我的表单提交函数会停止表单,但是我不知道如何重新激活该操作。这里是我有:

表单

@using (Html.BeginForm("Upload", "Management", FormMethod.Post, new {id = "formUpload", enctype = "multipart/form-data"})) { 

    <div class="editor-label">Pricing Model Workbook</div> 
    <div class="editor-field"> 
     <input type="file" name="file" id="file" size="50" /> 
     @Html.ValidationMessageFor(file => file.FileName) 
    </div> 
    <div><input type="submit" name="upload" id="upload" value="Upload" /></div> 
} 

jQuery的

<script type="text/javascript" language="javascript"> 
    $(document).ready(function() { 
     $('#formUpload').submit(function (e) { 
      var filePath = $('#file').val(); 
      $.getJSON('@Url.Action("CheckIfFileExists")', { path: filePath }, 
       function (exists) { 
        if (exists) { 
         var cancel = confirm('File "' + filePath + '" has already been uploaded. Overwrite?'); 
         if (cancel) { 
          e.preventDefault(); 
          return false; 
         } 
        } 

        return true; 
       } 
      ); 
     }); 
    }); 
</script> 

所以我的问题是,我究竟做错了什么?此外,作为奖励,如果客户端验证发现错误,是否有任何方法可以防止这种情况出现?

任何帮助将不胜感激!

UPDATE 我最终这样做,这对我正在尝试做的工作。

<script type="text/javascript" language="javascript"> 
    $(document).ready(function() { 
     var fileInvalid = false; 

     // check if file exists when user selects a new file 
     $('#file').change(function() { 
      var filePath = $('#file').val(); 
      $.getJSON('@Url.Action("CheckIfFileExists")', { path: filePath }, 
       function (exists) { 
        if (exists) { 
         var overwrite = confirm('Warning :: File "' + filePath + '" has already been uploaded.' 
               + 'The existing data will be overwritten on submission. Continue?'); 
         if (!overwrite) { 
          $('#file').replaceWith($('#file').clone(true)); 
         } 
        } 
       } 
      ); 
     }); 
    }); 
</script> 
+0

只是抬起头来,你仍然有一个竞争条件。如果用户在文件检查返回之前提交表单,用户将永远看不到对话框。 – jmar777

回答

2

的问题是,你的Ajax请求犯规可能完成,直到提交处理程序完成后,如果这篇文章继续,你将失去取消它的能力。这听起来像你需要的是一扇门;基本上,直到你设置标志为允许,你不能提交。像这样的东西:

var fileInvalid = true; 
$('#file').change(function() 
{ 
    $.getJSON('@Url.Action("CheckIfFileExists")', { path: filePath }, 
      function (exists) { 
       if (exists) { 
        var cancel = confirm('File "' + filePath + '" has already been uploaded. Overwrite?'); 
        if (cancel) { 
         fileInvalid = false; 
        } 
       } 
       else 
       { 
        fileInvalid = false; 
       } 
      } 
     ); 
}); 

$('#formUpload').submit(function(e) 
{ 
    if(fileInvalid) 
     e.preventDefault(); 
}); 
+0

谢谢,我最终在我的解决方案中使用了这个概念,但采取了稍微不同的方法(请参阅我原来的问题中的更新)。标记为答案。 – shuniar

1

我想你真正想要的是远程验证:

http://deanhume.com/Home/BlogPost/mvc-3-and-remote-validation/51

+0

再次,我没有解释downvoted。要清楚:你可以很简单地通过远程验证来做到这一点。 –

+0

远程验证看起来很有趣,但我没有看到允许覆盖的方法,只是防止它们被覆盖。我想显示警告文件存在,并仍然让他们上传,如果他们选择,因为可能有更新的数据。我想我会在我的应用程序的其他地方使用它。 – shuniar

+0

为您的模型添加覆盖布尔值,并将其作为验证字段。 –

1

这里有一种方法。基本的想法是始终取消表单提交,除非已设置标志。如果文件不存在,或者用户确认提交,则将该标志设置为true,然后重新提交表单。

<script type="text/javascript" language="javascript"> 
    $(document).ready(function() { 
     var $form = $('#formUpload'); 
     $form.submit(function (e) { 
      // if user already confirmed, then let form submit 
      if ($form.data('confirmed')) { 
       return true; 
      } 
      // otherwise, prevent form submission so we can do file check 
      e.preventDefault(); 
      var filePath = $('#file').val(); 
      $.getJSON('@Url.Action("CheckIfFileExists")', { path: filePath }, 
       function (exists) { 
        if (exists) { 
         var cancel = confirm('File "' + filePath + '" has already been uploaded. Overwrite?'); 
         if (!cancel) { 
          // user wants to submit, so set flag and re-submit form 
          $form.data('confirmed', true).submit(); 
         } 
        } else { 
         // the file doesn't exist, so we can force submission w/out the dialog 
         $form.data('confirmed', true).submit(); 
        } 
       } 
      ); 
     }); 
    }); 
</script>