Is there a way to display the title attribute when truncating a lengthy text in Vue?

Recently, I encountered an issue with my dynamically created table. I added the class truncate to the spans within the td elements to shorten the log sentences and implemented a title attribute to display the full sentence on hover. However, I noticed that the titles are now appearing for all spans, whereas I only want them to appear for spans with the truncate class. How can I resolve this?

Vue.component('TheTable', {
  template: `<table class="table">
    <tr
      v-for="(row, i) in data"
    >
      <td
        v-for="(item, index) in row"
      >
        <span
        :title="item"
        class="truncate"
        >
          {{ item }}
        </span>
      </td>
    </tr>
  </table>`,
  data() {
    return {
      data: [
        [
          'very very very very very very very very very very very very very very big sentence',
          'very very very very very very very very very very very very very very big sentence',
          'very very very very very very very very very very very very very very big sentence'],
        ['aaa', 'bbb', 'ccc'],
        ['ddd', 'eee', 'fff']
      ]
    }
  }
})

new Vue({
  el: "#app",
});
.truncate {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.table td {

  max-width: 100px;
}
<link type="text/css" rel="stylesheet" href="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f2909d9d868186809382b2c6dcc7dcc1">[email protected]</a>/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="95f7fafae1e6e1e7f4e5b8e3e0f0d5a7bba7a4bba7">[email protected]</a>/dist/bootstrap-vue.css" />

<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="681e1d0d285a465e46595a">[email protected]</a>/dist/vue.min.js"></script>
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1b7974746f686f697a6b366d6e7e5b2935292a3529">[email protected]</a>/dist/bootstrap-vue.min.js"></script>


<div id="app">
  <the-table/>
</div>

Answer №1

It's important to calculate the title's necessity on your own and also when the window is resized. To see how this works during resizing, expand the snippet below:

https://i.sstatic.net/cctj3.png

This solution was implemented quickly. Depending on the style changes in your specific scenario, some adjustments may be required.

Vue.component('TheTable', {
  template: `<table class="table">
    <tr
      v-for="(row, i) in data"
    >
      <td
        v-for="(item, index) in row"
      >
        <span
        class="truncate"
        >
          {{ item }}
        </span>
      </td>
    </tr>
  </table>`,
      methods:{
        calcTitles(){
          
          this.$el.querySelectorAll('.truncate').forEach(span => {

            const {display, overflow} = span.style;
            span.style.overflow = 'visible';
            span.style.display = 'inline-block';

            const td = span.closest('td');
            const rectTd = td.getBoundingClientRect();
            const rect = span.getBoundingClientRect();
            
            const needsTitle = rect.left - rectTd.left  +  rect.width > td.offsetWidth;

            if(needsTitle){
              span.setAttribute('title', span.textContent);
            }else{
              span.removeAttribute('title');
            }
            
            span.style.overflow = overflow;
            span.style.display = display;
          });
        }     
      },
      unmounted(){
        window.removeEventListener('resize', this.calcTitles);
      },
      mounted(){
        this.calcTitles = this.calcTitles.bind(this);
        window.addEventListener('resize', this.calcTitles);
        this.calcTitles();
      
      },  
  data() {
    return {
      data: [
        [
          'very very very very very very very very very very very very very very big sentence',
          'very very very very very very very very very very very very very very big sentence',
          'very very very very very very very very very very very very very very big sentence'],
        ['aaa', 'bbb', 'ccc'],
        ['ddd', 'eee', 'fff']
      ]
    }
  }
})

new Vue({
  el: "#app",
});
.truncate {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.table td {
  max-width: 100px;
}
<link type="text/css" rel="stylesheet" href="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="87e5e8e8f3f4f3f5e6f7c7b3a9b2a9b4">[email protected]</a>/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b0d2dfdfc4c3c4c2d1c09dc6c5d5f0829e82819e82">[email protected]</a>/dist/bootstrap-vue.css" />

<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2751524267150911091615">[email protected]</a>/dist/vue.min.js"></script>
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ceaca1a1babdbabcafbee3b8bbab8efce0fcffe0fc">[email protected]</a>/dist/bootstrap-vue.min.js"></script>


<div id="app">
  <the-table/>
</div>

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

The overflow hidden property in Tailwind CSS is not functioning properly during animations

I'm attempting to animate an image by moving it to different positions, but when it goes off the screen, the scrollbar appears. I tried adding overflow hidden to the parent element, but it didn't work as expected. Here is the relevant code snippe ...

Personalized Carousel using Ng-Bootstrap, showcasing image and description data fields

I have been working on customizing an Angular Bootstrap Carousel and have managed to successfully change the layout. I now have two columns - with the image on the right and text along with custom arrows on the left. My goal is twofold: First, I am lookin ...

Fonts displayed on websites may look different on Mac compared to Windows

After carefully selecting a Google Web Font to use as the main font for my website, I noticed that it appears slightly different in terms of dimensions and spatial conformations when displayed on both Mac and Windows computers. For more information about ...

I'm having trouble getting my Retina image code to work perfectly. The high resolution image isn't loading at its full

After learning how to display my Retina optimized logo from this tutorial (link), I encountered an issue when testing on my iPad and Samsung Galaxy Note II (using Safari, Firefox, Dolphin apps). The Retina image is showing up at its full size of 1200px x 5 ...

PHP Warning: Attempt to access undefined variable

Whenever I try to insert a new record into my HTML, I keep encountering errors. I'm unsure if it's due to incorrect code on my end or if the issue lies with inserting the records. <?php $servername = "localhost"; $dbusername = "r ...

Exploring the anatomy of the img src tag

Using jQuery, I have successfully implemented code to display an image when clicked by storing the image source into a variable like this: var imgSrc = $(event.target).attr('src'); I then use this variable to add the image to a div and show it o ...

Style not being applied to CSS class

When using the 'p' tag by itself, the first CSS rule works fine. However, when I apply the 'article' class with or without the 'p' tag, it does not work. Any thoughts on why that might be? Interestingly, the 'hr' tag ...

Constructing a horizontal slider using vertically floating divs

Struggling to create a basic horizontal image slider using overflow:hidden and floating divs. Despite efforts, the divs keep stacking vertically instead of horizontally. Numerous online examples have been attempted without success. HTML: <div id="slid ...

Having trouble displaying API JSON data in a Vue.js table component

In my HTML file, I have implemented fetching data from an API and displaying it in a table successfully. Now, I am trying to convert the HTML file to use Vue.js, but encountering some issues. Despite being able to fetch data from the API with Vue, the tab ...

Using Regular Expressions for Customized Formatting

I'm faced with a challenge involving a highly organized HTML string that contains numerous hyperlinks. I need to transform all of these links into bold text containing the word "XX1". Is there a way to accomplish this in PHP without relying on jQuery ...

Navigating React Router: Updating the page on back button press

Looking for a solution to a persistent issue. Despite various attempts and exhaustive research, the problem remains unresolved. Here's the situation: Within my React-Router-Dom setup, there is a parent component featuring a logo that remains fixed an ...

I want to learn how to display the rupee symbol instead of the default dollar symbol in AngularJS for specific currency symbols

When using 'currency' in AngularJS, I noticed that a dollar symbol is displayed. How can I change this to show the required currency symbol based on different requirements? Currently, I am looking for information on how to display a rupee symbol ...

The querySelector function seems to be identifying the element with the ID "submit" and another input element of type "submit"

My code includes a function that toggles between two elements' style.display values, switching them from "none" to "block" and vice versa. However, I've encountered an unexpected issue where the behavior of the "send" button seems to be linked wi ...

Resolving Issues with Text Overlaid on an Image Hyperlink

Alright, so this problem might be a bit too complex for CSS/HTML to handle, but I'll give it a shot anyway. I have some images that are dynamically placed using the code from this website. What I want to do with these images is add a text overlay w ...

Determine the variable height of a div containing dynamic content in order to execute a transform

Looking to create a dynamic container that expands when a button/link is clicked? The challenge lies in achieving this expansion effect with a smooth transition. By using the height: auto property, the container can expand to fit its content, but incorpora ...

When the v-select [NuxtJs] is altered, it returns as null

Welcome to my first post! I hope you can offer some assistance. I am currently working on a new project involving the migration to nuxtJs. I am facing some issues with my v-select and v-model, below is the code snippet: _id.vue: <template> <v- ...

The error message received states: "materialize-css Uncaught TypeError: Vel is not defined as

My current setup involves webpack as the bundler/loader, and I've successfully loaded materialize css (js/css). However, when attempting to use the toast feature, an error is thrown: Uncaught TypeError: Vel is not a function The library is being inc ...

Utilize a dual-color gradient effect on separate words within the <li> element

I am attempting to display the fizz buzz function in an unordered list, with each word being a different color ('fizz'-- green, 'buzz'--blue) as shown here: https://i.sstatic.net/Yvdal.jpg I have successfully displayed "fizz" and "buz ...

How to extract object properties in v-select using Vue.js and Vuetify

My specific scenario. I received an array of objects from a backend API. I aim to display these objects in a v-select This snippet shows my current code. <v-select :items="categories" name="category" label="Select a cate ...

"Arranging elements with identical class in a single column but on separate rows using CSS grid - a step-by-step guide

I'm facing an issue with organizing choices and matches in columns using grid CSS. Currently, the match column is overlapping with the choice column. Here is how it is coded at the moment: .grid{ display:grid; grid-template-columns: 1fr 1 ...