2016-01-11 17 views
16

Iam napisanie skryptu, który przesłane pliki za pomocą metody przeciągnij i upuść przy użyciu jQuery, który odczytuje plik na spadku i dodaje go do tablicy plików tak:

var files = []; 

$(document).ready(function() { 
    jQuery.fn.dropbox = function(config) { 
     var dragging = 0; 
     var dragEnter = function(e) { 
      e.stopPropagation(); 
      e.preventDefault(); 
      dragging++; 
      $(".external-drop-indicator").fadeIn(); 
      $(".toast.toast-success").fadeIn().css("display", "inline-block");; 
      return false; 
     }; 
     var dragOver = function(e) { 
      e.stopPropagation(); 
      e.preventDefault(); 
      return false; 
     }; 
     var dragLeave = function(e) { 
      e.stopPropagation(); 
      e.preventDefault(); 
      dragging--; 
      if(dragging === 0) { 
       $(".external-drop-indicator").fadeOut(); 
       $(".toast.toast-success").fadeOut(); 
      } 
      return false; 
     }; 
     var drop = function(e) { 
      var dt = e.dataTransfer; 
      var files_upload = dt.files; 

      e.stopPropagation(); 
      e.preventDefault(); 

      if(files_upload && files_upload.length > 0 && config.onDrop !== undefined) { 
       files.push(files_upload); 
       config.onDrop(files_upload); 
      } 

      $(".external-drop-indicator").fadeOut(); 
      $(".toast.toast-success").fadeOut(); 

     }; 
     var applyDropbox = function(dropbox) { 
      dropbox.addEventListener('dragenter', dragEnter, false); 
      dropbox.addEventListener('dragover', dragOver, false); 
      dropbox.addEventListener('dragleave', dragLeave, false); 
      dropbox.addEventListener('drop', drop, false); 
     }; 
     return this.each(function() { 
      applyDropbox(this); 
     }); 
    }; 
}); 

Podsumowując, co robi, dodaje rozszerzoną funkcję jQuery, aby umożliwić przeciąganie i upuszczanie na określonym elemencie strony internetowej, w której funkcja jest stosowana.

Potem zastosować rozszerzoną funkcjonalność do ciała na to, aby umożliwić Przeciągnij plik i upuść tak:

$(document).ready(function() { 
    $('body').dropbox({ 
     onDrop: function(f) { 
      $(f).each(function(idx, data) { 
       var file_name = data.name; 
       var extension = file_name.split('.'); 
       file_name = extension[0]; 
       extension = extension[1]; 
       if(extension == 'pdf' || extension == 'xls') { 
        showAjaxModal(base_url + 'index.php?modal/popup/file_create/' + folder_id + '/' + extension + '/' + file_name); 
       } else { 
        $(".upload-area").append('<div class="alert alert-danger" style="display:inline-block;width:480px;"><strong>Error!</strong> File type is incorrect.</div>'); 
       } 
      }); 
     } 
    }); 
}); 

Podsumowując co to robi to dodaje przeciągnij i upuść do ciała i kiedy po usunięciu pliku wykrywa rozszerzenie pliku, dzieląc nazwę i rozszerzenie, dzięki czemu mogę sprawdzić, czy rozszerzenie usuniętego pliku jest poprawne. Następnie pokazuje modalny sposób wypełniania informacji o pliku, który jest przesyłany do późniejszego przesyłania, jeśli rozszerzenie pliku jest poprawne.

Potem przystąpić do wypełnienia informacji o pliku przy użyciu funkcji CodeIgniter za „form_open()”, gdy modalne wyskakuje tak:

