Angular 8 | Hide element using Directive - html

I want to hide specific element using Directive in Angular 8 when user click on input field.
Code is as per below
HTML
<input [choosecountry] type="text" />
directive.ts
#Directive({
selector: '[choosecountry]'
})
export class ChoosecountryDirective {
constructor( ) { }
}

Angular already have ngIf to accomblish this piece of requirement.

You can use [hidden]="true" this element will created on DOM as hidden, which is opposite to ngIf

yes, using Directive you can hide or show element.here is an example

Related

How to extend Angular Form Directive to have globally autocomplete="off"

As we know in Angular <form> is a directive. I'm wondering if there is any way to extend that directive.
I need this because I want to append attribute autocomplete="off" always when I use <form> on my view. Or maybe there is another, easier way to set it globally?
Angular diretive selector can also be select by css.As #Andrei Gatej mentioned in the comment you can use hostbinding to bind autocomplete attribute to all input inside form like this:
import { Directive, HostBinding } from '#angular/core';
#Directive({
selector: 'input[type="text"]'
})
export class FormDirective {
#HostBinding('attr.autocomplete') autoComplete ='off';
constructor() {
}
}
you should write own directive. Here is docs https://angular.io/guide/attribute-directives

Angular 4 - On button click want to append textarea to view dynamically for each button click

Actually I want to create one textarea on button click over view. I don't have much idea in angular 4. Requirement is that on each click of button I want to create textarea over view. There should be multiple textarea's with cross buttons so I can remove the textarea if don't want.
Unfortunately I didn't try any code yet and didn't found any solution to implement it. But that is my requirement to create in angular 4. Any help will be appreciable.
Below code will serve your requirement of generating textarea on button click as well as removing specific textarea.
<div style="padding-top: 200px">
<button (click)="addTextarea()">Add Textarea</button>
<form>
<div *ngFor="let textarea of textAreasList; let textarea_index= index">
<textarea name="{{textarea}}"></textarea>
<button (click)="removeTextArea(textarea_index)">Remove</button>
</div>
</form>
place the above code in .html file.
import { Component } from '#angular/core';
#Component({
selector: 'home',
templateUrl: 'home.component.html',
styleUrls: ['home.component.css']
})
export class HomeComponent {
textAreasList:any = [];
addTextarea(){
this.textAreasList.push('text_area'+ (this.textAreasList.length + 1));
}
removeTextArea(index){
this.textAreasList.splice(index, 1);
}
}
place the above code in .ts file. Let me know if you have any other difficulties.

How to add disable attribute on component selector?

I am trying to disable button. But button is angular component.
And Html5 disabled attribute cannot work on component selector.
I tried to add like this but does not work: [attr.disabled]="isOpenModal
Button Html code:
<add-new-button [attr.disabled]="isOpenModal"
(click)="openModal('new')"
class="nano-bc-green hover-effect">
</add-new-button>
Button - Component "add new button"
#Component({
selector: 'nano-add-new-button',
template: `
<div class='nano-f-r nano-f'>
<i class='fa fa-plus'></i>
<span class='nano-ml-5'>
Add New
</span>
</div>`
})
export class NanoAddNewButtonComponent {
}
Open Modal method which is used on button:
public openModal(id: string): void {
const data = {id: id};
this.modalModel.add(AudienceModel.ENTITY_NAME, data);
}
Any idea for solution?
Because your add-new-button component can be anything, and disabled is not a property that all elements have, that can't work.
Check out the list of Global Attributes.
You have to define your own disabled property:
#Input() disabled: boolean;
And you can bind this to the elements you want to disable like:
<button [disabled]="disabled">My button</button>
You can use it like this after:
<add-new-button [disabled]="isOpenModal"
(click)="openModal('new')"
class="nano-bc-green hover-effect">
</add-new-button>
Just put the disabled logic into the click method itself:
Template:
<add-new-button (click)="onModalClick()"
class="nano-bc-green hover-effect">
</add-new-button>
TypeScript:
onModalClick() {
if (!this.isOpenModal) {
this.openModal('new');
}
}
here is disable attribute
<my-date-picker [options]="myOptions" [disabled]="disabled"
(dateChanged)="onDateChanged($event)"></my-date-picker>
it may be helpful ;)
You can use the CSS selector [ng-reflect-disabled] to trigger the disabled value.
and add [disabled]="isOpenModal" instead of [attr.disabled]="isOpenModal" in your HTML file.
and in your CSS file add the below code:
add-new-button[ng-reflect-disabled="true"] {
cursor: default;
pointer-events: none;
}

