Invoke Angular2 click event on non InputElement - javascript

I am testing a component which has a click input on a div.
<div (click)="handleClick(someArgs)"></div>
Now I want to validate the behaviour in a test. I tried using .click() on the native element:
const elem = fixture.debugElement.query(By.css('my-selector'));
elem.nativeElement.click();
// Check for desired changes
However this only works in specific browsers since .click() seems to only be defined for HTMLInputElements (Relevant StackOverflow). I get the following error 'undefined' is not a function (evaluating elem.nativeElement.click()') for a couple browsers.
What is the best way to invoke a click event on a non HTMLInputElement?

I think the best way is calling triggerEventHandler() on DebugElement
triggerEventHandler
Triggers the event by its name if there is a corresponding listener in
the element's listeners collection. The second parameter is the event
object expected by the handler.
If the event lacks a listener or there's some other problem, consider
calling nativeElement.dispatchEvent(eventObject)
From testing documentation
https://angular.io/docs/ts/latest/guide/testing.html#!#trigger-event-handler

Usually when you want to trigger click on html elements using plain js you have to call the event which is defined on the element.
UPDATE: if you are using Jasmine, you can try calling trigger on the element:
const elem = fixture.debugElement.query(By.css('my-selector'));
elem.nativeElement.trigger('click');

Related

How to prevent event handler attached in one userscript from interfering with another?

I have installed two separate userscripts, each requiring to invoke some code with document.body.onkeydown. However, I've noticed that with both userscripts enabled, only the latter event handler gets called.
Apparently, both userscripts are sharing the same DOM. This is contrary to my experience with Chrome extensions, where each Chrome extension has its own sandbox.
Either way, now how do I to fix this problem? I want both handlers to fire, and remain separate from each other.
I am executing my userscripts inside an IIFE with use strict mode enabled.
Using document.body.keydown will set the callback to the keydown event. Setting it again will replace the old one. Hence the latter script's event callback gets fired.
Instead use, document.body.addEventListener(<callback>) in both so, both the events will present.
In the below example, first keydown will get overridden by the second one. The addEventListener will append an listener to the keydown event. So on pressing a only 3rd event fired. On pressing b, both 2nd and 3rd are fired.
This is because the events added via the older method is added as like attribute values. Like,
<button id="show" onclick="show()">Click</button>
Hence, it got replaced.
The addEventListener adds the listener to the list of EventListners of the DOM Object.
In the example I replaced the onclick attribute with the function hide via the older method, hence it calls only the hide method.
For more info, please refer MDN Docs
document.body.onkeydown = function(event){if(event.key=="a")console.log("keydown")};
document.body.onkeydown = function(event){if(event.key=="b")console.log("b keydown")};
document.body.addEventListener("keydown",function(){console.log("addEventListener")})
function show(){console.log("show")}
function hide(){console.log("hide")}
var element = document.getElementById("show");
element.onclick=hide;
<button id="show" onclick="show()">Click</button>
You can change them to use
document.body.addEventListener("keydown", function(){ ... })
If they use the 'this' set in the onkeydown approach, you may need to make sure that is set correctly
document.body.addEventListener("keydown", (function(){ ... }).bind(document.body))

Click event listener

I'm working on an Electron-based application, and I don't have much experience with it or JavaScript or Node.js. Currently, I just want to close a window by a click on a button.
close.addEventListener('click', function () {
ipc.send('close-main-window')
})
This totally works! I am just confused with why it works. From what I understand, the first argument in addEventListener is just any arbitrary string. However, I don't specifically write anything to handle a 'click'. This should mean it's built in functionality, I think. Is this part of JavaScript, Node.js, or Electron? And where in the documentation can I find a list of built in events?
JavaScript has the function addEventListener which adds an event listener (surprise, surprise) to an element. The element in which the listener is applied to now listens for an event, a string passed into the function (in this case click). Once the event is triggered (in this case when a user clicks on the element), it will execute the callback, which is the function you declared. So, consider this:
element.addEventListener("click", function() {
console.log("hello!");
});
This will log hello every time element is clicked.
You can read more at the Mozilla's Documentation. Here's a list of all the available events.
The first argument is string which represent the event type.
I think internally it works like this
var event = new Event('click');
where Event is an event object & click is already a predefined event of javascript

need help understanding this code

this code in book jQuery in action page 131
i don't understand
.trigger('adjustName');
what is adjustName
and Simple explanation for trigger()
thanks :)
$('#addFilterButton').click( function() {
var filterItem = $('<div>')
.addClass('filterItem')
.appendTo('#filterPane')
.data('suffix','.' + (filterCount++));
$('div.template.filterChooser')
.children().clone().appendTo(filterItem)
.trigger('adjustName');
});
It is a string, the name of a custom event you defined.
E.g. it would trigger the event handler bound by:
el.bind('adjustName', function(){...});
For more information I suggest to have a look at the documentation:
Any event handlers attached with .bind() or one of its shortcut methods are triggered when the corresponding event occurs. They can be fired manually, however, with the .trigger() method. A call to .trigger() executes the handlers in the same order they would be if the event were triggered naturally by the user.
Without knowing the context of the code, I would say that calling .trigger() here has no effect, as it is called on the cloneed elements and the event handlers are only cloned if true is passed to clone.
Maybe the original jQuery manual could be helpful?
Description: Execute all handlers and
behaviors attached to the matched
elements for the given event type.
It allows you to trigger, or run, an event. For instance if you wanted the code to mimic the clicking of a button, you could write....
$("#myButton").trigger('click');
This would then run exactly as if you had clicked the button yourself.
'adjustName' is a custom event. So the trigger function is running that custom event. The custom event is assigned using the jQuery bind function.
$("#someElement").bind('adjustName', function() {/* Some Code */});
You might create a customer event for clarity. Perhaps your application opens a document, so you might want an event called 'openDocument' and 'closeDocument' assigned to the element containing the document.

