Is there a way to access the variable inside the onclick event? - javascript

I have this simple onclick eventfunction and i would like to know if it's possible to acces the variable that is inside it and use it outside this function, if not is there a way to do something similar?
document.querySelector('.check-parent').addEventListener('click', function() {
var a = 'abc';
return a;
});
console.log(a);
P.S.
In my homepage code i have 3 forms, each form has one id and it needs to display errors in case the fields are not completed properly. And when i click submit i get the parent id and that id goes in a switch function and determins with form it was and what errors needs to display

You'll have to get a few things correct:
The this variable changes inside the callback since the scope changes.
Hence bind outer this to your clickhandler(bind(this) in below snippet)
console.log(a) would not print undefined since it's again in different scope.
You'll have to trigger this call only after a click event is performed. Hence wrap it in a function & call this from the handler by passing the value.(this.fromClick(innerVariable) in below snippet)
Below's a sample snippet(ES5 demo & ES6 demo):
this.count =0;
document.getElementById('myButton').addEventListener('click', function() {
//Access outer variables
this.count++;
document.getElementById('buttonCount').innerHTML = this.count;
//Send something outside
var innerVariable = 'String from click handler!!';
this.fromClick(innerVariable);
}.bind(this));
this.fromClick = function (innerVariable) {
alert(innerVariable);
}

Related

Passing this and variables to imported function onclick

I am utterly confused by this peice of code, that does not seem to work in any way.
Simply, it's this:
// in app.js
import {layoutItemButtonClick} from '/blablaWrappeur.js'
document.addEventListener('DOMContentLoaded', function () {
var element = document.querySelector('.qq-element') //this is a html element obj
$('.layout-item-button').click(layoutItemButtonClick)
})
//in blablaWrappeur.js
export const layoutItemButtonClick = function () {
const selectedLayout = this.dataset.layout.split("")
doQqthing(element) // element is not defined
}
function doQqthing(element) {
alert(element) /// not defined
}
I need to pass the element and the this context of the clicked button to the layoutItemButtonClick function and then inside that, to the doQqthing function.
However, it does not work like this.
1) If I let the code like this and click the button nothing happens.
2) Now, if I change the click function to this (adding paranthese to the function call:
$('.layout-item-button').click(function () {
layoutItemButtonClick()
})
I get a dataset is not defined error.
3) If I change it to this:
$('.layout-item-button').click(layoutItemButtonClick())
I get the same error.
4) For this:
$('.layout-item-button').click(layoutItemButtonClick)
I get an element is not defined error.
I know that if I call the function inside a function, this would be the current element, and if inside the click parentheses like in 3) and 4), it would be the local scope this. So, how do I pass both the element and the this from the click into my function.
And why/how does using parenthesis make a difference when calling a function defined as a constant?
Thanks in advance.
And why/how does using parenthesis make a difference when calling a function defined as a constant?
layoutItemButtonClick is like any other variable access. It resolves to the value of the variable, which is a function object.
layoutItemButtonClick() otoh calls the function and resolves to its return value.
Therefore,
$('.layout-item-button').click(layoutItemButtonClick())
passes the return value of layoutItemButtonClick (which is undefined) to .click whereas
$('.layout-item-button').click(layoutItemButtonClick())
passes the function object itself to .click.
I get an element is not defined error.
And rightly so because element is not defined in the scope accessible to layoutItemButtonClick. It is only defined inside DOMContentLoaded event handler.
You'd have to pass element as argument to layoutItemButtonClick. So the function should be declared as
export const layoutItemButtonClick = function(element) { ... }
Now we need to call layoutItemButtonClick such that this refers to the clicked element and we pass element as argument. We can do this using .call:
$('.layout-item-button').click(function() {
layoutItemButtonClick.call(this, element);
});
However, there is no need for using this inside layoutItemButtonClick. We can just make the element that triggered the event an explicit argument:
export const layoutItemButtonClick = function(trigger, element) {
const selectedLayout = trigger.dataset.layout.split("")
doQqthing(element);
};
and call it as
$('.layout-item-button').click(function() {
layoutItemButtonClick(this, element);
});

getting the element's id from on click with (this)

