Hacker News new | ask | show | jobs
by JeremyNT 1911 days ago
There are a lot of ways to skin this cat!

You can also have a hidden form submission that does this from the existing controller so you don't need to specify the URL.

For example, you can add a hidden submit button like

  form.submit 'preview', data: { composer_target: 'submit' }, hidden: true
Instead of a stimulus target, you wrap your preview area in a turbo frame

  <turbo-frame id="output">
  ...
  </turbo-frame>
In your (ruby) controller you can re-use the existing controller action:

  def create
    @post = Post.new(post_attributes)
    preview && return if params[:commit] == 'preview'
    ...
  end
Do the turbo junk in a private method for the preview:

  private

  def preview
    render turbo_stream: turbo_stream.replace(
      'output', partial: "posts/preview", locals: { post: @post }
    end
  end

Your stimulus controller now just does this:

  preview() {
    this.submitTarget.click();
  }
I'm not sure which I prefer!
1 comments

Yep, that's what actually cross my mind first. In the end, I wanted to avoid depending on the model, but it's certainly interesting.
Once the complexity ramps up and the side effects compound, that's when I really appreciate server side rendering. And incidentally, that's exactly when I like to have the whole model!

I just refactored some old jquery stuff to use turbo and stimulus on a really complex form and it turned out well, I think. But below a certain level of complexity, it would have made sense to just do everything directly in stimulus with no AJAX at all.

I know your preview example is contrived (it's tough getting a real-world representative demo into a blog post, so please don't read this as criticism, I don't mean to say it's a bad example and I'm not trying to pick on it!) but really simple use cases are exactly the "sweet spot" for doing everything directly in the browser using Stimulus without having to call back to the server. Only once you start piling in business logic or reshuffling major parts of the display around does it fully pay off, and that's also about when you'll start appreciating having the whole model and the ability to re-use partials (rather than having to pick off a few pieces manually).

EDIT:

And just to be clear, in the sample code I put in above, you don't actually have to use the model. You can always just shove a single parameter into a special partial and go.