htmlcssangularhtml-table

Angular/HTML Add button after text-overflow in table cell


I have a table and some cells overflow. These <td>'s have a class that give them an ellipsis at the end. But is there a way I can add a small button/span/whatever AFTER the ellipsis?

<td #elCol ...>
  <ng-container *ngIf="overflows(elCol)">
    YES <!-- this is displayed when it overflows, the function works -->
  </ng-container>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
  <button *ngIf="overflows(elCol)">
    click me <!-- Can't get this to displayed because it is behind the text -->
  </button>            
</td>

td {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 20rem;
}

Both HTML/SCSS and TS/JS solutions could be employed


Solution

  • you may have a .container element inside the <td>, wrapping the elements you need next to each other thus styling it with display: flex.

    Then the total width of the <td> will be driven by its style as you did with width: 20rem and yet the text intended to be truncated will have its width decided by that amount minus the space occupied by the button following.

    function overflows(el) {
       return el.scrollWidth > el.clientWidth;
    }
    
    document.addEventListener('DOMContentLoaded', () => {
      const text1 = document.querySelector('tr:nth-child(1) .truncate');
      const text2 = document.querySelector('tr:nth-child(2) .truncate');
      console.log(`The text on the first row does overflow: ${overflows(text1)}`);
      console.log(`The text on the second row does overflow: ${overflows(text2)}`);
    })
    td {
      border: solid 1px;    
      padding: .5em;    
      max-width: 20rem;
    }
    
    .container{
      display: flex;
      flex-wrap: nowrap;
    }
    
    .truncate{  
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    
    .action{
      /*to force the button having a width large enough to avoid word wrap*/
      min-width: fit-content;
    }
    <table>
      <tr>
        <td>      
          <div class="container">
            <div class="truncate">              
              Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.        
            </div>        
            <button class="action">click me</button>                  
          </div>            
        </td>
      </tr> 
      
      <tr>
        <td>      
          <div class="container">
            <div class="truncate">Short text</div>        
            <button class="action">click me</button>                  
          </div>            
        </td>
      </tr> 
    </table>

    The demo is using vanilla js/css and not reproducing strictly your original intention aimed at Angular. By the way I understand what the logic *ngIf="overflows(elCol)" does is rendering the element if the content overflows the .truncate element size. So to show the concept I also implemented my own version of the overflows function that will return true or false given the element you are willing to check.

    In the demo such function is invoked over both the .truncate elements existing on the 2 table rows where the first one is overflowing and the second is not.