How to avoid duplicate submission for single input forms? - javascript

I have a single input form:
<form id="my_form">
<input id="my_input" type="text" />
</form>
In most browsers, when a user types text in this single input and hits 'enter' the form is submitted. That's great but I want to go one step further and make it so that if the user types something and focus is lost, the form is submitted.
I've currently tapped into jQuery's change event like so:
$("my_input").change(function() {
$("my_form").submit();
});
This works for the case when I change the input value and focus out but if I change the input value and hit 'enter' then the form is submitted twice (once for 'enter' and once for change).
I was starting to go down the path of lower level listening to keys and managing a submit state but figured I'd throw it out to the community to see if anyone knows of a cleaner way.

Instead of messing with error-prone checks, you can also attach a submit event to the form. If the value is equal to the old value, don't submit the form by using ev.preventDefault().
var oldvalue = "";
$("#my_form").submit(function(ev){
var newvalue = $("#my_input", this).val();
if(newvalue == oldvalue) ev.preventDefault(); //Same value, cancel submission
else oldvalue = newvalue;
})

Have you tried the blur event http://api.jquery.com/blur/
This will fire when the input loses focus.

Just an improvement to Rob W's solution.
$('#my_form').submit((function () {
//Enclose variables as to not pollute the global namespace
var oldValue,
input = $('#my_input'); //cache your input
//Same concept as Rob W's solution
return function (e) {
var newValue = input.val();
if(newValue === oldValue) {
e.preventDefault();
}
oldValue = newValue;
};
})());

Related

Does 'keypress' jQuery event fire before an inputs value is updated?

I have a keypress event listener on an input field to confirm a password. I want the button on the page to be disabled until the password and confirm-password fields have matching values. I am using the .keypress() jQuery function, but it seems to always be one character behind what I expect it to be?
Here is the code
$('#confirm').keypress(function() {
console.log('#confirm').val();
if($('#password').val() == $('#confirm').val()) {
$('button').removeProp('disabled');
console.log("yes");
} else {
console.log("no");
}
});
But when I inspect element and look at the console window on my page, the first time the event is fired it prints the form value as blank. Then when I enter a second character, it prints only the first, and when I type a third character it prints the first two, etc.
For example, if I put asd into the password field and begin typing the same into the confirm field the output will look like this:
<blank>
no
a
no
as
no
So at this point both password and confirm fields have "asd", but I need to enter an extra character before that is recognized and the "disabled" property is removed from the button.
I have tried using .change() instead of .keypress() but that doesn't fire until the input field loses focus, which is not what I want.
I want the button on the page to be disabled until the password and confirm-password fields have matching values
If this is your goal, you can add event listeners to both inputs that call a validation function:
$('#password').on("input", function() { validatePassword(); });
$('#confirm').on("input", function() { validatePassword(); });
function validatePassword() {
if($('#password').val() && $('#confirm').val() && $('#password').val() == $('#confirm').val()) {
$('button').prop('disabled', false);
} else {
$('button').prop('disabled', true);
}
}
It also may be worthwhile adding an ID to the button. Using 'button' would enable/disable all elements on the page.
Example: https://jsfiddle.net/doL4t9vv/1/
I had the same problem few months ago.
Try to use the keyup function from Jquery.
Keypress event is fired when you press the key, so the input is not fill yet.
Keyup event is fired when you release the key.
Can use input event and simplify this down to
var $passwords =$('#confirm, #password').on('input', function() {
var thisValue = this.value.trim();
// does this input have value and does it match other
var isValid = thisValue && thisValue === $passwords.not(this).val().trim();
// boolean used for disabled property
$('button').prop('disabled', !isValid);
});

JS prevent firing focusout event if input didn't changed

