modifying javascript variable within function - javascript

I've read up on declaring variables globally and then being able to modify them in functions, but things aren't working out for me.
Here is my code:
var selectee = "JK";
// get state selected
$('select.form-control.bfh-states').change(function () {
selectee = $('select option:selected').val();
// works correctly, but i need to access it outside the function
console.log(selectee);
});
// output JK, should change based on a select box on the form
console.log(selectee);

It is because the the change() handler will get executed only when the change event is fired from the select element. You are using the console.log() statement in a sequential executio which will get executed before the change handler is fired
//this is correct
var selectee = "JK";
//this registers a change handler for the select element
$('select.form-control.bfh-states').change(function () {
//but this will not execute now!!! it will get executed only when the select elements change event is fired
selectee = $(this).val();
console.log(selectee); // works correctly, but i need to access it outside the function
});
//this will get executed as soon as the change handler is registered not after the handler is executed
console.log(selectee);
If you want selectee to have the value selected in the select element then you can either do something like
var selectee = $('select.form-control.bfh-states').val() || "JK";
or manually fire the select change handler once the handler is attached on dom ready like
var selectee = "JK";
$('select.form-control.bfh-states').change(function () {
selectee = $(this).val();
console.log(selectee); // works correctly, but i need to access it outside the function
}).change();

The way to fix this problem is to execute the code that needs the value of selectee from within the change handler. You shouldn't be storing it in a global variable in the first place.
// get state selected
$('select.form-control.bfh-states').change(function () {
var selectee = $('select option:selected').val();
console.log(selectee); // works correctly, but i need to access it outside the function
// call your other code from here and pass it the current value of selectee
myOtherFunction(selectee);
});
To explain, the .change() callback function is ONLY executed when the value of the select actually changes. It will be called sometime LATER. So, to use the value of selectee sometime later, you need to execute the code that needs that value at the same time that the new value has been changed.