To initiate the onclick event, I have this
[].forEach.call(btnAddVendorDropDown, (btnAddVendorDropDown) => {
btnAddVendorDropDown.addEventListener('click', onAddVendorDropDownClick, false);
});
The function is
function onAddVendorDropDownClick(e) {
e.preventDefault();
addNewClass(modal, 'is-active');
addNewClass(modalAddVendorDropDown, 'is-active');
const test = $(this).attr('id');
console.log(test);
return test;
}
So what I'm trying to do is when a user clicks btnAddVendorDropDown, the function onAddVendorDropDownClick is called. I need to grab the id from the element. When I do console.log of the element attribute id from inside the function, I get exactly what I need. The problem I'm running into is when I try to grab it from outside the function, I keep getting undefined. I don't understand how I can grab the id once it calls this function from outside this function.
I tried this
var num = onAddVendorDropDownClick();
console.log("the function return is " + num);
Which is what shows undefined.
this is related directly to the caller's scope. This means that without "binding" a scope to your event handler, this is going to refer to your main application scope, and not the scope that jquery passes as you chain functions.
You can either wrap the event object's target:
function onClickHandler(e) {
$(e.target).attr('id');
}
Or you can use $(this) within the jquery context of a click handler:
$('#my-button').on('click', function(e) {
$(this).attr('id');
});
The last example works because it is occurring inside a JQuery closure, so it retains the scope from the previous function. Outside of a closure, this means something else.
$(this) is JQuery context, and you are inside javascript function. You can change the click button to JQuery to use it:
var test;
$("button").click(function(){
test = $(this).attr('id');
console.log(test);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id="btnTeste">
Teste
</button>

Event function triggering when passing div ID

I'm trying to write some Javascript that when a div is clicked, a function is called with the parameter of that divs ID, the function works when I just send the hardcoded div id like so:
$('#areaOne').on('show.bs.collapse', onSectionClick('#areaOne'));
function onSectionClick(){
var x = $('#areaOne).hasClass('toggled') ? 'false' : 'true';
console.log(x)
}
However when I try it like this:
$('#areaOne').on('show.bs.collapse', onSectionClick('#areaOne'));
function onSectionClick(secID){
var x = $(secID).hasClass('toggled') ? 'false' : 'true';
console.log(x)
}
Then the function is called as soon as the page is loaded, rather then when the area is clicked. I want it to work this way as there are many areas that should trigger the same function.
I'm pretty new to Javascript so any help, or advice on how to do this in a better way would be greatly appreciated.
The problem is that you call the function instead of giving a function reference. Try:
$('#areaOne').on('show.bs.collapse', function(){onSectionClick('#areaOne')});
THe line
$('#areaOne').on('show.bs.collapse', onSectionClick('#areaOne'));
calls onSectionClick, passing in '#areaOne', and passes its return avlue into on, exactly the way foo(bar()) calls bar and passes its return value into foo.
If you want to set it up to be called by the event, you pass a function reference rather than calling the function, e.g.:
$('#areaOne').on('show.bs.collapse', function() { onSectionClick('#areaOne'); });
In your case, though, you probably don't even want to do that. Instead:
$('#areaOne').on('show.bs.collapse', onSectionClick);
// Note no () -------------------------------------^
...and in onSectionClick, use this.id to get the ID of the clicked element ('areaOne' — add the # if you need it).
And if you have other "areas" that you also want to hook up, you can hook them up all at once:
$('selector-for-all-the-areas').on('show.bs.collapse', onSectionClick);
...and then you know which one relates to the event by which element this refers to in onSectionClick.

transfer of information from one function to another through a global variable in angular controler

I have a little trouble with passing value from one function to another in one angular controller.
i have event
onTimeRangeSelected: function (args) {
$scope.dayPilotCal.clearSelection();
$scope.createNewEventModalWindow(args);
},
event call function
$scope.createNewEventModalWindow = function(args)
{
console.log('create new event dialog');
$rootScope.newEvent.start = args.start.value;
console.log($rootScope.newEvent.start);
ngDialog.open({
......
});
}
than i handle dialog confirm button click event
<button
type="button"
class="ngdialog-button ngdialog-button-primary"
ng-click="btnCreateEventClicked()"
>Create</button>
and call function
$scope.btnCreateEventClicked = function(){
console.log('btn create event clicked');
ngDialog.close();
console.log($rootScope.newEvent.start);
};
so that my problem - in first case console.log($rootScope.newEvent.start); print to console real date. But in the second function console.log($rootScope.newEvent.start); print into console 'undefined' value.
all code are in the same controller. And in the first lines of controller i define my global variable $rootScope.newEvent={};
Please help me in that problem.
Global variables makes testing the code really difficult. Because any function can have access to the global scope. In your example I would assume their is another part of your coding that changes $rootScope.newEvent.
If this variable has to be globally available I would suggest to use a service.
If their is no need for this var to be globally accessible, than just change $rootScope.newEvent to $scope.newEvent.

The correct way to bind this?

I'm trying to access 'this' inside a method that is called from a button press, where this refers to both the class and the button pressed:
p.myVar = 'banana';
$('.go').on('click', this._init);
p._init = function(e){
//get the button pressed
//get this.myVar
};
To do this I bind this:
$('.go').on('click', this._init.bind(this));
The above works and I can now access my var via:
this.myVar; //banana
But I can no longer access the button.
How can I access it, use e.currentTarget or is there a better way?
You should use the data argument :
$('.go').on('click', {myVar:'banana'}, this._init);
p._init = function(e){
// use e.data.myVar;
// this is the right matching clicked element
};
I presume your declaring the event listener in a closure, if so you can use a local variable and pass it that, the reference is unique to the closure and can be accessed by the function in the listener when it is called. It becomes a kind of invisible global, the reference only exists to that specific call and the listener function but is still shared.
function initButtons(){
var selfRef = this;
$('.go').on('click',selfRef._init);
}

Categories

Resources