I have the following input:
<input name="video" value="" type="text">
And attached js event:
input.focusout(function(){
loadThumbnail();
});
The problem is it triggers always when focus leaves field. Actually it's goods behavior, but didn't fit my needs, because if user didn't changed the field the event will be triggered and the request will be made on server.
I've tried to replace it with change event, but it doesn't triggers when user clean's field.
So what I need is event that will be triggered after user finished editing the field and detect cases when user cleans field or moves focus to/from it, but don't change anything.
Would you suggest a solution?
Try something like this to save the old value and compare it with new value:
var oldVal = ''
input.focusout(function () {
var newVal = input.val();
if (oldVal != newVal) {
oldVal = newVal;
loadThumbnail();
}
});
Try the below part. You will have to tweak this. I just wrote a raw code for U.
var temp='';
input.focusin(function(){
temp = input.val();
});
input.focusout(function(){
if temp != input.val() then
loadThumbnail();
});

Set form hidden value on submit

I got a form, and I want to send hidden input by javascript, how to do it?
F.ex:
<input id="total" type="hidden" value="" name="total" />
And when someone click submit I want to set it value
Are you trying to instantaneously change the value of the hidden input? Something like that can be achieved with the onsubmit event, of course.
var submit = document.getElementById("submit");
var hidden = document.getElementById("hidden");
var eventListener = function(el, type, listener) {
if(el.addEventListener) {
el.addEventListener(type, listener, false);
} else if(el.attatchEvent) {
el.attatchEvent("on"+type, listener);
} else {
el['on'+type] = listener;
}
};
var onsubmit = function() {
var newVal = "value to set for hidden input";
hidden.value = newVal;
};
eventListener(submit, "submit", onsubmit);
The above code will listen to the submit event on the submit button and when triggered, it will change the value of the hidden input. To go into further detail with any answer, we'd need a more descriptive question. Otherwise, I really don't know what you want.
You can try following:
document.getElementById("total").value = "value you want to set";
document.formname.submit();
If you're trying to create a unique id so that you can add this person into some db with a unique key or you want to create some sort of session id or a similar id and store it in memory then I suggest using php or perl not javascript. I'm a newbie too but i've had that sort of dilemma come up with some stuff i was trying to do and php did the trick for me. I ended up using js to validate the form data and pass it to the php once it checked out. js is great if you want to check to see if the data is present and doesn't contain anything that you don't want or need in the form. it's not great for security.

How do I get curent value of text element via jQuery

I have text input element and an event is fired on blur event and when user presses enter.
My problem is that if user inputs "foo" and presses enter val() function nevertheless returns null, after the blur event val() returns foo. As far as I understand it is due to the fact that value property of HTML input element is updated only when it looses focus. Could you please give me a work around.
Here is the exact code I use:
var meetmove_address_field_listener = function(e){
var type = $(this).attr('data-marker-type');;
var value = $(this).val();
meetmove_map.geocodeAddress(type, value);
};
$(document).ready(function(){
$('input[data-type="name"]').blur(meetmove_address_field_listener);
$('input[data-type="name"]').keypress(function(event){
if (event.which == 13){
event.preventDefault();
meetmove_address_field_listener(event);
return false;
}
});
});
The value can be accessed straight away, you just need to use the correct handler. .keypress() will fire before the character is displayed in the input. Try .keyup() instead of .keypress() and it should work.
Well really Sudahir answer solved my issue --- i was misusing $(this) reference that changes meaning depending on context. Bu he deleted his answer so here is the working code:
$(document).ready(function(){
$('input[data-type="name"]').blur(meetmove_address_field_listener);
$('input[data-type="name"]').keyup(function(event){
if (event.which == 13){
event.preventDefault();
var type = $(this).attr('data-marker-type');
var value = $(this).val();
meetmove_map.geocodeAddress(type, value);
return false;
}
});
});

Can jQuery check whether input content has changed?