<?php echo form_open(base_url() . 'index.php?client/file/create/' . $param2, array('class' => 'form-horizontal form-groups-bordered validate ajax-upload', 'enctype' => 'multipart/form-data')); ?> 

    <div class="col-md-4 file-info"> 
     <div class="icon-<?=($param3 == 'pdf' ? 'pdf' : 'document')?>"></div> 
     <p> 
      <?php echo $param4;?> 
     </p> 
    </div> 

    <div class="col-md-8 new-file"> 

     <div class="form-group"> 
      <div class="col-sm-12"> 
       <div class="input-group"> 
        <input type="text" class="form-control" name="tags" data-validate="required" data-message-required="Field is required" placeholder="File tags" value="" autofocus> 
       </div> 
      </div> 
     </div> 

     <div class="form-group"> 
      <div class="col-sm-12"> 
       <div class="input-group"> 
        <input type="text" class="form-control" name="name" data-validate="required" data-message-required="Field is required" placeholder="File name" value="" autofocus> 
       </div> 
      </div> 
     </div> 

     <div class="form-group"> 
      <div class="col-sm-12"> 
       <div class="input-group"> 
        <textarea rows="5" class="form-control" name="description" data-validate="required" data-message-required="Field is required" placeholder="File description" value="" autofocus></textarea> 
       </div> 
      </div> 
     </div> 

    </div> 

    <div class="form-group"> 
     <div class="col-sm-offset-4 col-sm-7"> 
      <button type="submit" class="btn btn-info" id="submit-button">Upload</button> 
      <span id="preloader-form"></span> 
     </div> 
    </div> 

<?php echo form_close(); ?> 

To w zasadzie tworzy postać, która później zostanie przekazany za pośrednictwem Ajax.

Teraz przejdę do obsługi przedłożenia pliku za pomocą jQuery do informacji przekazywanych z pliku lub plikach, które są wrzucone tak:

$(document).ready(function(e) { 
    $('.ajax-upload').submit(function(e) { 
     e.preventDefault(); 

     var $elm = $(this); 

     var fd = new FormData(); 

     for(var i = 0; i < files.length; i++) { 
      fd.append("file_" + i, files[i]); 
     } 

     var form_data = $(".ajax-upload").serializeArray(); 

     $.each(form_data, function(key, input) { 
      fd.append(input.name, input.value); 
     }); 

     var opts = { 
      url: $elm.attr('action'), 
      data: fd, 
      cache: false, 
      contentType: false, 
      processData: false, 
      type: 'POST', 
      beforeSend: uValidate, 
      success: showResponse 
     }; 

     if(fd.fake) { 
      opts.xhr = function() { 
       var xhr = jQuery.ajaxSettings.xhr(); 
       xhr.send = xhr.sendAsBinary; 
       return xhr; 
      } 
      opts.contentType = "multipart/form-data; boundary=" + fd.boundary; 
      opts.data = fd.toString(); 
     } 

     jQuery.ajax(opts); 

     return false; 
    }); 
}); 

Zasadniczo forma domyślna akcja jest nadpisywany i plików zostały przesłane na poprzednim fragmencie kodu, ponieważ funkcje przeciągania i upuszczania są teraz dołączane do formData, które później zostają połączone przez dane formularza, które były w formularzu, który przesyłam. Następnie dane formularza są wysyłane za pośrednictwem wywołania AJAX.

Teraz kontroler wygląda tak, że obsługuje połączenie AJAX i następnie wykonuje metodę przesyłania pliku na modelu tak:

function file($param1 = '', $param2 = '', $param3 = 0) { 
    if ($this->session->userdata('client_login') != 1) { 
     $this->session->set_userdata('last_page', current_url()); 
     redirect(base_url(), 'refresh'); 
    } 

    if ($param1 == 'create') 
     $this->crud_model->create_file($param2); 

    if ($param1 == 'edit') 
     $this->crud_model->update_file($param2); 

    if ($param1 == 'delete') 
     $this->crud_model->delete_file($param2, $param3); 

    $page_data['page_name'] = 'files'; 
    $page_data['page_title'] = 'Files List'; 
    $page_data['folder_id'] = $param3; 
    $this->load->view('backend/index', $page_data); 
} 

