Skip to content

Instantly share code, notes, and snippets.

@secretpray
Last active May 5, 2024 03:32
Show Gist options
  • Save secretpray/2b72a41d3d08200967fcf7a7481944d9 to your computer and use it in GitHub Desktop.
Save secretpray/2b72a41d3d08200967fcf7a7481944d9 to your computer and use it in GitHub Desktop.
 fetch(href, {
      headers: {
        Accept: "text/vnd.turbo-stream.html",
      },
    })
      .then(r => r.text())
      .then(html => Turbo.renderStreamMessage(html))
//  optionally reflect the url    .then(_ => history.replaceState(history.state, "", href))
import { Controller } from '@hotwired/stimulus'

export default class extends Controller {
  static values = {
    src: String,
  }

  connect() {
    fetch(this.srcValue, {
      headers: {
        Accept: "text/vnd.turbo-stream.html",
      },
    }).then(r => r.text())
      .then(html => Turbo.renderStreamMessage(html))
  }
}
@secretpray
Copy link
Author

secretpray commented Jan 29, 2024

Observe changes

let observer = new MutationObserver(mutationRecords => {
  console.log(mutationRecords); // console.log(the changes)
  // execute your code here.
});
  
let elem = document.getElementById("div-id");
    
// observe everything except attributes
observer.observe(elem, {
  childList: true, // observe direct children
  subtree: true, // and lower descendants too
  characterDataOldValue: true // pass old data to callback
});

Link1

Link2

const afterRenderEvent = new Event("turbo:after-stream-render");
addEventListener("turbo:before-stream-render", (event) => {
  const originalRender = event.detail.render

  event.detail.render = function (streamElement) {
    originalRender(streamElement)
    document.dispatchEvent(afterRenderEvent);
  }
})

or

  show() {
      fetch("/path/to/partial")
        .then((res) => res.text())
        .then((html) => {
          const fragment = document
            .createRange()
            .createContextualFragment(html);

          this.element.appendChild(fragment);
          // OR document.getElementById("testy_element").appendChild(fragment)
        });
     
  }
<div class="container" data-controller="test">
<button data-action="test#show">Do the Thing</button>
<!-- partial would appear here -->
</div>

@secretpray
Copy link
Author

Broadcasting Progress from Background Jobs

# app/jobs/heavy_task_job.rb
class HeavyTaskJob < ApplicationJob
  queue_as :default
  before_perform :broadcast_initial_update

  def perform(current_user_id)

    total_count.times do |i|
      SmallTaskJob.perform_later(current_user_id, i, total_count)
    end
  end

  private

  def broadcast_initial_update
    Turbo::StreamsChannel.broadcast_replace_to ["heavy_task_channel", current_user.to_gid_param].join(":"),
      target: "heavy_task",
      partial: "heavy_tasks/progress",
      locals: {
        total_count: total_count
      }
  end

  def total_count
    @total_count ||= rand(10..100)
  end

  def current_user
    @current_user ||= User.find(self.arguments.first)
  end
end

@secretpray
Copy link
Author

Link

import { Controller } from "@hotwired/stimulus"
import { FetchRequest } from '@rails/request.js'


export default class extends Controller {
  static targets = [ "formSelect", "dynamicForm" ]

  async fetch_dynamic() {
    let selection = this.formSelectTarget.value
    const request = new FetchRequest('get', '/posts/new', { query: {type: selection}})
    const response = await request.perform()
    if (response.ok) {
      const form = await response.text
      const dynamic_form = this.dynamicFormTarget
      dynamic_form.innerHTML=form
    }
  }
}
= form_for @post, html: {'data-controller'=>'form'} do |f|

  = f.label :workflow 
  = f.select :workflow, options_for_select(@workflow_options), {}, 'data-action'=>'change->form#fetch_dynamic', 'data-form-target'=>'formSelect', id: 'form_select'
  %div{'data-form-target'=>'dynamicForm'}
    = f.label :information, "Enter your information"
    = f.text_field :information
  %br
  = f.submit "Create Post"
class PostsController < ApplicationController

# GET /posts/new
def new
  @post = Post.new
  @workflow_options = %i[foo bar baz qux] # different form partials
  requested_form = params[:type] # type of form partial specified in a query parameter
  if requested_form
    render partial: "#{requested_form}_form", layout: false
    return
  end
end

end
#_baz_form.html.haml

= label :post, :information, "Enter your baz information"
= text_field :post, :information

@secretpray
Copy link
Author

async uploadFileToServer(file) {
  // ...
  const response = await fetch("/test/upload", {
    // ...
  })
  
  const html = await response.text()
  Turbo.renderStreamMessage(html)
}

@secretpray
Copy link
Author

Turbo.visit(url, { frame: '_top', action: 'advance' })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment