renderedtext/render_async

render_async in table

toby-thanathip opened this issue · 9 comments

I have a partial view with root element <tr>
But the gem is wrapping this partial view with a <div>

<table>
  <tbody>
     <div>
        <tr> ... </tr>
    </div>
  </tbody>
</table> 

Which eventually will cause the partial view to be rendered outside of the table 
(Let's say it's invalid HTML)

This was bugging me too for some time :(

Can you please try out the newest version of the gem? It should be working now with the tables.

The problem is that it creates div element which is rendered outside the table before it's replaced with partial. The problem still exists after these changes.

@Postmodum37 thanks for reporting this 🙇

It would really help if you could tell me whether you have jQuery in your project or you're using vanilla JS?

I am using JQuery, but I don't think that matters because the initial div element is not initialized with Javascript.

In my case, I was trying to add tr elements to the existing table. The problem is that you can't actually use div outside td or th, so the initial div element is being placed outside the table scope.

The two solutions I came up with are:

  1. Create a dummy tr element instead of div and use insertAfter() JQuery method instead of replaceWith() and remove dummy element. (This would require modification of a source code.)
  2. Use render_async in dummy tr > td element and after rendering is completed fire a Javascript callback and move rendered elements with $(parent).before($(parent).children()) out of the td and then out of tr elements. Remove used dummy elements after.

I've implemented the second solution in my project for now and it seems to work fine, but it's a bit messy. If I will have free time in the future I'll make a pull request with the first solution implemented. It would be a good opportunity to make my first contribution to the open-source project.

I've released 1.2.0 version of render_async that should allow you to pass in html_element_name that you desire. In your case that would probably be tr, so the content could get rendered inside the table.

@Postmodum37 can you try it out and see if it's working out for you?

@nikolalsvk The bug is still there.

You can't load HTML this way into a table as I tried explaining before. Here is the basic html table structure:

<table>
    <thead>
        <tr>
            <th>
                *Here you can load any html tags.*
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                 *Here you can load any html tags.*
            </td>
        </tr>
    </tbody>
</table>

So going from

<tbody>
    <div>
        <tr>
        </tr>
    </div>
</tbody>

to

<tbody>
   <tr>
      <tr>
      </tr>
   </tr>
</tbody>

doesn't make a difference. The only way to put HTML into a table is to put it in td element and to move it out of it after or by creating a dummy tr element and instead of replacing use appending.

The quick fix, in this case, would be if tr element is passed as html_element_name, the tr element should not be destroyed and partial would contain only td elements that are inserted into tr element. This way you won't be breaking table style rules.

@Postmodum37 what are you trying to render inside the table using render_async?

Can you try to pass in a td as a html_element_name and then render as many tds as you want from a partial?

@nikolalsvk This solution fixes the problem. Creating a tr element in loop and calling render_async inside of it with td element as html_element_name option renders rows correctly. Might be a bit counter-intuitive but it works.

Woohoo, glad that it works 🎉

If you want, you can post a recipe to the project README so other people can refer to it :)