forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			85 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			85 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import BaseUIElement from "../BaseUIElement"
 | |
| import { InputElement } from "./InputElement"
 | |
| import { UIEventSource } from "../../Logic/UIEventSource"
 | |
| 
 | |
| export default class FileSelectorButton extends InputElement<FileList> {
 | |
|     private static _nextid
 | |
|     IsSelected: UIEventSource<boolean>
 | |
|     private readonly _value = new UIEventSource<FileList>(undefined)
 | |
|     private readonly _label: BaseUIElement
 | |
|     private readonly _acceptType: string
 | |
|     private readonly allowMultiple: boolean
 | |
| 
 | |
|     constructor(
 | |
|         label: BaseUIElement,
 | |
|         options?: {
 | |
|             acceptType: "image/*" | string
 | |
|             allowMultiple: true | boolean
 | |
|         }
 | |
|     ) {
 | |
|         super()
 | |
|         this._label = label
 | |
|         this._acceptType = options?.acceptType ?? "image/*"
 | |
|         this.SetClass("block cursor-pointer")
 | |
|         label.SetClass("cursor-pointer")
 | |
|         this.allowMultiple = options?.allowMultiple ?? true
 | |
|     }
 | |
| 
 | |
|     GetValue(): UIEventSource<FileList> {
 | |
|         return this._value
 | |
|     }
 | |
| 
 | |
|     IsValid(t: FileList): boolean {
 | |
|         return true
 | |
|     }
 | |
| 
 | |
|     protected InnerConstructElement(): HTMLElement {
 | |
|         const self = this
 | |
|         const el = document.createElement("form")
 | |
|         const label = document.createElement("label")
 | |
|         label.appendChild(this._label.ConstructElement())
 | |
|         el.appendChild(label)
 | |
| 
 | |
|         const actualInputElement = document.createElement("input")
 | |
|         actualInputElement.style.cssText = "display:none"
 | |
|         actualInputElement.type = "file"
 | |
|         actualInputElement.accept = this._acceptType
 | |
|         actualInputElement.name = "picField"
 | |
|         actualInputElement.multiple = this.allowMultiple
 | |
|         actualInputElement.id = "fileselector" + FileSelectorButton._nextid
 | |
|         FileSelectorButton._nextid++
 | |
| 
 | |
|         label.htmlFor = actualInputElement.id
 | |
| 
 | |
|         actualInputElement.onchange = () => {
 | |
|             if (actualInputElement.files !== null) {
 | |
|                 self._value.setData(actualInputElement.files)
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         el.addEventListener("submit", (e) => {
 | |
|             if (actualInputElement.files !== null) {
 | |
|                 self._value.setData(actualInputElement.files)
 | |
|             }
 | |
|             e.preventDefault()
 | |
|         })
 | |
| 
 | |
|         el.appendChild(actualInputElement)
 | |
| 
 | |
|         el.addEventListener("dragover", (event) => {
 | |
|             event.stopPropagation()
 | |
|             event.preventDefault()
 | |
|             // Style the drag-and-drop as a "copy file" operation.
 | |
|             event.dataTransfer.dropEffect = "copy"
 | |
|         })
 | |
| 
 | |
|         el.addEventListener("drop", (event) => {
 | |
|             event.stopPropagation()
 | |
|             event.preventDefault()
 | |
|             const fileList = event.dataTransfer.files
 | |
|             this._value.setData(fileList)
 | |
|         })
 | |
| 
 | |
|         return el
 | |
|     }
 | |
| }
 |