42
Views
9
Comments
Solved
Notify users attempting to paste characters exceeding the input fields maximum length
Application Type
Reactive

I want to notify my users with a custom alert when they try to paste in characters exceeding the maximum length of the input field.

Acceptance criteria:

  • Users should not be allowed to paste more characters than the maximum length.
  • Users should be notified when they focus on an input field and have data in the clipboard that exceeds the maximum length, or when they attempt to paste data that exceeds the maximum length.

What I have tried is js code: 

(function() {
    var maxLength = $parameters.MaxLength; // Set your max length here    document.addEventListener('keydown', function(event) {
        // Check if Ctrl+V was pressed
        if (event.ctrlKey && (event.key === 'v' || event.key === 'V')) {
            // Wait for the paste event
            document.addEventListener('paste', function(pasteEvent) {
                // Get the pasted data
                var pasteData = (pasteEvent.clipboardData || window.clipboardData).getData('text');                // Check the length of the pasted data
                if (pasteData.length > maxLength) {
                    $parameters.IsValidPaste  = true; // Set the output parameter to true
                } else {
                    $parameters.IsValidPaste = false; // Set the output parameter to false
                }            }, { once: true }); // Add the paste event listener only once
            return $parameters.IsValidPaste;
        }
    });
})(); 

These are my parameters: 
It appears that my output parameter never changes to true, even when a user tries to paste data that exceeds the maximum length. Can anyone help me solve this issue? 

UserImage.jpg
Gwendolyn Borchsenius
Solution

Hey there, 

I think the problem comes from Javascript's asynchronous handling of events. Javascript will execute the "return $parameters.IsValidPaste;" statement first. This means that the initial value is returned, before the event logic was finished.

I recreated this problem of yours in my own personal environment. This is how I managed to trigger a change in the return value in Outsystems depending on the user's input length

  • Use Javascript Promise and use await to make sure that the event logic finished before returning isLonger
  • Call another client action with the isLonger as input variable and log the value there to see it changing depending on the input text


// function for keydown event that returns promise whether input longer or less than max length        async function checkPastedData(maxLength) {            
return new Promise((resolve, reject) => {                
const inputField = document.getElementById("inputField");               inputField.addEventListener('keydown', function(event) {                    
if (event.ctrlKey && (event.key === 'v' || event.key === 'V')) {                        inputField.addEventListener('paste', function(pasteEvent) {                            
var pasteData = (pasteEvent.clipboardData || window.clipboardData).getData('text');                           var isLonger = pasteData.length > maxLength;                           
resolve(isLonger);                      
  });                    }                });            });        }        

// main function that sets isLonger and calls other client action with updated value       
async function main() {            
var isLonger = await checkPastedData($parameters.maxLength);            
if (isLonger) {                
console.log("Pasted data exceeds the maximum length.");                
//call other client action with updated value                
$actions.PrintResult(true);            } 
else {                
console.log("Pasted data is within the allowed length.");               
 //call other client action with updated value                
$actions.PrintResult(false);            }        }        
main();


For me this worked fine by calling the Javascript above from the onKeyDown event handler of the input field. 


Hope this works for you as well and excuse the Javascript formatting. I could not make it look prettier.

CopyPaste.jpg
2023-12-16 19-57-03
Sanjay Kushwah

Hi @Yalda Akhgar,

Firstly, your Output parameter name is IsValidPaste but in your code you written IsLonger, I couldn't see this (IsLonger ) output parameter in JS Node .

Could you please Check your code.


Kind regards,

Sanjay Kushwah 

2024-09-16 12-43-55
Yalda Akhgar

@Sanjay Kushwah sorry, I pasted wrong screenshoot. The code is correct. I think the issue is the output param being updated before the listener updates the parameter

2023-12-16 19-57-03
Sanjay Kushwah

Is your Code is running onONKeyPress Event Handler of your input field.? 

2024-09-16 12-43-55
Yalda Akhgar

I have tried it with onKeydown, onKeypress, onFocus, and onBlur

2023-12-16 19-57-03
Sanjay Kushwah