You code doesn't work procedural as you think. selectee will reflect the new value only after the change event of your select control is fired. The codes inside event handlers don't execute until they are called/triggered/fired. But those outside, like your console.log(selectee) will execute the first time the code is loaded (which in your case, the change event hasn't been called).

It is because change handler is a callbackļ¼Œ it will fired after the events happen, not executed the code order

An alternative method would be is to pass the selected value into a new function and hence access it within that function(not globally). Try this:
selectee = "JK";
// get state selected
$('select.form-control.bfh-states').change(function () {
selectee = $('select option:selected').val();
// works correctly, but i need to access it outside the function
mynewfunc(selectee);
});
function mynewfunc(){
alert(selectee);
}
Note: The variable selectee is not accessible outside new function mynewfunc once the change is triggered.
Demo

Related

variable, passed together with event, does not change

When I call editWorkout function for the first time, the variable 'workout' gets passed in the editWorkout2 function, but then, during the second time, when the same thing happens, but in this case 'workout' has new value, this value for some reason won't change in editWorkout2 function. How can I fix that?
function editWorkout(e, workout) {
e.stopImmediatePropagation();
saveBtn.addEventListener("click", function (e) {
console.log(workout);
editWorkout2(e, workout);
}.bind(this)
);
}
on each call of your editWorkout function, you're adding a new event listener to your "saveBtn" element with the same event type.
I recommend you read the usage notes of addEventListener.
So, the problem was as follows: because during the second call and all of the consecutive calls of the function editWorkout the event listener was going on top of the previous one, for some reason variable workout was not changing in that eventListener as a parameter. So I removed event listener in the editWorkout2 function, and everything started working fine

Passing additional parameter through Event Listener

this code:
var messageLine = "this is a line of text";
myTextField.addEventListener('change', textHasBeenChanged, false);
calls this function:
function textHasBeenChanged(e) { var target = e.target; messageLine = target.value;}
Now I want to pass an additional piece of data... like a simple number 1. Like this:
myTextField.addEventListener('change', function(){textHasBeenChanged(theValueOfTheTextField, theNumber1);});
How can this be done? I'm still a programming newbie, so please keep your answer as close as possible to the syntax you see above.
You can call/invoke the function inside of an anonymous function by passing the additional parameter. Also you can consider using input event instead of change which is fired synchronously when the value of an <input>, <select>, or <textarea> element is altered:
var messageLine = "this is a line of text";
var myTextField = document.getElementById('myTextField');
myTextField.addEventListener('input', function(){textHasBeenChanged(event, 1)}, false);
function textHasBeenChanged(e, other) {
var target = e.target;
messageLine = target.value;
console.clear(); //clear the previous data in console
console.log(messageLine);
console.log(other);
}
<input id="myTextField"/>
If you're not going to take the even listener off afterward than you should be able to just pass the argument right to the function you're giving to the event listener
myTextField.addEventListener('change', textHasBeenChanged(1), false);
you dont have to pass e for the event because when provide a named function to an event listener e is already assumed to be the first argument

My EventListener to a button continues to fire despite ownership being changed, why? (JavaScript)

I have a function, which at the end of its task assigns a button to a new id.
function altChecker() {
var doc = document,
out = [],
appButton = doc.getElementById('appButton'),
//re = /click-me/gi,
output = doc.createElement('p');
output.setAttribute('id', 'output');
EventUtility.addHandler(appButton, 'click', function(e) {
//I have not included all the function details to concentrate on the question
appButton.id = 'appButtonNextChecker';
var appButtonNextChecker = doc.getElementById('appButtonNextChecker');
nextChecker(appButtonNextChecker);
});
}
function nextChecker(newBtnName) {
EventUtility.addHandler(newBtnName, 'click', function(e) {
$('#output').innerHTML = "";
console.log('next Checker, button!')
});
}
So basically there is one button in the DOM assigned to appButton ID initially, and then I change it doing:
appButton.id = 'appButtonNextChecker';
when the altChecker function fires...
Then I assign the button to a new variable, and pass in the variable to the next function...
var appButtonNextChecker = doc.getElementById('appButtonNextChecker');
nextChecker(appButtonNextChecker);
While I can see the buttons' ID change in the DOM, and I see the console.log fire in the nextChecker function,
$('#output').innerHTML = ""; //doesn't fire
AND the altChecker function fires as well (again)?! Haven't I severed the connection to the click function when I reassigned the new ID?
Any help would be appreciated!
Javascript doesn't remember that you initially attached the event through it's id. The event is attached to the element itself, not the ID. It's not like CSS that way.
In fact your variables are still holding the same element as well, so there's no need to create a new variable after changing the ID, either. Since you're using jQuery you can just type $(appButton).unbind(); to remove the event handler. You may also want to look into .on() and .off()
The problem is that you're trying to use the innerHTML property in a jQuery's object.
That property belongs to Element, and it will not work in the way you're using it.
You can use the document.getElementById method, and it will work fine:
document.getElementById('output').innerHTML = '';
Or you can use jQuery's html method:
$('#output').html('');
And you can even use the first element of the jQuery's array, and use innerHTML again:
$('#output')[0].innerHTML = '';
It's up to you, but the first option will be faster, for sure.

Get value from DOM at run time

I am trying to get a value from a textbox and I'm only returning [object Object].
var key = $('body').on('click', '#ReportReferenceElectrical',function() {
$('#ReportReferenceElectrical').val();
});
var REPORTS_KEY = key;
I have tried the usual:
var key = $('#ReportReferenceElectrical').val();
The JS is in an iife and the value needs to retrieved when I submit the form to save but using this way its empty as the value was empty when the form loaded, I though the top code snippet might return me the value, but not.
The callback will get executed only when it is triggered. In this case, manually $.fn.triggering isn't an option, I suppose as it will be ""(Empty)
What you need is a callback.
function callback(key) {
alert(key);
// do something with the key now
}
And then call it in the event handler. I'd suggest going for the blur event rather than click
$('body').on('blur', '#ReportReferenceElectrical',function() {
callback($('#ReportReferenceElectrical').val());
});

$.getJSON trigger select change event

I'm trying to add categories to a drop down list using jQuery Ajax. When an option is selected I would like to load the subcategories.
The problem that I'm facing is that the addition of options to the drop down list by the Ajax function seems to trigger the change event as well. How can I avoid this or rewrite my code better in order to avoid this behavior?
Here's my code:
categoryHelper.loadLevel1 = function () {
// The control that needs to be filled with categories
var $control = $("#select1");
// This function runs $.getJSON() and fills the drop down list
// with option elements
fillDropDown(url, null, $control);
// When I select a value I want to run the function loadLevel2 which
// takes the currently selected value from level 1 as parameter
$control.change(categoryHelper.loadLevel2($control.val()));
};
Code for the fillDropDown:
function fillDropDown(url, parameters, dropdown) {
/// all data has been loaded</param>
$.getJSON(url, parameters, function (data) {
$(dropdown).empty();
$(dropdown).append(createOption("", ""));
$(data).each(function () {
$(dropdown).append(createOption(this.value, this.text));
});
});
}
All help is appreciated!
This line:
$control.change(categoryHelper.loadLevel2($control.val()));
will pass the result of calling categoryHelper.loadLevel2($control.val()) to .change(); if that isn't a function, then you're not going to be adding an event handler to the element but instead triggering any event handlers that are already bound. Change it to:
$control.change(function() {categoryHelper.loadLevel2($control.val())});
so that you're actually passing a function to .change(), and it should work.

Categories

Resources