aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/javascript/controllers/thing_controller.js63
-rw-r--r--app/views/things/_form.html.erb48
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>