I have a blur function already attached to my dropdown, now I want to call another function onchange after my blur function is called in javasript.
<select onchange="CheckAccommodation(this)" onblur="return UpdateFormSelect('UpdatePrice.aspx', 'BookNow_accommodation1', 'select', 'BookNow_accommduration');javascript:test()" id="BookNow_accommodation1" name="BookNow:accommodation1">
Now I want to call my javascript:test() after the blur is done
Please suggest!
Thanks.
Best Regards,
Yuv
This suggested by #Ghommey will work:
<select onchange="CheckAccommodation(this)" onblur="return
UpdateFormSelect('UpdatePrice.aspx', 'BookNow_accommodation1',
'select', 'BookNow_accommduration');test()" id="BookNow_accommodation1"
name="BookNow:accommodation1">
it works irrespective of what you return from UpdateFormSelect.
function onChangeHandler(){
//.........
}
$("SELECT_ID").blur(function(){
//handle blur
//call on change handler
onChangeHandler();
});
Now I want to call my javascript:test() after the blur is done
Then just remove the ‘return’ on the first statement, allowing it to fall through to the second:
onblur="UpdateFormSelect('UpdatePrice.aspx', 'BookNow\_accommodation1', 'select', 'BookNow\_accommduration');test()"
You could put return test(), but actually onblur doesn't need to return anything. <a onclick> often needs to return false to stop the link being followed, but other than that you often don't need any return value from an event handler.
It's also a bit of a mouthful to put in an event handler. You might benefit by breaking the JavaScript out:
<select id="BookNow_accommodation1" name="BookNow:accommodation1">
...
</select>
<script type="text/javascript">
var acc1= document.getElementById('BookNow_accommodation1');
acc1.onchange= function() {
CheckAccommodation(this);
// or just move the body of CheckAccommodation here
};
acc1.onblur= function() {
UpdateFormSelect('UpdatePrice.aspx', 'BookNow_accommodation1', 'select', 'BookNow_accommduration');
test();
};
</script>
Related
I have the following code:
myInput.change(function (e) { // this triggers first
triggerProcess();
});
myButton.click(function (e) { // this triggers second
triggerProcess();
});
The problem with the above is when I click myButton both events are triggered and triggerProcess() is fired twice which is not desired.
I only need triggerProcess() to fire once. How can I do that?
Small demo
You can have a static flag that disables any more triggers once the first trigger has occurred. Might look something like this:
var hasTriggered = false;
myInput.change(function (e) { // this triggers first
triggerProcess();
});
myButton.click(function (e) { // this triggers second
triggerProcess();
});
function triggerProcess () {
// If this process has already been triggered,
// don't execute the function
if (hasTriggered) return;
// Set the flag to signal that we've already triggered
hasTriggered = true;
// ...
}
For resetting the hasTriggered flag, that's entirely up to you and how this program works. Maybe after a certain event occurring in the program you'd want to reenable the ability to trigger this event again — all you'd need to do it set the hasTriggered flag back to true.
You can use the mousedown event, which will fire before the input is blurred, and then check if the input has focus by checking if it's the activeElement, and if it does have focus, don't fire the mousedown event, as the change event will fire instead.
Additionally, if you want a mousedown event to occur when the value hasn't changed, and the change event doesn't fire, you'll need a check for that as well
var myInput = $('#test1'),
myButton = $('#test2'),
i = 0;
myInput.change(function(e) { // this triggers first
$(this).data('prev', this.value);
triggerProcess();
});
myButton.mousedown(function(e) { // this triggers second
var inp = myInput.get(0);
if (document.activeElement !== inp || inp.value === myInput.data('prev'))
triggerProcess();
});
function triggerProcess() {
console.log('triggered : ' + (++i))
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="test1">
<br />
<br />
<button id="test2">
Click
</button>
In a fairly typical scenario where you have an input with a button next to ie, eg quick search.
You want to fire when the input changes (ie onblur) but also if the user clicks the button.
In the case where the user changes the input then clicks the button without changing input focus (ie no blur), the change event fires because the text has changed and the click event fires because the button has been clicked.
One option is to debounce the desired event handler.
You can use a plugin or a simple setTimeout/clearTimeout, eg:
$('#inp').change(debounceProcess)
$('#btn').click(debounceProcess);
function debounceProcess() {
if (debounceProcess.timeout != null)
clearTimeout(debounceProcess.timeout);
debounceProcess.timeout = setTimeout(triggerProcess, 100)
}
function triggerProcess() {
console.log('process')
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id="inp">
<button id="btn">Click</button>
Use a real <button>BUTTON</button>. If you click on input text, alert is triggered, then once you leave the input text to click anywhere else, that unfocuses the input text which triggers the change event, so now 2 events have been triggered from the text input.
This is an assumption since the code provided is far from sufficient to give a complete and accurate answer. The HTML is needed as well as more jQuery/JavaScript. What is myInput and myButton actually referring to, etc.?
So I bet if you change...
var myButton = $('{whatever this is}'); and <input type='button'>
...TO:
var myButton = $("button"); and <button></button>
...you should no longer have an event trigger twice for an element.
This is assuming that triggerProcess() is a function that does something that doesn't manipulate the event chain or anything else involving events. This is an entirely different ballgame if instead of click() and change() methods you are using .trigger() or triggerHandler(), but it isn't. I'm not certain why such complex answers are derived from a question with very little info...?
BTW, if myInput is a search box and myButton is the button for myInput, as freedomn-m has mentioned, simply remove:
myButton.click(...
Leave myButton as a dummy. The change event is sufficient in that circumstance.
SNIPPET
var xInput = $('input');
var xButton = $('button'); //«———Add
xInput.on('change', alarm);
xInput.on('click', alarm);
xButton.on('click', alarm);
function alarm() {
return alert('Activated')
}
/* For demo it's not required */
[type='text'] {
width: 5ex;
}
b {
font-size: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id='f1' name='f1'>
<input type='text'>
<input type='button' value='BUTTON TYPE'>
<label><b>⇦</b>Remove this button</label>
<button>BUTTON TAG</button>
<label><b>⇦</b>Replace it with this button</label>
</form>
Is it possible to add a javascript event to a DOM element that already has a onclick event, but I want to keep that event property.
I have radio buttons like this:
<input type="radio" name="checkout-payment" value="56" id="checkout-payment-56" class="checkout-radio checkout-payment-radio checkout-payment-radio" onclick="paymentChanged(this);" />
in which I want to add
window.location.href=window.location.href
while keeping the original onclick, but I have no access to the html, I can only modify through javascript.
so my desired code will be
<input type="radio" name="checkout-payment" value="56" id="checkout-payment-56" class="checkout-radio checkout-payment-radio checkout-payment-radio" onclick="paymentChanged(this); window.location.href=window.location.href" />
Wrap the
window.location.href=window.location.href
in function, lets call it
onRadioButtonClick()
then, just do
var self = this; //keep the context of the file
$("[name=checkout-payment]").on('click', function () {
onRadioButtonClick.call(self); //call the method with the normal context.
//continue code..
});
You could try:
var curHandler = $('#checkout-payment-56').attr("onclick");
$('#checkout-payment-56')[0].onclick = null;
$('#checkout-payment-56').click(function () {
window.location.href=window.location.href;
});
I actually found out there was a much simpler way to acheive my desired result.
$( '.webshop-checkout input[type="radio"]' ).click(function() {
location.reload(true);
});
i am sorry i was not clear in my original post, and it has been edited.
If you want to add this to every .webshop-checkout input[type="radio"], you could do it that way:
$('.webshop-checkout input[type="radio"]').click(function(){
window.location.href=window.location.href;
});
JS Fiddle Demo
$("#checkout-payment-56" ).bind( "click", function(evt) {
console.log('that works');
//sessionStorage.setItem(evt.target.id,evt.target.className);
});
This question has been asked/answered (mostly) before, BUT I've tried three things to stop the event from bubbling but nothing has worked:
return false;
e.stopPropagation();
e.preventDefault();
(return false should take care of the other two, correct?)
Here's the html:
<div class="tags-holder">
<input type="text" class="addField" id="addField_<%= visit.id %>" placeholder="add a new tag">
</div>
And the JS (UPDATE CLEANED UP):
$('.addField').show().keyup(function(event){
event.preventDefault();
if(event.keyCode == 13 || event.keyCode==9) {
ProfilePage.createTag( this, 'nada', 'addField')
$(this).hide().val('');
return false;
}
});
I left the redundant stoppers in there but really shouldn't return false simply kill the bubbling? (using Chrome).
Clue? keyCode=13 is "Enter"
Wow. Your help was great and helped me think it through.
BUT the solution feels a bit like a cop-out; effective, but the condition should never be there in the first place.
Here it is, which I found in the comments from here:
http://yuji.wordpress.com/2010/02/22/jquery-click-event-fires-twice/
$('.plus').unbind('click').bind('click',function(e){
console.log('clicked')
var id=$(this).attr('plus_id');
var field=$('<input type="text">').attr({'placeholder':'add a new tag','id': 'addField_' + id, 'visit_id':id});
field.focus();
field.show().keydown(function(event){
event.stopImmediatePropagation();
if(event.keyCode == 13 || event.keyCode==9) {
console.log(event)
ProfilePage.createTag( field, 'nada', 'addField')
field.hide().val('');
return false;
}
}).click(function(e){
return false;
})
;
$(this).append(field);
return false;
});
I had same issue and I used above method and it work for me.
$(document).unbind('keypress').bind('keypress', function (e) {
// some logic here
});
Try unbinding the event first then bind it, refer below code:
$('.addField').show().unbind('keyup').keyup(function(event){
event.preventDefault();
if(event.keyCode == 13 || event.keyCode==9) {
ProfilePage.createTag( this, 'nada', 'addField')
$(this).hide().val('');
return false;
}
An explanation is here, i had written a post about this on my new blog.
Hope this will solve your problem.
Instead of using event.preventDefault() use these two shown below.
In case of Microsoft browsers use
event.cancelBubble = true;
In case of W3C model browsers use
event.stopPropagation();
And Instead of Keyup event kindly use the keypress event, because during keypress itself the input will be sent to input field so whatever inputs you don't want to appear will appear on the field. So the enter button event will be triggered.
Instead of return false use event.returnValue = false.
Try changing all the instances of
$(field).functionCall()
to
field.functionCall()
since field is already a jQuery object.
Ok now we've established that this wasn't the error. I tested in Firefox 7 and Chrome 15 and saw that the code block in the if statement is only fired once when enter is pressed. Try checking to make sure that something inside the createTag() function isn't doing something twice.
What do you think is catching the event when it bubbles. I only get one firing with this test page.
<!DOCTYPE html>
<html>
<head>
<title>Scratch</title>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.setOnLoadCallback(function (){
$('input[type="text"]').keyup(function (){
console.debug('keyup');
});
});
google.load('jquery', '1.6.4');
</script>
</head>
<body>
<div class="something">
<input type="text" />
</div>
</body>
</html>
Maybe it's your selector. Is it nested inside another .addTag? When I change the jQuery selector and also make the div and input the same class I start to get two events firing. Like this:
$('.thing').show().keyup(...);
...and...
<div class="thing">
<input class="thing" type="text" />
</div>
This is a problem which always drives me insane but i think this is the solution
simply return false, if you return true it repeats it self randomly so im guessing it must have a listener which listens out for true responses.
Short Answer
Add return false;
$("#register-form #first_name").keyup(function(event) {
console.log('hello world');
return false;
});
in the original question if you look at the code closely is seems the return false was written one line too early.
I had this issue using Angular 11 EventEmitters. I solved it by creating a new instance of my event emitter whenever the
event is triggered.
#Output() keypress = new EventEmitter();
onKeyPress(event) {
this.keypress = new EventEmitter();
this.keypress.emit(event);
}
I passed through the same and this structure worked for me:
const onKeyPress = (e: React.KeyboardEvent): void => {
if (onSubmit && e.key.toLowerCase() === 'enter') {
onSubmit();
e.stopPropagation();
e.preventDefault();
}
};
I want to call a function when a certain field gets blurred, but only if a certain element is clicked. I tried
$('form').click(function() {
$('.field').blur(function() {
//stuff
});
});
and
$('.field').blur(function() {
$('form').click(function() {
//stuff
});
});
But neither works, I reckon it's because the events happen simultaneously?
HTML
<form>
<input class="field" type="textarea" />
<input class="field" type="textarea" />
</form>
<div class="click-me-class" id="click-me">Click Me</div>
<div class="click-me-class">Click Me Class</div>
jQuery
$('.field').blur(function() {
$('#click-me').click(function(e) {
foo = $(this).data('events').click;
if(foo.length <= 1) {
// Place code here
console.log("Hello");
}
$(this).unbind(e);
});
});
You can test it out here: http://jsfiddle.net/WfPEW/7/
In most browsers, you can use document.activeElement to achieve this:
$('.field').blur(function(){
if ($(document.activeElement).closest('form').length) {
// an element in your form now has focus
}
});
I have edited my answer because we have to take into account that the event is asigned every time.
It is not 100% satisfactory, and I don't recommend this kind of complicated way of doing things, but it is the more approximate.
You have to use a global variable to take into account the fact that the field was blurred. In the window event, it is automatically reset to 0, but if the click on "click-me" is produced, it is verified before the window event, becase window event is bubbled later, it happens inmediately after the "click-me" click event
Working code
$(window).click(function(e)
{
$("#result").html($("#result").html()+" isBlurred=0<br/>");
isBlurred=0;
});
var isBlurred=0;
$('.field').blur(function() {
$("#result").html($("#result").html()+" isBlurred=1<br/>");
isBlurred=1;
});
$('#click-me').click(function(e) {
if(isBlurred==1)
{
$("#result").html($("#result").html()+" clicked<br/>");
}
});
".field" would be the input and "#click-me" would be the element clicked only just once.
I have an anchor tag on my page, I want an event attached to it, which will fire when the display of this element change.
How can I write this event, and catch whenever the display of this element changes?
This is my way of doing on onShow, as a jQuery plugin. It may or may not perform exactly what you are doing, however.
(function($){
$.fn.extend({
onShow: function(callback, unbind){
return this.each(function(){
var _this = this;
var bindopt = (unbind==undefined)?true:unbind;
if($.isFunction(callback)){
if($(_this).is(':hidden')){
var checkVis = function(){
if($(_this).is(':visible')){
callback.call(_this);
if(bindopt){
$('body').unbind('click keyup keydown', checkVis);
}
}
}
$('body').bind('click keyup keydown', checkVis);
}
else{
callback.call(_this);
}
}
});
}
});
})(jQuery);
You can call this inside the $(document).ready() function and use a callback to fire when the element is shown, as so.
$(document).ready(function(){
$('#myelement').onShow(function(){
alert('this element is now shown');
});
});
It works by binding a click, keyup, and keydown event to the body to check if the element is shown, because these events are most likely to cause an element to be shown and are very frequently performed by the user. This may not be extremely elegant but gets the job done. Also, once the element is shown, these events are unbinded from the body as to not keep firing and slowing down performance.
You can't get an onshow event directly in JavaScript. Do remember that the following methods are non-standard.
IN IE you can use
onpropertychange event
Fires after the property of an element
changes
and for Mozilla
you can use
watch
Watches for a property to be assigned
a value and runs a function when that
occurs.
You could also override jQuery's default show method:
var orgShow = $.fn.show;
$.fn.show = function()
{
$(this).trigger( 'myOnShowEvent' );
orgShow.apply( this, arguments );
return this;
}
Now just bind your code to the event:
$('#foo').bind( "myOnShowEvent", function()
{
console.log( "SHOWN!" )
});
The code from this link worked for me: http://viralpatel.net/blogs/jquery-trigger-custom-event-show-hide-element/
(function ($) {
$.each(['show', 'hide'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
this.trigger(ev);
return el.apply(this, arguments);
};
});
})(jQuery);
$('#foo').on('show', function() {
console.log('#foo is now visible');
});
$('#foo').on('hide', function() {
console.log('#foo is hidden');
});
However the callback function gets called first and then the element is shown/hidden. So if you have some operation related to the same selector and it needs to be done after being shown or hidden, the temporary fix is to add a timeout for few milliseconds.