Oto metoda model:

function create_file($folder_id) { 
    $data['name']   = $this->input->post('name'); 
    $data['tags']   = $this->input->post('tags'); 
    $data['description'] = $this->input->post('description'); 
    $data['type']   = 'file'; 
    $data['folder_id'] = $folder_id; 
    $data['client_id'] = $this->session->userdata('login_user_id'); 

    $config['upload_path'] = 'uploads/tmp/'; 
    $config['allowed_types'] = '*'; 
    $config['max_size'] = '100'; 

    $this->load->library('upload'); 
    $this->upload->initialize($config); 

    var_dump($_FILES); 
    die(); 

    foreach($_FILES as $field => $file) 
    { 
     //var_dump($_FILES); die();     
     // No problems with the file 
     if($file['error'] == 0) 
     { 
      // So lets upload 
      if ($this->upload->do_upload($field)) 
      { 
       $data = $this->upload->data(); 
       echo $data['full_path']; 
      } 
      else 
      { 
       $errors = $this->upload->display_errors(); 
       var_dump($errors); 
      } 
     } 
    } 

    $this->db->insert('client_files' , $data); 
} 

Tak zasadniczo chodzi o to, że tablica $ _FILES jest pusta, a plik nie zostanie przesłany.

"Wniosek Payload", patrząc na Chrome Developer Tools wygląda następująco:

------WebKitFormBoundaryvVAxgIQd6qU8BtkF 
Content-Disposition: form-data; name="file_0" 

[object FileList] 
------WebKitFormBoundaryvVAxgIQd6qU8BtkF 
Content-Disposition: form-data; name="tags" 

bsd 
------WebKitFormBoundaryvVAxgIQd6qU8BtkF 
Content-Disposition: form-data; name="name" 

asd 
------WebKitFormBoundaryvVAxgIQd6qU8BtkF 
Content-Disposition: form-data; name="description" 

asd 

i odpowiedź dostaję od var_dump() na modelu jest następująca:

array(0) { 
} 

Próbowałem rozwiązania tego pytania: Sending multipart/formdata with jQuery.ajax Ale bez powodzenia do tej pory.

Każdy pomysł na temat tego, co robię źle i jak rozwiązać ten problem? Dzięki.

+0

Wysyłasz 'base_url + 'index.php? Modal/popup/file_create /' + id_folderu + '/' + rozszerzenie + '/' + nazwa_pliku' od AJAX, ale po stronie serwera oczekuje się tylko' function create_file ($ folder_id) {'. Zobacz trasami i/lub zmień metodę CI, aby zaakceptować poprawną liczbę parametrów. – Tpojka

+0

@Tpojka Ten adres URL jest po prostu dla modalu, faktyczny 'create_file ($ folder_id) ...' zostaje wywołany po przesłaniu formularza. Nie ma to nic wspólnego z rzeczywistym przesyłaniem plików. – Joscplan

Odpowiedz

7

Problem polega na tym, że jestem wysłanie tablicę plików zamiast pojedynczych plików na wywołanie AJAX, szczególnie w tej części kodu:

for(var i = 0; i < files.length; i++) { 
    fd.append("file_" + i, files[i]); 
} 

Rozwiązaniem było dołączyć plik po pliku do formData zamiast tablicy plików, coś takiego:

for(var i = 0; i < files[0].length; i++) { 
    fd.append("file_" + i, files[i]); 
} 

to doda każdy pojedynczy plik tablicy plików zamiast tablicy z siebie pliki i to rozwiązuje problem.

Podsumowując byłem wysyłania tablicę plików zamiast pojedynczych plików, wskazówką do tego był [object FileList] że wniosek został pokazując zamiast informacji, plików, który obecnie występuje z wnioskiem takiego:

Content-Disposition: form-data; name="file"; filename="exfile.pdf" 
Content-Type: application/pdf 
Powiązane problemy