What are the ways to change the newly loaded/rendered data within a <turbo-frame> tag?

I have successfully integrated a search form with a text input field that updates the src attribute value of a <turbo-frame> element, triggering an automatic fetch and render of data. The search result displayed within the <turbo-frame> is presented in a list format using <ul><li>.

Now, I am looking to include a custom attribute (using setAttribute()) to each <li> element in the list every time a search result is loaded/rendered.

I have attempted various methods such as utilizing addEventListener() on Stimulus controller, document, and window, experimenting with both Turbo and non-Turbo events. Additionally, I have explored the built-in Stimulus function afterLoad, along with other strategies like employing MutationObserver, but have not achieved the desired outcome.

What is the approach to modifying the content within the <turbo-frame> once it has been freshly loaded/rendered?

Answer №1

You can simplify the process by adding turbo_frame: "name" to your form and submitting it, rather than manually setting the src.

bin/rails g scaffold Item name
bin/rails db:migrate
bin/rails g stimulus search
# app/controllers/items_controller.rb

def index
  @items = if params[:search].present?
    Item.where(Item.arel_table[:name].matches("%#{params[:search]}%"))
  else
    Item.all
  end
end
# app/views/items/index.html.erb

<%= tag.div data: {controller: "search"} do %>

  <%= form_with url: :items, method: :get,
    data: {search_target: "form", turbo_frame: :items} do |f| %>
    <%# NOTE: target the frame    ^^^^^^^^^^^^^^^^^^^         %>

    <%= f.search_field :search, placeholder: "search...",
      data: {action: "search#autoSearch"} %>
  <% end %>

  <%= turbo_frame_tag :items, target: :_top,
    data: {search_target: "results", turbo_action: :advance} do %>
    <%# NOTE: to update url as well  ^^^^^^^^^^^^^^^^^^^^^^     %>

    <%= render @items %>
  <% end %>

<% end %>
// app/javascript/controllers/search_controller.js

import { Controller } from "@hotwired/stimulus";

// Connects to data-controller="search"
export default class extends Controller {
  static targets = ["form", "results", "item"];

  connect() {
    this.resultsTarget.addEventListener("turbo:frame-render", this.resultsHandler);
  }

  resultsHandler(event) {
    event.target.querySelectorAll("li").forEach((li) => { 
      li.setAttribute("loaded", true); // <li loaded="true"></li>
    });
  }

  autoSearch() {
    // don't search on every keystroke
    clearTimeout(this.timeout);
    this.timeout = setTimeout(() => this.formTarget.requestSubmit(), 500);
  }

  // NOTE: you can also add a target and use target callbacks
  // <li data-search-target="item"> </li>
  itemTargetConnected(element) {
    // to skip initial page load
    if (this.resultsTarget.src) {
      element.setAttribute("loaded", true);
    }
  }

  disconnect() {
    this.resultsTarget.removeEventListener("turbo:frame-render", this.resultsHandler);
  }
}


To streamline the process further, consider using data-action instead of adding event listeners within the controller:

<%= turbo_frame_tag :items, target: :_top,
  data: {
    turbo_action: :advance,
    action: "turbo:frame-render->search#resultsHandler"
  } do %>

  <%= render @items %>
<% end %>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Displaying a label in AngularJS and Ionic based on the current scroll position

I am facing a challenge with an ion-content scrollable item that contains anchors to jump to specific positions. In addition to the ion-content, there is also a button outside that allows users to jump to the next position. Here's an example: Jump ...

Length Indeterminate - Pug, Express, and MongoDB

I keep encountering a persistent TypeError message stating that the length is undefined in the following code snippet. This issue is quite frustrating, especially since I've utilized the same code elsewhere in my project without any problems. users.j ...

Unable to attach numerous parameters to the content of the request

