Binding multiple actions to the same event with Stimulus

229 Views Asked by At

Does anyone know if it's possible to bind multiple actions to the same event with Stimulus in a Rails template?

I currently have this:

<%= form.text_area :content, value: '', id: "message-input",
                           data: { action: "input->message-form#inputChange input->form#autogrowInput 
                           keydown.enter->message-form#sendMessage keydown.enter->message-actions#clearReply 
                           keydown.ctrl+enter->message-form#addNewLine keydown.ctrl+enter->form#autogrowInput", message_form_target: "messageInput", form_target: "inputField" },
                           class: "form-input-no-label", autofocus: true %>

I want to avoid duplicating the event calls and chain multiple actions like this:

<%= form.text_area :content, value: '', id: "message-input",
                           data: { action: "input->message-form#inputChange form#autogrowInput
                           keydown.enter->message-form#sendMessage message-actions#clearReply
                           keydown.ctrl+enter->message-form#addNewLine form#autogrowInput", message_form_target: "messageInput", form_target: "inputField" },
                           class: "form-input-no-label", autofocus: true %>

But this causes the actions named to stop working.

Does anyone know if it's possible to avoid event duplication?

1

There are 1 best solutions below

1
Alex On BEST ANSWER

You'd be better off just formatting your code:

<%= form.text_area :content,
  data: {
    action: %(
      input->message-form#inputChange
      input->form#autogrowInput
      keydown.enter->message-form#sendMessage
      keydown.enter->message-actions#clearReply
      keydown.ctrl+enter->message-form#addNewLine
      keydown.ctrl+enter->form#autogrowInput
    ),
    message_form_target: :messageInput,
    form_target: :inputField
  }
%>

This way you can quickly copy paste lines and move things around.


Alternatively, you could make a helper:

# app/helpers/application_helper.rb

def data_action hash
  hash.map do |event, actions|
    actions.map do |controller, action|
      "#{event}->#{controller.to_s.dasherize}##{action}"
    end
  end.join(" ")
end
<%= form.text_area :content,
  data: {
    action: data_action(
      input:                {message_form: :inputChange, form: :autogrowInput},
      "keydown.enter":      {message_form: :sendMessage, message_actions: :clearReply},
      "keydown.ctrl+enter": {message_form: :addNewLine,  form: :autogrowInput}
    ),
    message_form_target: :messageInput,
    form_target: :inputField
  }
%>