Making an entire td link while having a different link within (JQuery)

Has anyone else tried this?

I wanted to make the call to action a bit more active so users would be inclined to click on a topic, so I added a hover/link on the entire TD. One complication is that we had moved the category link just underneath in the same cell.

Here’s the code I’m using…

For the topic area…

<td class='main-link clickable-cell clearfix' data-href='{{topic.lastUnreadUrl}}' colspan="{{titleColSpan}}">
  {{raw "topic-status" topic=topic}}
  {{topic-link topic}}
  {{#if controller.showTopicPostBadges}}
    {{raw "topic-post-badges" unread=topic.unread newPosts=topic.displayNewPosts unseen=topic.unseen url=topic.lastUnreadUrl}}
  {{/if}}
  {{plugin-outlet "topic-list-tags"}}
  {{#if expandPinned}}
    {{raw "list/topic-excerpt" topic=topic}}
  {{/if}}
  {{raw "list/action-list" topic=topic postNumbers=topic.liked_post_numbers className="likes" icon="heart"}}
  
  {{#unless controller.hideCategory}}
  {{#unless topic.isPinnedUncategorized}}
  <div class="foro">{{category-link content.category}}</div>
    {{/unless}}
{{/unless}}
</td>

Jquery. the event.stopPropagation was key so that the TD click did not interfere.

<script>
jQuery(document).ready(function($) {
    $(".clickable-cell").click(function() {
        window.document.location = $(this).data("href");
    });
    $(".clickable-cell a").click(function (event) {
        event.stopPropagation();
    });
});
</script>

And some CSS to ensure that the cell still acted like a link, with some emphasis that the category link is its own link

.clickable-cell:hover {background-color: gold; cursor: pointer;}
.clickable-cell a:hover {text-decoration: none;}
.foro a.badge-wrapper.bullet span.badge-category:hover {font-weight: bold;}

Curious to see how it performs and feedback is always welcome.

3 Likes

Looks like I had to revert the code. Strangely, the jquery that enabled it to work on load of the homepage, worked upon first load, but it didn’t work as you continued to navigate.

And the only reason I thought the event.stopPropagation worked was because I had tested that second.

Hopefully there’s a way to execute the effect I’m looking for…

Doc ready is only called on complete page loads, either when first arriving on the Discourse site, or when you request a hard reload/refresh, or when you move to a page that has little or nothing in common with the page you are viewing.

This is is because Discourse, on occasion, decides that a complete new page isn’t needed, and instead just changes a small part of the page, e.g. topic or category list, and loads this with an Ember ajax call. In such cases, doc ready isn’t fired by the browser page load mechanism because technically, a new ‘page’ hasn’t been loaded.

So your doc ready code below will bind to the .clickable-cell element first time round because an entire new DOM has loaded and the target elements could be found. However, once the body of the page is destroyed and replaced with new contents, the previous binding has disappeared into the ether (even though you can still see the doc ready routine on the page) and the new elements that have been loaded will have no bindings associated with them - e.g. no instructions to notify listeners when something happens.

In saying that, there is nothing to stop the Discourse team manually firing the doc ready event to indicate to client side code_rs_ that their latest async loading is complete. Although, they may not actually know when their code has finished loading the new fragment/view etc, given the nature of the Ember just in time load mechanism.

In the meantime you can track part page loads by hooking into view rendered events and, or page tracker events provided by Discourse/Ember.

See my mention of a similar problem here and possible solutions.

https://meta.discourse.org/t/help-with-client-side-event/39486/2


One other approach would be to render your event code alongside the elements in your views, meaning that whenever these were loaded as part of a whole new page, _or as fragments_ (ajax calls) they'd always fire given they'd always accompany the code to which they were bound to. Problem is, you'd need to ensure that previous event handlers were chained to, which can be complicated and time-consuming for the browser to execute. EDIT: Although I am sure Sam will show you how to do this properly given Ember allows you to bind events on the server without resorting to the hacks I suggested here.
3 Likes

Thx for the info @ccdw, perhaps it will come in handy in the future. I took another look at what I was trying to do and realized it could be done just with CSS :slightly_smiling:

I went with a simpler topic link display:

{{#if controller.hideCategory}}
  <a href="{{topic.lastUnreadUrl}}" class="title" title="Escrito por {{content.creator.username}}"><div class="category-title">{{topic.title}}</div></a>
{{else}}
  <a href="{{topic.lastUnreadUrl}}" class="title" title="Escrito por {{content.creator.username}}"><div class="home-title">{{topic.title}}</div></a>
  <span class="foro">{{category-link content.category}}</span>
{{/if}} 

And then applied the following CSS, floating the category title and adjusting margins so that it would still appear within the anchor block for the title link.

td.main-link  {width: 70% !important; padding:0px !important;}
td.main-link .title {font-size: 19px; display: block;}
td.main-link .title:hover {background-color: gold;}
td.main-link .title .home-title {padding: 0px 5px 40px 15px; margin-bottom: -20px;}
td.main-link .title .category-title {padding: 8px 5px 8px 15px;}
td.main-link .foro {  float: left; margin-top: -30px; padding-left: 15px; margin-bottom: -40px;}
.foro a.badge-wrapper.bullet span.badge-category {font-size: 14px; color: #333 !important; padding-bottom: 0px;}
.foro .badge-wrapper.bullet .badge-category-parent-bg, 
.foro .badge-wrapper.bullet .badge-category-bg {line-height: 10px;}

Feel free to check it out. I think it could really improve the microinteraction of accessing topics.

1 Like

Cool, very colourful. Your site is like a ray of sunshine :sunglasses:

1 Like