web-dev-qa-db-fra.com

Comment détecter le type d'entrée = fichier "changer" pour le même fichier?

Je veux déclencher un événement lorsque l'utilisateur sélectionne un fichier. Cela avec l'événement .change cela fonctionne si l'utilisateur modifie le fichier à chaque fois.

Mais je veux déclencher l'événement si l'utilisateur sélectionne à nouveau le même fichier.

  1. Fichier de sélection d'utilisateur A.jpg (événement déclenché)
  2. Fichier de sélection d'utilisateur B.jpg (événement déclenché)
  3. Fichier de sélection d'utilisateur B.jpg (l'événement ne se déclenche pas, je veux qu'il se déclenche)

Comment puis-je le faire?

77
Gadonski

Vous pouvez tromper. Supprimez l'élément de fichier et ajoutez-le au même endroit sur l'événement change. Il effacera le chemin du fichier en le rendant modifiable à chaque fois.

Exemple sur jsFiddle.

Ou vous pouvez simplement utiliser .prop("value", ""), voir cet exemple sur jsFiddle .

  • jQuery 1.6+ prop
  • Anciennes versions attr
58
BrunoLM

Si vous avez essayé .attr("value", "") et que cela n'a pas fonctionné, ne paniquez pas (comme je l'ai fait)

il suffit de faire .val("") à la place et cela fonctionnera bien

61
Wagner Leonardi

Pour que cela fonctionne, effacez la valeur d'entrée du fichier onClick, puis publiez le fichier onChange. Cela permet à l'utilisateur de sélectionner le même fichier deux fois de suite tout en laissant le changement d'événement déclencher pour qu'il soit publié sur le serveur. Mon exemple utilise le le plugin de formulaire jQuery .

$('input[type=file]').click(function(){
    $(this).attr("value", "");
})  
$('input[type=file]').change(function(){
    $('#my-form').ajaxSubmit(options);      
})
14
braitsch

Vous pouvez simplement définir sur null le chemin du fichier chaque fois que l'utilisateur clique sur le contrôle. Maintenant, même si l'utilisateur sélectionne le même fichier, l'événement onchange sera déclenché.

<input id="file" onchange="file_changed(this)" onclick="this.value=null;" type="file" accept="*/*" />
11
Mariusz Wiazowski

Ce travail pour moi

<input type="file" onchange="function();this.value=null;return false;">
6
user2678106

Utilisez l'événement onClick pour effacer la valeur de l'entrée cible, chaque fois que l'utilisateur clique sur un champ. Cela garantit que l'événement onChange sera également déclenché pour le même fichier. Travaillé pour moi :) 

onInputClick = (event) => {
    event.target.value = ''
}

<input type="file" onChange={onFileChanged} onClick={onInputClick} />

Utiliser TypeScript

onInputClick = ( event: React.MouseEvent<HTMLInputElement, MouseEvent>) => {
    const element = event.target as HTMLInputElement
    element.value = ''
}
2
Trafalgar Law

Par défaut, la propriété value de l'élément input est effacée après la sélection des fichiers si l'entrée a plusieurs attributs. Si vous ne nettoyez pas cette propriété, l'événement "change" ne sera pas déclenché si vous sélectionnez le même fichier. Vous pouvez gérer ce problème en utilisant l'attribut multiple.

<!-- will be cleared -->
<input type="file" onchange="yourFunction()" multiple/>
<!-- won't be cleared -->
<input type="file" onchange="yourFunction()"/>

Référence

2
Pulkit Aggarwal

Inspirant de @braitsch J'ai utilisé ce qui suit dans mon AngularJS2 input-file-component

