I'm trying to catch paste event occuring on input fields.
It works perfectly on textarea and input but not on dropdowns. Select.
Here is my directive, the console.log is never called.
import { Directive, HostListener } from '#angular/core';
#Directive({ selector: '[catchPasteEvents]' })
export class CatchPastEvent {
#HostListener('onpaste') onPaste(event) {
console.log('Paste', event);
}
}
I created this directive that set a listener on document paste (as suggested by Sergey) but only when the select element is focused.
#Directive({ selector: 'select[selectPaste]' })
export class SelectPasteDirective implements OnDestroy {
#Output()
public paste: EventEmitter<ClipboardEvent> = new EventEmitter();
private listener: (event: ClipboardEvent) => void = this.handlePaste.bind(
this,
);
public ngOnDestroy(): void {
document.removeEventListener('paste', this.listener);
}
#HostListener('focus')
public onFocusedItem() {
document.addEventListener('paste', this.listener);
}
#HostListener('blur')
public onBlurItem() {
document.removeEventListener('paste', this.listener);
}
private handlePaste(event: ClipboardEvent) {
this.paste.emit(event);
}
}
Related
I'm in Angular group project and I'm trying to implement delete functions for current workspace but I'm not sure how to do that. Any suggestion or help on how to do that?
Inside add-workspace.HTML file, I have a button that display a dialog box (delete-workspace-dialog).
Inside delete-workspace-dialog components file and there is a delete button. I'm trying use that button to delete current workspace.
Inside delete-workspace.dialog.ts file aka delete dialog box
export class DeleteWorkspaceDialogComponent implements OnInit {
constructor(
public dialogRef: MatDialogRef<DeleteWorkspaceDialogComponent>,
#Inject(MAT_DIALOG_DATA) public data: any) { }
ngOnInit(): void {
}
onNoClick(): void {
this.dialogRef.close();
}
onDeleteClick(): void{
// Delete workspace here
}
}
I'm trying to use that "Yes,Delete it" button to delete the current workspace
Hope the below snippet might help:
In Delete pop up component:
import { WorkspaceService } from 'src/app/core/services/workspace.service';
export class DeleteWorkspaceDialogComponent implements OnInit {
constructor(
public dialogRef: MatDialogRef<DeleteWorkspaceDialogComponent>,
#Inject(MAT_DIALOG_DATA) public data: any,
private workspaceService: WorkspaceService) { }
ngOnInit(): void {
}
onNoClick(): void {
this.dialogRef.close();
}
onDeleteClick(): void{
// Delete workspace here
this.workspaceService.deleteWorkspace(data.workspace).subscribe(response=>{
// Do some logic and close the popup
this.dialogRef.close();
},error=>{
// Error handling and close the popup
this.dialogRef.close();
})
}
}
From parent component to open delete popup:
HTML:
<button (click)="delete()">Delete</button>
TS:
delete(){
this.dialog.open(DeleteWorkspaceDialogComponent,{
data: {
workspace: this.workspace
}
});
}
Here you are passing the work space to be deleted and in delete popup, you are calling the service to delete the work space.
Hope it will help.
I have written a directive in angular4, which works on input fields.
When I apply that on SPAN tag, it is not working.
Can we apply the directives on SPAN TAG, or is there any work around.
<span dirTemp>45789</span>
dirTemp actually corrects the value to 45,789
import { Directive, HostListener, ElementRef, OnInit, AfterViewInit, AfterViewChecked, AfterContentChecked } from '#angular/core';
#Directive({
// tslint:disable-next-line:directive-selector
selector: '[dirTemp ]',
})
export class FormatterDirective implements AfterViewChecked {
private el: HTMLInputElement;
constructor(
private elementRef: ElementRef,
private cPipe: MyPipe
) {
this.el = this.elementRef.nativeElement;
}
// ngOnInit() {
// this.el.value = this.cPipe.transform(this.el.value);
// }
ngAfterViewChecked(): void {
this.el.value = this.cPipe.parse(this.el.value);
this.el.value = this.cPipe.transform(this.el.value);
}
#HostListener('focus', ['$event.target.value'])
onFocus(value) {
console.log('in formatter directive:', value);
this.el.value = this.cPipe.parse(value);
}
#HostListener('focusout', ['$event.target.value'])
onFocusout(value) {
this.el.value = this.cPipe.transform(value);
}
}
Workaround: span doesn't have value but has innerText or innerHTML. So, On ngOnInit you can do:
ngOnInit() {
if(this.el.tagName.toUpperCase() !== 'INPUT') {
// Apply your tranform here:
var originalValue = this.el.innerText;
this.el.innerText = this.cPipe.transform(originalValue);
}
}
I have an issue where i'm displaying a webview on one view and then once the user logs in i'm navigating to another view but the html for that view won't display, only the action bar. Help appreciated!
This is the login component navigating to secure--
this.router.navigate(["/secure"], { queryParams: { accessToken: accessToken } }).then((success)=>{
console.log(success);
});
}
This is the secure component-
#Component({
moduleId: module.id,
selector: "ns-secure",
templateUrl: "secure.component.html",
})
export class SecureComponent implements AfterViewInit{
public accessToken: string;
public onceLoggedInSrc: string; //TODO
public htmlString: string;
public constructor(private _router:Router, private _activatedRoute: ActivatedRoute, private cdRef:ChangeDetectorRef) {
this.htmlString = '<span><h1>HtmlView demo in <font color="blue">NativeScript</font> App</h1></span>';
this._activatedRoute.queryParams.subscribe(params => {
this.accessToken = params["accessToken"];
console.log('accessToken2');
console.log(this.accessToken);
this.ngAfterViewInit();
});
}
ngAfterViewInit() {
console.log('accessToken');
}
I can pass a class object like Person into a child component from parent component without any problems. But I would like to also manipulate that object in child component and pass it back to parent component.
This is the child component class:
export class ActionPanelComponent {
#Input('company') company: Company;
#Output() notify: EventEmitter = new EventEmitter();
constructor() {
}
public deleteCompany() {
console.log('display company');
console.log(this.company);
// FIXME: Implement Delete
this.company = new Company();
}
public onChange() {
this.notify.emit(this.company);
}
}
This is the html of this component (excerpt):
<div class="row" (change)="onChange()">
<div class="col-xs-2">
<button md-icon-button >
<md-icon>skip_previous</md-icon>
</button>
</div>
This is the parent component class (excerpt):
public onNotify(company: Company):void {
this.company = company;
}
And the parent component html (excerpt):
<action-panel [company]="company" (notify)="onNotify($event)"></action-panel>
I am doing something wrong because I cannot pass my company object inside the .emit and nothing works.
What is the correct way of achieving two way object binding between components?
Thanks in advance!
You were missing the type on the initialization of the EventEmitter.
You could use the Output binding to implement the two way object binding:
Child component (ts)
export class ActionPanelComponent {
#Input('company') company: Company;
#Output() companyChange: EventEmitter = new EventEmitter<Company>();
constructor() {
}
public deleteCompany() {
console.log('display company');
console.log(this.company);
// FIXME: Implement Delete
this.company = new Company();
}
public onChange() {
this.companyChange.emit(this.company);
}
}
Parent component (html)
<action-panel [(company)]="company"></action-panel>
So like this you don't need to declare an extra function onNotify. If you do need the onNotify function, use another name for the output binding:
export class ActionPanelComponent {
#Input('company') company: Company;
#Output() notify: EventEmitter = new EventEmitter<Company>();
constructor() {
}
public deleteCompany() {
console.log('display company');
console.log(this.company);
// FIXME: Implement Delete
this.company = new Company();
}
public onChange() {
this.notify.emit(this.company);
}
}
Change it like this to tell TS which Type the EventEmitter should emit:
export class ActionPanelComponent {
#Input('company') company: Company;
#Output() notify = new EventEmitter<Company>(); //<---- On this line!
constructor() {
}
public deleteCompany() {
console.log('display company');
console.log(this.company);
// FIXME: Implement Delete
this.company = new Company();
}
public onChange() {
this.notify.emit(this.company);
}
}
It is a workaround that worked for me, if it is helpful for anyone.
Your parent parent-component.ts would be like;
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'parent',
templateUrl:'./parent.component.html',
styleUrls: ['./parent.component.css']
})
export class Parent implements OnInit {
let parentInstance= this; //passing instance of the component to a variable
constructor() { }
parentMethod(var:<classtyepyourchoice>){
console.log(var);
}
ngOnInit() {
}
}
In you parent.component.html, you would have your child
<child [parent]="parentInstance" ></child>
This object will be available in the child component
Now, in your child component you will receive this like
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'child',
templateUrl:'./child.component.html',
styleUrls: ['./child.component.css']
})
export class Child implements OnInit {
#Input('parent') parent;
constructor() { }
childMethod(yourClassObject){
this.parent.parentMethod(yourClassObject);
}
ngOnInit() {
}
}
Thus, you can pass classobject from your child, like this, it worked for me.
I'm fairly new to Angular 2 and I have a little problem.
I have a header component, in the header I want to use an ngIf, cause in the login-screen I will hide the header(navbar).
Furthermore, I want to hide some more things from the header, depending on the users-profile.
To store, if a user is logged in, I have a global service named variables.ts, which looks like this:
import { Injectable } from '#angular/core';
#Injectable()
export class Variables {
private url = "...";
private username;
private password;
private isLoggedIn = false;
constructor() {}
setUrl(val) {
this.url = val;
}
getUrl() {
return this.url;
}
setUsername(val) {
this.username = val;
}
getUsername() {
return this.username;
}
setPassword(val) {
this.password = val;
}
getPassword() {
return this.password;
}
setIsLoggedIn(val) {
this.isLoggedIn = val;
}
getIsLoggedIn() {
return this.isLoggedIn;
}
}
My header-component looks like this:
import { Component } from '#angular/core';
import { Router } from '#angular/router';
import { Variables } from '../../services/variables';
#Component({
selector: 'app-header',
moduleId: module.id,
templateUrl: 'header.component.html'
})
export class HeaderComponent {
constructor(private variables: Variables) {}
isLoggedIn() {
return this.variables.getIsLoggedIn();
}
console.log(loggedIn);
}
And last but not least, in the header.component.html I did this:
<nav class="navbar navbar-default navbar-static-top" *ngIf="isLoggedIn()">
My problem now is, that the header-component do not automatically update the var loggedIn, so the header is hidden if I'm logged in.
How can i make it functional?
I updated my original post, so that it is functional now ;)
Thanks for your help!
Solution: DonĀ“t bind it directly to a variable, but to a function and in the "ngIf" just ask the function ;)