diff --git a/app/javascript/controllers/textarea_controller.ts b/app/javascript/controllers/textarea_controller.ts new file mode 100644 index 000000000..410c5be65 --- /dev/null +++ b/app/javascript/controllers/textarea_controller.ts @@ -0,0 +1,44 @@ +import { ApplicationController } from './application_controller'; + +export class TextareaController extends ApplicationController { + static values = { + maxRows: Number + }; + + declare readonly maxRowsValue: number; + + connect() { + if (this.maxRowsValue) { + this.attachEvents(); + } + } + + private attachEvents() { + this.on('keyup', (event: KeyboardEvent) => { + if (event.key === 'Enter') { + this.processTextareaContent(event); + } + }); + + this.on('paste', (event: ClipboardEvent) => { + // Wait for the paste event to complete + setTimeout(() => this.processTextareaContent(event), 0); + }); + } + + private processTextareaContent(event: Event) { + const target = event.target as HTMLTextAreaElement; + let lines = target.value.split('\n'); + + if (lines.length > this.maxRowsValue) { + // Truncate lines to the maximum allowed + lines = lines.slice(0, this.maxRowsValue); + target.value = lines.join('\n'); + + if (event instanceof KeyboardEvent) { + // Prevent the default action only for KeyboardEvent (enter key) + event.preventDefault(); + } + } + } +} diff --git a/app/views/administrateurs/attestation_template_v2s/edit.html.haml b/app/views/administrateurs/attestation_template_v2s/edit.html.haml index dc5de4e26..533511fa3 100644 --- a/app/views/administrateurs/attestation_template_v2s/edit.html.haml +++ b/app/views/administrateurs/attestation_template_v2s/edit.html.haml @@ -30,7 +30,7 @@ %h6 En-tête .fr-fieldset__element{ class: class_names("hidden" => !@attestation_template.official_layout?), data: { "attestation-target": 'logoMarianneLabelFieldset'} } - = render Dsfr::InputComponent.new(form: f, attribute: :label_logo, input_type: :text_area, required: false, opts: { rows: 3 }) do |c| + = render Dsfr::InputComponent.new(form: f, attribute: :label_logo, input_type: :text_area, required: false, opts: { rows: 3, data: { controller: :textarea, textarea_max_rows_value: 3 } }) do |c| - c.with_hint { "Exemple: Ministère de la Mer. 3 lignes maximum" } .fr-fieldset__element{ data: { attestation_target: 'logoAttachmentFieldset' } } @@ -47,7 +47,7 @@ = render Attachment::EditComponent.new(attached_file: @attestation_template.logo, direct_upload: false) .fr-fieldset__element - = render Dsfr::InputComponent.new(form: f, attribute: :label_direction, input_type: :text_area, required: false, opts: { rows: 2 }) do |c| + = render Dsfr::InputComponent.new(form: f, attribute: :label_direction, input_type: :text_area, required: false, opts: { rows: 2, data: { controller: :textarea, textarea_max_rows_value: 2 } }) do |c| - c.with_hint { "Exemple: Direction interministérielle du numérique. 2 lignes maximum" } .fr-fieldset__element.fr-mt-2w @@ -85,7 +85,7 @@ = render Attachment::EditComponent.new(attached_file: @attestation_template.signature, direct_upload: false) .fr-fieldset__element - = render Dsfr::InputComponent.new(form: f, attribute: :footer, input_type: :text_area, required: false, opts: { rows: 3 }) do |c| + = render Dsfr::InputComponent.new(form: f, attribute: :footer, input_type: :text_area, required: false, opts: { rows: 3, data: { controller: :textarea, textarea_max_rows_value: 3 } }) do |c| - c.with_hint { "Exemple: 20 avenue de Ségur, 75007 Paris" } .fr-col-12.fr-col-md-4.fr-background-alt--blue-france