2012-08-25 15 views
14

मेरे पास नियमित रूप से <input type="file"> फ़ाइल अपलोड के साथ एक वेबसाइट है, जो फॉर्म सबमिट होने पर बैकएंड पर डेटा पोस्ट कर रहा है।AJAX के बिना फ़ाइल को खींचें और ड्रॉप करें, अग्रभूमि में समकालिक रूप से?

मैं प्रपत्र को प्रगतिशील रूप से बढ़ाने के लिए चाहता हूं ताकि आप इसे अपलोड करने के लिए व्यूपोर्ट में कहीं भी ब्राउज़र से बाहर फ़ाइल को छोड़ सकें (केवल फाइल इनपुट फ़ील्ड पर नहीं, जैसे कि कुछ ब्राउज़रों में बनाया गया हो)।

फॉर्म ऑटोसबमिट महत्वपूर्ण नहीं है या नहीं। तो यदि ड्रैग-एंड-ड्रॉप केवल फ़ाइल फ़ील्ड में फ़ाइल को चुनने के बिना फ़ाइल को चुनता है, तो यह ठीक है। मुझे एकाधिक फाइलों के लिए समर्थन की आवश्यकता नहीं है। मुझे अपलोड प्रगति, थंबनेल या कुछ भी फैंसी दिखाने की ज़रूरत नहीं है।

मुझे पता है कि जेएस libs हैं जो ड्रैग-एंड-ड्रॉप अपलोड का समर्थन करते हैं, लेकिन वे सभी AJAX के माध्यम से अपलोड करने लगते हैं। मैं ऐसा कर सकता था, लेकिन फिर मुझे अपलोड त्रुटियों को संभालने, रीडायरेक्ट करने और सफलता पर सही संदेश दिखाने के लिए बैकएंड और फ्रंटएंड को संशोधित करने की आवश्यकता होगी।

मुझे एक प्रगतिशील वृद्धि चाहिए जो किसी भी बैकएंड परिवर्तन की आवश्यकता नहीं है। यह पृष्ठ में प्रपत्र का उपयोग कर समकालिक रूप से होना चाहिए। जेएस ठीक है, जब तक कि "अग्रभूमि में" अपलोड होता है। सिंक्रोनस AJAX निश्चित रूप से काम नहीं करेगा।

+1

क्रोम में, कम से कम, आप ड्रॉप पर एक फ़ाइल इनपुट की फ़ाइलों को सेट कर सकते हैं: http://jsfiddle.net/qMmPr/

यहाँ टुकड़ा है। क्या आप इसके बाद क्या कर रहे हैं? – pimvdb

+0

@pimvdb यह सुंदर है! वास्तव में मैं क्या चाहता था। और मैं यह उल्लेख करना भूल गया कि यह एक आंतरिक सेवा के लिए है, क्रोम केवल ठीक है। यदि आप इसे एक उत्तर के रूप में लिखते हैं (टिप्पणी के अतिरिक्त), तो मैं इसे स्वीकार के रूप में चिह्नित करूंगा। –

उत्तर

15

हालांकि वास्तव में "तुल्यकालिक" नहीं है (जावास्क्रिप्ट निष्पादन वास्तव में बंद नहीं होगा), आप <input type="file"> द्वारा प्रोग्राम की गई फ़ाइलों को सेट कर सकते हैं। वास्तव में, ऐसे तत्व और ड्रैगिंग उनके फ़ाइल बैकएंड कार्यान्वयन (File और FileList उदाहरण) साझा करते हैं, इसलिए यह वास्तव में सीधे आगे है। और क्या है, FileList एस का उपयोग कर दोनों अग्रभागों के कारण, एकाधिक फाइलों को खींचने से सहजता से काम किया जाता है।

यह क्रोम (jQuery का उपयोग करके) में काम करता है: http://jsfiddle.net/qMmPr/

$(document).on("dragover drop", function(e) { 
    e.preventDefault(); // allow dropping and don't navigate to file on drop 
}).on("drop", function(e) { 
    $("input[type='file']") 
     .prop("files", e.originalEvent.dataTransfer.files) // put files into element 
     .closest("form") 
      .submit(); // autosubmit as well 
}); 
+0

@ हेनरिक एन: अब मुझे एहसास है कि इसे विंडोज़ पर '.lnk' फाइल पसंद नहीं है।इनपुट तत्व के माध्यम से उन्हें चुनना फ़ाइल को शॉर्टकट लिंक का चयन करता है, जबकि '.lnk' फ़ाइल को छोड़कर आपको' .lnk' फ़ाइल मिलती है। – pimvdb

+0

मेरे उपयोग के मामले में कोई समस्या नहीं है। इसके लिए फिर से धन्यवाद! –

+3

एक क्रॉस-ब्राउज़र समाधान पर कोई विचार? (केवल एफएफ 16 पर प्रोप() का परीक्षण किया गया है: काम नहीं कर रहा है) –

-1

यह गलत पर autoUpload मोड़, एक सरणी में फ़ाइलों को इकट्ठा करके किया जा सकता है, तो प्रपत्र पर प्रस्तुत एक साथ प्रपत्र डेटा के साथ सभी फाइलों के साथ एक एकल ajax कॉल करते हैं, के रूप में वर्णित here

+0

इसके लिए धन्यवाद, लेकिन "अजाक्स के बिना" नोट करें प्रश्न :) –

+0