Html Select List: why would onchange be called twice?

I have a page with a select list (ASP.NET MVC Page)
The select list and onchange event specified like this:
<%=Html.DropDownList("CompanyID", Model.CompanySelectList, "(select company)", new { #class = "data-entry-field", #onchange = "companySelectListChanged()" })%>
The companySelectListChanged function is getting called twice?
I am using the nifty code in this question to get the caller.
both times the caller is the onchange event, however if i look at the callers caller using:
arguments.callee.caller.caller
the first call returns some system code as the caller (i presume) and the second call returns undefined.
I am checking for undefined to only react once to onchange, but this doesnt seem ideal, whcy would onchange be called twice?
UPDATE:
ok, found the culprit! ...apart from me :-) but the issue of calling the companySelectListChanged function twice still stands.
The onchange event is set directly on the select as mentioned. This calls the companySelectListChanged function.
..notice the 'data-entry-field' class, now in a separate linked javascript file a change event on all fields with this class is bound to a function that changes the colour of the save button. This means there is two events on the onchange, but the companySelectListChanged is called twice?
The additional binding is set as follows:
$('.data-entry-field').bind('keypress keyup change', function (e) { highLightSaveButtons(); });
Assuming its possible to have 2 change events on the select list, its would assume that setting keypress & keyup events may be breaking something?
Any ideas?
ANOTHER UPDATE:
The select element looks fine and all works if I remove the additional 'change' binding. when the 'change' binding is added that event fires once and the hard-wired 'onchange' is fired twice.
If both events are bound via jQuery all works ok, it seems that mixing hard-wired onchange and jquery bound change events cannot be mixed? I guess this answers my question but seems like an issue with IE and binding these events with jquery.
I agree with your assessment. I've updated my small example at http://gutfullofbeer.net/onchange.html to include a jQuery handler in addition to the DOM 0 handler (the one set with the "onchange" attribute). It appears to be a jQuery bug, or at least a failure of jQuery to deal with the IE weirdness.
I logged jQuery ticket 6593.
I also encountered this issue when using IE8 and made some changes to fix this.
Instead of specifying the onchange event on the dropdownlist, I used the jquery.change() event.
Markup:
#Html.DropDownList("drpList", myList, new { #class = "myClass", id = "drpList" })
Script:
$(function () {
$('#drpList').change(function () {
.... your functionality
});
});
This works for me.. Hopes this help.

What is the "event" parameter that so often is defined for JavaScript event handler functions?

A lot of time I see jQuery code that looks like this:
$('a').live( 'click', function(event){
..
});
What does the event parameter do? Does it correspond to the element 'a' or the event 'live'?
It means that every anchor element on the page (a) as well as any dynamically added anchor elements in the future will have a click event attached to them that will run whatever the function is passed in.
jQuery documentation of the live method
the parameter event of the function that is passed in is the result of a click on an anchor element. If you are using Firefox with Firebug you can examine this object by doing this:
$("a").live("click", function(event) {
console.dir(event);
});
When you click on an anchor you will then be able to see the whole object in the Firebug console.
I think you were asking specifically about what an event is and not necessarily the live function. event is a jQuery.Event (http://docs.jquery.com/Events/jQuery.Event) object which holds numerous things about the event including a reference to the clicked object.
event is, in this case, associated with the 'click' event that happens on every a tag in the HTML. It is an object that holds all the associated properties of the mouse click.
live is more effective than just binding an event, because it will attach itself to any a tags dynamically created after all of the event binding is done.
In javascript (not just specific to jQuery) the event object is an object that describes the event that just happened. W3C DOM standards specifies that the event object is the first parameter passed to an event handler. On IE, the event object is a global variable instead. So in regular javascript (without libraries like jQuery) you'll often find people write things like:
div.onclick = function (event) {
event = event || window.event; // take care of IE
..
}
Most libraries like jQuery take care of this for you so you only need to do the W3C standard thing.
The event object is the only standard mechanism of finding out things like mouse pointer xy location, which key is pressed etc.
see: https://developer.mozilla.org/En/DOM:event

Categories