Binding click event with css class in angular 7 - angular7

Is there any way to bind click event with class name in angular 7 like we used to with jquery?
In jquery I was able to do this
$('.my-class-name').on('click',function(){});
Is there something similar standard way in angular 7?

You can directly add the click event to the HTML tag which has the required class
In your case:
****** Method 1 ******
lets say you are writing the above className on a button, then
<button class="my-class-name" (click)="yourFunction($event)">
Your button
</button>
If you want to add it from the TS File only, then you can use the following method:
*** Method 2 ******
**STEP 1:**
// Create a view child template reference
#viewChild('someName', {static: false})
private someNameVC: ElementRef
**STEP 2:**
// Add this 'someName' to the HTML Element in .html FIle
<button class="my-class-name" #someName>
Your button
</button>
**STEP 3:**
// In your component.ts file, whenever you want to add the event listener, create a function and do the following :
yourMainFunction() {
if (someCondition) {
this.addEventListenerToButtonMethod();
......rest of the code
}
}
addEventListenerToButtonMethod() {
const parentElement: HTMLElement =
this.someNameVC.nativeElement.parentNode as HTMLElement;
// Here you can add your event listener
parentElement.addEventListener('click', function() {});
}

Related

Add event handler to element in custom child component for MapContainer

I am using react-leaflet (v3.2.5) with leaflet (v1.8.0). We need pretty custom zoom buttons and one additional 'home' like button on the map, which look like this:
So I am trying to create a custom controls component like this (<FeatherIcon /> is another component from our codebase):
function MapControls() :JSX.Element {
const map = useMap();
return <div className="leaflet-top leaflet-right vertical-controls clickable">
<span className="control-icon-box" onClick={() => { console.log('in', map); map.zoomIn();}}><FeatherIcons iconId='plus-circle' className="feather vertical-control-icon" /></span>
<span className="control-icon-box" onClick={() => { map.zoomOut();}}><FeatherIcons iconId='minus-circle' className="feather vertical-control-icon" /></span>
<span className="control-icon-box"><FeatherIcons iconId='target' className="feather vertical-control-icon" /></span>
</div>
}
I want to use it like this
<MapContainer center={[buildingsData.geoCenter.y, buildingsData.geoCenter.x]} zoom={buildingsData.geoCenter.zoom} scrollWheelZoom={true}
zoomControl={false} zoomDelta={0.5}>
<!-- other stuff -->
<MapControls />
</MapContainer>
But the click handler is not added in the MapContainer context (like mentioned here).
Do I need to use something like
const minusRef = useRef(null);
useEffect(() => {
function minusClick() { /* doing stuff */ }
if (minusRef.current !== null) {
minusRef.current.addEventListener('click', minusClick);
}
return () => {
if (minusRef.current !== null) {
minusRef.current.removeEventLister('click', minusClick);
}
}
}, [map]);
This solution here is not really clear to me:
I am not sure how to achieve that using your approach where
react-leaflet's wrapper ZoomControl is not a child of Map wrapper when
you try to place it outside the Map wrapper.
However, for a small control like the ZoomControl, an easy solution
would be to create a custom Zoom component, identical to the original,
construct it easily using the native css style and after accessing the
map element, invoke the zoom in and out methods respectively.
In the below example I use react-context to save the map element after
the map loads:
const map = mapRef.current.leafletElement;
setMap(map); }, [mapRef, setMap]); ```
and then here use the map reference to make a custom Zoom component
identical to the native (for css see the demo):
``` const Zoom = () => { const { map } = useContext(Context);
// etc ```

How to show google popup confirm dialog with angular7?

I am trying to display the chrome popup confirm dialog after a modification done when i try to leave to go another url (route) in my application .
I add this code :
#HostListener('window:beforeunload', ['$event']) beforeUnload($event) {
$event.returnValue = '';
}
but when i try to move to another route i didn't get any confirm dialog.
I'm working with angular7. How to resolve that? any example ? thanks in advance.
Angular provides Guards for Route events. Based on the documentation of CanDeactivate Guard, you can show confirmation dialog before leave from page.
#Injectable()
class CanDeactivateExample implements CanDeactivate<YourComponent> {
canDeactivate(
component: YourComponent,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState: RouterStateSnapshot
): Observable<boolean|UrlTree>{
if(component.isModified){
return confirm('Are you sure to leave from page?');
}
return true;
}
}
To use it, you should edit your routes like:
imports:[
...
RouterModule.forRoot([
{
path: '<path>',
component: YourComponent,
canDeactivate: [CanDeactivateExample]
}
])
]
Also Guards are injectables, so you need to provide it at your module which you want to use inside.
provides: [..., CanDeactivateExample]

