Client side form validation for Copy/Pastes via Right-Click - javascript

I'm using the following line (Struts1 syntax) to display a text field and allow some client side checks via Javascript.
<html:text styleId="myField" property="myProperty" onkeyup="function()" />
My intention is for a message to appear and a dropdown to disable whenever there is text entered into the form field (regardless of content). The onkeyup attribute works fine for all cases except for when the user pastes in text using mouse right-click.
It doesn't appear that onmousedown and onmouseup events notice right clicks. The same goes for onfocus.
onchange only makes the check when focus is lost, however the user can circumvent this by pasting data and clicking the form submit (same for onblur).
onmouseout somewhat works (I can break functionality) in IE8, but doesn't work at all in Chrome v41.0.2272.89
Has anyone encountered client-side form checks on Mouse-Right Click? I'd like to cover this use case across browsers and cannot count on the end user to always paste via keyboard shortcuts.

I went with a jQuery solution as suggested by Aleksandr M above in comments.
Initially I had this function:
$(document).ready(function(){
$('#myField').bind("paste",function(e) {
toggleFunction(); //preserve already existing function in use with other cases
});
});
But then came to find that while the function would run following the user's paste, it would run prior to the text actually being pasted.
Example:
User pastes (Right-click > paste OR Ctrl+V);
Function is called and executes, condition checks made
Text is pasted.
So instead I replaced the function call in the jQuery with my intended end result, making some additional changes elsewhere so that my assumptions are met.
But those conditions aside, the below ends up doing what I needed.
$(document).ready(function(){
$('#myField').bind("paste",function(e) {
document.getElementById("dropdownID").disabled = true;
document.getElementById("showMessage").style.visibility = "visible";
});
});

Related

Run Code on Click Button or Update Field, but Not Both at the Same Time

I want both:
<input onchange='fncChkVrification()'>
<button onmouseup='fncChkVrification()'>Hit Enter after pasting or typing the Code. Or Click Here.</button>
For ease of use, I want the user to be able to hit Enter after an input text box is filled in, and have code run. The problem is, that the user may need to come back to that input field later, and re-run the code with the same value.
For example:
User enters a verification code in the input field and hits the Enter key.
But they haven't signed in. So the user gets a message stating that they haven't signed in.
They sign in, and come back to the input field to run the verification, but when they tab out of the field or hit Enter, no code runs because the verification code is the same.
The code only runs if the value changes. I'm assuming that the browser records and tracks the value and whether it's been changed.
I could:
clear that field if there is an error, and make the user enter the verification code again. But I'd like to avoid that.
Only use a button, and not the onchange event.
I want to give the user both options. I've read that JavaScript will not simultaneously run two functions at the same time, but if the code is very short, and runs very quickly, will it get run twice, not simultaneously, but immediately in sequence?
If for some reason the code runs a second time, it might not affect the outcome at all, but I'd like to avoid unnecessary duplication.
The code DOES run twice! If I click the button, both events trigger. The onmouseup from the button, and the onchange from the input field.
window.countTimesRun = 0;
window.fncChkVrification = function() {
console.log('fncChkVrification ran: ');
countTimesRun = countTimesRun + 1;
console.log('countTimesRun: ' + countTimesRun);
var getVrfyChkCode = document.getElementById('divForOnHoldKey').value;
google.script.run.withFailureHandler(onFailure)
.withSuccessHandler(rtrnFromVerify)
.verifyCode(getVrfyChkCode);
};
Technically, JavaScript might not be running simultaneously, but the code is so short, and so quick that it's running twice, back to back.
I could somehow pause, or track, or keep a timer. But that just seems like way to much overkill to make it worth it. I may need to just have a button, and no onchange event. Unless someone has a simple solution. I'm not using jQuery.
If JavaScript had an onexit event for an input field, that would probably solve the problem. But as far as I know, that doesn't exist.
I thought maybe changing the button onmouseup event to onclick might do something, but that doesn't work.
I just tried using onblur and that created a lot of very undesirable situations. The code runs when the field looses the focus, but then the cursor stayed in the input field. So it got stuck in a loop if I clicked on a new browser tab. The code would run, the new browser tab would NOT load, and then the focus went right back to the same place!
I experimented with the button getting the focus, but when I hit Enter, the cursor does not move to the next tab element. If I click Tab, the button gets the focus, and the code runs. But if I hit Enter, nothing happens.
I've come to realize, that the solution to my problem is by controlling what happens when the user hits the Enter key. So, in a sense, this is a duplicate question to making code run when the Enter key is pressed. Which I didn't realize at the time I posted this.
I found a solution. The key to the solution is they keyCode check. Here is a working jsFiddle: Run Code on Either Enter Key Press, or Button Click, but not Both
It sounds like you have gotten yourself in a muddle here. If I have understood correctly this fiddle does what you are describing: http://jsfiddle.net/wR32h/
This is the meat of it:
FormManager.prototype.initialize = function () {
this.elements.input.onkeyup = this.handleInputKeyup.bind(this);
this.elements.button.onclick = this.handleButtonClick.bind(this);
};
FormManager.prototype.handleInputKeyup = function (evt) {
// check to see if the key was enter
if (evt.keyCode !== 13) {
return;
}
if (this.checkState()) {
this.validateCode();
} else {
alert('you need to log in before validation can take place');
}
};
FormManager.prototype.handleButtonClick = function (evt) {
if (this.checkState()) {
this.validateCode();
} else {
alert('you need to log in before validation can take place');
}
};
We can eliminate any problems which occur as a result of blur and change events by capturing the onkeyup and simply returning out if the key wasn't enter.
With this approach you shouldn't have multiple events firing etc... It is hard to see what exactly is going wrong without more of your code but hopefully I have understood correctly and covered your question.

