diff --git a/app/components/tag_list_input_component/tag_list_input_component.html.haml b/app/components/tag_list_input_component/tag_list_input_component.html.haml index 0149584b2c..e1e4440933 100644 --- a/app/components/tag_list_input_component/tag_list_input_component.html.haml +++ b/app/components/tag_list_input_component/tag_list_input_component.html.haml @@ -1,7 +1,8 @@ - #%div{ "data-controller": "tag-list-input-component--tag-list-input" } -%div{ "data-controller": "tag-list-input-component--tag-list-input" } - = f.hidden_field method.to_sym, value: tags.join(","), "data-tag-list-input-component--tag-list-input-target": "tagList" - .tags-input{ } +%div{ "data-controller": "tag-list-input-component--tag-list-input", "data-tag-list-input-component--tag-list-input-highlight-class-value": "changed" } + - # We use display:none instead of hidden field, so changes to the value can be picked up by the bulkFormController + = f.text_field method.to_sym, value: tags.join(","), "data-tag-list-input-component--tag-list-input-target": "tagList", "style": "display: none" + .tags-input .tags %ul.tag-list{"data-tag-list-input-component--tag-list-input-target": "list"} %template{"data-tag-list-input-component--tag-list-input-target": "template"} diff --git a/app/components/tag_list_input_component/tag_list_input_component.scss b/app/components/tag_list_input_component/tag_list_input_component.scss index 64e7998d29..551cbebb8c 100644 --- a/app/components/tag_list_input_component/tag_list_input_component.scss +++ b/app/components/tag_list_input_component/tag_list_input_component.scss @@ -12,6 +12,11 @@ height: 100%; box-shadow: none; + &.changed { + border: 1px solid $color-txt-changed-brd; + border-radius: 4px; + } + .tag-list { margin: 0; padding: 0; diff --git a/app/components/tag_list_input_component/tag_list_input_controller.js b/app/components/tag_list_input_component/tag_list_input_controller.js index 1316b85855..c65c0aa230 100644 --- a/app/components/tag_list_input_component/tag_list_input_controller.js +++ b/app/components/tag_list_input_component/tag_list_input_controller.js @@ -2,6 +2,7 @@ import { Controller } from "stimulus"; export default class extends Controller { static targets = ["tagList", "newTag", "template", "list"]; + static values = { highlightClass: String }; addTag() { // add to tagList @@ -13,6 +14,8 @@ export default class extends Controller { spanElement.innerText = this.newTagTarget.value; this.listTarget.appendChild(newTagElement); + this.#highlightList(); + // Clear new tag value this.newTagTarget.value = ""; } @@ -27,6 +30,10 @@ export default class extends Controller { tags.splice(index, 1); this.tagListTarget.value = tags.join(","); + // manualy dispatch an Input event so the change gets picked up by the bulk form controller + this.tagListTarget.dispatchEvent(new InputEvent("input")); + this.#highlightList(); + // Remove HTML element from the list event.srcElement.parentElement.parentElement.remove(); } @@ -34,7 +41,17 @@ export default class extends Controller { // Strip comma from tag name filterInput(event) { if (event.key === ",") { - event.srcElement.value = event.srcElement.value.replace(",",""); + event.srcElement.value = event.srcElement.value.replace(",", ""); + } + } + + // private + + #highlightList() { + if (this.highlightClassValue !== "") { + // div with the tags class + const tagsInputDiv = this.tagListTarget.nextElementSibling.firstElementChild; + tagsInputDiv.classList.add(this.highlightClassValue); } } } diff --git a/app/webpacker/controllers/bulk_form_controller.js b/app/webpacker/controllers/bulk_form_controller.js index 5cffebaee9..7b6a308008 100644 --- a/app/webpacker/controllers/bulk_form_controller.js +++ b/app/webpacker/controllers/bulk_form_controller.js @@ -24,7 +24,7 @@ export default class BulkFormController extends Controller { connect() { // disable form submit via enter key, so we can use enter key to create new product tags - hotkeys('enter', function (event, handler) { + hotkeys("enter", function (event, handler) { event.preventDefault(); }); @@ -32,7 +32,6 @@ export default class BulkFormController extends Controller { this.form = this.element; // Start listening for any changes within the form - // TODO make sure tag inpug appreas here when deleted this.#registerElements(this.form.elements); this.toggleFormChanged(); @@ -174,6 +173,8 @@ export default class BulkFormController extends Controller { return !areBothBlank && selectedOption !== defaultSelected; } else { + // This doesn't work with hidden field + // Workaround: use a text field with "display:none;" return element.defaultValue !== undefined && element.value != element.defaultValue; } } diff --git a/spec/javascripts/stimulus/tag_list_input_controller_test.js b/spec/javascripts/stimulus/tag_list_input_controller_test.js index b9c266de1d..b054c2fba2 100644 --- a/spec/javascripts/stimulus/tag_list_input_controller_test.js +++ b/spec/javascripts/stimulus/tag_list_input_controller_test.js @@ -13,7 +13,10 @@ describe("TagListInputController", () => { beforeEach(() => { document.body.innerHTML = ` -
+
{ describe("addTag", () => { beforeEach(() => { variant_add_tag.value = "new_tag"; - // { key: "Enter" } variant_add_tag.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter" })); }); @@ -95,6 +97,12 @@ describe("TagListInputController", () => { it("clears the tag input", () => { expect(variant_add_tag.value).toBe(""); }); + + it("higlights the tag list", () => { + const tagList = document.getElementsByClassName("tags")[0]; + + expect(tagList.classList).toContain("changed"); + }); }); describe("removeTag", () => { @@ -113,11 +121,17 @@ describe("TagListInputController", () => { // 1 template + 2 tags expect(tagList.childElementCount).toBe(3); }); + + it("higlights the tag list", () => { + const tagList = document.getElementsByClassName("tags")[0]; + + expect(tagList.classList).toContain("changed"); + }); }); describe("filterInput", () => { it("removes comma from the tag input", () => { - variant_add_tag.value = "text" + variant_add_tag.value = "text"; variant_add_tag.dispatchEvent(new KeyboardEvent("keyup", { key: "," })); expect(variant_add_tag.value).toBe("text");