Input fill with keypress simulation - javascript

Let's say we have an input and we want to add some texts to it:
<form>
First name:<br>
<input type="text" id="thename" name="firstname">
</form>
The simple thing is to add value to input with classic element.value... .
But what if I want to add for example 'David' by simulating the keypress event?
I followed several approaches like this:
function simulateKeyEvent(character) {
var evt = document.createEvent("KeyboardEvent");
(evt.initKeyEvent || evt.initKeyboardEvent)("keypress", true, true, window,
0, 0, 0, 0,
0, character.charCodeAt(0))
var canceled = !body.dispatchEvent(evt);
if(canceled) {
// A handler called preventDefault
alert("canceled");
} else {
// None of the handlers called preventDefault
alert("not canceled");
}
}
Taken from here and read almost every solutions but they didn't work.
Note: I'm working in Firefox and Chrome

Are you just trying to add text to the input, but make it seem as if its being typed by a ghost?
function typeToInput(id, str){
var ctr = 0;
var tmr = setInterval(function(){
document.getElementById(id).value += str[ctr];
ctr++;
if(ctr >= str.length) clearInterval(tmr);
}, 250);
}
though, you'll probably want to cancel the timer and clear the text if the input gets focus..

Already answered here.
For security reasons, you are not allowed to fire an event that will cause text to populate an input. See workarounds in the linked answer.

Related

How to alert when unload page while checking whether each element is changed or not

I developed page in which multiple input and textarea exist.
I would like to set unload event to prevent what we inputed are not inserted.
To set this,I also add checking whether each input elements are changed.
If text are changed. I would like to set this alert system.
while these texts are not changed, we can easily leave page and unload event will not be fired.
I have tried following . I would like to combile window.addEventListener('beforeunload') and window.addEventListener('load'). are there any good ways to achieve this?
My point is how to handle beforeUnloadAlert variables..
Thanks
window.addEventListener('beforeunload', function(e) {
e.returnValue = 'Are you sure you want to exit?';
}, false);
window.addEventListener('load', function (e) {
let beforeUnloadAlert = true;
var inputs = document.querySelectorAll('.inputForm');
for (var i = inputs.length - 1; i >= 0; i--) {
inputs[i].addEventListener('change', displayName);
}
function displayName(e) {
console.log(this);
beforeUnloadAlert = false;
}
return beforeUnloadAlert
});
<input class='inputForm'>
<input class='inputForm'>
<input class='inputForm'>
<input class='inputForm'>

How to manipulate clipboard data using jquery in chrome, IE 8&9?

