1

I am trying to make a prototype of file browser on web, and it has a table that shows list of files. I want to make the table flexible, to adjust column widths according to screen width and to truncate file names to show only 1-line texts in cells. I want it truncate the strings in the middle, not in tails, to show file name extensions.

I was able to make a code with some research. But the problem is that, the code seems too heavy so when I tested it makes web view slow and crash sometime. Is there any way simpler to bring out same result?

  • When screen is resized and I call the width value of table cell, the number never goes below certain number - but visually the width is smaller than the number. Can you inform me what is causing that problem?

function getvisualLength(target){
    var ruler = document.getElementById("ruler");
    ruler.innerHTML = target;
    return ruler.offsetWidth;
}
function getTrimmedString(targetString, targetWidth){
    var tmp = targetString;
    var tail = targetString.substr(targetString.indexOf('.')-3);
    var truncLength = getvisualLength("...");
    var tailLength = getvisualLength(truncLength);
    
    if (getvisualLength(tmp) > targetWidth){
        while (getvisualLength(tmp) > (targetWidth-(truncLength+tailLength+10))){
            tmp = tmp.substr(0, tmp.length-1);
        }
    }
    
    else{
        return tmp;
    }
    
    return tmp+"..."+tail;
}
window.addEventListener("resize", function(){
    var table = document.getElementById("listTable");
    for (var i = 4; i < table.rows.length; i++){
        var getCellWidth = document.getElementById("listTable").rows[0].cells[2].offsetWidth;
        var str = files[i][0];
        var tmp = getTrimmedString(str, getCellWidth);
        document.getElementById("listTable").rows[i].cells[2].innerHTML = tmp;
    }
});
function addListToTable(target, list){
    var table = document.getElementById(target);
    for (var i=0; i<list.length; i++){
        var rowCount = table.rows.length;
        var row = table.insertRow(rowCount);
        var getIconSource;
        
        row.style.cssText = "height:41px; border-bottom: 1px solid #f4f4f4";
        
        for (var k=0; k<thmbIconList.length; k++){
            if (thmbIconList[k][0] == list[i][2]){
                getIconSource = thmbIconList[k][1];
            }
        }
        row.clickStat = "off";
        row.id = "tableRow";
        var checkbox = row.insertCell(0);
        var type = row.insertCell(1);
        var name = row.insertCell(2);
        var owner = row.insertCell(3);
        var lastmodified = row.insertCell(4);
        var update = row.insertCell(5);
        var size = row.insertCell(6);
        checkbox.innerHTML = "<img src=\"assets/unchecked.png\" style = \"width: 16px; display: table-cell; margin: auto;\">"
        type.innerHTML = "<img src=\""+getIconSource+"\"style = \"width: 20px; display: table-cell; margin: auto;\">"
        name.innerHTML = list[i][0];
        name.style.cssText = "display: block;"
        name.style.cssText = "text-align: left; padding-left: 18px";
        owner.innerHTML = "me";
        owner.style.cssText = "min-width: 72px; text-align: center"
        lastmodified.innerHTML = list[i][1];
        lastmodified.style.cssText = "min-width: 72px; text-overflow:ellipsis; overflow: hidden; white-space: nowrap; text-align: center";
        update.innerHTML = list[i][1];
        update.style.cssText = "min-width: 72px; text-align: center";
        size.innerHTML = list[i][3];
        size.style.cssText = "min-width: 72px;text-align: center";        
    }
}
addListToTable("listTable", folders);
addListToTable("listTable", files);

var folders = [["Documents", "Oct 24 2019", "folder","-"], ["MyFolder_1", "Jan 2 2019", "folder","-"], ["MyFolder_2", "Oct 1 2019", "folder","-"]]
var files = [["description20191025.docx","Oct 25 2019","word", "20MB"], ["description20191025.pptx","Oct 25 2019","ppt", "20MB"], ["description20191025.xlsx","Oct 25 2019","excel", "20MB"], ["nppt_slideBackup.nppt","Oct 25 2019","nppt", "20MB"],["7D65EC6E-4A3882CF.png", "Oct 21 2019", "img", "128MB"], ["photo-153855424537648538.png", "Oct 17 2019", "img", "1.2MB"], ["photo-1538537642458538.png", "Oct 17 2019", "img", "20MB"], ["photo-15385376424548538.png", "Oct 17 2019", "img", "128MB"], ["photo-15385376425248538.png", "Oct 17 2019", "img", "1.2MB"]]
#ruler { visibility: hidden; white-space: nowrap; }
#listTable{
    width: calc(100% - 20px);
    border-collapse: collapse;
}
.listTable_firstRow{
    height: 41px;
    border-bottom: 1px solid #d8d8d8;
}
<table id = "listTable">
    <tr class = "listTable_firstRow">
        <th style = "width: 54px;"><img src="assets/unchecked.png" style = "width: 16px; display: table-cell; margin: auto;" id = "tableSelAll"></th>
        <th style = "width: 54px;">Type</th>
        <th style = "text-align: left;padding-left: 18px; min-width: 0px;">Name</th>
        <th style = "width: 12%; min-width: 72px;">Owner</th>
        <th style = "width: 12%; min-width: 72px;">Last modified</th>
        <th style = "width: 12%; min-width: 72px;">Updated</th>
        <th style = "width: 12%; min-width: 72px;">File size</th>
    </tr>
</table>
bluestar0505
  • 338
  • 1
  • 14
Jaeeul Bae
  • 23
  • 5
  • Please let me know if my recommended solution worked. Good luck! – Muckee Dec 14 '19 at 21:11
  • Your comment on ruler problem helped me well so far. However, regarding the truncation, your solution works to result +"..."+. However, solution that I am looking for is to truncate middle of string to fit changing width of table cell. Would you help me to find solution? – Jaeeul Bae Dec 15 '19 at 19:52
  • Understood. I will have another go at it this evening. – Muckee Dec 15 '19 at 23:09

1 Answers1

0

You could implement a regular expression instead by using JavaScript's str.replace(); function.

An example can be found here: Replacing filename with a Regex in JavaScript

You could split each string to remove the first three characters, then modify the code in the example to replace all but the extension from the filename.

Like this:

function truncateFilename(str) {
  // Find first 3 characters of filename
  var start = str.substring(0,3);

  /* Replace everything before the final '.' with an ellipsis.
   * The final '.' is retained and therefore only two additional '.' are needed.
   */
  var end = str.replace(/^.*(?=\.[^.]+$)/g, "..");

  /* Append resulting extention to the first 3 characters of
   * the file name that we found earlier.
   */
  return start + end;
}

var filename = "my_very_long_file_name.exe";
console.log(truncateFilename(filename));

I've made a fiddle so you can test it.

With regards to your ruler problem, I suggest that you post a separate question for each issue you have and you will more likely find a solution. Your question already has an answer here. offsetWidth includes padding, borders etc. whereas clientWidth measures the actual width of the element. You should try:

function getvisualLength(target){
    var ruler = document.getElementById("ruler");
    ruler.innerHTML = target;
    return ruler.clientWidth;
}
Muckee
  • 474
  • 1
  • 8
  • 26