Я пытаюсь создать пользовательский интерфейс, в котором есть форма с парой текстовых полей, input type="file"
и div
, в которые вы можете добавлять изображения для загрузки вместе с остальной частью формы.
Моя цель / логика
используйте тот же div
, чтобы перетащить изображение или щелкнуть по нему и открыть проводник папок, как ведет себя input type="file"
. Включение щелчка имеет смысл на маленьких экранах, где «перетаскивать» практически невозможно. И поскольку в форме уже есть input type="file"
, нет причин брать изображение из div
и добавлять его в форму и т.д. и т.д. Я пытаюсь взять изображение, которое было сброшено в div
, установить его как значение в input type="file"
и отправьте форму один раз. (если пользователь щелкнул div
, то input type="file"
уже имеет значение, поэтому я снова могу отправить форму снова).
Вот код
<div id="imageDrop" (click)='imageInput.click()' (drop)="drop($event)" (dragover)="allowDrop($event)" #imageDrop>
</div>
<input type="file" formControlName="imageInput" required #imageInput id="imageInput" (change)='imageChange($event)' > <!-- use css to hide it -->
Итак, когда нажимается imageDrop
, фактически вызывается imageChange
через (click)='imageInput.click()'
Это машинописный текст в компоненте.
//imageUpload is the name of the reactive form
acceptedImageTypes = {'image/png': true,'image/jpeg': true,'image/gif': true};
@ViewChild('imageDrop') imageDrop;
allowDrop(e) {
e.preventDefault();
}
drop(e) {
e.preventDefault();
//clear in case we selected something before via click
this.imageUpload.controls.imageInput.reset();
this.imageDrop.innerHTML="";
this.checkfiles(e.dataTransfer.files);
}
imageChange(event){
this.imageDrop.innerHTML="";
this.checkfiles(event.target.files);
}//imageChange
checkfiles(files){
if (this.acceptedImageTypes[files[0].type] !== true){
this.imageDrop.nativeElement.innerHTML="Not an image";
return;
}
else if (files.length>1){
this.imageDrop.nativeElement.innerHTML="Only one image/time";
return;
}
else { this.readfiles(files); }
}//checkfiles
readfiles(files){
const reader = new FileReader();
let image = new Image();
reader.onload = (event) =>{
this.imageDrop.nativeElement.innerHTML="";
let fileReader = event.target as FileReader;
image.src = fileReader.result;
image.width = 150;
this.imageDrop.nativeElement.appendChild(image);
};
reader.readAsDataURL(files[0]);
if (this.imageUpload.controls.imageInput.value==null) {
//if its null then means that we dragging an img, so the previous image from the input file is deleted
//now we got to put this image to the input file in order to submit the form
this.imageUpload.controls.imageInput.reset(files[0] );
}
}//readfiles
imageUploadSubmitted(){
//when form submit, for now just check image value to check if its the right one
console.log('IMAGE VALUE SUBMIT = = ',this.imageUpload.controls.imageInput.value);
}
Ошибки
Когда я пытаюсь перетащить изображение, я получаю ERROR DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string
, который указывает на эту строку HTML <div id="imageDrop" (click)='imageInput.click()' (drop)="drop($event)" (dragover)="allowDrop($event)" #imageDrop>
, но я уверен, что это связано с
if (this.imageUpload.controls.imageInput.value==null) {
this.imageUpload.controls.imageInput.reset(files[0] );
}
часть функции readfiles
.
Есть идеи, как это исправить, чтобы входной файл мог получить значение, а затем можно было отправить форму?
Спасибо
imageInput
? Но я хочу, чтобы изображение было ценностью. - person codebot   schedule 15.09.2018this.imageUpload.controls.imageInput.reset(files[0] );
наthis.imageUpload.controls.imageInput.setValue(files[0]);
.setValue
здесь имеет больше смысла. Я пытаюсь исправить это, и когда я создам stackblitz, я дам вам знать. - person codebot   schedule 15.09.2018Template parse errors
, но, по крайней мере, это весь код, и это дает мне проблему. Спасибо еще раз - person codebot   schedule 15.09.2018