Limit text length in table

Hi smart minds,

My table component is showing information with random info, some blanks are with URL, some randomly with long text… (more than 1000 characters). Is there anyway to limit the text length in the column?

Say showing as “…” or even click to show detail on pop-up box, if the text length exceeds the limit.

Thanks…

Hey @tenny

Are you saying that your table is displaying data in error? Or the data that you’re intentionally showing is sometimes upwards of 1000 characters? Sorry, just confused by your phrasing.

I had this thought actually about a rich text field where it could be 20 characters or it could be 500.

You could try something like this…

You’d have to sub out .p with the table field you want to shorten.

You could also use JavaScript but I can’t help with that.

1 Like

Here’s another solution you can use if you wanted to be able to limit the number of characters text inside a table component and have a “Show More” and “Show Less” option.

Here’s how that would look.
2020-11-17_14-28-39

The first thing you’ll need to do is find the component ID of the table you are applying this to.

Then I added the following code to the JavaScript of the page.

Remember to change component_id to your tables component id

JavaScript

function showMore(id) {
    document.getElementById(id + 'Overflow').className = '';
    document.getElementById(id + 'MoreLink').className = 'hidden';
    document.getElementById(id + 'LessLink').className = '';
}
function showLess(id) {
    document.getElementById(id + 'Overflow').className = 'hidden';
    document.getElementById(id + 'MoreLink').className = '';
    document.getElementById(id + 'LessLink').className = 'hidden';
}

var trun = function(){
    if(!$('.shrinkables').length){
        var len = 60;
        var shrinkables = $('tbody td span');
        if (shrinkables.length > 0) {
            for (var i = 0; i < shrinkables.length; i++) {
                var fullText = shrinkables[i].innerHTML;
                if (fullText.length > len && !$(shrinkables[i].offsetParent).hasClass('allow-inline-edit')) {
                    var trunc = fullText.substring(0, len).replace(/\w+$/, '');
                    var remainder = "";
                    var id = 'shrinkable' + i;
                    remainder = fullText.substring(len, fullText.length);
                    shrinkables[i].innerHTML = '<span class="shrinkables">' + trunc + '<span class="hidden" id="' + id + 'Overflow">' + remainder + '</span></span>&nbsp;<a id="' + id + 'MoreLink" style="cursor:pointer;" onclick="showMore(\'' + id + '\');">Show More</a><a class="hidden" style="cursor:pointer;" id="' + id + 'LessLink" onclick="showLess(\'' + id + '\');">Show Less</a>';
    
                }
            }
        }
    }
};

TB.render('component_id',function(){
    trun();
});
$('body, button').click(function(){
    setTimeout(function(){
        if($('.shrinkables').length === 0){
             trun();
        }
    },500);
});
2 Likes

Greetings Tada Community -

This JS works great but I am getting duplicate “more/less” links (see picture)…anyone have any idea what my be causing this?

@Chem and I were working on this and he updated the script to this but the problem still exists:

function showMore(id) {
    document.getElementById(id + 'Overflow').className = '';
    document.getElementById(id + 'MoreLink').className = 'hidden';
    document.getElementById(id + 'LessLink').className = '';
}
function showLess(id) {
    document.getElementById(id + 'Overflow').className = 'hidden';
    document.getElementById(id + 'MoreLink').className = '';
    document.getElementById(id + 'LessLink').className = 'hidden';
}

var trun = function(){
    var len = 100;
    var shrinkables = $('tbody td span');
    if (shrinkables.length > 0) {
        for (var i = 0; i < shrinkables.length; i++) {
            var fullText = shrinkables[i].innerHTML;
            if (fullText.length > len && !$(shrinkables[i].offsetParent).hasClass('allow-inline-edit')) {
                var trunc = fullText.substring(0, len).replace(/\w+$/, '');
                var remainder = "";
                var id = 'shrinkable' + i;
                remainder = fullText.substring(len, fullText.length);
                shrinkables[i].innerHTML = '<span class="shrinkables">' + trunc + '<span class="hidden" id="' + id + 'Overflow">' + remainder + '</span></span>&nbsp;<a id="' + id + 'MoreLink" style="cursor:pointer;" onclick="showMore(\'' + id + '\');"><strong>Read More</strong></a><a class="hidden" style="cursor:pointer;" id="' + id + 'LessLink" onclick="showLess(\'' + id + '\');"><strong>Read Less</strong></a>';

            }
        }
    }
};

