Skip to content
Snippets Groups Projects
Commit 1ec3ff57 authored by Neuber, Eugen Ramon's avatar Neuber, Eugen Ramon :speech_balloon: Committed by Reiter, Christoph
Browse files

Add sending to server

parent 2bc61466
No related branches found
No related tags found
No related merge requests found
...@@ -3,15 +3,20 @@ ...@@ -3,15 +3,20 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<script type="module" id="vpu-fileupload-src" src="bundle.js"></script> <script type="module" id="vpu-fileupload-src" src="bundle.js"></script>
<style>
vpu-fileupload-demo {
--FUBorderWidth: 2px;
--FUBorderStyle: dotted;
--FUBorderColor: #555;
--FUBorderColorHighlight: #935;
--FUBorderRadius: 10px;
--FUBorder: 2px dashed red;
--FUMargin: 20px;
--FUPadding: 5px;
--FUWidth: 450px;
}
</style>
</head> </head>
<style>
vpu-fileupload-demo {
--FUBorderRadius: 10px;
--FUBorder: 2px dashed red;
--FUMargin: 20px;
--FUPadding: 5px;
}
</style>
<body> <body>
<vpu-fileupload-demo lang="de" url="http://127.0.0.1:8080"></vpu-fileupload-demo> <vpu-fileupload-demo lang="de" url="http://127.0.0.1:8080"></vpu-fileupload-demo>
......
import {i18n} from './i18n'; import {i18n} from './i18n';
import {html, LitElement} from 'lit-element'; import {html, LitElement} from 'lit-element';
import {unsafeHTML} from 'lit-html/directives/unsafe-html.js';
import './vpu-fileupload'; import './vpu-fileupload';
import * as commonUtils from 'vpu-common/utils'; import * as commonUtils from 'vpu-common/utils';
...@@ -17,6 +18,17 @@ class FileUploadDemo extends LitElement { ...@@ -17,6 +18,17 @@ class FileUploadDemo extends LitElement {
}; };
} }
connectedCallback() {
super.connectedCallback();
this.updateComplete.then(() => {
this.shadowRoot.querySelectorAll('vpu-fileupload')
.forEach(element => {
element.addEventListener('vpu-fileupload-finished', this.addLogEntry.bind(this));
});
});
}
update(changedProperties) { update(changedProperties) {
changedProperties.forEach((oldValue, propName) => { changedProperties.forEach((oldValue, propName) => {
if (propName === "lang") { if (propName === "lang") {
...@@ -27,14 +39,26 @@ class FileUploadDemo extends LitElement { ...@@ -27,14 +39,26 @@ class FileUploadDemo extends LitElement {
super.update(changedProperties); super.update(changedProperties);
} }
addLogEntry(ev) {
const ul = this.shadowRoot.querySelector('#log');
const li = document.createElement('li');
li.innerHTML = `<li><b>${ev.detail.status}</b> <tt>${ev.detail.filename}</tt>`;
ul.appendChild(li);
}
render() { render() {
return html` return html`
<style> <style>
vpu-fileupload.clean { vpu-fileupload.clean {
--FUBorder: initial; --FUBorderWidth: initial;
--FUBorderStyle: initial;
--FUBorderColor: initial;
--FUBorderColorHighlight: initial;
--FUBorderRadius: initial; --FUBorderRadius: initial;
--FUMargin: initial; --FUMargin: initial;
--FUPadding: initial; --FUPadding: initial;
--FUWidth: initial;
} }
vpu-fileupload.opt { vpu-fileupload.opt {
--FUBorder: 2px solid blue; --FUBorder: 2px solid blue;
...@@ -43,13 +67,19 @@ class FileUploadDemo extends LitElement { ...@@ -43,13 +67,19 @@ class FileUploadDemo extends LitElement {
<section class="section"> <section class="section">
<div class="content"> <div class="content">
<h1 class="title">File-Upload-Demo</h1> <h1 class="title">${i18n.t('demo-title')}</h1>
<p>You need an upload server listening at <tt>${this.url}</tt> to receive the files...</p> <p>${unsafeHTML(i18n.t('required-server', { url: this.url}))}</p>
</div> </div>
<div class="content"> <div class="content">
<h2 class="subtitle">Send to Server</h2> <h2 class="subtitle">Send any File to Server</h2>
<p>Drop some files here:</p> <p>There is no restriction for a specific file type:</p>
<vpu-fileupload lang="de" url="${this.url}"></vpu-fileupload> <vpu-fileupload lang="de" url="${this.url}"></vpu-fileupload>
<p>Only images are allowed here (JPG, PNG, GIF, TIF, ...):</p>
<vpu-fileupload lang="de" url="${this.url}" accept="image/*"
text="Abgabe nur für Bilder "></vpu-fileupload>
<p>This is for PDF only:</p>
<vpu-fileupload lang="de" url="${this.url}" accept="application/pdf"
text="Einreichung als PDF" button-label="PDF auswählen"></vpu-fileupload>
</div> </div>
<div class="content"> <div class="content">
<h2>Log of uploads</h2> <h2>Log of uploads</h2>
......
...@@ -3,5 +3,10 @@ ...@@ -3,5 +3,10 @@
"is-forbidden": "ist verboten", "is-forbidden": "ist verboten",
"troubled-server": "macht Probleme am Server", "troubled-server": "macht Probleme am Server",
"unknown-problems": "mit unbekanntem Problem", "unknown-problems": "mit unbekanntem Problem",
"was-not-found": "wurde nicht gefunden" "was-not-found": "wurde nicht gefunden",
"demo-title": "Datei Abgabe Demo",
"server-required": "Es wird unter der URL <a href=\"{{- url}}\"><tt>{{- url}}</tt></a> ein Server benötigt um die Dateien zu empfangen.",
"intro": "Laden Sie mehrere Dateien mit dem Auswahldialog oder durch Ziehen und Fallenlassen in diesem Bereich hoch",
"upload-label": "Dateiauswahl"
} }
...@@ -3,5 +3,10 @@ ...@@ -3,5 +3,10 @@
"is-forbidden": "is forbidden", "is-forbidden": "is forbidden",
"troubled-server": "troubled server", "troubled-server": "troubled server",
"unknown-problems": "with unknown problems", "unknown-problems": "with unknown problems",
"was-not-found": "was not found" "was-not-found": "was not found",
"demo-title": "File Upload Demo",
"required-server": "You need an upload server listening at <a href=\"{{- url}}\"><tt>{{- url}}</tt></a> to receive the files...",
"intro": "Upload multiple files with the file dialog or by dragging and dropping images onto the dashed region",
"upload-label": "Select some files"
} }
import {i18n} from './i18n'; import {i18n} from './i18n';
import {html} from 'lit-element'; import {css, html} from 'lit-element';
import {ifDefined} from 'lit-html/directives/if-defined';
// import JSONLD from 'vpu-common/jsonld'; // import JSONLD from 'vpu-common/jsonld';
import VPULitElement from 'vpu-common/vpu-lit-element' import VPULitElement from 'vpu-common/vpu-lit-element'
import "vpu-common/vpu-mini-spinner.js"; import "vpu-common/vpu-mini-spinner.js";
import * as commonUtils from "vpu-common/utils"; import * as commonUtils from "vpu-common/utils";
import {unsafeHTML} from 'lit-html/directives/unsafe-html.js';
import 'vpu-common/vpu-icon.js'; import 'vpu-common/vpu-icon.js';
/** /**
...@@ -15,6 +15,10 @@ class VPUFileUpload extends VPULitElement { ...@@ -15,6 +15,10 @@ class VPUFileUpload extends VPULitElement {
super(); super();
this.lang = 'de'; this.lang = 'de';
this.url = ''; this.url = '';
this.dropArea = null;
this.accept = '';
this.text = '';
this.buttonLabel = '';
} }
/** /**
...@@ -24,6 +28,9 @@ class VPUFileUpload extends VPULitElement { ...@@ -24,6 +28,9 @@ class VPUFileUpload extends VPULitElement {
return { return {
lang: { type: String }, lang: { type: String },
url: { type: String }, url: { type: String },
accept: { type: String },
text: { type: String },
buttonLabel: { type: String, attribute: 'button-label'},
}; };
} }
...@@ -38,56 +45,130 @@ class VPUFileUpload extends VPULitElement { ...@@ -38,56 +45,130 @@ class VPUFileUpload extends VPULitElement {
super.update(changedProperties); super.update(changedProperties);
} }
connectedCallback() {
super.connectedCallback();
this.updateComplete.then(() => {
this.dropArea = this.shadowRoot.querySelector('#dropArea');
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
this.dropArea.addEventListener(eventName, this.preventDefaults, false)
});
['dragenter', 'dragover'].forEach(eventName => {
this.dropArea.addEventListener(eventName, this.highlight.bind(this), false)
});
['dragleave', 'drop'].forEach(eventName => {
this.dropArea.addEventListener(eventName, this.unhighlight.bind(this), false)
});
this.dropArea.addEventListener('drop', this.handleDrop.bind(this), false);
this.shadowRoot.querySelector('#fileElem').addEventListener('change', this.handleChange.bind(this));
});
}
preventDefaults (e) {
e.preventDefault();
e.stopPropagation();
}
highlight(e) {
this.dropArea.classList.add('highlight')
}
unhighlight(e) {
this.dropArea.classList.remove('highlight')
}
handleDrop(e) {
let dt = e.dataTransfer;
console.dir(dt);
let files = dt.files;
this.handleFiles(files);
}
handleChange(e) {
this.handleFiles(this.shadowRoot.querySelector('#fileElem').files);
}
handleFiles(files) {
console.log('handleFiles: files.length = ' + files.length);
([...files]).forEach(this.uploadFile.bind(this))
}
sendFinishedEvent(status, filename) {
const data = {
status: status,
filename: filename
};
const event = new CustomEvent("vpu-fileupload-finished", { "detail": data, bubbles: true, composed: true });
this.dispatchEvent(event);
}
uploadFile(file) {
let url = this.url;
let formData = new FormData();
formData.append('my_file', file);
fetch(url, {
method: 'POST',
body: formData
})
.then((response) => {
/* Done. Inform the user */
console.log(`Status: ${response.status} for file ${file.name}`);
this.sendFinishedEvent(response.status, file.name);
})
.catch((response) => {
/* Error. Inform the user */
console.log(`Status: ${response.status} for file ${file.name}`);
this.sendFinishedEvent(response.status, file.name);
})
}
static get styles() {
// language=css
return css`
#dropArea {
border: var(--FUBorderWidth, 2px) var(--FUBorderStyle, dashed) var(--FUBBorderColor, #ccc);
border-radius: var(--FUBorderRadius, 0);
width: var(--FUWidth, auto);
margin: var(--FUMargin, 10px);
padding: var(--FUPadding, 20px);
}
#dropArea.highlight {
border-color: var(--FUBorderColorHighlight, purple);
}
p {
margin-top: 0;
}
.my-form {
margin-bottom: 10px;
}
.button {
display: inline-block;
padding: 10px;
background: #ccc;
cursor: pointer;
border-radius: calc(var(--FUBorderRadius, 0)/2);
border: 1px solid #ccc;
}
.button:hover {
background: #ddd;
}
#fileElem {
display: none;
}
`;
}
render() { render() {
return html` return html`
<style> <div id="dropArea">
#drop-area {
border: 2px dashed #ccc;
border-radius: 20px;
width: 480px;
font-family: sans-serif;
margin: 100px auto;
padding: 20px;
}
#drop-area.highlight {
border-color: purple;
}
p {
margin-top: 0;
}
.my-form {
margin-bottom: 10px;
}
#gallery {
margin-top: 10px;
}
#gallery img {
width: 150px;
margin-bottom: 10px;
margin-right: 10px;
vertical-align: middle;
}
.button {
display: inline-block;
padding: 10px;
background: #ccc;
cursor: pointer;
border-radius: 5px;
border: 1px solid #ccc;
}
.button:hover {
background: #ddd;
}
#fileElem {
display: none;
}
</style>
<div id="drop-area">
<form class="my-form"> <form class="my-form">
<p>Upload multiple files with the file dialog or by dragging and dropping images onto the dashed region</p> <p>${this.text || i18n.t('intro')}</p>
<input type="file" id="fileElem" multiple accept="image/*" name='my_file' onchange="handleFiles(this.files)"> <input type="file" id="fileElem" multiple accept="${ifDefined(this.accept)}" name='my_file'>
<label class="button" for="fileElem">Select some files</label> <label class="button" for="fileElem">${this.buttonLabel || i18n.t('upload-label')}</label>
</form> </form>
</div> </div>
`; `;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment