jquery .bind prevent running on page load - javascript

I have a jquery function that binds a select field on a form to multiple actions. It binds to both change and keyup, so that mouse and keyboard clicks are both captured.
$(document).ready(function(){
$('#user_id').bind('change keyup',function () {
calculateAmounts();
}).change();
});
This works perfectly.
However, in addition to running on the change and keyup functions, the calculateAmounts() function is also called when first loading the page. I'd like to prevent this code from running when the page is first loaded.

You're triggering a change event when you call .change() on the $('#user_id') element, which will call your change/keyup event handler. If you remove the .change() call, then that event won't be triggered when the page loads:
$(document).ready(function(){
$('#user_id').bind('change keyup',function () {
calculateAmounts();
});
});

try this (taking in consederation that #user_id is input field)
$(document).ready(function(){
var yourVAL = $("#user_id").val();
$('#user_id').bind('change keyup',function () {
if($("#user_id").val() != yourVAL){
calculateAmounts();
}
}).change();
});

Related

jQuery load function not working on binding

I bind "load" and "change" in jQuery code.
My goal is: disable some field based on logic when page load.
jQuery( document ).ready(function() {
//Question 34.1
jQuery('select#fever').bind('load change', function () {
var drug_reaction = jQuery(this).val();
if(drug_reaction== 1){
jQuery('input#fever_days').attr('disabled',false);
jQuery('select#character_of_fever').attr('disabled',false);
jQuery('select#evening_raise_of_temparature').attr('disabled',false);
jQuery('select#night_sweats').attr('disabled',false);
}else{
jQuery('input#fever_days').val("");
jQuery('input#fever_days').attr('disabled',true);
jQuery('select#character_of_fever').val("");
jQuery('select#character_of_fever').attr('disabled',true);
jQuery('select#evening_raise_of_temparature').val("");
jQuery('select#evening_raise_of_temparature').attr('disabled',true);
jQuery('select#night_sweats').val("");
jQuery('select#night_sweats').attr('disabled',true);
}
});
});
When I change fever dropdown , its working. But when page load, I fetch data from Database and this code not working:
var drug_reaction = jQuery(this).val();
if(drug_reaction== 1){
jQuery('input#fever_days').attr('disabled',false);
jQuery('select#character_of_fever').attr('disabled',false);
jQuery('select#evening_raise_of_temparature').attr('disabled',false);
jQuery('select#night_sweats').attr('disabled',false);
}else{
jQuery('input#fever_days').val("");
jQuery('input#fever_days').attr('disabled',true);
jQuery('select#character_of_fever').val("");
jQuery('select#character_of_fever').attr('disabled',true);
jQuery('select#evening_raise_of_temparature').val("");
jQuery('select#evening_raise_of_temparature').attr('disabled',true);
jQuery('select#night_sweats').val("");
jQuery('select#night_sweats').attr('disabled',true);
}
load events fire on elements which load data from a URL (e.g. the whole page, img elements and iframe elements).
A select element doesn't load external data, and nor do any of its descendants. There is no load event.
Even if there was, it would have already loaded by the time the ready event fires.
Trigger the change event as part of your ready event handler instead.
jQuery('select#fever')
.bind('change', function () { ... })
.trigger("change");

How to wrap multiple dynamic eventListeners into one?

I just started to learn js and need a little help: I have the following function:
//SET CHAT BEHAVIOR
function chatSettings() {
console.log('ChatSettings called')
function BtnAndScrollBar(texteditor) {
console.log('BTNAndScrollBar called');
const sendBtn = $('.cl.active').find('.sendBtn');
const attachBtn = $('.cl.active').find('.attachBtn');
console.log(sendBtn)
}
function sendAndDeleteMessage(send) {
console.log(send);
}
var sendBtn = $('.cl.active').find('.sendBtn');
sendBtn.mousedown(function () {
sendAndDeleteMessage(this);
});
var textEditor1 = $('.cl.active').find('.chatTextarea');
textEditor1.on('focus change mousedown mouseout keyup mouseup', function (){
console.log(this);
BtnAndScrollBar(this)
});
}
$('document').ready(function () {
console.log('hello');
$('.tabs').tabs();
chatSettings();
});
I prepared a js.fiddle - As you can see from console.log when clicking into the textarea, the eventListener always listens to #cl1, even if .cl.active switches along with the according TAB.
The events in the textarea are just relevant, if .cl is active. My target is to wrap all three eventListener into one and apply the event to the textarea in the active stream, but all I tried went wrong... Can anyone help? #Dontrepeatyourself #DRY
$(".chatTextarea").on(
'focus change mousedown mouseout keyup mouseup',
function (this) {
//this.id can contain the unique id
greatFunction(this);
});
This will bind event individually with unique id found with this keyword and also wraps all event listener into one function but this is better when you want to process each event with same functionality
please let me know if this helps.
Peace
$(".cl textarea").on('focus change mousedown mouseout keyup mouseup', function () {
greatFunction(this)
});
Tada!
P.S. Is there a reason greatFunction is defined inside window.onload?
Try using $(document).ready function to load code when the page loads.
Also use $('textarea #cl1').on to get the textarea with the #cl1 or whichever id you want to use and then call the function after using the .on.
Hope this helps!
Let me know if it works!
$(document).ready(function () {
function greatFunction(elem) {
//do stuff
}
$('textarea').on('focus change mousedown mouseout keyup mouseup', function () {
greatFunction(this)
});
}
First off, I changed the onload to bind with jQuery, so all your logic is doing jQuery bindings, rather than swapping back and forth between jQuery and vanilla javascript. Also, doing an actual binding removes an inline binding.
Next, the binding has been condensed into a single delegate event listener. Since you eluded in your comments that it wasn't working for the active element after the active was moved or added, this reflected that you were dealing with dynamic elements. Delegate event listeners are one way to handle such things.
Delegate event listeners bind on a parent element of the elements that will change, or be created. It then waits for an event to happen on one of it's children. When it gets an event it is listening for, it then checks to see if the element that it originated from matches the child selector (second argument) for the listener. If it does match, it will then process the event for the child element.
Lastly, I added some buttons to swap around the active class, so you could see in the snippet that the event handler will start working for any element that you make active, regardless of it starting out that way.
$(window).on('load', function () {
function greatFunction (elem) {
console.log(elem.value);
}
$(document.body).on(
'focus change mousedown mouseout keyup mouseup',
'.cl.active .chatTextarea',
function () {
greatFunction(this);
}
);
$('.makeActive').on('click', function () {
$('.active').removeClass('active');
$(this).closest('div').addClass('active');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cl1" class="cl active"><textarea class="chatTextarea">aa</textarea><button class="makeActive">Make Active</button></div>
<div id="cl2" class="cl"><textarea class="chatTextarea">bb</textarea><button class="makeActive">Make Active</button></div>
<div id="cl3" class="cl"><textarea class="chatTextarea">cc</textarea><button class="makeActive">Make Active</button></div>

Why I cannot change button event with JQuery .click() function?

Say I have a button whose id is "btn" and I add an event to the button as:
$(document).ready(function() {
$("#btn").click(function(){
$("#label1").html((new Date()).getSeconds());
$("#btn").click(function () {});
};
})
where #label1 is a label tap supposed to show the current second.
I wish by click the button at the first time, current second will shown in the label1. And for following click on this button, nothing happen. But what I got is every time the button is clicked, new current second is shown in label1. What's wrong?
Use one() to bind event
$("#btn").one('click', function(){
$("#label1").html((new Date()).getSeconds());
});
Note that $("#btn").click(function () {}); does not unbind the event. It binds click event on that element one more time, so next time when the button is clicked two event handlers will be called one to update the html and other empty function that does nothing.
To unbind the event, off() can be used, but in this case one() is preferred.
$("#btn").on('click', function () {
$("#label1").html((new Date()).getSeconds());
$(this).off('click');
});
You can simply use .one().
Attach a handler to an event for the elements. The handler is executed at most once per element per event type.
$(document).ready(function() {
$("#btn").one('click', function(){
$("#label1").html((new Date()).getSeconds());
});
})
At-present you are binding another click handler using $("#btn").click(function () {});
Hello you can remove the click Listener the following way.
$(document).ready(function() {
$("#btn").click(function(){
$("#label1").html((new Date()).getSeconds());
$('#btn').off('click');
});
})

Ajax Load Event Incrementing By One

I have a simple textarea where users can input text which is then passed through via AJAX to a URL once they hit the return key. My issue is that on the first press of the return key the text data is sent once, on the second it's sent twice, and so on incrementing my one each time.
After some reading up I realise that if I was using a form submit I'd have to unbind it to prevent this happening. I've tried adding a value flag to prevent the multiple events, but have only got so far as to get it to trigger once only.
My code is as follows. Any guidance on how to prevent the incrementing events would be appreciated - as you can probably tell my confidence/knowledge in Javascript isn't the best. Thank you!
$(function() {
$("#myTextarea").keypress(function(e) {
// If the user hits the return key
if(e.which == 13) {
e.preventDefault();
$.ajax({
success: function(){
var modal = $('#myModal'), modalBody = $('#myModal .modal-body');
modal
// Load the webpage result within the modal Body
.on('show.bs.modal', function () {
modalBody.load('http://www.things.co.uk/things' + document.getElementById('myTextArea').value)
})
.modal();
// Hide the modal after five seconds
myModalTimeout = setTimeout(function() {
$('#myModal').modal('hide');
}, 5000);
}
});
}
});
});
Edit: I solved this by using one() for my modal event via http://www.andismith.com/blog/2011/11/on-and-off/. Thank you everyone.
You must attach the event handler only once. I suppose you're getting the JS in your AJAX response, and executing it again and again on each AJAX load. Removing and re-attaching the handlers is a hacky solution.
To avoid to attach the event handlers more than once, simply put your script in a part of the page which is not reloaded by AJAX, so the event is attached only once.
You can even attach an event handler to an element that is reloaded by ajax using delegated events: Understanding Event Delegation
With this technique, you attach the event handler to a container parent element which is not reloaded by ajax, and handle the events of the reloaded children specified by a filter.
$( "#container" ).on("<event>", "<children filter>", function( event ) {
// code to handle the event
});
Note that in this sample #container is the element which isn't reloaded by ajax. And <children filter> is a jquery selector that chooses the children whose event mus be handled. (<event> is obviously the event name, like click or keyPress).
Explanation: when the event is trigger in the child element, it pops up to the container. The container catches it, and checks that the children passes the filter. If so, the vent is handled.
If there are no more event handlers on myTextarea div code below should suffice.
If there are multiple event handlers attached to keypress event you will have to use named function and remove it using $.unbind() more on how to do this.
$(function() {
$("#myTextarea").off();
$("#myTextarea").keypress(function(e) {
// If the user hits the return key
if(e.which == 13) {
e.preventDefault();
$.ajax({
success: function(){
var modal = $('#myModal'), modalBody = $('#myModal .modal-body');
modal
// Load the webpage result within the modal Body
.on('show.bs.modal', function () {
modalBody.load('http://www.things.co.uk/things' + document.getElementById('myTextArea').value)
})
.modal();
// Hide the modal after five seconds
myModalTimeout = setTimeout(function() {
$('#myModal').modal('hide');
}, 5000);
}
});
}
});
});

Javascript onclick function trouble

I'm using a popover in bootstrap, and I want it to close when the user clicks anywhere else on the screen. The code I have is this:
$('#popover').bind('click', function() {
$(".popover").live('click', function(){ return false; });
$(document).one("click", function() {
alert('click');
});
});
The problem is that the click on the button is triggering the alert. For some reason javascript uses that click to start the function and trigger the click event inside of it. What am I doing wrong?
EDITED:
This code doesn't do anything:
$(".popover").live('clickoutside', function(){
alert('click');
});
Check out these:
https://developer.mozilla.org/en-US/docs/DOM/event.stopPropagation
https://developer.mozilla.org/en-US/docs/DOM/event.stopImmediatePropagation
If your .popover is inside #popover, you're triggering events from all the affected elements.
NOTE: jQuery's live is in deprecating process, use the alternatives:
http://api.jquery.com/on/
http://api.jquery.com/delegate/

Categories