I am encountering an issue with my code where I have two classes and need to call two separate models using two store procedures to insert data into both tables. The controller is set up like this: [HttpPost] public IHttpActionResult AddData([FromBody]ILi ...

"Developing with create-react-app can be frustrating due to its sluggish performance and tendency

As I delve into the world of React, my lack of experience becomes evident. Each time I attempt to start a new project using the create-react-app command, I find myself waiting for what seems like an eternity. Discovering CodeSandbox was a game-changer - ...

What is the best way to expand the subcategories within a list?

I have successfully implemented a script to open my hamburger menu. However, I am facing an issue with subitems as some list items contain them. How can I modify the script to ensure that the subitems expand when clicked instead of just hovering? functi ...

Switching views from vertical to horizontal tab-sets in angular-ui-bootstrap

At the moment, I am using a variable called isNotMobileView passed to the template from the controller as $scope.isNotMobileView: <uib-tabset active="0" vertical="isNotMobileView"> <uib-tab index="0" heading="foo"> ... </uib-tab> ...

Learn how to access an array within an object using JavaScript and an API URL

Trying to fetch data from the swapi API to display film titles using jQuery. Below is the JavaScript code: $(function(){ function promiseTest(){ return $.ajax({ type: 'GET', url: 'https://swapi.co/api/people/', } ...

Creating a visual illustration with the simple click of a button utilizing AngularJS

I am trying to create a button that, when clicked, will draw a circle on the screen. Eventually, I plan to expand this functionality to draw multiple circles in specific locations, but for now, I just need it to draw one circle. The issue seems to be wit ...

Creating a customizable triangle design using the power of three.js

Recently, I came across the three.js library and I'm eager to incorporate it into my projects. One idea I have is to create a 2D triangle shape with hand holds on the vertices which allow me to adjust the shape in real-time. Can anyone provide guidanc ...

Is there a way to enable automatic scrolling in a Django chat application?

Hello! I am looking to implement an automatic scroll-down feature on my webpage. Every time I refresh the page, I find myself at the top of the conversation, specifically at the "start-conversation" section. Below is the code snippet that I am currently ...

If the condition is met with the presence of X in the string, execute one action; otherwise, proceed with

Currently, my code successfully grabs the results: module.exports = async function grabResult(page) { const message = await page.$eval( 'div > div:nth-child(2)', (el) => el.innerText ); const username = await page.$eval( ...

Having trouble accessing the href attribute after clicking on an <a> tag with JavaScript

My issue lies in retrieving the href attribute of <a> tags when there is another element nested inside them: Here's the code snippet: const $elems = document.querySelectorAll('.content-container a') var elems = Array.from($elems) e ...

issue encountered while attempting to load a previously saved game

I recently developed a puzzle game and added a save system, but I encountered an error while trying to load the saved data: Check out the website here And this is the saved file Here's the code snippet that is executed when loading the saved data: ...

Initiate a JavaScript promise chain using Bluebird that effectively manages and deals with potential errors

My goal is to efficiently handle all types of errors using the .catch method, including those occurring in initial synchronous code. The approach I want to take for my promise chain is as follows: const bbPromise = require('bluebird'); bbPromis ...

Transmit and Interpret Data Array using JSON

Having an array of `People` objects, I am trying to send them to PHP. However, the process of retrieving my objects back in PHP for manipulation appears to be quite complex. Although I currently have only one `Person` object in my array, I want to ensure e ...

angular.js selected row in a table

I am facing an issue with a table that includes the ng-class directive in the following format: <tbody> <tr style="cursor: pointer" class="clickable-row" ng-repeat="firm in device.firmwares" ng-class="{'success': firm.vulnScore< ...

How to iterate through two arrays using AngularJS ng-repeat

I have been attempting to create a specific layout by iterating through two arrays However, the output I am receiving from the ng-repeats does not match my desired view Below is the current code that I am working with: $scope.properties = ["First name", ...

The functionality of deep linking is currently not working properly with react-navigation

Currently working on an app using react-native 0.58 with react-navigation 3.1.5, but encountering difficulties in getting it to run properly. Here is a snippet of my code: app-navigation.js const MainStack = createBottomTabNavigator({ Home: { screen: ...

When attempting to execute the 'npm start' command, an error was encountered stating "start" script is

Encountering an issue when running "npm start." Other users have addressed similar problems by adjusting the package.json file, so I made modifications on mine: "scripts": { "start": "node app.js" }, However, t ...

I'm having trouble receiving a response after uploading an image on Cloudinary using React js

Once the image is uploaded using the API, it should return a response. However, I am not receiving any response through the API even after uploading the image. if (pic.type === "image/jpeg" || pic.type === "image/png") { const da ...