diff --git a/tildes/static/js/behaviors/auto-focus.js b/tildes/static/js/behaviors/auto-focus.js index cb1cf63..17c408e 100644 --- a/tildes/static/js/behaviors/auto-focus.js +++ b/tildes/static/js/behaviors/auto-focus.js @@ -1,11 +1,14 @@ // Copyright (c) 2018 Tildes contributors // SPDX-License-Identifier: AGPL-3.0-or-later -$.onmount('[data-js-auto-focus]', function() { - $input = $(this); +$.onmount("[data-js-auto-focus]", function() { + var $input = $(this); // just calling .focus() will place the cursor at the start of the field, // so un-setting and re-setting the value moves the cursor to the end var original_val = $input.val(); - $input.focus().val('').val(original_val); + $input + .focus() + .val("") + .val(original_val); }); diff --git a/tildes/static/js/behaviors/autocomplete-chip-clear.js b/tildes/static/js/behaviors/autocomplete-chip-clear.js index e90b3a1..7f3b784 100644 --- a/tildes/static/js/behaviors/autocomplete-chip-clear.js +++ b/tildes/static/js/behaviors/autocomplete-chip-clear.js @@ -1,13 +1,13 @@ // Copyright (c) 2019 Tildes contributors // SPDX-License-Identifier: AGPL-3.0-or-later -$.onmount('[data-js-autocomplete-chip-clear]', function() { +$.onmount("[data-js-autocomplete-chip-clear]", function() { function clearChip($chip) { - var $tagsHiddenInput = $('[data-js-autocomplete-hidden-input]'); - var $autocompleteInput = $('[data-js-autocomplete-input]'); + var $tagsHiddenInput = $("[data-js-autocomplete-hidden-input]"); + var $autocompleteInput = $("[data-js-autocomplete-input]"); - var textToReplace = new RegExp($chip.text() + ','); - $tagsHiddenInput.val($tagsHiddenInput.val().replace(textToReplace, '')); + var textToReplace = new RegExp($chip.text() + ","); + $tagsHiddenInput.val($tagsHiddenInput.val().replace(textToReplace, "")); $chip.remove(); $autocompleteInput.focus(); } @@ -19,7 +19,7 @@ $.onmount('[data-js-autocomplete-chip-clear]', function() { $(this).keydown(function(event) { switch (event.key) { - case 'Backspace': + case "Backspace": event.preventDefault(); clearChip($(this).parent()); break; diff --git a/tildes/static/js/behaviors/autocomplete-input.js b/tildes/static/js/behaviors/autocomplete-input.js index 0549bef..910094d 100644 --- a/tildes/static/js/behaviors/autocomplete-input.js +++ b/tildes/static/js/behaviors/autocomplete-input.js @@ -1,38 +1,47 @@ // Copyright (c) 2019 Tildes contributors // SPDX-License-Identifier: AGPL-3.0-or-later -$.onmount('[data-js-autocomplete-input]', function() { +$.onmount("[data-js-autocomplete-input]", function() { function addChip($input) { - var $autocompleteContainer = $input.parents('[data-js-autocomplete-container]').first(); - var $chips = $autocompleteContainer.find('[data-js-autocomplete-chips]').first(); - var $tagsHiddenInput = $('[data-js-autocomplete-hidden-input]'); - - $input.val().split(',').map(function(tag) { - return tag.trim(); - }).filter(function(tag) { - return tag !== ''; - }).forEach(function(tag) { - if (!$tagsHiddenInput.val().match(new RegExp('(^|,)' + tag + ','))) { - var clearIcon = document.createElement('a'); - clearIcon.classList.add('btn'); - clearIcon.classList.add('btn-clear'); - clearIcon.setAttribute('data-js-autocomplete-chip-clear', ''); - clearIcon.setAttribute('aria-label', 'Close'); - clearIcon.setAttribute('role', 'button'); - clearIcon.setAttribute('tabindex', $chips.children().length); - - var $chip = $(document.createElement('div')); - $chip.addClass('chip'); - $chip.html(tag); - $chip.append(clearIcon); - - $chips.append($chip); - - $tagsHiddenInput.val($tagsHiddenInput.val() + tag + ','); - } - }); - $autocompleteContainer.find('[data-js-autocomplete-input]').val(''); - $autocompleteContainer.find('[data-js-autocomplete-suggestions]').html(''); + var $autocompleteContainer = $input + .parents("[data-js-autocomplete-container]") + .first(); + var $chips = $autocompleteContainer + .find("[data-js-autocomplete-chips]") + .first(); + var $tagsHiddenInput = $("[data-js-autocomplete-hidden-input]"); + + $input + .val() + .split(",") + .map(function(tag) { + return tag.trim(); + }) + .filter(function(tag) { + return tag !== ""; + }) + .forEach(function(tag) { + if (!$tagsHiddenInput.val().match(new RegExp("(^|,)" + tag + ","))) { + var clearIcon = document.createElement("a"); + clearIcon.classList.add("btn"); + clearIcon.classList.add("btn-clear"); + clearIcon.setAttribute("data-js-autocomplete-chip-clear", ""); + clearIcon.setAttribute("aria-label", "Close"); + clearIcon.setAttribute("role", "button"); + clearIcon.setAttribute("tabindex", $chips.children().length); + + var $chip = $(document.createElement("div")); + $chip.addClass("chip"); + $chip.html(tag); + $chip.append(clearIcon); + + $chips.append($chip); + + $tagsHiddenInput.val($tagsHiddenInput.val() + tag + ","); + } + }); + $autocompleteContainer.find("[data-js-autocomplete-input]").val(""); + $autocompleteContainer.find("[data-js-autocomplete-suggestions]").html(""); $.onmount(); } @@ -46,70 +55,92 @@ $.onmount('[data-js-autocomplete-input]', function() { // attach an event handler to the form that will add the input's value to // the end of the tags list before submitting (to include any tag that's // still in the input and wasn't converted to a chip) - $(this).closest("form").on("beforeSend.ic", function(evt, elt, data, settings, xhr, requestId) { - $autocompleteInput = $(elt).find("[data-js-autocomplete-input]").first(); - if (!$autocompleteInput.val()) { - return; - } - - var dataPieces = settings.data.split("&"); - for (i = 0; i < dataPieces.length; i++) { - if (dataPieces[i].indexOf("tags=") === 0) { - dataPieces[i] += $autocompleteInput.val(); - break; + $(this) + .closest("form") + /* eslint-disable-next-line no-unused-vars */ + .on("beforeSend.ic", function(evt, elt, data, settings, xhr, requestId) { + var $autocompleteInput = $(elt) + .find("[data-js-autocomplete-input]") + .first(); + if (!$autocompleteInput.val()) { + return; } - } - settings.data = dataPieces.join("&"); - }); + + var dataPieces = settings.data.split("&"); + for (var i = 0; i < dataPieces.length; i++) { + if (dataPieces[i].indexOf("tags=") === 0) { + dataPieces[i] += $autocompleteInput.val(); + break; + } + } + settings.data = dataPieces.join("&"); + }); } - if ($(this).val() !== '') { + if ($(this).val() !== "") { addChip($(this)); } - $(this).focus(function(event) { - var $autocompleteContainer = $(this).parents('[data-js-autocomplete-container]').first(); - var $chips = $autocompleteContainer.find('[data-js-autocomplete-chips]').first(); + $(this).focus(function() { + var $autocompleteContainer = $(this) + .parents("[data-js-autocomplete-container]") + .first(); + var $chips = $autocompleteContainer + .find("[data-js-autocomplete-chips]") + .first(); - $chips.children().removeClass('active'); + $chips.children().removeClass("active"); }); $(this).keydown(function(event) { + var $autocompleteMenu = $("[data-js-autocomplete-menu]").first(); + var $nextActiveItem = null; + switch (event.key) { - case 'Escape': - $('[data-js-autocomplete-menu]').remove(); + case "Escape": + $("[data-js-autocomplete-menu]").remove(); $(this).blur(); break; - case ',': - case 'Enter': + case ",": + case "Enter": event.preventDefault(); addChip($(this)); break; - case 'ArrowDown': + case "ArrowDown": event.preventDefault(); - var $autocompleteMenu = $('[data-js-autocomplete-menu]').first(); - var $nextActiveItem = $autocompleteMenu.children('.menu-item').first(); - $nextActiveItem.children('[data-js-autocomplete-menu-item]').first().focus(); + $nextActiveItem = $autocompleteMenu.children(".menu-item").first(); + $nextActiveItem + .children("[data-js-autocomplete-menu-item]") + .first() + .focus(); break; - case 'ArrowUp': + case "ArrowUp": event.preventDefault(); - var $autocompleteMenu = $('[data-js-autocomplete-menu]').first(); - var $nextActiveItem = $autocompleteMenu.children('.menu-item').last(); - $nextActiveItem.children('[data-js-autocomplete-menu-item]').first().focus(); + $nextActiveItem = $autocompleteMenu.children(".menu-item").last(); + $nextActiveItem + .children("[data-js-autocomplete-menu-item]") + .first() + .focus(); break; - case 'Backspace': - if ($(this).val() === '') { + case "Backspace": + if ($(this).val() === "") { event.preventDefault(); - var $autocompleteContainer = $(this).parents('[data-js-autocomplete-container]').first(); - var $chips = $autocompleteContainer.find('[data-js-autocomplete-chips]').first(); - var $tagsHiddenInput = $("[data-js-autocomplete-hidden-input]"); + var $autocompleteContainer = $(this) + .parents("[data-js-autocomplete-container]") + .first(); + var $chips = $autocompleteContainer + .find("[data-js-autocomplete-chips]") + .first(); var $lastChip = $chips.children().last(); if ($lastChip.length) { $(this).blur(); - if (!$lastChip.hasClass('active')) { + if (!$lastChip.hasClass("active")) { $lastChip.addClass("active"); - $lastChip.children('[data-js-autocomplete-chip-clear]').first().focus(); + $lastChip + .children("[data-js-autocomplete-chip-clear]") + .first() + .focus(); } } } @@ -117,37 +148,44 @@ $.onmount('[data-js-autocomplete-input]', function() { } }); - $(this).keyup(function(event) { + $(this).keyup(function() { var $this = $(this); - var $autocompleteMenu = $('[data-js-autocomplete-menu]'); + var $autocompleteMenu = $("[data-js-autocomplete-menu]"); if ($autocompleteMenu) { $autocompleteMenu.remove(); } - if ($this.val() === '') { + if ($this.val() === "") { return; } - var $tagsHiddenInput = $('[data-js-autocomplete-hidden-input]'); - var suggestions = $this.data('js-autocomplete-input').filter(function(suggestion) { - return suggestion.startsWith($this.val().toLowerCase()) && - !$tagsHiddenInput.val().match(new RegExp('(^|,)' + suggestion + ',')); - }); + var $tagsHiddenInput = $("[data-js-autocomplete-hidden-input]"); + var suggestions = $this + .data("js-autocomplete-input") + .filter(function(suggestion) { + return ( + suggestion.startsWith($this.val().toLowerCase()) && + !$tagsHiddenInput + .val() + .match(new RegExp("(^|,)" + suggestion + ",")) + ); + }); if (suggestions.length === 0) { return; } - var $autocompleteSuggestions = $('[data-js-autocomplete-suggestions]'); + var $autocompleteSuggestions = $("[data-js-autocomplete-suggestions]"); $autocompleteMenu = $('