diff --git a/photo21/locale/fr/LC_MESSAGES/django.po b/photo21/locale/fr/LC_MESSAGES/django.po
index 18d2014019c859e01213adf201ff261fde033161..575683dfb614b13a32348b348044d6268324100c 100644
--- a/photo21/locale/fr/LC_MESSAGES/django.po
+++ b/photo21/locale/fr/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-10-22 16:05+0000\n"
+"POT-Creation-Date: 2021-10-23 15:29+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -42,19 +42,19 @@ msgstr ""
 msgid "hash"
 msgstr ""
 
-#: photo21/settings.py:163
+#: photo21/settings.py:162
 msgid "German"
 msgstr ""
 
-#: photo21/settings.py:164
+#: photo21/settings.py:163
 msgid "English"
 msgstr ""
 
-#: photo21/settings.py:165
+#: photo21/settings.py:164
 msgid "Spanish"
 msgstr ""
 
-#: photo21/settings.py:166
+#: photo21/settings.py:165
 msgid "French"
 msgstr ""
 
@@ -229,10 +229,9 @@ msgstr ""
 msgid "Galleries"
 msgstr "Galeries"
 
-#: photo21/templates/base.html:41
+#: photo21/templates/base.html:41 photologue_custom/forms.py:76
 #: photologue_custom/templates/photologue/upload.html:6
 #: photologue_custom/templates/photologue/upload.html:54
-#: photologue_custom/templates/photologue/upload.html:65
 msgid "Upload"
 msgstr "Téléversement"
 
@@ -279,33 +278,46 @@ msgstr ""
 msgid "owner"
 msgstr "propriétaire"
 
-#: photologue_custom/forms.py:22
+#: photologue_custom/forms.py:34
 msgid "Gallery"
 msgstr "Galerie"
 
-#: photologue_custom/forms.py:24
+#: photologue_custom/forms.py:36
+msgid "-- Create a new gallery --"
+msgstr "-- Créer une nouvelle galerie --"
+
+#: photologue_custom/forms.py:37
 msgid ""
 "Select a gallery to add these images to. Leave this empty to create a new "
 "gallery from the supplied title."
 msgstr ""
 
-#: photologue_custom/forms.py:28
+#: photologue_custom/forms.py:41
 msgid "New gallery title"
 msgstr "Titre de la nouvelle galerie"
 
-#: photologue_custom/forms.py:33
+#: photologue_custom/forms.py:46
 msgid "New gallery event start date"
 msgstr "Date de début de l'évènement de la nouvelle galerie"
 
-#: photologue_custom/forms.py:38
+#: photologue_custom/forms.py:51
 msgid "New gallery event end date"
 msgstr "Date de fin de l'évènement de la nouvelle galerie"
 
-#: photologue_custom/forms.py:46
+#: photologue_custom/forms.py:57
+msgid "New gallery tags"
+msgstr "Tags de la nouvelle galerie"
+
+#: photologue_custom/forms.py:59
+msgid ""
+"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
+msgstr ""
+
+#: photologue_custom/forms.py:82
 msgid "A gallery with that title already exists."
 msgstr ""
 
-#: photologue_custom/forms.py:55
+#: photologue_custom/forms.py:91
 msgid "Select an existing gallery, or enter a title for a new gallery."
 msgstr ""
 
diff --git a/photologue_custom/forms.py b/photologue_custom/forms.py
index 2d823f31cbe51b903ad9474efb98476da61e7db0..c343d987b55b1762a1e11c8d11fb1a2a9e45ccfb 100644
--- a/photologue_custom/forms.py
+++ b/photologue_custom/forms.py
@@ -1,13 +1,25 @@
 import datetime
 
+from crispy_forms.helper import FormHelper
+from crispy_forms.layout import Div, Layout, Submit
 from django import forms
 from django.utils.text import slugify
 from django.utils.translation import gettext_lazy as _
 from photologue.models import Gallery
+from taggit.models import Tag
 
 from .models import GalleryExtended
 
 
+class GalleryChoiceField(forms.ModelChoiceField):
+    def label_from_instance(self, obj):
+        """Show gallery event date."""
+        if hasattr(obj, 'extended'):
+            return f"{ obj.title } ({obj.extended.date_start})"
+        else:
+            return obj.title
+
+
 class UploadForm(forms.Form):
     file_field = forms.FileField(
         label="",
@@ -17,10 +29,11 @@ class UploadForm(forms.Form):
             'class': 'mb-3',
         }),
     )
