Javascript come vedere in anteprima le foto caricate nel input file prima di mandarle al server

Stato
Discussione chiusa ad ulteriori risposte.
Ciao;
c'è il modo di farlo: scrivi la stringa che rappresenta l'elemento e la appendi all'eventuale container.
Qui la documentazione di esempio.
 
  • Mi piace
Reazioni: coronel
Non funziona così, sarebbe una magia se ti funzionasse: il listener non viene assegnato automaticamente solo perché il contatore aumenta.
Stai facendo un errore logico abbastanza grave.
Tu stai assegnando un listener ad UN elemento (il primo), poi quando viene triggerato l'evento il contatore aumenta ma tu non stai assegnando alcun listener nuovo.
Per far sì che funzioni potresti wrappare l'assegnazione dei listener sugli elementi in una funzione che viene chiamata ogni volta che aggiungi un'immagine.
Comunque ti ripeto, guarda il codice che ho scritto per renderti conto di come fare :lol:
 
  • Mi piace
Reazioni: coronel
Continuo a non condividere questa soluzione perché è molto confusionaria e alcune cose potrebbero esser fatte in maniera più efficiente e logicamente corretta, però se per te va bene e funziona allora non ci sono problemi.

Il come mandare i file al server dipende anche dal backend ricevente, come ti ho già detto.

Puoi usare la Fetch API plain JS oppure jQuery, sta a te decidere - quanto l'invio dei file non cambia niente, devi solamente usare il Content-Type corretto.
 
  • Mi piace
Reazioni: coronel
Secondo te perche voglio mantenere il mio codice e non il tuo? Voglio imparare x questo lo faccio
Si, ma se uno scrive un codice che non funziona o che funziona per grazia del Signore....capisci bene che non stai imparando proprio nulla.
Vuoi imparare e tenere il tuo codice? Bene, cancella tutto e riscrivilo da zero.
Dopo confronta la tua soluzione con quella che ti è stata fornita da una persona più esperta di te e cerca di capire perchè lui ha fatto determinate scelte strutturali.

Ha molto più senso confrontarsi nel cercare di capire perchè Dany ha raggiunto una determinata soluzione piuttosto che continuare con qualcosa di oggettivamente sbagliato.
 
  • Grazie
Reazioni: Dany©

coronel

Utente Gold
28 Agosto 2017
455
111
32
254
vorrei poter avere un anteprima in miniatura delle foto che carico sul input file ma non trovo il modo, ho provato a recuperare il value del input file x poi inserirlo dentro un src di un anchor ma la path non e quella della foto ma una path che comincia con fakepath, e quindi non funziona, il progetto trattasi di un marketplace del usato con vari filtri, di vestiti e di scarpe, se volete continuare il progetto vi lascio qui il codice sorgente


Vedi: https://pastebin.com/6ZF0f7cJ
 
Ultima modifica:
Ciao!

HTML, div galleria e file input:
HTML:
<input type="file" name="file" id="file_input">
<div id="galleria">
    <img id="preview" src="" alt="preview" />
</div>

JavaScript, per visualizzare la preview:
JavaScript:
var imgInput = document.getElementById('file_input');
imgInput.addEventListener("change", (e) => {
  const [file] = imgInput.files
  if (file) {
    document.getElementById('preview').src = URL.createObjectURL(file);
  }
})

Puoi adattare la soluzione alle tue esigenze, come vedi la soluzione è VJS ma puoi anche decidere di usare JQuery.
scusami ma perche assegni una funzione con parametro e se gia c'e l'evento change che va parte ogni volta che premo il pulsante x caricare il file? e poi non mi e chiaro perche dichiari una variabile con le parentesi quadre tipo java var x [] = valore
tra l'altro mi hanno consigliato di usare l 'attributo multiple nel tag input file, altri di impostare un name con le [] e sono un po confuso.. aproposito quello che ecmascript e?
 
Ciao,
onestamente ho guardato la logica che avevi scritto e non mi era chiarissima, inoltre ai fini di quello che chiedevi non era rilevante, quello che ho postato riguarda solo e soltanto la preview di un'immagine caricata.

La "dichiarazione" (assegnazione) che menzioni si chiama Destructuring Assignment, ti lascio la referenza per capire meglio di cosa si tratta.

Per l'input dipende da quello che vuoi fare -- il multiple attribute ti permette di selezionare più file insieme.