"'this.byId' is not a Function" error in console

I have a script file that I would like to load into a Main.controller.js
myScript.js
sap.ui.define([], function () {
return {
/////
testFunc : function(){
var test = this.byId("someId");
console.log(test);
};
});
The myScript.js file is successfully read in the main controller when I load it in as a dependency (see below), but I get an error in the myScript.js :
"'this.byId' is Not a Function" (console.log)
Inside the main controller, "this.byId()" works because the 'this' keyword points to the xml view associated with the main controller (main.view.xml). How can I have a dependency like 'myScript.js' point to the same xml view as the controller that loads it?
main controller
sap.ui.define([
'jquery.sap.global',
'sap/ui/core/mvc/Controller',
'sap/ui/model/json/JSONModel',
'sap/ui/model/Filter',
'sap/ui/model/FilterOperator',
'pricingTool/controller/myScript'
],
function (jQuery, Controller, JSONModel, Filter, FilterOperator, myScript) {
"use strict";
var mainController = Controller.extend("pricingTool.controller.Main", {
myScript.testFunc();
...
});
return mainController;
});
main.view.xml
<mvc:View
controllerName="pricingTool.controller.Main"
xmlns:l="sap.ui.layout"
xmlns:core="sap.ui.core"
xmlns:f="sap.ui.layout.form"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m">
...
</mvc:View>
You need to change the context passed to the script function. You can do this with following code:
myScript.testFunc.apply(this);
Let me know if this resolved your issue.

Binding child ember objects to handlebars class

Having a binding issue with a child object of an ember.view object. Code is as follows:
--Textbox class extended from Ember.TextField
App.TextBox = Ember.TextField.extend({
attributeBindings:['placeholder', 'autocorrect','autocapitalize'],
value:null,
isInvalid:true,
validate:function(){
this.set('isInvalid', false);
return false;
},
focusOut:function(event){
this.validate();
}});
---View that uses App.Textbox
App.ViewTextBox = Ember.View.extend({
name:"viewName",
label:"View Label",
input: App.TextBox.extend({
placeholder:function(){
return this.get('parentView').get('label');
}.property('label').cacheable()
})});
--Handlebars with bindings
{{#view App.ViewTextBox}}
{{label}}<br/>
{{#view input valueBinding="parentView.value"}}
<div {{bindAttr class="isInvalid"}}></div>
{{/view}}{{/view}}
Issue is this:
1) After the initial rendering of the view, the class is properly set, but subsequent changes to the isInvalid value, through the onFocusOut call, do not change the class in the DOM. Ideas?
You can't use a view block helper with Ember.TextField.

Unable to move from JQuery.live() to JQuery.on()

I am loading some html via $.get() into a Jquery-dialog-popup.
Upon clicking a link in the newly inserted html some function should be triggered.
This works with live() but NOT with on().
This works:
$(".remove").live("click", function () {
// enter ok
}
This does not:
$("div").on("click", ".remove", function () {
// or $("#delete").on("click", ".remove", function () {
// or $(".remove").on("click", function () {
// never enters...
});
html:
<div id="delete">
<a class="remove" href="#">link</a>
</div>
The on()-function works in case I am calling it directly from my main-template without loading the content into a dialog-window first via $.get.
To pre-bind events for dynamic content, they have to be bound to a pre-existing element.
So, if the <div id="delete"> is part of the dynamic content, then you shouldn't use it to bind the event. You can, however, bind to the container that the dynamic content is loaded into.
So, if the resulting HTML is:
<div id="contents">
<!-- start template -->
<div id="delete">
<a class="remove" href="#">link</a>
</div>
<!-- end template -->
</div>
Then, your JavaScript can be:
$('#contents').on('click', 'div a.remove', function () {
// ...
});
.live() uses document for this -- an element that exists until reload or redirect -- making the following lines equivalent:
$("a.remove").live("click", function () { /* ... */ });
$(document).on("click", "a.remove", function () { /* ... */ });
I can't see the whole code but I would bet that you're not putting the
$("div").on("click", ".remove", function () {
// or $("#delete").on("click", ".remove", function () {
// or $(".remove").on("click", function () {
// never enters...
}
part ONCE the new code has been inserted into the DOM.
You need to attach the event listeners to the new elements created. Live works because it works for existing and future elements like that.
EDIT:
If you want the click handler to work for an element that gets loaded dynamically, then you need to set the event handler on a parent object (that does not get loaded dynamically) and give it a selector that matches your dynamic object like this:
$('#parent').on("click", ".remove", function() {});

Resources