<input id="file" onclick="onClick($event) onchange="onChange($event)" type="file" accept="*/*" />

export class InputFile {

    @Input()
    file:File|Blob;

    @Output()
    fileChange = new EventEmitter();

    onClick(event) {
        event.target.value=''
    }
    onChange(e){
        let files  = e.target.files;
        if(files.length){
            this.file = files[0];
        }
        else { this.file = null}
        this.fileChange.emit(this.file);
    }
}

Ici la onClick(event) m'a sauvé :-)

1
MKJ

Si vous ne voulez pas utiliser jQuery

<form enctype='multipart/form-data'>
    <input onchange="alert(this.value); return false;" type='file'>
    <br>
    <input type='submit' value='Upload'>
</form>

Cela fonctionne bien dans Firefox, mais pour Chrome, vous devez ajouter this.value=null; après alerte.

1
elshnkhll

La chose la plus simple que vous puissiez faire est probablement de définir la valeur sur une chaîne vide. Cela l'oblige à "changer" le fichier à chaque fois, même si le même fichier est sélectionné à nouveau.

<input type="file" value="" />

1
Curt

Vous ne pouvez pas déclencher change ici (comportement correct, puisque rien n'a changé). Cependant, vous pouvez aussi lier click ... bien que cela puisse déclencher aussi souvent ... il n’ya pas beaucoup de juste milieu entre les deux.

$("#fileID").bind("click change", function() {
  //do stuff
});
1
Nick Craver

J'ai rencontré le même problème, j'ai passé en revue les solutions ci-dessus, mais elles n'ont pas obtenu d'explication valable sur ce qui se passait réellement. 

Cette solution que j’ai écrite https://jsfiddle.net/r2wjp6u8/ ne fait pas beaucoup de modifications dans l’arborescence DOM, elle ne fait que modifier les valeurs du champ de saisie. Du point de vue de la performance, cela devrait être un peu mieux.

Lien vers le violon: https://jsfiddle.net/r2wjp6u8/

<button id="btnSelectFile">Upload</button>

<!-- Not displaying the Inputfield because the design changes on each browser -->
<input type="file" id="fileInput" style="display: none;">
<p>
  Current File: <span id="currentFile"></span>
</p>
<hr>
<div class="log"></div>


<script>
// Get Logging Element
var log = document.querySelector('.log');

// Load the file input element.
var inputElement = document.getElementById('fileInput');
inputElement.addEventListener('change', currentFile);

// Add Click behavior to button
document.getElementById('btnSelectFile').addEventListener('click', selectFile);

function selectFile() {
  if (inputElement.files[0]) {
    // Check how manyf iles are selected and display filename
    log.innerHTML += '<p>Total files: ' + inputElement.files.length + '</p>'
    // Reset the Input Field
    log.innerHTML += '<p>Removing file: ' + inputElement.files[0].name + '</p>'
    inputElement.value = '';
    // Check how manyf iles are selected and display filename
    log.innerHTML += '<p>Total files: ' + inputElement.files.length + '</p>'
    log.innerHTML += '<hr>'
  }

  // Once we have a clean slide, open fiel select dialog.
  inputElement.click();
};

function currentFile() {
    // If Input Element has a file
  if (inputElement.files[0]) {
    document.getElementById('currentFile').innerHTML = inputElement.files[0].name;
  }
}

</scrip>
0
Ballpin

Solution VueJs

<input
                type="file"
                style="display: none;"
                ref="fileInput"
                accept="*"
                @change="onFilePicked"
                @click="$refs.fileInput.value=null"
>
0
Micheal C Wallas

Créez pour l'entrée un événement click et un événement change. L'événement click vide l'entrée et l'événement change contient le code que vous souhaitez exécuter.

Ainsi, l'événement click sera vide lorsque vous cliquerez sur le bouton de saisie (avant que la fenêtre de sélection de fichier ne s'ouvre), c'est pourquoi l'événement de changement se déclenchera toujours lorsque vous sélectionnerez un fichier.

$("#input").click(function() {
  $("#input").val("")
});

$("#input").change(function() {
  //Your code you want to execute!
});
<input id="input" type="file">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
0
hoi ja

Vous pouvez utiliser form.reset() pour effacer la liste files de l'entrée du fichier . Cela réinitialisera tous les champs aux valeurs par défaut, mais dans de nombreux cas, vous utiliserez peut-être uniquement le type d'entrée = 'fichier' dans un formulaire pour télécharger des fichiers ..__ Dans cette solution, il n'est pas nécessaire de cloner l'élément et de raccrocher à nouveau.

Merci à philiplehmann

0
Rui Nunes

Il n’ya donc aucun moyen de s’assurer à 100% qu’ils sélectionnent le même fichier, à moins que vous stockiez chaque fichier et que vous les compariez par programme.

La façon dont vous interagissez avec les fichiers (ce que JS fait lorsque l'utilisateur "télécharge" un fichier) est HTML5 File API and JS FileReader .

https://www.html5rocks.com/en/tutorials/file/dndfiles/

https://scotch.io/tutorials/use-the-html5-file-api-to-work-with-files-locally-in-the-browser

Ces tutoriels vous montrent comment capturer et lire les métadonnées (stockées sous forme d'objet js) lorsqu'un fichier est chargé.

Créez une fonction qui déclenche 'onChange' pour lire-> stocker-> comparer les métadonnées du fichier actuel par rapport aux fichiers précédents. Ensuite, vous pouvez déclencher votre événement lorsque le fichier souhaité est sélectionné.

0

Croyez-moi, ça va certainement vous aider!

// there I have called two `onchange event functions` due to some different scenario processing.

<input type="file" class="selectImagesHandlerDialog" 
    name="selectImagesHandlerDialog" 
    onclick="this.value=null;" accept="image/x-png,image/gif,image/jpeg" multiple 
    onchange="delegateMultipleFilesSelectionAndOpen(event); disposeMultipleFilesSelections(this);" />


// delegating multiple files select and open
var delegateMultipleFilesSelectionAndOpen = function (evt) {

  if (!evt.target.files) return;

  var selectedPhotos = evt.target.files;
  // some continuous source

};


// explicitly removing file input value memory cache
var disposeMultipleFilesSelections = function () {
  this.val = null;
};

J'espère que cela aidera beaucoup d'entre vous.

0
ArifMustafa