diff --git a/app/webpacker/controllers/input_char_count_controller.js b/app/webpacker/controllers/input_char_count_controller.js new file mode 100644 index 0000000000..cafd93a673 --- /dev/null +++ b/app/webpacker/controllers/input_char_count_controller.js @@ -0,0 +1,21 @@ +import { Controller } from "stimulus"; + +export default class extends Controller { + static targets = ["count", "input"]; + + connect() { + this.inputTarget.addEventListener("keyup", this.countCharacters.bind(this)); + this.countCharacters(); + } + + countCharacters() { + this.displayCount( + this.inputTarget.value.length, + this.inputTarget.maxLength + ); + } + + displayCount(count, max) { + this.countTarget.textContent = `${count}/${max}`; + } +} diff --git a/spec/javascripts/stimulus/input_char_count_controller_test.js b/spec/javascripts/stimulus/input_char_count_controller_test.js new file mode 100644 index 0000000000..668531bfd1 --- /dev/null +++ b/spec/javascripts/stimulus/input_char_count_controller_test.js @@ -0,0 +1,34 @@ +/** + * @jest-environment jsdom + */ + +import { Application } from "stimulus"; +import input_char_count_controller from "../../../app/webpacker/controllers/input_char_count_controller"; + +describe("InputCharCountController", () => { + beforeAll(() => { + const application = Application.start(); + application.register("input-char-count", input_char_count_controller); + }); + + describe("default behavior", () => { + beforeEach(() => { + document.body.innerHTML = `
+ + +
`; + }); + + it("handle the content", () => { + const input = document.getElementById("input"); + const count = document.getElementById("count"); + // Default value + expect(count.textContent).toBe("5/280"); + + input.value = "Hello world"; + input.dispatchEvent(new Event("keyup")); + + expect(count.textContent).toBe("11/280"); + }); + }); +});