diff options
author | Raphael Kabo <raphaelkabo@hey.com> | 2023-10-10 15:18:12 +0100 |
---|---|---|
committer | Raphael Kabo <raphaelkabo@hey.com> | 2023-10-10 15:18:12 +0100 |
commit | 2f4ffd5d86aa695afaffed9c6780f695d0bfde9d (patch) | |
tree | 0f963b59a0bd18065ed55ab3e0aa220c3d3e3d7e | |
parent | 29e9314211376807c934f284e71aadce71a31ea3 (diff) |
Improve group selector styling to use Select2
-rwxr-xr-x | public/css/style.css | 68 | ||||
-rw-r--r-- | public/js/modules/event-edit.js | 1 | ||||
-rw-r--r-- | public/js/modules/group-linker.js | 90 | ||||
-rw-r--r-- | public/js/modules/new.js | 3 | ||||
-rwxr-xr-x | views/partials/eventForm.handlebars | 46 |
5 files changed, 141 insertions, 67 deletions
diff --git a/public/css/style.css b/public/css/style.css index afa7471..d50ab11 100755 --- a/public/css/style.css +++ b/public/css/style.css @@ -294,17 +294,22 @@ body, html { .select2-selection__rendered { line-height: 2.25rem !important; } -.select2-container .select2-selection--single { - height: 2.25rem !important; -} + .select2-selection__arrow { - height: 2.25rem !important; + height: 100% !important; } -.select2-container--default .select2-selection--single { +.select2-container .select2-selection--single { /* Match Bootstrap 4 styling */ border: 1px solid #ced4da; - height: calc(2.25rem + 2px); + height: 2.25rem; +} + +.select2-results__option[aria-selected="true"] .group-preview__text, +.select2-results__option[aria-selected="true"] + .group-preview__text + p.text-muted { + color: white !important; } .attendee-name { @@ -413,26 +418,41 @@ article.static-page header { border-bottom: 1px solid #e0e0e0; } -.card--group-preview { +.select2-selection__rendered, +.select2-selection--single { + overflow: hidden; +} + +.group-preview { display: grid; grid-template-columns: 60px 1fr; overflow: hidden; gap: 1rem; - - transition: background-color 0.15s; } -.card--group-preview:hover { - background-color: #f5f5f5; +.select2-selection__rendered .group-preview { + transform: translateX(-8px); } -.card--group-preview img { +img.group-preview__image { width: 100%; height: 60px; object-fit: cover; } -.card--group-preview__text { +.select2-container .select2-selection--single.group-select-dropdown { + height: 60px; +} + +.select2-container + .select2-selection--single.group-select-dropdown + .select2-selection__rendered { + height: 100%; + display: flex; + align-items: center; +} + +.group-preview__text { text-decoration: none; color: #1b1b1b; overflow: hidden; @@ -440,20 +460,17 @@ article.static-page header { display: flex; flex-direction: column; justify-content: center; + line-height: 1.5; } -.card--group-preview__text strong, -.card--group-preview__text p { +.group-preview__text strong, +.group-preview__text p { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; margin: 0; } -.card--group-preview:hover { - text-decoration: none; -} - @keyframes shimmer { 100% { transform: translateX(100%); @@ -492,3 +509,16 @@ article.static-page header { left: 100%; } } + +.slider { + height: 0; + opacity: 0; + overflow: hidden; + transition: all 0.45s; + pointer-events: none; +} + +.slider.slider--open { + opacity: 1; + pointer-events: auto; +} diff --git a/public/js/modules/event-edit.js b/public/js/modules/event-edit.js index afe41d4..740c861 100644 --- a/public/js/modules/event-edit.js +++ b/public/js/modules/event-edit.js @@ -46,7 +46,6 @@ function editEventForm() { this.data.timezone = event.target.value; }); this.select2.val(this.data.timezone).trigger("change"); - console.log(JSON.stringify(this.data, null, 2)); // Set checkboxes this.data.eventGroupCheckbox = !!window.eventData.eventGroupID; diff --git a/public/js/modules/group-linker.js b/public/js/modules/group-linker.js index ca5e159..a21fec3 100644 --- a/public/js/modules/group-linker.js +++ b/public/js/modules/group-linker.js @@ -5,23 +5,87 @@ function eventGroupLinker() { eventGroupEditToken: "", groups: [], }, + manualGroupInputVisible: false, + eventGroupOptionTemplate(state) { + if (!state.id) { + return state.text; + } + if (!this.data.groups.length) { + return state.text; + } + const group = this.data.groups.find( + (group) => group.id === state.id, + ); + if (!group) { + return state.text; + } + const template = ` + <span class="group-preview"> + <img src="${ + group.image + ? `/events/${group.image}` + : "/images/seigaiha-single.png" + }" class="group-preview__image" /> + <div class="group-preview__text"> + <strong>${group.name}</strong> + <p class="text-muted">${group.description}</p> + </div> + </span>`; + return $(template); + }, async init() { + this.select2 = $(this.$refs.eventGroupSelect).select2({ + placeholder: "No group selected", + templateResult: this.eventGroupOptionTemplate.bind(this), + templateSelection: this.eventGroupOptionTemplate.bind(this), + selectionCssClass: "group-select-dropdown", + }); + this.select2.on("select2:select", (event) => { + this.selectGroup(event); + }); + this.select2.on("select2:unselect", () => { + this.data.eventGroupID = ""; + this.data.eventGroupEditToken = ""; + }); this.$watch("data.eventGroupID", () => { this.$dispatch( "event-group-id-changed", this.data.eventGroupID, ); + const matchingGroup = this.data.groups.find( + (group) => + group.id === this.data.eventGroupID && + group.editToken === this.data.eventGroupEditToken, + ); + if (matchingGroup) { + this.select2.val(matchingGroup.id).trigger("change"); + } else { + this.resetGroupSelector(); + } }); this.$watch("data.eventGroupEditToken", () => { this.$dispatch( "event-group-edit-token-changed", this.data.eventGroupEditToken, ); + const matchingGroup = this.data.groups.find( + (group) => + group.id === this.data.eventGroupID && + group.editToken === this.data.eventGroupEditToken, + ); + if (matchingGroup) { + this.select2.val(matchingGroup.id).trigger("change"); + } else { + this.resetGroupSelector(); + } }); - if (window.eventData && window.eventData.eventGroupID !== "") { + this.$watch("data.groups", () => { + this.select2.val(this.data.eventGroupID).trigger("change"); + }); + if (window.eventData && !!window.eventData.eventGroupID) { this.data.eventGroupID = window.eventData.eventGroupID; } - if (window.eventData && window.eventGroupEditToken !== "") { + if (window.eventData && !!window.eventGroupEditToken) { this.data.eventGroupEditToken = window.eventData.eventGroupEditToken; } @@ -42,7 +106,7 @@ function eventGroupLinker() { if (!response.ok) { return; } - const json = await (await response).json(); + const json = await response.json(); this.data.groups = json; } catch (e) { return false; @@ -60,26 +124,8 @@ function eventGroupLinker() { this.data.eventGroupID = group.id; this.data.eventGroupEditToken = group.editToken; }, - showGroupPreview() { - return ( - this.data.eventGroupID !== "" && - this.data.groups.some( - (group) => - group.id === this.data.eventGroupID && - group.editToken === this.data.eventGroupEditToken, - ) - ); - }, - groupPreview() { - if (!this.showGroupPreview()) { - return {}; - } - return this.data.groups.find( - (group) => group.id === this.data.eventGroupID, - ); - }, resetGroupSelector() { - this.$refs.eventGroupSelect.value = ""; + this.select2.val(null).trigger("change"); }, }; } diff --git a/public/js/modules/new.js b/public/js/modules/new.js index ca875bc..2d880f8 100644 --- a/public/js/modules/new.js +++ b/public/js/modules/new.js @@ -95,12 +95,13 @@ function newEventForm() { errors: [], submitting: false, init() { - // Set up Select2 + // Set up timezone Select2 this.select2 = $(this.$refs.timezone).select2(); this.select2.on("select2:select", (event) => { this.data.timezone = event.target.value; }); this.data.timezone = this.select2.val(); + // Reset checkboxes this.data.eventGroupCheckbox = false; this.data.interactionCheckbox = false; diff --git a/views/partials/eventForm.handlebars b/views/partials/eventForm.handlebars index 97e25af..c44a2ef 100755 --- a/views/partials/eventForm.handlebars +++ b/views/partials/eventForm.handlebars @@ -87,39 +87,37 @@ <label>Choose a group you've edited before</label> </div> <div class="form-group" x-show="data.groups.length > 0"> - <select x-ref="eventGroupSelect" id="eventGroupSelect" name="eventGroupSelect" class="form-control" x-on:change="selectGroup" x-model="data.eventGroupID"> - <option value="">Choose a group</option> + <select + x-ref="eventGroupSelect" + id="eventGroupSelect" + name="eventGroupSelect" + class="form-control" + x-on:change="selectGroup" + > + <option></option> <template x-for="group in data.groups"> <option :value="group.id" x-text="group.name"></option> </template> </select> </div> - <a class="card shadow-sm card--group-preview mb-3" x-show="showGroupPreview()" x-bind:href="groupPreview().url" target="_blank"> - <template x-if="groupPreview().image"> - <img :src="'/events/' + groupPreview().image"/> - </template> - <template x-if="!groupPreview().image"> - <img src="/images/seigaiha-single.png"/> - </template> - <div class="card--group-preview__text"> - <strong x-text="groupPreview().name"></strong> - <p x-text="groupPreview().description"></p> - </div> - </a> - <div class="alert alert-info text-center" role="alert" x-show="data.groups.length > 0"> - <i class="fas fa-info-circle"></i> You can also enter the group ID and secret editing code manually. - </div> - <div class="form-group"> - <label for="eventGroupID">Event group ID</label> + <button type="button" class="btn btn-outline-secondary w-100 text-center" x-on:click="manualGroupInputVisible = !manualGroupInputVisible"> + Enter group details manually <i class="fas" :class="{'fa-caret-down': !manualGroupInputVisible, 'fa-caret-up': manualGroupInputVisible}"></i> + </button> + <div + class="form-group slider" + id="manualGroupInput" + :class="manualGroupInputVisible && 'slider--open'" + :style="manualGroupInputVisible && {height: $el.scrollHeight+`px`}" + :aria-hidden="!manualGroupInputVisible" + > + <label for="eventGroupID" class="mt-2">Event group ID</label> <div class="form-group"> - <input type="text" class="form-control" id="eventGroupID" name="eventGroupID" x-model="data.eventGroupID" x-on:input="resetGroupSelector"> + <input type="text" class="form-control text-monospace" id="eventGroupID" name="eventGroupID" x-model="data.eventGroupID" x-on:input="resetGroupSelector"> <small class="form-text">You can find this short string of characters in the event group's link, in your confirmation email, or on the event group's page.</small> </div> - </div> - <div class="form-group"> <label for="eventGroupEditToken">Event group secret editing code</label> - <div class="form-group"> - <input type="text" class="form-control" id="eventGroupEditToken" name="eventGroupEditToken" x-model="data.eventGroupEditToken" x-on:input="resetGroupSelector"> + <div class="form-group mb-0"> + <input type="text" class="form-control text-monospace" id="eventGroupEditToken" name="eventGroupEditToken" x-model="data.eventGroupEditToken" x-on:input="resetGroupSelector"> <small class="form-text">You can find this long string of characters in the confirmation email you received when you created the event group.</small> </div> </div> |