diff options
Diffstat (limited to 'app')
| -rw-r--r-- | app/javascript/controllers/thing_controller.js | 63 | ||||
| -rw-r--r-- | app/views/things/_form.html.erb | 48 |
2 files changed, 88 insertions, 23 deletions
diff --git a/app/javascript/controllers/thing_controller.js b/app/javascript/controllers/thing_controller.js index 1518216..9c19eb6 100644 --- a/app/javascript/controllers/thing_controller.js +++ b/app/javascript/controllers/thing_controller.js @@ -2,6 +2,67 @@ import { Controller } from "@hotwired/stimulus" // Gathers all the methods that are relevant when manipulating things. export default class extends Controller { + static targets = ["identifier"]; + + connect() { + // The "target" completion is achieved by managing updates from authors + // (first part) and year (last one). We have to account when connecting that + // we might come from a reload of the page, which would contain partial + // data. Hence, this ought to be initialized with the current values from + // their respective inputs. + this.firstPart = document.getElementById("thing_authors").value.trim(); + this.lastPart = document.getElementById("thing_year").value.trim(); + + // Whether autocompletion has been canceled or not. This will be forced to + // true when `#cancel` is called (i.e. the user has manually entered a value + // for "target"), or if we are coming from a page that already had data + // filled in. + this.canceled = this.firstPart !== '' && this.lastPart !== '' && + document.getElementById("thing_target").value.trim() !== ''; + } + + // Update the information we get from the authors field so to autocomplete it + // into the "target" field if possible. + authorsUpdate() { + if (this.canceled) { + return; + } + + const text = document.getElementById("thing_authors").value.trim(); + if (text === '') { + return; + } + + const authors = text.split(',').map(function(author) { + return author.split(' ').pop().trim(); + }); + + this.firstPart = authors.join(''); + this.identifierTarget.value = `${this.firstPart}${this.lastPart}`; + } + + // Update the information we get from the year field so to autocomplete it + // into the "target" field if possible. + yearUpdate() { + if (this.canceled) { + return; + } + + const text = document.getElementById("thing_year").value.trim(); + if (text === '') { + return; + } + + this.lastPart = text; + this.identifierTarget.value = `${this.firstPart}${this.lastPart}`; + } + + // The user is writing into the "target" field directly: cancel autocompletion + // altogether. + cancel() { + this.canceled = true; + } + // Update the external link depending on the changed value. The link will also // be hidden/shown depending if the current URL is empty or not. updateLink() { @@ -9,8 +70,10 @@ export default class extends Controller { if (cur === "") { document.getElementById("thing-external-url-id").classList.add('hidden'); + document.getElementById("thing-access-div").classList.add('hidden'); } else { document.getElementById("thing-external-url-id").classList.remove('hidden'); + document.getElementById("thing-access-div").classList.remove('hidden'); document.getElementById("thing-external-url-id").href = cur; } } diff --git a/app/views/things/_form.html.erb b/app/views/things/_form.html.erb index 4aa3dc7..11d2230 100644 --- a/app/views/things/_form.html.erb +++ b/app/views/things/_form.html.erb @@ -1,7 +1,7 @@ <%= form_with(model: thing) do |form| %> <%= render "layouts/errors", model: thing %> - <div id="thing_form"> + <div id="thing_form" data-controller="thing"> <div class="thing_large"> <%= form.label :title %> <%= form.text_field :title, autofocus: true, autocapitalize: 'on', required: true %> @@ -9,7 +9,7 @@ <div class="thing_large"> <%= form.label :authors %> - <%= form.text_field :authors, autocapitalize: 'words', required: true %> + <%= form.text_field :authors, autocapitalize: 'words', "data-action": "thing#authorsUpdate", required: true %> <%= form.check_box :editors %> <%= form.label :editors %> </div> @@ -20,36 +20,18 @@ </div> <div> - <%= form.label :target %> - <%= form.text_field :target, autocapitalize: 'on', required: true %> - </div> - - <div> <%= form.label :publisher %> <%= form.text_field :publisher, autocapitalize: 'on' %> </div> <div> <%= form.label :year %> - <%= form.number_field :year %> + <%= form.number_field :year, "data-action": "thing#yearUpdate" %> </div> <div> - <%= form.label :address %> - <%= form.text_field :address, autocapitalize: 'on' %> - </div> - - <div data-controller="thing"> - <%= form.label :url do %> - <%= I18n.t('activerecord.attributes.thing.url') %> - <a id="thing-external-url-id" href="<%= thing.url %>" target="_blank" title="<%= I18n.t('things.go-to') %>" class="<%= 'hidden' if thing.url.blank? %>"><i class="gg-external"></i></a> - <% end %> - <%= form.text_field :url, "data-action": "thing#updateLink" %> - </div> - - <div> - <%= form.label :access %> - <%= form.date_field :access %> + <%= form.label :target %> + <%= form.text_field :target, autocapitalize: 'on', "data-action": "thing#cancel", "data-thing-target": "identifier", required: true %> </div> <div> @@ -68,6 +50,26 @@ </div> <div> + <%= form.label :address %> + <%= form.text_field :address, autocapitalize: 'on' %> + </div> + + <div> + <%= form.label :url do %> + <%= I18n.t('activerecord.attributes.thing.url') %> + <a id="thing-external-url-id" href="<%= thing.url %>" target="_blank" title="<%= I18n.t('things.go-to') %>" class="<%= 'hidden' if thing.url.blank? %>"><i class="gg-external"></i></a> + <% end %> + <%= form.text_field :url, "data-action": "thing#updateLink" %> + </div> + + <div> + <div id="thing-access-div" class="<%= 'hidden' if thing.url.blank? %>"> + <%= form.label :access %> + <%= form.date_field :access %> + </div> + </div> + + <div> <%= form.label :status %> <%= form.select :status, options_for_select(Thing.statuses.map { |k, _| [I18n.t("things.status.#{k}"), k] }.sort, thing.status) %> </div> |