Track/Observe TextBox value changed

Is there is any way to detect text box value changed , whether users changes it explicitly or some java script code modified the text box? I need to detect this change.
To track for user changes you can add a handler for key presses:
$(selector).keypress(function() {
// your code
});
Update: besides watching for key presses,
you can use the change function to watch from changes via JavaScript. It won't work immediatly for user changes (is only called after the input loses focus), but together with the keypress I believe you cover all cases:
$(selector).change(function() {
// the same code
});
setTimeout(function() { $(selector).val("changed"); }, 2000); // Will trigger the change
Edit: sorry, it seemed to work for JavaScript too, but I was mistaken... This question, however, will be able to solve your problem (tested with setTimeout, and it was able to detect the change).
I posted an example in jsFiddle. With this new watch plugin, you no longer need keypress or change: it will work for key typing, copy/pasting, JavaScript, etc.

Suppress Safari’s “You have entered text…” warning?

Safari helpfully (?) prompts before closing a tab or window when text has been entered into an input.
There are some cases where, as a web developer, this isn’t desirable — for example, when the input is a live search where the user has probably already gotten the results he’s looking for when the window is closed, even though there’s still text in the field.
How can I let Safari know that text in a particular input doesn’t need its protection?
It seems like you are able to disable this warning for an entire page by having an onbeforeunload handler on <body> (even an empty one will do). For example, the following will not produce the warning:
<body onbeforeunload="">
<form method="get"><input></form>
</body>
I'm not sure if this is the intended behaviour, or a bug.
I think I've got a solution to this problem, though it's unquestionably a hack (i.e. if Safari changes how this feature is implemented, it could stop working). Shown here with a touch of jQuery:
$('.unimportant').live('blur', function(){
var olddisplay = this.style.display;
this.style.display = 'none';
this.clientLeft; // layout
this.style.display = olddisplay;
});
Demo (try typing in the "unimportant" field, click somewhere else on the page, then close the window).
In short:
Hide the input
Trigger layout
Show the input
You can also change the value of the input, trigger layout, and change it back.
The one limitation here is that cleaning the input has to be done explicitly. In this case, it will be dirty until blur. This works well in my situation, and probably in many others, since the input will be protected from an accidental window close until something else on the page is manipulated (e.g. a link is clicked). You could choose to run this on keyup if you're willing to live with a flicker of the insertion point every time a key is pressed.
I'm open to cleaner solutions.
I found what I think is a pretty good solution to this problem. When I use AJAX to submit the form then I want the warning to suppress. This is accomplished with onbeforeunload.
window.onbeforeunload=function(e){}
But after I submit I might make additional changes and so I want the warning to show again. To do this I added a keyup handler to a form element.
$('txtarea').onkeyup=dirty;
What dirty does is checks is the input field has changed if it has then I set onbeforeunload to null.
function dirty(e){
if (e.srcElement.value != e.srcElement.defaultValue){
window.onbeforeunload=null;
}
}
I just found another solution to prevent Safari from displaying the "Are you sure you want to reload this page?" dialog when textareas have changed their content.
It turns out that setting the value through Javascript clears Safari's changed state:
$(document).on('blur', 'textarea', function() {
var value = $(this).val();
$(this).val('').val(value);
});
Clearing the value first is important, directly setting it to the content it already is does not work.
EDIT Apparently setting window.onbeforeunload to an empty function still works, however $(window).on('beforeunload', function() {}) does not.

