Copy to clipboard

Hi, I'm trying to copy data to the clipboard, but, I guess due to limitations, it doesn't finish copying all of it, the chain is cut off.

The idea is, in the tree grid, to make a selection and copy the values ​​of a field determined by me. In practice, it copies the data, but without the selection it is very large and it doesn't copy anything. It copies about 200 characters at most.

Note that the variable I pass to the clipboard does have all the values, but if it is longer than about 200 characters, it does not copy anything to the clipboard.

This is my code:

if (!inArgs || !inArgs.results || !inArgs.results.getItemByIndex(0))
{
    return;
}

var thisType = this.getType();
	
var items = inArgs.results;
var count = items.getItemCount();
var innovator = new Innovator();
var cadena ="";

for(var i=0;i<items.getItemCount();i++){
    var id = items.getItemByIndex(i).getProperty("id","");
    
    var thisType = this.getType();

    switch (thisType) {
        case "MT Ruta":
            var valorTomado = items.getItemByIndex(i).getProperty("mt_rut_nam","");
            break;
    
        case "AIT Production Order":
            var valorTomado = items.getItemByIndex(i).getProperty("ait_po_code","");
            break;
    
        case "MT ProdRef":
            var valorTomado = items.getItemByIndex(i).getProperty("mt_proref_code","");
            break;
    
        case "MT LineaPVE":
            var valorTomado = items.getItemByIndex(i).getProperty("mt_lpve_code","");
            break;

        case "MT Necesidad":
            var valorTomado = items.getItemByIndex(i).getProperty("mt_nec_code","");
            break;
    
        default:
            // Lógica para tipos no esperados
            var valorTomado = items.getItemByIndex(i).getProperty("keyed_name","");
    }


    cadena = cadena + valorTomado +"|";
    
}
    const topWindow = aras.getMostTopWindowWithAras(window); 
    if (topWindow.work && topWindow.work.grid) 
    {
        main.work.searchContainer.runSearch();
    }
    else
    {
        parent.onRefresh();
    }

var buffer = cadena.substring(0,cadena.length-1);

// Not all browsers support programmatic access to the clipboard (Firefox).
// If clipboard access is not supported, print the result in an alert 
// and tell the user to copy contents with Ctrl+C.
if (aras.utils.isClipboardSupported())
{
    copyToBuffer(buffer);
    return alert("Item(s) copiados.");
} 
else 
{
    return alert("Browser does not allow clipboard access:\n\n" + buffer);
}

//navigator.clipboard.writeText(cadena.substring(0,cadena.length-1));
//copyToBuffer(cadena.substring(0,cadena.length-1));
return;


function copyToBuffer(buffer) {
    alert(buffer);
    if (window.clipboardData) {
        window.clipboardData.setData('Text', buffer);
    } else {
        aras.utils.setClipboardData('Text', buffer, window);
    }
}    


/*
function copyToBuffer(buffer) {
    alert(buffer);
    const maxLength = 200; // Define un tamaño máximo por iteración
    if (window.clipboardData) {
        alert(1);
        // Para Internet Explorer
        window.clipboardData.setData('Text', buffer);
    } else {
        alert(2);
        let start = 1;
        alert(buffer.length);
        while (start < buffer.length) {
            const part = buffer.substring(start, start + maxLength);
            aras.utils.setClipboardData('Text', part, window);
            start += maxLength;
            alert(start);
//        }
        alert("Texto copiado al portapapeles en partes.");
    }
}
*/

I have tried several ways, but without any luck.

As a base, I have taken the code from:

https://github.com/ArasLabs/copy-to-clipboard

Any idea??. Too many thanks!!!

