GithubHelp home page GithubHelp logo

Render on click? about render_async HOT 15 CLOSED

renderedtext avatar renderedtext commented on May 26, 2024 1
Render on click?

from render_async.

Comments (15)

nikolalsvk avatar nikolalsvk commented on May 26, 2024 4

Hey @jabbett, thanks for creating this issue.

It seems like a new feature :D

I love the idea of being able to call render_async on click or another event. We could implement this feature to listen to a certain event, and after that event is dispatched, render_async logic would be called. You could, for example, pass in an element ID to render_async call and then we would listen to click (or whatever) event like this:

document.getElementById("element-ID").addEventListener("event-name", performRenderAsyncLogic)

A call to render_async could look something similar to this:

# toggle_element_id: ID of your button
# toggle_event_name: would default to "click", but you could pass whatever you wanted here

<%= render_async comment_stats_path, toggle_element_id: "my-button", toggle_event_name: "click" %>  

How does this sound?

from render_async.

nikolalsvk avatar nikolalsvk commented on May 26, 2024 2

Awesome, I'll implement this feature then :)

I just can't agree with putting href="javascript:void(0);" inside the gem since it's obtrustive JavaScript (see Unobtrusive JavaScript). I do agree that it's more in the spirit of Rails by making you write less code, but I don't find it a good practice :(

Also, the main role of <a> tag is to show links in HTML or link to content on page. We often bypass this by either doing what you suggested, or putting href="#", or the CSS class to make it a link without href attribute set. Maybe in your case it's better to convert <a> tags to <button> tags or make those links point to #message-container div element.

In that spirit, I would replace <a> with <button> element in the previous comment and put it like that in the docs.

What do you think of this? If you have any ideas or suggestions, please let me know, don't be discouraged by this comment 😄

from render_async.

nikolalsvk avatar nikolalsvk commented on May 26, 2024 2

Hey y'all, I've released version 2.1.1 which solves this issue!

If you have time, please try it out and see if it brings any bugs with it, thanks 🍰

from render_async.

jabbett avatar jabbett commented on May 26, 2024

@nikolalsvk Thanks for your response!

I like your approach for something like a set of tabs that loads an object's sub-items, i.e. don't load a the "comments" tab content until the user clicks into it.

In a situation where I have a dynamic set of links, any of which could load their destination's content into the same element, what about using a link-driven approach?

<div id="message-navigation">
  <% @messages.each do |message| %>
    <%= link_to_async message.subject, message_path(message), replace: "#message-container" %>
  <% end %>
</div>

<div id="message-container">
  Click any message to display it here.
</div>

I understand that introducing a second method beyond render_async might be beyond the scope of the project, but I hope it doesn't hurt to ask ;)

from render_async.

nikolalsvk avatar nikolalsvk commented on May 26, 2024

Oh OK, now I get it :)

You are trying to render content to the same container, you are "replacing" content of one container by clicking on different links if I'm correct.

We could add another method that could be called render_async_trigger or trigger_render_async. It could look something like this:

# you would have to set a class that will show a element as link 
# since we would leave out the href empty so it doesn't refresh the page
# or we could use event.preventDefault() and pass href in options below
<%= html_element_options = { class_name: 'link' } %>

<div id="message-navigation">
  <% @messages.each do |message| %>
    <%= render_async_trigger "#message-container", 
                             message_path(message), # path to load
                             # this will create a element
                             html_element_name: 'a',
                             html_element_options: html_element_options %>
        <%= message.subject %>
    <% end %>
  <% end %>
</div>

<div id="message-container">
  Click any message to display it here.
</div>

Which would render in HTML like:

<div id="message-navigation">
  <a class="link" id="render_async_trigger_123">
    First message
  </a>
  <a class="link" id="render_async_trigger_1234">
    Second message
  </a>
</div>

<div id="message-container">
  Click any message to display it here.
</div>

...

<script>
  // listen for #render_async_trigger_123 element click and then load defined path to #message-container