In questo pezzo di codice la cosa più recente che vedi è proprio destructuring assignment che se non sbaglio è arrivato con ES6.
capisco, funziona piumeno come un array associativo php, cmq l'idea e quella di xmettere al utente di caricare piu di una foto e di poterle visualizzare in anteprima tutte quante, e il codice che mi hai suggerito ne consente solo la preview di 1 sola, cioe quando vado a caricare la seconda foto prende il posto della prima.. tra l'altro ho fatto una modifica al codice x capire meglio, in questo modo
JavaScript:
var imgInput = document.getElementById('file_input');
imgInput.addEventListener("change", function() {
  img = imgInput.files[0]
  if (img) {
    document.getElementById('preview').src = URL.createObjectURL(img);
  }

e non funziona piu, non capisco come mai
 
Ciao di nuovo,
se vuoi la preview di più immagini devi generare dinamicamente gli elementi nel DOM (a meno che non vuoi seguire un approccio statico ma questo necessita che la quantità di foto caricabili sia ben definita e sempre uguale).
L'approccio dinamico è il seguente:

HTML:
<input type="file" name="file" id="file_input" multiple>
<div id="gallery">
 
</div>

Nota bene: adesso non devi più destrutturare l'array di file in quanto lo stai già traversando con un ciclo!

JavaScript:
var fileInput = document.getElementById('file_input');
fileInput.addEventListener("change", () => {
   for(let file of fileInput.files) {
      const image = file;
      if (image) {
         var imageElement = new Image();
         imageElement.src = URL.createObjectURL(image);
         document.getElementById('gallery').appendChild(imageElement);
      }
   }
});



Vedi: https://jsfiddle.net/DanieleFI/gxq9nkuy/21/



Il codice che hai postato non funziona perché se fa riferimento all'HTML che avevi non hai alcun elemento img con id "preview" a cui settare il source dell'immagine.

sbagli. si che ce l lemento img con id preview, te lo riposto di nuovo e ti linko tutto a codepen alla fine
HTML:
<input type="file" name="file" id="file_input" multiple>
<div id="galleria">
    <img id="preview" src="" alt="preview" width=100 />
</div>

JavaScript:
var imgInput = document.getElementById('file_input');
imgInput.addEventListener("change", function() {
  img = imgInput.files[0]
  if (img) {
    document.getElementById('preview').src = URL.createObjectURL(img);
  }
})


Vedi: https://codepen.io/prosteven/pen/oNeQbgM?editors=1010

cmq ho riprovato ora e adesso funziona il mio codice modificato, cmq non ho capito perche dichiari la var image come const ..
 
nb. ho editato la mia risposta, avevo copiato il tuo codice e ho lasciato qualche typo.

Ho fatto riferimento all'HTML che hai postato nel primo messaggio della discussione, che non aveva alcun tag image con id preview, e l'unica spiegazione per il quale potesse darti errore era che non avessi quell'elemento (ndr., non hai postato HTML nella domanda prima della mia risposta), ergo la mia risposta :D

https://www.freecodecamp.org/news/var-let-and-const-whats-the-difference/ per capire perché usare const e let invece di var.

p.s. ovviamente per far funzionare la preview multipla devi generarti gli elementi della galleria dinamicamente, traversando l'array di FileInput.
ho fatto alcune modifiche e ha funzionato, ti lascio il risultato1

Vedi: https://codepen.io/prosteven/pen/oNeQbgM
cmq ora vorrei avere la possibilita tramite un button di rimuovere le foto che voglio che avevo caricato, .. come potrei fare secondo te? visto che e tutto generato in modo dinamico risulta piu complicato
 
Da quanto so FileList è readonly e non c'è modo di modificarne il contenuto.
Per modificare (ndr. rimuovere elementi) dall'input hai necessità di customizzare la gestione delle immagini stesse.
E' un po' tedioso e richiede un po' di tempo, puoi provare a fare qualche ricerca e trovare una soluzione che ti si addice (ricerca).
Rimuovere le preview dal DOM invece è semplice, però non penso ti sia utile visto che comunque rimarrebbero nella coda dell'input.
 
Da quanto so FileList è readonly e non c'è modo di modificarne il contenuto.
Per modificare (ndr. rimuovere elementi) dall'input hai necessità di customizzare la gestione delle immagini stesse.
E' un po' tedioso e richiede un po' di tempo, puoi provare a fare qualche ricerca e trovare una soluzione che ti si addice (ricerca).
Rimuovere le preview dal DOM invece è semplice, però non penso ti sia utile visto che comunque rimarrebbero nella coda dell'input.
In che senso nella coda del input scusa? Io voglio qualcosa tipo kijiji se hai presente che quando vai a mettere in vendita qualcosa nella sezione di foto ti fa aggiungere foto e rimioverle
 
Nel senso che i file presenti nella FileList, che è l'oggetto che viene usato dalle input (type="file"), non è modificabile.
Quindi, nel momento in cui tu aggiungi dei file, non hai modo di cambiarne solo alcuni - infatti se provi a caricare dei nuovi file quelli precedenti verranno sovrascritti.
Ciò non toglie che puoi provare a crearti il tuo oggetto con il quale gestirti le immagini caricate e renderlo accessibile, oppure puoi appoggiarti a soluzioni alternative già postate - che ignoro - ma sulle quali puoi fare un po' di ricerca!
Sono abbastanza sicuro che gli sviluppatori di Kijiji abbiano customizzato i loro input delle immagini affinché l'utente potesse avere pieno controllo su di esse :)
 
Nel senso che i file presenti nella FileList, che è l'oggetto che viene usato dalle input (type="file"), non è modificabile.
Quindi, nel momento in cui tu aggiungi dei file, non hai modo di cambiarne solo alcuni - infatti se provi a caricare dei nuovi file quelli precedenti verranno sovrascritti.
Ciò non toglie che puoi provare a crearti il tuo oggetto con il quale gestirti le immagini caricate e renderlo accessibile, oppure puoi appoggiarti a soluzioni alternative già postate - che ignoro - ma sulle quali puoi fare un po' di ricerca!
Sono abbastanza sicuro che gli sviluppatori di Kijiji abbiano customizzato i loro input delle immagini affinché l'utente potesse avere pieno controllo su di esse :)
..cmq guarda io l.ho altro giorno ho usato il metodo files del input file e questo metodo è una specie di array , quindi io riesco ad accedere a tutte le foto che avevo caricato su questo input file, poi non saprei, dovrei riprovare x rivedere
 
Ciao, mi dispiace ma anche se volessi non ne avrei fisicamente il tempo!
Posso però continuare a darti delle dritte qui su inforge come per il discorso delle preview, la cosa che comunque (vi) ti consiglio è provare, provare e riprovare, sbattere la testa su queste cose e soprattutto fare ricerca riguardo tutto ciò che non ti è chiaro e cercare di imparare le cose che (per ora) non sai! :)
scusa sapresti dirmi come mai il listener che ho assegnato a tutte le img non va?

Vedi: https://codepen.io/prosteven/pen/oNeQbgM
 
Ciao,
ti consiglio di pulire un po' il codice perché è difficile da leggere ed interpretare al volo :)

Comunque, a quale event listener ti stai riferendo?

JavaScript:
$("img").click(function() {
    console.log(4);
})

Questo?

P.S. Ti chiedo inoltre di usare JSFiddle, è più comodo visto che stai usando jQuery, perché permette l'import diretto della libreria!
Si mi riferivo a quel listener, e vabene userp jsfiddle
 
Ultima modifica:
Danyyy brooo, nn mi abbandonare ^_^, hai visto che non va il mio codice? Cmq riguarda a js fiddle e codepen, sappi che anche su codepen si può importare la libreria di jqiery
Stai usando la versione corretta di JQuery?
Se usi vanilla js (ndr. addEventListener) ti funziona?
Non credo che il problema sia dovuto alla versione di jquery visto che senza quei menuselect funziona il listener dei IMG... Proverò a farlo con vjs ma nn credo cambi il risultato
Messaggio unito automaticamente:

guarda, stesso risultato con vjs

Vedi: https://codepen.io/prosteven/pen/mdMvMYg?editors=1011

Messaggio unito automaticamente:

Dani scusa il disturbo, 6 riuscito a identificare il problema? Io x piu ch3 ci provo.nn riesco
Messaggio unito automaticamente:

@Dany© fammi sapere x favore
Messaggio unito automaticamente:

sn riuscito a risolvere il problema col listener delle img, ora ho un altro problema sempre col listener di imageelement2 e questa volta mi segnala errore di syntax ma e tutto scritto bene, dagli un occhiata xfav

Vedi: https://codepen.io/prosteven/pen/mdMvMYg?editors=0010
 
Ciao,
come ti ho anticipato non ho fisicamente il tempo per seguire il progetto, posso risponderti quando ho un attimo libero :)