This is my jquery code that I am using to truncate the pasted text, so that it doesn't exceed the maxlength of an element. The default behaviour on Chrome is to check this automatically but in IE 8 and 9 it pastes the whole text and doesn't check the maxLength of an element. Please help me to do this. This is my first time asking a question here, so please let me know if I need to provide some more details. Thanks.
<script type="text/javascript">
//var lenGlobal;
var maxLength;
function doKeypress(control) {
maxLength = control.attributes["maxLength"].value;
value = control.value;
if (maxLength && value.length > maxLength - 1) {
event.returnValue = false;
maxLength = parseInt(maxLength);
}
}
//function doBeforePaste(control) {
//maxLength = control.attributes["maxLength"].value;
//if (maxLength) {
// event.returnValue = false;
//var v = control.value;
//lenGlobal = v.length;
// }
// }
$(document).on("focus","input[type=text],textarea",function(e){
var t = e.target;
maxLength = parseInt($(this).attr('maxLength'));
if(!$(t).data("EventListenerSet")){
//get length of field before paste
var keyup = function(){
$(this).data("lastLength",$(this).val().length);
};
$(t).data("lastLength", $(t).val().length);
//catch paste event
var paste = function(){
$(this).data("paste",1);//Opera 11.11+
};
//process modified data, if paste occured
var func = function(){
if($(this).data("paste")){
var dat = this.value.substr($(this).data("lastLength"));
//alert(this.value.substr($(this).data("lastLength")));
// alert(dat.substr(0,4));
$(this).data("paste",0);
//this.value = this.value.substr(0,$(this).data("lastLength"));
$(t).data("lastLength", $(t).val().length);
if (dat == ""){
this.value = $(t).val();
}
else
{
this.value = dat.substr(0,maxLength);
}
}
};
if(window.addEventListener) {
t.addEventListener('keyup', keyup, false);
t.addEventListener('paste', paste, false);
t.addEventListener('input', func, false);
} else{//IE
t.attachEvent('onkeyup', function() {keyup.call(t);});
t.attachEvent('onpaste', function() {paste.call(t);});
t.attachEvent('onpropertychange', function() {func.call(t);});
}
$(t).data("EventListenerSet",1);
}
});
</script>
You could do something like this, mind you this was done in YUI but something simlar can be done for jquery. All you need to do is get the length of the comment that was entered and then truncate the text down the the desired length which in the case of this example is 2000 characters.
comment_text_box.on('valuechange', function(e) {
//Get the comment the user input
var comment_text = e.currentTarget.get('value');
//Get the comment length
var comment_length = comment_text.length;
if(comment_length > 2000){
alert('The comment entered is ' + comment_length + ' characters long and will be truncated to 2000 characters.');
//Truncate the comment
var new_comment = comment_text.substring(0, 2000);
//Set the value of the textarea to truncated comment
e.currentTarget.set('value', new_comment);
}
});
You're putting too much effort into something that is apparently a browser quirk and is mostly beyond your control and could change in the future. In fact, I can't recreate this in IE10 - it behaves just like Chrome for me.
Make sure you are validating the length on the server-side, since it's still possible to get around a field's maxlength when submitting the form input to the server (see this somewhat similar question). That's not to say you shouldn't have some client-side logic to validate the length of the input to enforce the maxlength constraint - I just think you don't need to go to the length you are attempting here to essentially intercept a paste command. Keep it simple - having a basic length validation check in your JavaScript is going to be a lot less messy than what you have here.
Perhaps consider a bit of jQuery like this:
$("#myTextControl").change(function() {
if ($(this).val().length > $(this).attr('maxlength')) {
DisplayLengthError();
}
});
(where DisplayLengthError() is an arbitrary function that triggers some kind of feedback to the user that they have exceeded the maxlength constraint of the field, be it an error label, and alert box, etc.)

Firefox: lose focus when clear textbox value

I have a search box (textbox) and I want to clear it's content when I click inside. (some kind of watermark. Watermark control was not good for me in this case).
I am using "onKeyDown" event to clear the content:
function clearTbSearch(tbSearch) {
if (tbSearch != null && tbSearch.value == '<%= TypeHereText %>') {
tbSearch.value = "";
tbSearch.style.color = "#000000";
}
return true;
}
It works fine in IE and Chrome but in Firefox it takes 3 (!!!) clicks to get it focused. First click does not do anything. The second one clears the textbox but do not focus. The third click get the cursor focused. I tried anything... I would be glad for any suggestions...
Thanks!!!
You can try this to make it look cleaner:
<input type="text" name="myInput" value="Your initial trademark" onfocus="this.value=''" />
No need to use onkeydown event, just use the generic onfocus instead:
var firstTime = true;
window.onload = function() {
var input = document.getElementById("MyInput");
input.onfocus = function() {
if (!firstTime)
clearTbSearch(this);
firstTime = false;
};
input.focus();
};
This way it will work either by keyboard focus or mouse focus e.g. when clicking the textbox.

Problem invoking a function on change event