</script>
<script>
  // listen for #render_async_trigger_1234 element click and then load defined path to #message-container
</script>

This will make it more usable if someone wants to render a div that needs to trigger render_async for example. In your example, we would narrow element choice to tag with link_to_async name, so that's why I changed the name of the method and expanded it a bit :)

What do you think of this approach?

from render_async.

jabbett avatar jabbett commented on May 26, 2024

Great!

(I solve the link styling issue by using href="javascript:void(0);" - typically less effort than duplicating all the CSS styles that need to be applied to links and their pseudo-classes.)

Come to think of it, I'd assume the most common case will be using this as a link. At the least, could we make the default behavior of render_async_trigger use an element of a with options of { href: "javascript:void(0);" }, and then these can be overridden by the developer? To me, this feels more in the spirit of Rails ;)

from render_async.

sqlninja avatar sqlninja commented on May 26, 2024

I think I have a similar issue to this as well...
I have a table that is rendered using this gem (each row actually) and I have a bunch of filter checkboxes that a user can click with makes a remote call to a controller to filter this list based on the criteria.

Call to the controller is getting the correct number of items based on the filter ( I know this based on the placeholders rendered) but it never actually renders the content.

Here's a short video showing the issue: https://screencast.com/t/r9fYJPcqyW

from render_async.

nikolalsvk avatar nikolalsvk commented on May 26, 2024

@sqlninja thanks for commenting! You would definitely benefit from this feature too :)

I'll see to implemenet this, sounds and looks really cool 🍰

from render_async.

sqlninja avatar sqlninja commented on May 26, 2024

@nikolalsvk so I only see this issue when I have one async request (ajax and/or remote: true) attempt to render_async after success... Could you shed any light on what is (or isn't) happening for my edification?

from render_async.

nikolalsvk avatar nikolalsvk commented on May 26, 2024

@sqlninja could you explain further how you're using render_async in your case? Maybe it's related to #70 if you're trying to call render_async in the response of the filtering request.

Fix for that would be to switch over to jQuery part of the gem, which is explained in the Configuration part of the README.

from render_async.

sqlninja avatar sqlninja commented on May 26, 2024

I'll add a full write up of my use case on Monday, but as for simply using jQuery, that didn't work and actually introduced a new issue.

The new issue was that the html_element_name was not being utilized.
As you may have noticed in my video, I am rendering each row asynchronously, so I render a tr element. Although when using jQuery it just rendered the contents of the partial, which is this case was all the td elements

from render_async.

sqlninja avatar sqlninja commented on May 26, 2024

@nikolalsvk sorry, forgot to add my use case:

I have a table where we load each row using render_async from the index method (we pass an array of ids to lookup each row record)

we also render_async a list of filter checkboxes

before adding render_async, the table was loaded in one fail swoop and clicking on the filter checkboxes would make an ajax call to "search" for records that match the filter and just reload the table.

Now that render_async is in place the rows render fine, but when the ajax call happens from clicking a filter the controller is called and the records attempt to load but the individual record lookup never happens.

so basically an ajax call is made to get the list of ids and then attempts to render the rows, but the render_async call is not firing.

That being said, are you at a point of being able to provide an estimated timeframe for the fix?
Do you know that the issue is? Is it an issue with dynamic element js calls?
Can you point me in a direction to possible help with a resolution, where should I look in the codebase?

Thanks for this gem by the way, it has sped up page load significantly...

John

from render_async.

sqlninja avatar sqlninja commented on May 26, 2024

Also, just tried adding an event name to see if it is ever emitted after an ajax request and it isn't...

from render_async.

nikolalsvk avatar nikolalsvk commented on May 26, 2024

Hey @sqlninja, could you open a new issue with your problem there so that we no longer post in this thread. It seems like a whole another problem, and this issue is about a new feature :)

I can post a possible solution to a new issue 🍰

from render_async.

sqlninja avatar sqlninja commented on May 26, 2024

Well in lieu of the potential new feature, I just removed the ajax calls and let the js do a redirect instead, and all is working...

from render_async.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.