Phoenix link tag generated twice

Dear Elixir forum,

I truly hope that I’m not missing something very obvious here, for this would waste some people their time… But I’m facing the following situation:

Simply trying to generate an arrow up, arrow down, that can be click to order an item higher or lower in a list. This is the following code that I’m trying to achieve this: (using following icons)

<td>
              <%= link(tag(:i, class: "fa fa-angle-up"), to: "/link/moveup", method: :post) %>
              <%= link(tag(:i, class: "fa fa-angle-down"), to: "/link/movedown", method: :post) %>
              <%= link "Delete",
              to: Routes.link_path(@conn, :delete, link),
              method: "delete" %></td>

Which results in the following html code and how it looks like:
image

image

When I change the lines of code so that it’s first the Delete link, then an arrow, it doesn’t get generated twice. Am I doing something wrong or could this be a potential bug?

Thank you in advance,

Can you post the raw HTML that this generates? The DOM inspector can sometimes display odd things as it tries to “fix” broken markup.

3 Likes

Thank you for your quick answer.

<td>
<a data-csrf="fw0wEg4GNXkbHj9HAFpAKywgABRjJgAAHTjSLWy3ugZvfnscFQgG1w==" data-method="post" data-to="/link/moveup" href="/link/moveup" rel="nofollow"><i class="fa fa-angle-up"></i></a><i class="fa fa-angle-up">              
<a data-csrf="fw0wEg4GNXkbHj9HAFpAKywgABRjJgAAHTjSLWy3ugZvfnscFQgG1w==" data-method="post" data-to="/link/movedown" href="/link/movedown" rel="nofollow"><i class="fa fa-angle-down"></i></a><i class="fa fa-angle-down">
             
<a data-csrf="fw0wEg4GNXkbHj9HAFpAKywgABRjJgAAHTjSLWy3ugZvfnscFQgG1w==" data-method="delete" data-to="/link/1" href="/link/1" rel="nofollow">Delete</a></i></i>
</td>

This should be the relevant part (quickly dumped it all in a td element).

Thanks again in advance!

The link function accepts the string contents as the first arg. I actually wouldn’t have expected the above to work, but I need to check the source. Try this:

<%= link to: "/link/moveup", method: :post do %> 
  <%= tag(:i, class: "fa fa-angle-up") %>
<% end %>

Thank you for responding.
I’ve tried the following code: (as per your suggestion)

              <%= link to: "/link/moveup", method: :post do %> 
                <%= tag(:i, class: "fa fa-angle-up") %>
              <% end %>
              <%= link to: "/link/movedown", method: :post do %> 
                <%= tag(:i, class: "fa fa-angle-down") %>
              <% end %>

Which resulted in:
image

With the following raw html:

<td>
<a data-csrf="Qx0cETNnJwsLLCZUB1FnP10YM2cmEAAAtDFPq6kAeUCeaeTw7iT4tA==" data-method="post" data-to="/link/moveup" href="/link/moveup" rel="nofollow">                <i class="fa fa-angle-up">
</i></a><i class="fa fa-angle-up">              
<a data-csrf="Qx0cETNnJwsLLCZUB1FnP10YM2cmEAAAtDFPq6kAeUCeaeTw7iT4tA==" data-method="post" data-to="/link/movedown" href="/link/movedown" rel="nofollow"> 
<i class="fa fa-angle-down">              </i></a><i class="fa fa-angle-down">
              
<a data-csrf="Qx0cETNnJwsLLCZUB1FnP10YM2cmEAAAtDFPq6kAeUCeaeTw7iT4tA==" data-method="delete" data-to="/link/22" href="/link/22" rel="nofollow">Delete</a></i></i></td>

The problem remains I’m afraid. (right now solved it with images, that works. Not sure if patch is the correct action for this though…)

<%= img_tag("images/icons8-sort-down-24.png") |> link(to: Routes.link_path(@conn, :movedown, link), method: :patch)%>

How did you check the generated HTML? Did you use curl or a similar tool or did you use some view of your browser, the later might still be subject of DOM manipulation via scripts.

1 Like

Checked it with firefox, I’ll check it with curl as well. Editing this post soon!

<td>
<a data-csrf="KBhHPXYcNQc7DhhZbi8caUoQJXkhNgAAJ/uIOIP7Qf+0Azu/rjnATg==" data-method="post" data-to="/link/moveup" href="/link/moveup" rel="nofollow">                <i class="fa fa-angle-up"></a>              
<a data-csrf="KBhHPXYcNQc7DhhZbi8caUoQJXkhNgAAJ/uIOIP7Qf+0Azu/rjnATg==" data-method="post" data-to="/link/movedown" href="/link/movedown" rel="nofollow"> <i class="fa fa-angle-down"></a>
              
<a data-csrf="KBhHPXYcNQc7DhhZbi8caUoQJXkhNgAAJ/uIOIP7Qf+0Azu/rjnATg==" data-method="delete" data-to="/link/28" href="/link/28" rel="nofollow">Delete</a></td>

It is as you suggested @NobbZ! Though do you have any idea as to how this can help with finding a solution?

Check the output without having loaded any scripts, then add java script module by module, then you’ll see which one breaks your site, then debug that module.

Just using a default generated Phoenix project. The only js files that are getting compiled from webpack are socket.js (default) and app.js (default) which imports phoenix_html, does this mean that the “bug” is most likely in the phoenix_html package?

Can you try content_tag(:i, …)? This to me seems like a browser trying to fix improper html.

3 Likes

Im Not sure, perhaps the issue is in the font awesome provided scripts or styles? Disabling them will probably brake more :wink:

Have you tried with other symbols, or some content that is not font awesome? Perhaps an image?

1 Like

Oh, you are right, as I see now, the i tags don’t get closed.

1 Like

The output is: (tested with curl)

<td>
<i class="fa fa-angle-down"></i>              
              <a data-csrf="US9sIjgJOn1jDRsPCjcyJlhSKAhIJgAA9YUxHDMN6HxjCtUMkciqgA==" data-method="delete" data-to="/link/28" href="/link/28" rel="nofollow">Delete</a></td>

Adjusted the code to the following, ant this works:

<%= link(content_tag(:i, "", class: "fa fa-angle-up"), to: "/link/moveup", method: :post) %>
              <%= link(content_tag(:i, "", class: "fa fa-angle-down"), to: "/link/movedown", method: :post) %>

So… apparently “tag” is not usable for tags? is this normal behaviour?

tag/2 is a low level function which does only create a “tag”, aka <name {attrs}>. It doesn’t concern itself with the notion of opening/closing tag.

3 Likes

Thank you everyone! Going to mark @LostKobrakai his answer as the solution.

@NobbZ, thank you a lot as well! :smiley:

1 Like