Is it possible to bind javascript (jQuery is best) event to "change" form input value somehow?
I know about .change() method, but it does not trigger until you (the cursor) leave(s) the input field. I have also considered using .keyup() method but it reacts also on arrow keys and so on.
I need just trigger an action every time the text in the input changes, even if it's only one letter change.
There is a simple solution, which is the HTML5 input event. It's supported in current versions of all major browsers for <input type="text"> elements and there's a simple workaround for IE < 9. See the following answers for more details:
jQuery keyboard events
Catch only keypresses that change input?
Example (except IE < 9: see links above for workaround):
$("#your_id").on("input", function() {
alert("Change to " + this.value);
});
Yes, compare it to the value it was before it changed.
var previousValue = $("#elm").val();
$("#elm").keyup(function(e) {
var currentValue = $(this).val();
if(currentValue != previousValue) {
previousValue = currentValue;
alert("Value changed!");
}
});
Another option is to only trigger your changed function on certain keys. Use e.KeyCode to figure out what key was pressed.
You can also store the initial value in a data attribute and check it against the current value.
<input type="text" name="somename" id="id_someid" value="" data-initial="your initial value" />
$("#id_someid").keyup(function() {
return $(this).val() == $(this).data().initial;
});
Would return true if the initial value has not changed.
function checkChange($this){
var value = $this.val();
var sv=$this.data("stored");
if(value!=sv)
$this.trigger("simpleChange");
}
$(document).ready(function(){
$(this).data("stored",$(this).val());
$("input").bind("keyup",function(e){
checkChange($(this));
});
$("input").bind("simpleChange",function(e){
alert("the value is chaneged");
});
});
here is the fiddle http://jsfiddle.net/Q9PqT/1/
You can employ the use of data in jQuery and catch all of the events which then tests it against it's last value (untested):
$(document).ready(function() {
$("#fieldId").bind("keyup keydown keypress change blur", function() {
if ($(this).val() != jQuery.data(this, "lastvalue") {
alert("changed");
}
jQuery.data(this, "lastvalue", $(this).val());
});
});
This would work pretty good against a long list of items too. Using jQuery.data means you don't have to create a javascript variable to track the value. You could do $("#fieldId1, #fieldId2, #fieldId3, #fieldId14, etc") to track many fields.
UPDATE: Added blur to the bind list.
I had to use this kind of code for a scanner that pasted stuff into the field
$(document).ready(function() {
var tId,oldVal;
$("#fieldId").focus(function() {
oldVal = $("#fieldId").val();
tId=setInterval(function() {
var newVal = $("#fieldId").val();
if (oldVal!=newVal) oldVal=newVal;
someaction() },100);
});
$("#fieldId").blur(function(){ clearInterval(tId)});
});
Not tested...
I don't think there's a 'simple' solution. You'll probably need to use both the events onKeyUp and onChange so that you also catch when changes are made with the mouse. Every time your code is called you can store the value you've 'seen' on this.seenValue attached right to the field. This should make a little easier.
You can set events on a combination of key and mouse events, and onblur as well, to be sure. In that event, store the value of the input. In the next call, compare the current value with the lastly stored value. Only do your magic if it has actually changed.
To do this in a more or less clean way:
You can associate data with a DOM element (lookup api.jquery.com/jQuery.data ) So you can write a generic set of event handlers that are assigned to all elements in the form. Each event can pass the element it was triggered by to one generic function. That one function can add the old value to the data of the element. That way, you should be able to implement this as a generic piece of code that works on your whole form and every form you'll write from now on. :) And it will probably take no more than about 20 lines of code, I guess.
An example is in this fiddle: http://jsfiddle.net/zeEwX/
Since the user can go into the OS menu and select paste using their mouse, there is no safe event that will trigger this for you. The only way I found that always works is to have a setInterval that checks if the input value has changed:
var inp = $('#input'),
val = saved = inp.val(),
tid = setInterval(function() {
val = inp.val();
if ( saved != val ) {
console.log('#input has changed');
saved = val;
},50);
You can also set this up using a jQuery special event.

Categories

Resources