TB.render('component_12',function(){
    trun();
});
$('body, button').click(function(){
    setTimeout(function(){
        if($('.shrinkables').length === 0){
             trun();
        }
    },500);
});
TB.render('component_12',function(data){
    var number = parseInt(data.ele.find('.t-records-button').text());
    data.ele.find('.t-records-button').text(number + ' Observations');
});

Does anyone have any thoughts on the issue? P.S. this is the only JS I have on the page.

Thanks in advance,
Adam

I’ve updated the code in the post above to resolve this.

2 Likes

@Chem you are the BEST!!! :grinning: :muscle: :+1:

Hi Chem,

A nice addition to the tricks box - thank you. It is a feature I will use a lot.

Should adding the following allo the function to work with other table references in so you only put the bulk of the code in once, e.g.

TB.render(‘component_21’,function(){
trun();
});
TB.render(‘component_13’,function(){
trun();
});

It would awesome if the “show more” and “Show Less” were in a different colour to stand out. I dont like to mess with JS so I very crudely did it with some css, but it would be very convenient for the JS to do it:

[onclick="showLess\(\'shrinkable12\'\)\;"] {
  color: blue;
}

Of course you have to do that for each table and each line for ‘show more’ or ‘show less’ so its not really viable.

image

image

Also, would it be possible for the script to stop the comments opening up after a new record is added from the table?

As always, thank you.

Which post with which code is the right one? @Chem

Hey @Peter, Post #3

Any ideas on how to use this with a rich text field, so it just shows the first line?

Note: this does not work properly with rich text fields.

Hello everyone-

I have used ChatGPT to alter the code that @Chem provided since the originial Javascript doesn’t hide all of the text if using a rich text field where line or paragraph breaks are present. Feel free to test the following in your applciation.

TB.render('component_14', function(data) {
    setTimeout(() => {
        var len = 60;
        var shrinkables = jQuery('tbody td.component_14_field_682 span', data.ele);

        shrinkables.each(function(i) {
            var fullText = jQuery(this).html();
            var visibleText = getVisibleText(fullText, len);
            var hiddenText = fullText.slice(visibleText.length);

            var id = `shrinkable${i}`;
            var html = `<span>${visibleText}<span class="hidden" id="${id}Overflow">${hiddenText}</span></span><a id="${id}MoreLink">... <span style="display: inline-block; color: blue; text-decoration: underline;">Show More</span></a><a class="hidden" id="${id}LessLink"> <span style="display: inline-block; color: blue; text-decoration: underline;">Show Less</span></a>`;
            jQuery(this).html(html);

            jQuery(`#${id}MoreLink, #${id}LessLink`).css("cursor", "pointer");
            jQuery(this).find(`#${id}MoreLink, #${id}LessLink`).on('click', function() {
                jQuery(`#${id}Overflow, #${id}MoreLink`).toggleClass('hidden');
                jQuery(`#${id}LessLink`).toggleClass('hidden');
            });
        });
    });
});

function getVisibleText(text, maxLength) {
    var result = '';
    var charCount = 0;
    var insideTag = false;
    var firstChar = true;

    for (var i = 0; i < text.length; i++) {
        var char = text[i];

        if (char === '<') {
            insideTag = true;
        } else if (char === '>') {
            insideTag = false;
        }

        if (!insideTag) {
            if (firstChar && char === '>') {
                firstChar = false;
                continue;
            }

            result += char;
            charCount++;

            if (charCount >= maxLength) {
                if (char === ' ' || char === '\n' || char === '\r') {
                    break;
                }
            }
        }
    }

    return result;
}

Adam