-    gallery = forms.ModelChoiceField(
+    gallery = GalleryChoiceField(
         Gallery.objects.all(),
         label=_('Gallery'),
         required=False,
+        empty_label=_('-- Create a new gallery --'),
         help_text=_('Select a gallery to add these images to. Leave this empty to '
                     'create a new gallery from the supplied title.')
     )
@@ -29,16 +42,39 @@ class UploadForm(forms.Form):
         max_length=250,
         required=False,
     )
-    date_start = forms.DateField(
+    new_gallery_date_start = forms.DateField(
         label=_('New gallery event start date'),
         initial=datetime.date.today,
         required=False,
     )
-    date_end = forms.DateField(
+    new_gallery_date_end = forms.DateField(
         label=_('New gallery event end date'),
         initial=datetime.date.today,
         required=False,
     )
+    new_gallery_tags = forms.ModelMultipleChoiceField(
+        Tag.objects.all(),
+        label=_('New gallery tags'),
+        required=False,
+        help_text=_('Hold down "Control", or "Command" on a Mac, to select more than one.')
+    )
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.helper = FormHelper()
+        self.helper.use_custom_control = False
+        self.helper.layout = Layout(
+            'file_field',
+            'gallery',
+            'new_gallery_title',
+            Div(
+                Div('new_gallery_date_start', css_class='col'),
+                Div('new_gallery_date_end', css_class='col'),
+                css_class='row'
+            ),
+            'new_gallery_tags',
+            Submit('submit', _('Upload'), css_class='btn btn-success mt-2')
+        )
 
     def clean_new_gallery_title(self):
         title = self.cleaned_data['new_gallery_title']
@@ -67,7 +103,8 @@ class UploadForm(forms.Form):
             gallery = Gallery.objects.create(title=title, slug=slugify(title))
             GalleryExtended.objects.create(
                 gallery=gallery,
-                date_start=self.cleaned_data['date_start'],
-                date_end=self.cleaned_data['date_end'],
+                tags=self.cleaned_data['new_gallery_tags'],
+                date_start=self.cleaned_data['new_gallery_date_start'],
+                date_end=self.cleaned_data['new_gallery_date_end'],
             )
         return gallery
diff --git a/photologue_custom/templates/photologue/upload.html b/photologue_custom/templates/photologue/upload.html
index fbe1ee06216b2f2925a8aae6e4a3f946cfdf2751..d2e00478c6ca15ae5e89de13ed791a91d9c2c9ea 100644
--- a/photologue_custom/templates/photologue/upload.html
+++ b/photologue_custom/templates/photologue/upload.html
@@ -28,6 +28,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
 
 {% block extrajs %}
 <script>
+// When user drags files, register them in the file field
 const dropZone = document.getElementById('drop-zone');
 const uploadInput = document.getElementById('id_file_field');
 
@@ -47,6 +48,24 @@ dropZone.ondragleave = function() {
     this.className = 'upload-drop-zone';
     return false;
 }
+
+// When user selects an existing gallery, disable new gallery fields
+const gallerySelect = document.getElementById('id_gallery')
+gallerySelectUpdate = () => {
+    const useGallery = (gallerySelect.value !== "");
+    document.getElementById('id_new_gallery_title').disabled = useGallery;
+    document.getElementById('id_new_gallery_date_start').disabled = useGallery;
+    document.getElementById('id_new_gallery_date_end').disabled = useGallery;
+    document.getElementById('id_new_gallery_tags').disabled = useGallery;
+}
+gallerySelect.addEventListener('change', gallerySelectUpdate);
+gallerySelectUpdate();
+
+// On submit, show a message to make user wait
+document.getElementById('upload_form').addEventListener('submit', (e) => {
+    document.getElementById('submit-id-submit').disabled = true;
+    document.getElementById('submit-id-submit').value = "Please be patient";
+})
 </script>
 {% endblock %}
 
@@ -54,15 +73,14 @@ dropZone.ondragleave = function() {
 <h1>{% trans "Upload" %}</h1>
 <div class="card">
     <div class="card-body">
-        <form method="post" enctype="multipart/form-data">{% csrf_token %}
+        <form method="post" enctype="multipart/form-data" id="upload_form">{% csrf_token %}
             <div class="upload-drop-zone" id="drop-zone">
                 {% trans "Drag and drop photos here" %}
             </div>
-            {{ form|crispy }}
+            {% crispy form %}
             <p class="mt-3">
                 {% trans "Owner will be" %} <code>{{ request.user.get_full_name }} ({{ request.user.username}})</code>.
             </p>
-            <button type="submit" class="btn btn-success">{% trans "Upload" %}</button>
         </form>
     </div>
 </div>