Angular2 Declaring a directive's selector to require a text input

I have just created a number directive :
#Directive({
selector: '[ngModel][number]'
})
export class NumberDirective {...}
I would like my selector to be even more specific and requires a text input :
<input type="text" [(ngModel)]="..." [number]="...">
You can use attribute selectors with value
selector: 'input[type="text"][ngModel][number]'
See also https://developer.mozilla.org/en/docs/Web/CSS/Attribute_selectors

Styled HTML content dynamically switched with tabs using Angular 2

I am attempting to create a reusable angular2 component that accepts an array of URLs to html files on my server and creates a content window with tabs to switch between "chapters", effectively swapping out the html and css inside the content window. I have tried all sorts of things including iframes but those don't work, the angular 1 ng-include work-arounds that I can find on StackOverflow but they have all since been deprecated, and the closest I've got is building a component that you can #Input html and it interpolates the content but style won't apply and angular strips out any style or script tags. Here is what I have tried.
In my parent component class:
htmlInput: string = "<h1>Why Does Angular make this so hard?</h1>";
cssInput: string = "h1 { color:red; }"
Parent Component HTML:
<app-html [html]='htmlInput' [css]='cssInput'></app-html>
My HTML Component:
import { Component, Input, OnInit } from '#angular/core';
#Component({
selector: 'app-html',
template: '<div [innerHtml]=html></div>', //This works but no style
//template: '{{html}}', //This displays the actual markup on page
styles: ['{{css}}'] //This does nothing
//styles: ['h1 { color: red; }']//Also nothing
})
export class HtmlComponent implements OnInit {
#Input() html: string = "";
#Input() css: string = "";
ngOnInit() {
}
}
The result of this code is
Why Does Angular make this so hard?
But no red color. Maybe style is applied before the innerHtml is added to DOM? I don't know but just putting {{html}} results in displaying the actual markup with the h1 tags visible.
The reason I want to do it this way is that I have a bunch of HTML pages already created sitting in a folder on my server from before I angularized my site that all share a single style sheet. I'd like to just be able to flip through them like pages in a book without reloading the page and since there are so many and I'm likely to add more all the time, I'd really rather not create routing for every single one. (I already have routing for basic site navigation.)
Does anybody have a better suggestion for how to embed styled HTML into a page dynamically in the most recent version of Angular 2? At the time of this post we are in 2.0.0-beta.17.
OR... I already figured I may be approaching this issue from the entirely wrong angle. There must be a reason Angular is making this so difficult and deprecating all the solutions people have come up with so If anyone has a suggestion about how I could achieve the same results in a more angular friendly way I'd love to hear that too.
Thank you.
Edit:
I was able to fix my issue by creating a pipe which sanatizes the html before adding it to an iframe.
import { Pipe, PipeTransform } from '#angular/core';
import { DomSanitizer } from '#angular/platform-browser';
#Pipe({ name: 'safe' })
export class SafePipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) {}
transform(url: string) {
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
}
}
And then you can just pass your html into the iframe.
<iframe width="100%" height="1000" frameBorder="0" [src]="url | safe"></iframe>
This is useful to me since I have some old pages that use all sorts of jquery and style etc. This works as a quick fix to have them show up.
Angular2 rewrites the styles added to a component by including the dynamically added attributes like _ngcontent-yle-18 into the CSS selectors.
Angular2 uses this to emulate shadow DOM style encapsulation. These attributes are not added to dynamically added HTML (for example with innerHTML).
Workarounds
add styles to index.html because these styles are not rewritten by Angular2
set ViewEncapsulation.None because then Angular doesn't add the encapsulation emulation attributes
use /deep/ to make Angular2 ignore the encapsulation emulation attributes
See also Angular 2 - innerHTML styling
You should wrap your css into an object and use ngStyle to bind it to your component rather than the styles attribute, because styles does not support data binding.
Example:
htmlInput: string = "<h1>Why Does Angular make this so hard?</h1>";
cssInput: string = "{h1 { color:red; }}"
Parent Component HTML:
<app-html [html]='htmlInput' [css]='cssInput'></app-html>
Your HTML Component:
import { Component, Input, OnInit } from '#angular/core';
#Component({
selector: 'app-html',
template: '<div [innerHtml]="html" [ngStyle]="css"></div>',
styles: []
})
export class HtmlComponent implements OnInit {
#Input() html: string = "";
#Input() css: string = "";
ngOnInit() {
}
}