Usuwanie załączników do uploadowania.

Usuwanie załączników do uploadowania.
tymek42
  • Rejestracja:około 11 lat
  • Ostatnio:9 miesięcy
  • Postów:181
0

Sprawa jak w temacie. Potrzebuje mieć uploader który potrafiłby usunąć załączoną jakby informację o pliku który ma być dopiero uploadowany.

serek
  • Rejestracja:około 11 lat
  • Ostatnio:około 3 godziny
  • Postów:1475
1
tymek42
No mniej więcej coś takiego. A może wiesz jak to zrobić "ręcznie" co trzeba zrobić by uruchomić usuwanie takich informacji? ;) Chodzi mi o to że jestem po prostu ciekawy co odpowiada za to. Kurcze, człowiek cuda robi w ajaxie, a nie wiem jak cos samemu takie zrobić.
serek
Nie wiem, czy jest sens wymyślać koło na nowo, skoro są gotowe pluginy
tymek42
No ok. W sieci nie mogłem nic znaleźć na ten temat aż byłem zaskoczony.
serek
Jak chcesz wiedzieć w jaki sposób to zrobić, to po prostu przeanalizuj sobie kod tych powyższych pluginów
tymek42
Nie mam wyjścia cos widzę
Freja Draco
Freja Draco
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:3394
0

Znaczy chodzi ci o ten przycisk "cancel"?
Ze względów bezpieczeństwa JS nie bardzo może manipulować na <input type="file">, ale może już wydobyć z niego informację, a później skopiować ją do innego pola. A z tym innym polem możesz już sobie robić co chcesz, a później przy próbie wysłania odpalasz skrypt, który sprawdza jego zawartość i zależnie od stanu, wysyła lub nie wysyła.


edytowany 1x, ostatnio: Freja Draco
tymek42
I wlaśnei chodzi o te wysylanie lub nie wysyłanie jak to zatrzymać? Co jest odpowieddzialne w kodzie za to że jak to usune to uploader tego nie wyśle!
Freja Draco
Freja Draco
Patrz: onsubmit: return false; / retrun: true; https://stackoverflow.com/questions/35037069/what-is-the-meaning-of-onsubmit-return-false-javascript-jquery (return: true chyba można pominąć).
tymek42
No dobra, ale tutaj jest to dla całego formularza, a co wtedy kiedy chcemy wysłac kilka plików i tylko jeden usunąc? Masz jakis pomysł?
Freja Draco
Freja Draco
Tego się prawdopodobnie nie da zrobić. Wątpię, żeby JS pozwolił ci manipulować przy liście wczytywanych plików.
DE
  • Rejestracja:ponad 9 lat
  • Ostatnio:12 miesięcy
  • Postów:1788
1
tymek42
No ok, widzę jak się dostać do informacji o wysyłanym pliku, ale jaką funkcją badź co trzeba zrobić by usunac np files[1]?
DE
  • Rejestracja:ponad 9 lat
  • Ostatnio:12 miesięcy
  • Postów:1788
0

@tymek42: odpowiadaj w postach na temat.

Twoja tablica files, to nic innego, jak wartość pola zawierającego pliki. No, może nie do końca wartość. Pole <input type="file" multiple> ma właściwość files. Ta właściwość, to obiekt FileList. Niestety póki co jest on readonly, więc nie możesz usunąć tego pliku. Można to obejść robiąc coś takiego jak poniżej. Czyli sam zarządzasz tablicą plików, a przy wysyłaniu na serwer manualnie ją składasz, a nie używasz wartości pola do uploadowania plików.

JSFiddle

Kopiuj
class Uploader {
  constructor(config) {
    this.url = config.url;
    this.filesContainer = config.filesContainer;
    this.uploader = config.uploader;
    this.previewTemplate = config.previewTemplate;

    this.files = [];

    this.handleUpload = this.handleUpload.bind(this);
    this.handleRemove = this.handleRemove.bind(this);

    this.bindEvents();
  }

  bindEvents() {
    this.uploader.addEventListener('change', this.handleUpload);
  }

  handleUpload(e) {
    this.files = [...this.uploader.files];
    this.renderFiles();
  }

  handleRemove(e, file) {
    this.files = this.files.filter(f => f !== file);
    this.renderFiles();
  }

  renderFiles() {
    this.filesContainer.querySelectorAll('img')
      .forEach(node => node.remove());

    this.files
      .map(file => this.previewTemplate(this, file))
      .forEach(file => this.filesContainer.appendChild(file));
  }

  upload() {
    const body = new FormData();

    this.files.forEach(file => body.append('files[]', file));

    return fetch(this.url, {
      body: body,
      method: 'post',
    });
  }
}