Parents
  • Ohh the clipboard project! I remember this one! I still use it in a completely different context. 

    Modern Innovator version have integrated the copy&paste clipboard feature. In general everything above I14 has become very copy&paste friendly. 

    I wonder why your content is cut. I did a quick test with following code from the Method editor. I worked fine in my environment. It just throws a long string to the buffer. Does this part fail in your environment?

    const buffer = "12312321908098098888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk000000000000000000000000000000000000000000000000000000000000000zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzjmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm,";
    
    if (window.clipboardData) {
        window.clipboardData.setData('Text', buffer);
    } else {
        aras.utils.setClipboardData('Text', buffer, window);
    }

  • Hello, researching and trying and trying, I have realized something curious.

    If I choose 1 or a few records in the grid, the value of the variable is copied to the clipboard, but if many records are chosen, even if the value of the variable is correct, it has the correct data, nothing is copied to the clipboard. That is calculated in the "for", I don't know if it is for speed reasons or something like that.

    This is what ChatGPT tells me:

    "The problem seems to be related to the time it takes for the for loop to execute when there are many items (i.e. getItemCount returns a large number). This can cause the browser to temporarily crash or a problem to occur in the code execution flow due to the accumulation of synchronous operations.

    Also, if you try to copy to the clipboard after a long cycle, some browsers or API functions may fail due to runtime restrictions or memory limitations."

    I could also skip copying the "id"s to the clipboard, for example, and just launch the search automatically, but I don't know how to force a search in the grid directly.

  • Where do I start....your code is inefficient by design. Sweat smile It´s like one of my early works from 8 years ago. Don´t worry, it´s not completely wrong, just some aspects don´t work well if you have a huge amount of data. A lot of Innovator code people write just look like this so it´s super normal. But the forum community can do better Sunglasses :

    TIP: Chat GPT can also give you many tips how to make things more efficient.

    Following code is not tested and can be wrong, but it collects a few things I noticed. 

    // TIP 1: Why using a switch/case, if you just need to merge an static ItemType name with a static property?
    // Create a MAP to match ItemType names to target properties directly
    const propertyMap = {
        "MT Ruda": "mt_rut_nam",
        "AIT Production Order": "ait_po_code",
        // Add more types here
    };
    
    let content = [];
    for (let i = 0; i < items.getItemCount(); i++) {
        const thisType = this.getType();
    
        // TIP 2: Get the index item only ONCE to avoid repeating function call of getItemByIndex
        const singleItem = items.getItemByIndex(i);
        const id = singleItem.getProperty("id", "");
    
        // TIP 3: Declare helper variable HERE, outside of next if block, not "inside" like you have done in the "switch". In your case you declared the variable inside the switch but used it outside
        let valorTomado = "";
        
        // Use the map to get the property dynamically
        const propertyKey = propertyMap[thisType];
        
        // Check if key exists, only use it if it´s there
        if (propertyKey) {
            valorTomado = singleItem.getProperty(propertyKey, "");
        } else {
            // if no entry in map exists do something else
            valorTomado = ....
            // TIP 4: Maybe throw error message to inform people to tell the admin to update the map
            aras.AlertError("Couldn´t get value for " + thisType + ". Method xyz needs to be updated. Please inform admin.");
        }
        content.push(valorTomado + "|");
    }
    
    
    // TIP 5: Ask your favourite AI tool about efficient connectin of very large strings. E.g. instead of concatenating directly, push values into an array and join them into a string afterward. This minimizes the overhead of repeatedly creating new strings. 
    let cadena = content.join("");

    I am not sure if it will really help for your use case. For copy&paste from the grid there is also a CSS solution available. I will need to look it up. It´s not perfect, but maybe sufficient for your use case.

Reply
  • Where do I start....your code is inefficient by design. Sweat smile It´s like one of my early works from 8 years ago. Don´t worry, it´s not completely wrong, just some aspects don´t work well if you have a huge amount of data. A lot of Innovator code people write just look like this so it´s super normal. But the forum community can do better Sunglasses :

    TIP: Chat GPT can also give you many tips how to make things more efficient.

    Following code is not tested and can be wrong, but it collects a few things I noticed. 

    // TIP 1: Why using a switch/case, if you just need to merge an static ItemType name with a static property?
    // Create a MAP to match ItemType names to target properties directly
    const propertyMap = {
        "MT Ruda": "mt_rut_nam",
        "AIT Production Order": "ait_po_code",
        // Add more types here
    };
    
    let content = [];
    for (let i = 0; i < items.getItemCount(); i++) {
        const thisType = this.getType();
    
        // TIP 2: Get the index item only ONCE to avoid repeating function call of getItemByIndex
        const singleItem = items.getItemByIndex(i);
        const id = singleItem.getProperty("id", "");
    
        // TIP 3: Declare helper variable HERE, outside of next if block, not "inside" like you have done in the "switch". In your case you declared the variable inside the switch but used it outside
        let valorTomado = "";
        
        // Use the map to get the property dynamically
        const propertyKey = propertyMap[thisType];
        
        // Check if key exists, only use it if it´s there
        if (propertyKey) {
            valorTomado = singleItem.getProperty(propertyKey, "");
        } else {
            // if no entry in map exists do something else
            valorTomado = ....
            // TIP 4: Maybe throw error message to inform people to tell the admin to update the map
            aras.AlertError("Couldn´t get value for " + thisType + ". Method xyz needs to be updated. Please inform admin.");
        }
        content.push(valorTomado + "|");
    }
    
    
    // TIP 5: Ask your favourite AI tool about efficient connectin of very large strings. E.g. instead of concatenating directly, push values into an array and join them into a string afterward. This minimizes the overhead of repeatedly creating new strings. 
    let cadena = content.join("");

    I am not sure if it will really help for your use case. For copy&paste from the grid there is also a CSS solution available. I will need to look it up. It´s not perfect, but maybe sufficient for your use case.

Children
No Data