How to figure out what event is being called in javascript

I'm using ASP.NET, but on a certain page I am using regular html text boxes as the request is done with AJAX, rather than the traditional full page post back. My issue is that when the user fills out the last text box and presses enter the text box loses focus and the page scrolls all the way to the bottom.
I tried using the onblur event but it's not working, so I'm wondering what event is actually being called when the enter key is pressed(or any key for that matter).
I tried this:
$("#loginPass").blur(function (e) {
if (e.keyCode == 13)
$("#DealerLogin").click();
});
I have firebug for Firefox but can't figure out how to look at what js related operations are firing.
In the Firebug scripts panel, you can click the pause button:
Try it right before you hit enter, then step through the code.
I wouldn't call myself a javascript expert, but this is what I would try.
When I get stuck, and don't know if or when my methods are being called , I fall back to using the trusty old "alert('in method 1');" technique to debug my code.
$(document).ready(function(){
alert("In document.ready()");
$("#loginPass").blur(function(e)
{
alert("In loginPass.blur() with keycode = " + e.keyCode);
});
$("#loginPass").keydown(function(e)
{
alert("In loginPass.keydown() with keycode = " + e.keyCode);
});
});
It certainly isn't an elegant technique, but is often revealing. If you find none of your methods are getting called, I guess make sure your text box id correctly matches "loginPass".
My issue is that when the user fills
out the last text box and presses
enter the text box loses focus and the
page scrolls all the way to the
bottom.
Hmm. This is definitely not a default behaviour for browsers. You need to know, what does this and just catch this event or part of code.

DOM problem with click initiating a focusout event on a different input

I have an <input type=text> with focusout event handler
I have a <button> with click event handler
Focusout checks whether format in input box is correct. It does so by testing input value against a regular expression. If it fails it displays a message (a div fades-in and -out after some time) and refocuses my input by calling
window.setTimout(function() { $(this).focus(); }, 10);
since I can't refocus in focusout event handler. focusout event can't be cancelled either. Just FYI.
Click collects data from input elements and sends it using Ajax.
The problem
When user TABs their way through the form everything is fine. When a certain input box failes formatting check it gets refocused immediately after user presses TAB.
But when user doesn't use TAB but instead clicks on each individual input field everything works fine until they click the button. focusout fires and sets time-out for refocusing. Since time-out is so short focusing happens afterwards and then click event fires and issues an Ajax request.
Question
I have implemented my formatting check as an independent jQuery plugin that I want to keep that way. It uses .live() to attach focusout on all input fields with a particular attribute where format regular expression is defined.
Data submission is also generic and I don't want to make it dependant on formatting plugin. They should both stay independent.
How can I prevent click event from executing without making these two plugins dependant?
Example code I'm fiddling with
After some searching I've seen that all major browser support document.activeElement but I can't make it work in Chrome. FF and IE both report this being the active element, but Chrome always says it's BODY that is active even though click fired on the button element.
Check this code http://jsfiddle.net/Anp4b/1/ and click on the button. Test with Chrome and some other browser and see the difference.
You could use a flag...
Live demo: http://jsfiddle.net/Anp4b/4/
So your question is:
How can I prevent click event from executing without making these two plugins dependent?
Well, you obviously cannot prevent the click event. If the user wants to click the button, he will, and the click event will trigger. There's nothing you can do about that.
So the answer to the above question is: You cannot.
Based on the current conditions, you have to - inside the click handler - retrieve the validation result, and based on that result, decide if form submission should or should not occur.
JS Code:
$("#Name").focusout(function(){
var that = this;
valid = this.value.length ? true : false;
!valid && window.setTimeout(function() {
$(that).focus();
}, 0);
});
$("#Confirm").click(function(e) {
if ( !valid ) { return false; }
e.preventDefault();
alert('AJAX-TIME :)');
});
HTML Code:
<input type="text" id="Name">
<button id="Confirm">OK</button>
Is there are reason you use .focusout instead of .blur?
Using a flag is a good idea, but I would rather use a class on the element. By using classes to determine the state you can also style it accordingly. Here's my example based on your fiddle.
Another solution that hopefully gives the result you are looking for.
1) Create a named click handler:
var clickHandler = function(e){ /** submit form or whatever you want to do**/ };
$("button").click(clickHandler);
2) Add the following to the focusout event when it's failing validation:
$("button").unbind("click", clickHandler).one("click", function(){ button.click(clickHandler); return false;});
You can find an example of this here.

Categories