How to pass `$(this)` as parameter to a "callready" function in Javascript - javascript

The leanModal function triggers a modal with some parameters. One of this parameters is a function (ready) that will be executed once the Modal is open. The point is, I need to do some stuff inside that function (ready) just with the element (tag) which triggered the modal, so I need to pass $(this) as parameter to that function. The leanModal() function is provided by MaterializeCss which's the framework that I'm using.
I've been trying this, but thisTag is always undefined. I also have tried to pass directly $(this) to the function, but it also doesn't work at all, it's still undefined. So, how can I reach this?
$('.modal-trigger-editMedic').leanModal({
thisTag: $(this),
ready: function(thisTag){
var refereeNum = thisTag.siblings("[name*='refereeNumToEdit']" )[0].value;
$('#surname').val($("input[id*='medicNameToModal"+refereeNum+"'").val());
}
});

Following the source code, .leanModal supports a ready function (which is triggered once the modal is visible) but doesn't bind or send the element which triggered the modal, the easiest way to fix this is to store a reference outside. To do so, you need to iterate over the triggers yourself instead of relying on that functionality of provided by this jQuery plugin.
Like so:
var $surname = $('#surname'); // you should store the selector as a reference
// outside the loop for better performance
$('.modal-trigger-editMedic').each(function() {
var $this = $(this); // this is the current item in the set of elements,
// therefore our trigger element
// EDIT: using var makes this a local variable
$this.leanModal({
ready: function() {
var refereeNum = $this.siblings("[name*='refereeNumToEdit']" )[0].value;
$surname.val($("input[id*='medicNameToModal"+refereeNum+"'").val());
}
});
});

When you are inside the leanModal it becomes this. Try setting a var to $(this) and pass that through.
var that = $(this);
$('.modal-trigger-editMedic').leanModal({
thisTag: that,
ready: function(thisTag){
var refereeNum = thisTag.siblings("[name*='refereeNumToEdit']" )[0].value;
$('#surname').val($("input[id*='medicNameToModal"+refereeNum+"'").val());
}
});

Related

Correctly binding click event to a function using .on()

As mentioned, I'm trying to bind clicking the 'a' tags on my page to my handleClickTag() function, but am struggling to implement the .on() method to bind the function and 'a' tag. I'm not sure if bind() would be more appropriate. Hope this makes sense!
a.data('tagId', tag.id); //save info inside html element
$(a).on('click', handleClickTag(a)); //bind click event of the "a" tag to the "handleClickTag" function - need help here
//code above contained inside forEach loop
function handleClickTag (event) {
var link = $(event.target);
var tagId = link.data('tagId');//would like to retrieve data from the tagId variable
//---continue function after data is correctly retrieved
}
To pass argument to the function you can wrap the function call inside of an anonymous function:
$(a).on('click', function(){ handleClickTag(a); });
Though I think you do not need to pass the argument here, Simply the following should work:
$(a).on('click', handleClickTag);

How to trigger element.on('mouseleave') in a Uint Test to call my AngularJS function

I want to call myFunction. Then I want to verify it was called with a Unit Test.
Javascript:
var self = this;
self.myFunction= function myFunction() {
// do stuff
};
self.onClickChange = function onClickChange() {
$('.checkBox').on('mouseleave', function(){
self.myFunction();
});
};
I have tried this test:
it('should call myFunction', inject(function ($compile, $rootScope) {
spyOn(this.instance, 'onClickChange').and.callThrough();
spyOn(this.instance, 'myFunction').and.callThrough();
this.instance.onClickChange('messageBoard');
var scope = $rootScope.$new(),
element = $compile('<md-checkbox class="checkBox"></md-checkbox>')(scope);
element.triggerHandler('mouseleave');
scope.$digest();
expect(this.instance.myFunction).toHaveBeenCalled();
}));
I have also tried using
scope.$broadcast('mouseleave');
And
var event = document.createEvent('MouseEvents');
event.initEvent('mouseleave', true, true);
$('.checkBox').dispatchEvent(event);
And this instead of the last line in the previous three lines:
document.body.dispatchEvent(event);
How can I get .on('mouseleave') to work and ferify that myFunction has been called?
Several things here. First, to answer your immediate question, you are calling: this.instance.onClickChange('messageBoard'); before you have created any DOM. So, you are going to try adding the click handler to absolutely nothing.
You need to add the click handler only after you create the DOM when you call compile.
But, there's another problem. You are compiling the directive and creating a DOM element, but it is not rooted in the document, so using the jquery $ on the document will not work.
It is bad style to use jQuery selectors in angular.
You could do something like this, where you use the $element of the current scope.
var self = this;
var $element = getElement(); // do some magic to get the current element
self.myFunction= function myFunction() {
// do stuff
};
self.onClickChange = function onClickChange() {
$element.on('mouseleave', function(){
self.myFunction();
});
};
And then your tests could work in the same way. The difference is that the $element never needs to be added to the DOM in order for the code to work.
But really, I would avoid this whole approach. You should not be using jQuery inside of angular. That is an outdated style. Instead, I recommend using ng-click to add the handler directly to the DOM.

Using "this" as parameter in an existing Javascript function called by jQuery.on() event

Problem:
I have some selects with options in my HTML code and I have set an on change event handler, to figure out, when a selection will be changed.
The following code shows the jQuery code to get the on change:
$(document).on('change', '.anyHtmlSelect', updateState);
I have an existing Javascript function, that should be used as callback function.
The Javascript function looks like:
function updateState(element)
{
var currentId = element.attr("id");
}
Question:
How can I get the changed select as element?
I have tried the following:
$(document).on('change', '.anyHtmlSelect', updateState($(this));
but it doesn't work.
The first argument that is automatically passed to an event handler is a reference to the event itself, not the element that caused the event. To access the DOM element that triggered the event, use this:
Simply change:
function updateState(element)
{
var currentId = element.attr("id");
}
to:
function updateState(event) {
var currentId = this.attr("id");
}
After some research I have found a solution I would share with you.
In my solution, I created an anonymous function, which calls the updateState function with $(this) as parameter.
$(document).on('change', '.anyHtmlSelect', function () {
updateState($(this));
});
Is there a better solution?

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.

How to get a reference to the event's source element

Inside an event listener, I need a reference to the element that was the event source. How do I get that?
This should be a no-brainer for anyone doing JavaScript for some time.
All the functions including the event handler are in global scope, and therefore, implicitly made a part of the DOM window object.
function WireHandlers() {
$('.updateResourceImageButton').click(UpdateResourceLinkClickedHandler);
}
function UpdateResourceLinkClickedHandler() {
// I would like a reference to the hyperlink/anchor
// that was actually clicked, i.e. the hyperlink that
// was the source of this event
// would the keyword 'this' evaluate to the element I need?
// or will it evaluate to the HTML DOM 'window' object
// in this context?
}
$(document).ready(function () { WireHandlers(); });
When you pass the function by reference you still get access to the parameters as normal. As such event.target or this will be the clicked element within the UpdateResourceLinkClickedHandler function:
function UpdateResourceLinkClickedHandler(e) {
// clicked element as a native DOM element
var foo = e.target;
var bar = this;
// jQuery object containing clicked element
var $foo = $(this);
}
Note, both foo and bar in this example will contain the same value.
I think you can do it like this
$(this)
also this is from jquery documentation
var target = $( event.target );
as in this page http://api.jquery.com/event.target/ and look at this article for more information http://www.pkshiu.com/loft/archive/2009/01/understanding-this-this-and-event-in-a-jquery-callback-function

Categories

Resources