const form = document.querySelector('form');
const uploader = new Uploader({
  url: form.action,
  filesContainer: document.querySelector('#files-container'),
  uploader: document.querySelector('#uploader'),
  previewTemplate: (uploader, file) => {
    const preview = document.createElement('img');
    preview.addEventListener('click', e => uploader.handleRemove(e, file));

    const reader = new FileReader();
    reader.onload = () => preview.src = reader.result;
    reader.readAsDataURL(file);

    return preview;
  }
});

form.addEventListener('submit', e => {
  e.preventDefault();

  uploader.upload().then(resp => resp.json()).then(resp => console.log(resp));
});
edytowany 1x, ostatnio: Desu
Freja Draco
Freja Draco
Możesz to jakoś opisać? Nic z tego nie ogarniam co toto tu robi.
DE
  • Rejestracja:ponad 9 lat
  • Ostatnio:12 miesięcy
  • Postów:1788
1

@Freja Draco: Pooooosty!

  1. Używamy zwykłego pola, które pozwala nam załadować pliki. Wpinamy się w zdarzenie change i dzięki temu mamy dostęp do plików, które załadował użytkownik.
  2. Ponieważ pobrana tablica plików jest tylko do odczytu, a my chcemy móc usuwać coś z niej, to pliki przetrzymujemy we własnej tablicy.
Kopiuj
this.files = [...this.uploader.files];
  1. Teraz możemy dowolnie dodawać i usuwać elementy z tej tablicy. Ale do usuwania potrzebujemy jakiegoś mechanizmu. Musimy najpierw te pliki wyświetlić. Do tego używamy funkcji renderFiles. Ona używa funkcji dostarczonej przez klienta naszej klasy, do stworzenia elementów previewTemplate, co daje nam większą reużywalność, bo każdy może sobie wyświetlić plik do podglądu tak jak mu się będzie podobało.
  2. Wewnątrz previewTemplate nie ma żadnej magii. Tak po prostu ładuje się plik, żeby go wyświetlić.
  3. W tej samej funkcji previewTemplate dodajemy zdarzenie click, na którym to usuwamy nasz kliknięty plik z tablicy files. Do tego używamy API dostarczonego przez naszą klasę Uploader.
  4. Jeżeli chcemy wysłać pliki na serwer, to wywołujemy kolejną funkcję z naszego API, jakie dostarcza nam klasa Uploader. Wewnątrz funkcji upload też nie ma żadnej magii. Po prostu używamy FormData, pakujemy pliki do środka i wysyłamy na serwer.
edytowany 1x, ostatnio: Desu
Freja Draco
Freja Draco
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:3394
0

@Desu: Dobra, to może inaczej. Pomijając szczegóły skryptów, skupmy się na efekcie.

Potrafię sobie wyobrazić sytuację, w której:

  • tworzymy kopię oryginalnej tablicy plików,
  • modyfikujemy ją i ładujemy do kolejnego pola formularza,
  • formularzem przesyłamy `wszystkie' pierwotnie zaznaczone pliki, ale zmodyfikowana tablica plików mówi serwerowi, które z nich ma obsłużyć i załadować, a które zignorować.
    I zakładam, że tak właśnie działa powyższy skrypt.

Czy też może jest jednak jakaś metoda na usunięcie plików z formularza jeszcze przed wysłaniem i w efekcie nieprzesyłanie ich?


DE
  • Rejestracja:ponad 9 lat
  • Ostatnio:12 miesięcy
  • Postów:1788
1

Przesyłasz tylko pliki, które masz w swojej tablicy. Pliki z pola, którego używasz do załadowania plików ignorujesz. Jeżeli używasz mojej metody, czyli ajax, to nie musisz nic z nimi robić. Na serwer pójdą tylko pliki z Twojej tablicy, z której możesz dowolnie usuwać. Jeżeli wysyłasz formularz normalnie, to pole do załadowania plików możesz albo usunąć, albo umieścić je poza formularzem, co spowoduje, ze załadowane pierwotnie pliki w ogóle nie zostaną wysłane. Innej metody nie ma, ponieważ nie możesz zmodyfikować zawartości pola do załadowania plików, trzeba kombinować. Jedyny znany mi sposób, to ten który przedstawiłem. Tak działają wszystkie biblioteki do uploadowania plików, ja stworzyłem minimum konieczne, bez wodotrysków, żebyś zobaczył jak to działa pod spodem.

edytowany 3x, ostatnio: Desu
Freja Draco
Freja Draco
@Desu - ok, dzięki :) Przeanalizuję to kiedyś na spokojnie.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.