I am trying to invoke an ajax call as soon as my input fields length is 15 (for now I have just put in an alert box in place of .ajax{ }), but the alert box is not firing up until I click somewhere on the screen after input field is filled with 15 characters.
what am I doing wrong here?
$("#serialCode").change(function () {
var d = $("#serialCode").val();
if (d.length == 15) {
var $code = d.substring(0, 9);
alert('Serial code ' + $code);
}
$(this).val("");
});
You'll likely want to use keypress instead of keyup or keydown, as those won't be called for subsequent characters if someone holds a key down.
$("#serialCode").keypress(function () {
var d = $("#serialCode").val();
if (d.length == 15) {
var $code = d.substring(0, 9);
alert('Serial code ' + $code);
}
$(this).val("");
});
I wrote a blog post earlier today on why onkeyup isn't a great idea for detecting user input. The better option is to either use onkeydown with a 0ms timer, or a combination of the newer HTML 5 event oninput for standards compliant browsers and onpropertychange in Internet Explorer.
These two events will handle other forms of input such as cut, paste, undo, redo, drag and drop, and even changes made by a native spell checker.
Something like this should work for you:
// Check for which event we need to bind to, onpropertychange or oninput
var evt = "onpropertychange" in document.body ? "propertychange" : "input";
$("#serialCode").bind(evt, function (event) {
// For the onpropertychange event, check that the value property changed
if (evt == "propertychange" && event.propertyName != "value")
return;
var d = $("#serialCode").val();
if (d.length == 15) {
var $code = d.substring(0, 9);
alert('Serial code ' + $code);
}
$(this).val("");
});
Note that if you need to support older browsers, you'll need to use some form of event detection to see if these events are available and if not, fall back to the keydown with timer method.
The change event doesn't fire until you lose focus on the input.
Try using keyup instead:
$("#serialCode").keyup(function () {
var d = this.value;
if (d.length == 15) {
var $code = d.substring(0, 9);
alert('Serial code ' + $code);
}
// this.value = '';
});
You should note that people can get around this by using the GUI to paste text into the input, so you may want to add the same functionality on change as well.
$("#serialCode").bind('keyup keydown change', function () {
Because there are multiple events, you should have some sort of flag that is set when the AJAX request is sent, so you're not sending it multiple times.
i experienced issues with the jQuery ajax interface. those issues disappeared when i decided to just use to javascript only interace.
see this link hosted at IBM. once you read this you will never again have a question with how ajax does or should function.

What is the best way to track changes in a form via javascript?

I'd like to track changes in inputs in a form via javascript. My intent is (but not limited) to
enable "save" button only when something has changed
alert if the user wants to close the page and something is not saved
Ideas?
Loop through all the input elements, and put an onchange handler on each. When that fires, set a flag which lets you know the form has changed. A basic version of that would be very easy to set up, but wouldn't be smart enough to recognize if someone changed an input from "a" to "b" and then back to "a". If it were important to catch that case, then it'd still be possible, but would take a bit more work.
Here's a basic example in jQuery:
$("#myForm")
.on("input", function() {
// do whatever you need to do when something's changed.
// perhaps set up an onExit function on the window
$('#saveButton').show();
})
;
Text form elements in JS expose a .value property and a .defaultValue property, so you can easily implement something like:
function formChanged(form) {
for (var i = 0; i < form.elements.length; i++) {
if(form.elements[i].value != form.elements[i].defaultValue) return(true);
}
return(false);
}
For checkboxes and radio buttons see whether element.checked != element.defaultChecked, and for HTML <select /> elements you'll need to loop over the select.options array and check for each option whether selected == defaultSelected.
You might want to look at using a framework like jQuery to attach handlers to the onchange event of each individual form element. These handlers can call your formChanged() code and modify the enabled property of your "save" button, and/or attach/detach an event handler for the document body's beforeunload event.
Here's a javascript & jquery method for detecting form changes that is simple. It disables the submit button until changes are made. It detects attempts to leave the page by means other than submitting the form. It accounts for "undos" by the user, it is encapsulated within a function for ease of application, and it doesn't misfire on submit. Just call the function and pass the ID of your form.
This function serializes the form once when the page is loaded, and again before the user leaves the page. If the two form states are different, the prompt is shown.
Try it out: http://jsfiddle.net/skibulk/ev5rE/
function formUnloadPrompt(formSelector) {
var formA = $(formSelector).serialize(), formB, formSubmit = false;
// Detect Form Submit
$(formSelector).submit( function(){
formSubmit = true;
});
// Handle Form Unload
window.onbeforeunload = function(){
if (formSubmit) return;
formB = $(formSelector).serialize();
if (formA != formB) return "Your changes have not been saved.";
};
// Enable & Disable Submit Button
var formToggleSubmit = function(){
formB = $(formSelector).serialize();
$(formSelector+' [type="submit"]').attr( "disabled", formA == formB);
};
formToggleSubmit();
$(formSelector).change(formToggleSubmit);
$(formSelector).keyup(formToggleSubmit);
}
// Call function on DOM Ready:
$(function(){
formUnloadPrompt('form');
});
Try
function isModifiedForm(form){
var __clone = $(form).clone();
__clone[0].reset();
return $(form).serialize() == $(__clone).serialize();
}
Hope its helps ))
If your using a web app framework (rails, ASP.NET, Cake, symfony), there should be packages for ajax validation,
http://webtecker.com/2008/03/17/list-of-ajax-form-validators/
and some wrapper on onbeforeunload() to warn users taht are about to close the form:
http://pragmatig.wordpress.com/2008/03/03/protecting-userdata-from-beeing-lost-with-jquery/
Detecting Unsaved Changes
I answered a question like this on Ars Technica, but the question was framed such that the changes needed to be detected even if the user does not blur a text field (in which case the change event never fires). I came up with a comprehensive script which:
enables submit and reset buttons if field values change
disables submit and reset buttons if the form is reset
interrupts leaving the page if form data has changed and not been submitted
supports IE 6+, Firefox 2+, Safari 3+ (and presumably Opera but I did not test)
This script depends on Prototype but could be easily adapted to another library or to stand alone.
$(document).observe('dom:loaded', function(e) {
var browser = {
trident: !!document.all && !window.opera,
webkit: (!(!!document.all && !window.opera) && !document.doctype) ||
(!!window.devicePixelRatio && !!window.getMatchedCSSRules)
};
// Select form elements that won't bubble up delegated events (eg. onchange)
var inputs = $('form_id').select('select, input[type="radio"], input[type="checkbox"]');
$('form_id').observe('submit', function(e) {
// Don't bother submitting if form not modified
if(!$('form_id').hasClassName('modified')) {
e.stop();
return false;
}
$('form_id').addClassName('saving');
});
var change = function(e) {
// Paste event fires before content has been pasted
if(e && e.type && e.type == 'paste') {
arguments.callee.defer();
return false;
}
// Check if event actually results in changed data
if(!e || e.type != 'change') {
var modified = false;
$('form_id').getElements().each(function(element) {
if(element.tagName.match(/^textarea$/i)) {
if($F(element) != element.defaultValue) {
modified = true;
}
return;
} else if(element.tagName.match(/^input$/i)) {
if(element.type.match(/^(text|hidden)$/i) && $F(element) != element.defaultValue) {
modified = true;
} else if(element.type.match(/^(checkbox|radio)$/i) && element.checked != element.defaultChecked) {
modified = true;
}
}
});
if(!modified) {
return false;
}
}
// Mark form as modified
$('form_id').addClassName('modified');
// Enable submit/reset buttons
$('reset_button_id').removeAttribute('disabled');
$('submit_button_id').removeAttribute('disabled');
// Remove event handlers as they're no longer needed
if(browser.trident) {
$('form_id').stopObserving('keyup', change);
$('form_id').stopObserving('paste', change);
} else {
$('form_id').stopObserving('input', change);
}
if(browser.webkit) {
$$('#form_id textarea').invoke('stopObserving', 'keyup', change);
$$('#form_id textarea').invoke('stopObserving', 'paste', change);
}
inputs.invoke('stopObserving', 'change', arguments.callee);
};
$('form_id').observe('reset', function(e) {
// Unset form modified, restart modified check...
$('reset_button_id').writeAttribute('disabled', true);
$('submit_button_id').writeAttribute('disabled', true);
$('form_id').removeClassName('modified');
startObservers();
});
var startObservers = (function(e) {
if(browser.trident) {
$('form_id').observe('keyup', change);
$('form_id').observe('paste', change);
} else {
$('form_id').observe('input', change);
}
// Webkit apparently doesn't fire oninput in textareas
if(browser.webkit) {
$$('#form_id textarea').invoke('observe', 'keyup', change);
$$('#form_id textarea').invoke('observe', 'paste', change);
}
inputs.invoke('observe', 'change', change);
return arguments.callee;
})();
window.onbeforeunload = function(e) {
if($('form_id').hasClassName('modified') && !$('form_id').hasClassName('saving')) {
return 'You have unsaved content, would you really like to leave the page? All your changes will be lost.';
}
};
});
I would store each fields value in a variable when the page loads, then compare those values when the user unloads the page. If any differences are detected you will know what to save and better yet, be able to specifically tell the user what data will not be saved if they exit.
// this example uses the prototype library
// also, it's not very efficient, I just threw it together
var valuesAtLoad = [];
var valuesOnCheck = [];
var isDirty = false;
var names = [];
Event.observe(window, 'load', function() {
$$('.field').each(function(i) {
valuesAtLoad.push($F(i));
});
});
var checkValues = function() {
var changes = [];
valuesOnCheck = [];
$$('.field').each(function(i) {
valuesOnCheck.push($F(i));
});
for(var i = 0; i <= valuesOnCheck.length - 1; i++ ) {
var source = valuesOnCheck[i];
var compare = valuesAtLoad[i];
if( source !== compare ) {
changes.push($$('.field')[i]);
}
}
return changes.length > 0 ? changes : [];
};
setInterval(function() { names = checkValues().pluck('id'); isDirty = names.length > 0; }, 100);
// notify the user when they exit
Event.observe(window, 'beforeunload', function(e) {
e.returnValue = isDirty ? "you have changed the following fields: \r\n" + names + "\r\n these changes will be lost if you exit. Are you sure you want to continue?" : true;
});
I've used dirtyforms.js. Works well for me.
http://mal.co.nz/code/jquery-dirty-forms/
To alert the user before closing, use unbeforeunload:
window.onbeforeunload = function() {
return "You are about to lose your form data.";
};
I did some Cross Browser Testing.
On Chrome and Safari this is nice:
<form onchange="validate()">
...
</form>
For Firefox + Chrome/Safari I go with this:
<form onkeydown="validate()">
...
<input type="checkbox" onchange="validate()">
</form>
Items like checkboxes or radiobuttons need an own onchange event listener.
Attach an event handler to each form input/select/textarea's onchange event. Setting a variable to tell you if you should enable the "save" button. Create an onunload hander that checks for a dirty form too, and when the form is submitted reset the variable:
window.onunload = checkUnsavedPage;
var isDirty = false;
var formElements = //Get a reference to all form elements
for(var i = 0; len = formElements.length; i++) {
//Add onchange event to each element to call formChanged()
}
function formChanged(event) {
isDirty = false;
document.getElementById("savebtn").disabled = "";
}
function checkUnsavedPage() {
if (isDirty) {
var isSure = confirm("you sure?");
if (!isSure) {
event.preventDefault();
}
}
}
Here's a full implementation of Dylan Beattie's suggestion:
Client/JS Framework for "Unsaved Data" Protection?
You shouldn't need to store initial values to determine if the form has changed, unless you're populating it dynamically on the client side (although, even then, you could still set up the default properties on the form elements).
You can also check out this jQuery plugin I built at jQuery track changes in forms plugin
See the demo here and download the JS here
If you are open to using jQuery, see my answer a similar question:
Disable submit button unless original form data has changed.
I had the same challenge and i was thinking of a common solution. The code below is not perfect, its from initial r&d. Following are the steps I used:
1) Move the following JS to a another file (say changeFramework.js)
2) Include it in your project by importing it
3) In your html page, whichever control needs monitoring, add the class "monitorChange"
4) The global variable 'hasChanged' will tell, if there is any change in the page you working on.
<script type="text/javascript" id="MonitorChangeFramework">
// MONITOR CHANGE FRAMEWORK
// ALL ELEMENTS WITH CLASS ".monitorChange" WILL BE REGISTERED FOR CHANGE
// ON CHANGE IT WILL RAISE A FLAG
var hasChanged;
function MonitorChange() {
hasChanged = false;
$(".monitorChange").change(function () {
hasChanged = true;
});
}
Following are the controls where I used this framework:
<textarea class="monitorChange" rows="5" cols="10" id="testArea"></textarea></br>
<div id="divDrinks">
<input type="checkbox" class="chb monitorChange" value="Tea" />Tea </br>
<input type="checkbox" class="chb monitorChange" value="Milk" checked='checked' />Milk</br>
<input type="checkbox" class="chb monitorChange" value="Coffee" />Coffee </br>
</div>
<select id="comboCar" class="monitorChange">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
<button id="testButton">
test</button><a onclick="NavigateTo()">next >>> </a>
I believe there can be huge improvement in this framework. Comment/Changes/feedbacks are welcome. :)

Categories

Resources