Il problema è qui:
JavaScript:
imageElement2.css("transform":"rotate(-90)");
Ti consiglio di leggere le docs della funzione css() di jQuery per capire meglio come funziona.

La soluzione (tenendo per filo e per segno ciò che stai cercando di fare tu) è questa:
JavaScript:
$(imageElement2).on('click', function() {
    $(imageElement2).css({ WebkitTransform: 'rotate(-90deg)'});
});

Comunque, ci sono diversi problemi e ti invito (consiglio) a rifletterci:
  • Il codice è confuso e alla lunga ti renderai conto che non è mantenibile - è fondamentale, per il proseguo del progetto, che tu riesca a pulirlo e cercare di seguire uno standard (ndr. il prossimo punto parla di questo);
  • Stai facendo un po' di confusione nell'utilizzo di jQuery (ti consiglio di guardare attentamente le docs per capire in principio come si usa jQuery e fare più attenzione all'utilizzo delle sue funzioni) e VanillaJS - ricordati che non puoi utilizzare jQuery su elementi VJS (o almeno, non direttamente), questo era un altro problema nel codice - è giusto usare jQuery over Vanilla ove serve, però se decidi di standardizzare il progetto con l'utilizzo di jQuery devi anche mantenerne la logica.
Ti chiedo nuovamente di usare JSFiddle, è molto, molto, molto più facile consultare il codice e debuggarlo per chi ti aiuta :D
io uso firefox, cmq nn va neanche su jsfiddle, la foto non si gira


Vedi: https://jsfiddle.net/soyrhc8p/
 
Non funziona perché, come ti ho menzionato nel punto due dei problemi, dovresti studiarti un po' come funziona jQuery in modo da avere una visione più completa e sicura della tecnologia, stai facendo confusione con gli elementi VJS e jQuery - utilizzando funzioni dell'ultimo su elementi del primo - e questa cosa fa sì che il codice ritorni errori di sintassi e/o semplicemente non funzioni.
 
Ultima modifica:
Non funziona perché, come ti ho menzionato nel punto due dei problemi, dovresti studiarti un po' come funziona jQuery in modo da avere una visione più completa e sicura della tecnologia, stai facendo confusione con gli elementi VJS e jQuery - utilizzando funzioni dell'ultimo su elementi del primo - e questa cosa fa sì che il codice ritorni errori di sintassi e/o semplicemente non funzioni.
fammi capi se ho capito bene, il problema e dovuto perche uso funzioni di jquery su elementi vjs? cmq il metodo click e il on sono entrambi metodi di jquery
Messaggio unito automaticamente:

se fossi stato un po piu speficifico e mi avresti detto che i metodi jquery non funzionano su variabili normali e che bisognava selezionarli prima, magari avrei capito subito, mi e nuova questa cosa, perche di solito jquery li uso con i tag html e non con le variabili, che contengono tag html, suona confuso lo so, ma non pensavo che la funziona di selezione $() fosse applicata anche x le variabili, cmq penso che se avrei dichiarato la variabile imageelement in questo modo $imageElement nn avrei dovuto usare la funziona selezione, ma vabbe, in ogni caso, ora c'e u nuovo problema aha , la foto si gira solo 1 volta



Vedi: https://jsfiddle.net/soyrhc8p/1/
 
La foto si gira una sola volta perché la rotazione non è cumulativa ma una direttiva fissa.
Quando tu dici rotate(-90deg) setti la rotazione a -90° rispetto alla posizione iniziale.
Per farmi capire in modo semplice:
  • Clicco sull'icona per ruotare -> setto la rotazione a -90deg e ruota l'immagine;
  • Clicco nuovamente sull'icona per ruotare -> setto nuovamente la rotazione a -90deg, ma questa non va a ruotare rispetto alla rotazione attuale ma rispetto alla posizione iniziale, quindi la posizione rimane invariata.
Per far sì che la rotazione sia continuativa devi tener conto della rotazione attuale con una variabile.
Ti mockuppo una logica ma non ho possibilità di scriverla rispetto al tuo codice al momento.

JavaScript:
let rotation = 0;
// ...
// quando clicco sull'icona per ruotare, decremento la rotazione di 90°
rotation -= 90;
$(element).css('transform', `rotate(${rotation}deg)`)

Prova a partire da questo ed adattarlo alla tua necessità.

P.S. Specificità a parte, è importante che tu conosca bene le librerie che usi! Preferisco indicarti di guardare le docs piuttosto che dirti esattamente la risposta, altrimenti non imparerai niente, considerando che stai cercando di fare un progetto immagino che sia interessato a questi argomenti :)
ho capito ma non va cmq

Vedi: https://jsfiddle.net/soyrhc8p/3/
 
Stato
Discussione chiusa ad ulteriori risposte.