Skip to content

Commit 2288520

Browse files
committed
image upload (issue #3 )
image upload from file to front-end
1 parent b09ff40 commit 2288520

File tree

2 files changed

+123
-34
lines changed

2 files changed

+123
-34
lines changed

src/public/index.html

+40-30
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<title>Evolving Posters</title>
44
<meta charset="utf-8" />
55
<link rel="stylesheet" href="bundle.css">
6+
<script src="bundle.js"></script>
67
</head>
78
<body>
89
<div class="temp-results container-fluid bg-light d-none" id="error-handle">
@@ -33,46 +34,55 @@ <h1 class="mb-3">Emotional analysis Results</h1>
3334
<div id="temp-res-lexicon-lines"></div>
3435
<p id="temp-res-lexicon-global"></p>
3536
</div>
37+
<div id="input-images" class="mt-4 d-none"></div>
3638
</section>
3739
</div>
3840
</div>
3941
<aside class="container-fluid">
4042
<div class="row">
4143
<section class="input-form-outer col-10 offset-1 mt-5">
4244
<form id="input-form" class="input-form-inner">
43-
<div class="form-group row mb-2">
44-
<label for="formControlTextarea" class="col-sm-2 col-form-label-sm">Input Text</label>
45-
<textarea class="form-control col-sm-10" id="formControlTextarea" rows="6" required></textarea>
46-
</div>
47-
<!-- TODO: select required -->
48-
<div class="form-group row mb-2">
49-
<label for="formControlLang">Language</label>
50-
<input class="form-control form-control-lg" id="formControlLang" type="text" value="en" required>
51-
</div>
52-
<div class="form-check form-check-inline mb-2">
53-
<input class="form-check-input" type="checkbox" value="1" id="lineDivisionCheck" checked>
54-
<label class="form-check-label" for="lineDivisionCheck"> Automatic line division</label>
55-
</div>
56-
<div class="form-group row mb-2">
57-
<label for="formControlTextDelimiter">Text Line delimiter</label>
58-
<input class="form-control form-control-lg" id="formControlTextDelimiter" type="text" value="">
59-
</div>
60-
<div class="form-group row mb-2">
61-
<label for="exampleFormControlImages">Example file input</label>
62-
<input type="file" class="form-control-file" id="exampleFormControlImages">
63-
</div>
64-
<div class="form-group row mb-2">
65-
<label for="formControlImagePlaceholderDelimiter">Image Placeholder Delimiter</label>
66-
<input class="form-control form-control-lg" id="formControlImagePlaceholderDelimiter" type="text"
67-
placeholder="§">
68-
</div>
69-
<div class="col-auto">
70-
<button type="submit" class="btn btn-primary mb-2">Submit</button>
71-
</div>
45+
<fieldset>
46+
<div class="form-group row mb-2">
47+
<label for="formControlTextarea" class="col-sm-2 col-form-label-sm">Input Text</label>
48+
<textarea class="form-control col-sm-10" id="formControlTextarea" rows="6" required></textarea>
49+
</div>
50+
<!-- TODO: select required -->
51+
<div class="form-group row mb-2">
52+
<label for="formControlLang">Language</label>
53+
<input class="form-control form-control-lg" id="formControlLang" type="text" value="en" required>
54+
</div>
55+
<div class="form-check form-check-inline mb-2">
56+
<input class="form-check-input" type="checkbox" value="1" id="lineDivisionCheck" checked>
57+
<label class="form-check-label" for="lineDivisionCheck"> Automatic line division</label>
58+
</div>
59+
<!-- TODO: ONLY OPEN SELECTED -->
60+
<div class="form-group row mb-2">
61+
<label for="formControlTextDelimiter">Text Line delimiter</label>
62+
<input class="form-control form-control-lg" id="formControlTextDelimiter" type="text" value="">
63+
</div>
64+
<div class="form-group row mb-2">
65+
<label for="formControlImages">Example file input</label>
66+
<input type="file" class="form-control-file" id="formControlImages"
67+
name="files[]" accept="image/jpeg, image/png, image/jpg" multiple>
68+
</div>
69+
70+
<div class="form-check form-check-inline mb-2">
71+
<input class="form-check-input" type="checkbox" value="1" id="imagePlacementCheck">
72+
<label class="form-check-label" for="imagePlacementCheck"> Image Placement Division</label>
73+
</div>
74+
75+
<div class="form-group row mb-2">
76+
<label for="formControlImagePlaceholderDelimiter">Image Placeholder Delimiter</label>
77+
<input class="form-control form-control-lg" id="formControlImagePlaceholderDelimiter" type="text">
78+
</div>
79+
<div class="col-auto">
80+
<button type="submit" class="btn btn-primary mb-2">Submit</button>
81+
</div>
82+
</fieldset>
7283
</form>
7384
</section>
7485
</div>
7586
</aside>
76-
<script src="bundle.js"></script>
7787
</body>
7888
</html>

src/public/main.js

+83-4
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,47 @@
11
const bootstrap = require('bootstrap');
22
const style = require('./main.css');
33

4+
// global variables
5+
const app = {
6+
images: {
7+
imageRandomPlacement: true,
8+
hasImages: false,
9+
blobs: [],
10+
loading: false
11+
}
12+
};
13+
414
window.onload = () => {
515
const form = document.getElementById('input-form');
6-
form.addEventListener("submit", get);
16+
const inputImages = document.getElementById('formControlImages');
17+
form.addEventListener('submit', get);
18+
inputImages.addEventListener('change', _uploadImages);
719
}
820

9-
const get = (e) => {
21+
const get = async (e) => {
1022
e.preventDefault();
1123
let textArea = encodeURIComponent(document.getElementById('formControlTextarea').value);
1224
const shouldDivide = document.getElementById('lineDivisionCheck').checked;
1325
const lang = encodeURIComponent(document.getElementById('formControlLang').value);
26+
const images = document.getElementById('formControlImages').files;
27+
app.hasImages = images.files && images.files[0];
28+
app.imageRandomPlacement = document.getElementById('imagePlacementCheck').checked;
29+
1430
let handler = `text`;
1531
if (!shouldDivide) {
1632
const delimiter = encodeURIComponent(document.getElementById('formControlTextDelimiter').value);
1733
handler = `lines/${delimiter}`;
1834
}
1935

36+
if (!app.hasImages) {
37+
if (!app.imageRandomPlacement) {
38+
// random placement
39+
} else {
40+
// defined placement -> server side
41+
}
42+
}
43+
44+
2045
const url = `/${handler}/${lang}/${textArea}`;
2146

2247
fetch(url).then((response) => response.json()).then((result) => {
@@ -28,10 +53,64 @@ const get = (e) => {
2853
}
2954

3055
const handleErr = (res = {success: false}) => {
31-
document.getElementById('err-message').textContent = res.message;
56+
const container = document.getElementById('err-message');
57+
if (container.innerHTML.length > 0) container.innerHTML = container.innerHTML + "<br>";
58+
container.innerHTML = container.innerHTML+res.message;
3259
document.getElementById('error-handle').classList.replace('d-none', 'd-block');
3360
}
3461

62+
const _uploadImages = async (e) => {
63+
app.images.blobs = [];
64+
app.images.loading = true;
65+
app.images.blobs = await _readImages(e.target.files).catch((err) => {
66+
console.error (`not possible to load the image ${err}`);
67+
handleErr({ message: `error on uploading image(s). ${err}`});
68+
})
69+
app.images.loading = false;
70+
_displayImages(app.images.blobs);
71+
}
72+
73+
const _displayImages = (files) => {
74+
const imgContainer = document.getElementById('input-images');
75+
for (let i = 0; i<files.length; i++) {
76+
const img = new Image();
77+
img.src = files[i];
78+
img.classList.add('d-inline-block');
79+
if (i > 0) img.classList.add(`mx-2`);
80+
img.style.height = `100px`;
81+
img.style.width = `auto`;
82+
imgContainer.appendChild(img);
83+
}
84+
imgContainer.classList.replace('d-none', 'd-block');
85+
}
86+
87+
const _readImages = async (files) => {
88+
const res = [];
89+
let err = [];
90+
const getBase64 = (file) => {
91+
const reader = new FileReader()
92+
return new Promise(resolve => {
93+
reader.onload = (ev) => {
94+
resolve(ev.target.result)
95+
}
96+
reader.readAsDataURL(file);
97+
});
98+
};
99+
for (let i = 0; i < files.length; i++) {
100+
if (files[i].type.includes('image')) {
101+
res.push(getBase64(files[i]));
102+
} else {
103+
err.push (files[i].name);
104+
}
105+
}
106+
107+
if (err.length > 0) {
108+
handleErr({message: `error loading the following image(s): ${err.flat()}`});
109+
}
110+
111+
return await Promise.all(res);
112+
}
113+
35114
const displayResults = (res) => {
36115
if (!res.success) { return handleErr(res);}
37116

@@ -49,6 +128,6 @@ const displayResults = (res) => {
49128
}
50129

51130
document.getElementById('temp-res-lexicon-global').innerHTML = `<b>global lexicon</b>: ${res.lexicon.global[0][0]} (${res.lexicon.global[0][1]})`
52-
53131
document.getElementById('temp-info').classList.replace('d-none', 'd-block');
132+
document.querySelector('#input-form fieldset').disabled = true;
54133
}

0 commit comments

Comments
 (0)