सच है, मेरा दृष्टिकोण अभी भी AJAX का उपयोग करता है, लेकिन यह केवल एक अनुरोध है और इस तरह से यह उपयोगकर्ता के लिए सामान्य सबमिट ऑपरेशन के रूप में दिखाई देता है। – Tor

+0

हाँ, यह निश्चित रूप से कई मामलों में एक अच्छा समाधान है। लेकिन जैसा कि सवाल उल्लेख करता है, अजाक्स के माध्यम से इसे करने का मतलब है कि आपको विशेष त्रुटि प्रबंधन की आवश्यकता है और इसी तरह। यह इस मामले में मैं नहीं था, लेकिन मैं इनपुट की सराहना करता हूं :) –

0

@pimvdb टिप्पणी के लिए धन्यवाद, मैं एक सुंदर सुरुचिपूर्ण समाधान के साथ आया था।

<input type="file" /> पर ड्रैग और ड्रॉप करने के बाद से, यह सुनिश्चित करने के लिए कि उपयोगकर्ता इसे याद नहीं कर सकता है, dragstart पर पूर्ण स्क्रीन क्यों नहीं बना रहा? वैसे भी वह खींच रहा है इसलिए इस समय उनके इरादे स्पष्ट हैं। https://jsfiddle.net/08wbo4um

एनबी::

यहाँ एक डेमो है दुर्भाग्य से इस एक iframe में काम करने के लिए नहीं लगता है, लेकिन यह एक वास्तविक पृष्ठ पर काम करता है। आप अभी भी व्यवहार को पकड़ सकते हैं।

$('input[type="file"]').on('change', function(e){ 
 
    var fileName = e.target.files[0].name; 
 
    if (fileName) { 
 
     $(e.target).parent().attr('data-message', fileName); 
 
    } 
 
    }); 
 
    
 
    $(document).on('drag dragstart dragend dragover dragenter dragleave drop', function(e) { 
 
    if ($('input[type="file"]').length) { 
 
     if (['dragover', 'dragenter'].indexOf(e.type) > -1) { 
 
     if (window.dragTimeout) 
 
      clearTimeout(window.dragTimeout); 
 
     $('body').addClass('dragged'); 
 
     } else if (['dragleave', 'drop'].indexOf(e.type) > -1) { 
 
     // Without the timeout, some dragleave events are triggered 
 
     // when the :after appears, making it blink... 
 
     window.dragTimeout = setTimeout(function() { 
 
      $('body').removeClass('dragged'); 
 
     }, 100); 
 
     } 
 
    } 
 
    });
h3, p { 
 
    text-align: center; 
 
} 
 

 
.form-group { 
 
    margin: 30px; 
 
} 
 

 
.file-upload .form-control { 
 
    height: 150px; 
 
    outline: 1px dashed #ccc; 
 
    outline-offset: -15px; 
 
    background-color: #eee; 
 
} 
 
.file-upload .form-control:before { 
 
    content: "\f093"; 
 
    font: normal normal normal 14px/1 FontAwesome; 
 
    font-size: 3em; 
 
    left: 0; 
 
    right: 0; 
 
    display: block; 
 
    margin: 20px auto; 
 
    text-align: center; 
 
} 
 
.file-upload .form-control:after { 
 
    content: attr(data-message); 
 
    left: 0; 
 
    right: 0; 
 
    bottom: 0; 
 
    text-align: center; 
 
    display: block; 
 
} 
 
.file-upload .form-control input[type="file"] { 
 
    cursor: pointer; 
 
    opacity: 0; 
 
    width: 100%; 
 
    height: 100%; 
 
    position: absolute; 
 
    top: 0; 
 
    bottom: 0; 
 
    right: 0; 
 
    left: 0; 
 
} 
 
body.dragged .file-upload .form-control input[type="file"] { 
 
    /* Make sure it is full screen, whatever the position absolute container */ 
 
    position: fixed; 
 
    top: -50vh; 
 
    bottom: -50vh; 
 
    left: -50vw; 
 
    right: -50vw; 
 
    height: 200vh; 
 
    width: 200vw; 
 
    z-index: 10002; 
 
} 
 

 
body:after { 
 
    content: 'You can drop the file. :-)'; 
 
    font-size: 2em; 
 
    text-align: center; 
 
    line-height: 100vh; 
 
    position: absolute; 
 
    top: 10px; 
 
    bottom: 10px; 
 
    left: 10px; 
 
    right: 10px; 
 
    background-color: #eee; 
 
    z-index: 10000; 
 
    border-radius: 4px; 
 
    border: thin solid #ccc; 
 
    visibility: hidden; 
 
    opacity: 0; 
 
    transition: visibility 0s, opacity 0.5s ease; 
 
} 
 

 
body.dragged:after { 
 
    opacity: 1; 
 
    visibility: visible; 
 
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> 
 
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> 
 

 
<h3>Drag N Drop file upload without AJAX Demo</h3> 
 
<p>Try drag and dropping a file. :-)</p> 
 

 
<div class="form-group file-upload" required="required"> 
 
    <label class="cols-sm-2 control-label" for="document_file">File Upload</label><br> 
 
    <div class="cols-sm-10"> 
 
     <div class="input-group"> 
 
     <span class="input-group-addon"><i class="fa fa-file" aria-hidden="true"></i></span> 
 
     <div class="form-control" data-message="Click to select file or drag n drop it here"> 
 
      <input required="required" title="Click to select file or drag n drop it here" type="file" name="document[file]" id="document_file"> 
 
     </div> 
 
     </div> 
 
    </div> 
 
    </div>

संबंधित मुद्दे