Hi @Yalda Akhgar, Actually the problem is here, when handler runs the code is defining (your function and adding event Listener before the JS done your handler End.

Hence your Event Listener has been added there but not running that code actually.

The code should be run in next paste, but it will not before again onONKeyPress Event Handler (outsystems handler) will run and again whole function in JS code will define again.

and the process is going on so on. 

Code (function) is only defining not running actually.

If you want to make your code work.

Use OnReady Action of your SCREEN/BLOCK to define whole JS Code and For Assinging Output parameter. 

Make a separate screen action which will take a input parameter boolean type and will show the custom error message

now call this action into your JS Code. 

for Example 

el.addEventListener('keypress',function(){

//your js code here//

//store true / false value into a local variable inside js.

// isvalidate=false; (forexample)

$Action.yourSCreenACtionWithInputparam(isvalidate); // pass that value in action which return the same 

// when action will fire base on its input (passing from this js code) you can show your custom error message

});


Hope this will help you.

2024-06-01 07-14-16
Vaishali Thakur

Hey, @Yalda Akhgar 

  1. you have to set the input field max length check here
  2. you have to try this js this. also works for your requirements -

document.addEventListener("DOMContentLoaded", function () {

    const inputField = document.querySelector("[name='InputField']");

    const alertMessage = document.querySelector("[name='AlertMessage']");


    inputField.addEventListener("paste", handlePaste);

    inputField.addEventListener("focus", handleFocus);


    function handlePaste(event) {

        event.preventDefault();

        navigator.clipboard.readText().then(text => {

            const maxLength = inputField.maxLength;

            if (text.length > maxLength) {

                alertMessage.innerHTML = `You cannot paste more than ${maxLength} characters.`;

                alertMessage.style.display = "block";

            } else {

                inputField.value = text.substring(0, maxLength);

                alertMessage.style.display = "none";

            }

        });

    }


    function handleFocus() {

        navigator.clipboard.readText().then(text => {

            const maxLength = inputField.maxLength;

            if (text.length > maxLength) {

                alertMessage.innerHTML = `Clipboard data exceeds the maximum length of ${maxLength} characters.`;

                alertMessage.style.display = "block";

            } else {

                alertMessage.style.display = "none";

            }

        });

    }

});

I'm just sharing this with you to help you,

thanks


2024-09-16 12-43-55
Yalda Akhgar

@Vaishali Bhatt I tried the solution you linked. Removing the max length property from the input field allows users to input more than they are allowed, which is not what we want. Our application has auto-save functionality, so doing this could lead to database errors. 

2021-03-18 21-03-15
Benjith Sam
 
MVP

Hi Yalda,

For your use case, you can use the JavaScript snippet below to register the paste event handler for the input widget in the OnReady screen event handler flow using the JS element.

JS Snippet:

var inputElement = document.getElementById($parameters.InputId);
 const maxLength = 10; // Set your desired length limit

 inputElement.addEventListener('paste', function(event) {
    const pastedText = event.clipboardData.getData('text');

    // Check if pasted text exceeds the max length
    if (pastedText.length > maxLength) {
        event.preventDefault();
        $actions.CustomFeedbackMsg(`The text you are trying to paste exceeds the maximum length of ${maxLength} characters.`);
    }
});

Demo App: InputPasteEventDemo

Refer to the attached oml 


Kind regards,

Benjith Sam

ReactLab_InputPasteEvtDemo.oml
UserImage.jpg
Gwendolyn Borchsenius
Solution

Hey there, 

I think the problem comes from Javascript's asynchronous handling of events. Javascript will execute the "return $parameters.IsValidPaste;" statement first. This means that the initial value is returned, before the event logic was finished.

I recreated this problem of yours in my own personal environment. This is how I managed to trigger a change in the return value in Outsystems depending on the user's input length

  • Use Javascript Promise and use await to make sure that the event logic finished before returning isLonger
  • Call another client action with the isLonger as input variable and log the value there to see it changing depending on the input text


// function for keydown event that returns promise whether input longer or less than max length        async function checkPastedData(maxLength) {            
return new Promise((resolve, reject) => {                
const inputField = document.getElementById("inputField");               inputField.addEventListener('keydown', function(event) {                    
if (event.ctrlKey && (event.key === 'v' || event.key === 'V')) {                        inputField.addEventListener('paste', function(pasteEvent) {                            
var pasteData = (pasteEvent.clipboardData || window.clipboardData).getData('text');                           var isLonger = pasteData.length > maxLength;                           
resolve(isLonger);                      
  });                    }                });            });        }        

// main function that sets isLonger and calls other client action with updated value       
async function main() {            
var isLonger = await checkPastedData($parameters.maxLength);            
if (isLonger) {                
console.log("Pasted data exceeds the maximum length.");                
//call other client action with updated value                
$actions.PrintResult(true);            } 
else {                
console.log("Pasted data is within the allowed length.");               
 //call other client action with updated value                
$actions.PrintResult(false);            }        }        
main();


For me this worked fine by calling the Javascript above from the onKeyDown event handler of the input field. 


Hope this works for you as well and excuse the Javascript formatting. I could not make it look prettier.

CopyPaste.jpg
Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.