From 30b5a7660f1af208eae244393828a5662473a6c1 Mon Sep 17 00:00:00 2001 From: florian-boubou Date: Tue, 29 Oct 2019 23:34:14 +0100 Subject: [PATCH] Pictures display and upload --- package.json | 1 + public/javascript/livePictures.js | 42 +++++++++ public/stylesheets/style.css | 17 +++- routes/ads.js | 21 ++++- views/ad_create.hbs | 151 ++++++++++++++++-------------- 5 files changed, 161 insertions(+), 71 deletions(-) create mode 100644 public/javascript/livePictures.js diff --git a/package.json b/package.json index 53106bd..a3bd53f 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "hbs": "~4.0.4", "mongoose": "^5.7.6", "morgan": "~1.9.1", + "multer": "^1.4.2", "passport": "^0.4.0", "passport-local": "^1.0.0" }, diff --git a/public/javascript/livePictures.js b/public/javascript/livePictures.js new file mode 100644 index 0000000..3d3163c --- /dev/null +++ b/public/javascript/livePictures.js @@ -0,0 +1,42 @@ +/** + * Adds event listener to file input so that + * it shows selected images in real time + */ +function picturesWatch() { + const picturesInput = document.querySelector('#pictures'); + const picturesOutput = document.querySelector('#pictures-display'); + + picturesInput.addEventListener('change', (e) => { + const files = e.target.files; + + // Clear existing images + while (picturesOutput.lastChild) { + picturesOutput.removeChild(picturesOutput.lastChild); + } + + for (const file of files) { + if (!file.type.startsWith('image/')) { + continue; + } + + const img = document.createElement('img'); + img.file = file; + + picturesOutput.appendChild(img); + + // Read file's contents and assign it to img + const reader = new FileReader(); + reader.onload = (function(aImg) { + return function(e) { + aImg.src = e.target.result; + }; + })(img); + reader.readAsDataURL(file); + } + }); +} + +document.addEventListener('DOMContentLoaded', function() { + picturesWatch(); + console.info('file input is being watched'); +}); diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 991b01e..085847b 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -24,7 +24,8 @@ form > fieldset, form > button { } div.form-input { - display: inline; + display: inline-block; + margin-bottom: 15px; } span.error-message { @@ -48,4 +49,18 @@ span.error-message { .close-btn { cursor: pointer; +} + +.ad-photos { + display: flex; + width: 100%; + justify-content: space-around; +} + +.ad-photos > img { + max-width: 20%; + max-height: 100%; + border: solid 2px #333; + padding: 2px; + margin-bottom: 15px; } \ No newline at end of file diff --git a/routes/ads.js b/routes/ads.js index bfba03e..3755db6 100644 --- a/routes/ads.js +++ b/routes/ads.js @@ -1,13 +1,18 @@ const express = require('express'); +const multer = require('multer'); const router = new express.Router(); const adModel = require('../models/ad'); +const upload = multer({ + storage: multer.memoryStorage(), +}); + /* GET to get to get to the ad creation form */ router.get('/create', function(req, res, next) { res.render('ad_create'); }) - .post('/create', function(req, res, next) { + .post('/create', upload.array('pictures', 3), function(req, res, next) { // TODO : gérer l'upload de fichier // (avec le middleware multiparty par exemple) const body = req.body; @@ -24,6 +29,12 @@ router.get('/create', function(req, res, next) { null : body.availabilityDate, }; + if (req.files.length) { + formData.pictures = req + .files + .map((f) => ({name: f.fieldName, body: f.buffer})); + } + if (id) { // Peut-être charger l'objet en amont et le retourner si erreur ? @@ -87,6 +98,14 @@ router.get('/create', function(req, res, next) { req.flash('error', 'L\'annonce n\'a pas pu être supprimée'); }) .finally(() => res.redirect(303, '/ads/')); + }) + .get('/:id/picture/:index', function(req, res, next) { + adModel.Ad.findOne({_id: req.params.id}) + .then((ad) => { + res.type('image/*'); + res.send(ad.pictures[parseInt(req.params.index)].body); + }) + .catch(next); }); module.exports = router; diff --git a/views/ad_create.hbs b/views/ad_create.hbs index b594896..8fe4c6e 100644 --- a/views/ad_create.hbs +++ b/views/ad_create.hbs @@ -1,87 +1,100 @@

Créer une annonce immobilière

- {{#each errors_update}} -

{{this}}

- {{/each}} + {{#each errors_update}} +

{{this}}

+ {{/each}}
-
+ +
+ + + {{errors.title.message}} +
+ + +
+ Informations sur l'annonce +
- - - {{errors.title.message}} + +
    + A la vente + A la location +
+ {{errors.type.message}}
- -
- Informations sur l'annonce +
+ +
    + Disponible + Louée + Vendue +
+ {{errors.transactionStatus.message}} +
-
- -
    - A la vente - A la location -
- {{errors.type.message}} -
+
+ +
+ € +
+ {{errors.price.message}} +
-
- -
    - Disponible - Louée - Vendue -
- {{errors.transactionStatus.message}} -
+
+
+ + +
+ {{errors.published.message}} +
+
-
- -
- € -
- {{errors.price.message}} -
+ +
+ Détails de l'annonce -
-
- - -
- {{errors.published.message}} -
-
+
+ + + {{errors.pictures.message}} +
- -
- Détails de l'annonce +
+ {{#with ad as |ad|}} + {{#each ad.pictures}} + {{title}} + {{/each}} + {{/with}} +
-
- - - {{errors.description.message}} -
+
+ + + {{errors.description.message}} +
-
- - - {{errors.date.message}} -
+
+ + + {{errors.date.message}} +
+
-
- - - {{errors.pictures.message}} -
-
+ - + +
- - \ No newline at end of file + \ No newline at end of file -- GitLab