Hide elements using Typescript - html

I'm new to Typescript and Angular Material. I want to hide elements inside elements like this.
<div id="abc">
<div id="123">
<p>Hello!</p>
</div>
<p>World</p>
</div>
<div id="def">
<p>Hello World</p>
</div>
I want to hide div block(id:123).I tried in this way.
var formElement = <HTMLFormElement>document.getElementById('123');
formElement.style.display='block';
It gets an error saying Cannot read property 'style' of null.... How can I solve this problem.

This is not the way to hide elements in Angular. Bind your element's style attribute to a boolean, like this:
<form [style.display]="isVisible ? 'block' : 'none'">... contents</form>
And in your component class:
this.isVisible = false; // whenever you need to hide an element
Or you can use *ngIf:
<form *ngIf="isVisible">... contents</form>
Please, note that *ngIf removes the node and its children completely from the DOM tree completely if the conditions turns to false, and fully recreates them from scratch when the condition turns true.

You can access the dom element using ViewChild with #localvariable as shown here,
import {Component, NgModule,ViewChild,ElementRef} from '#angular/core'
import {BrowserModule} from '#angular/platform-browser'
#Component({
selector: 'my-app',
template: `
<div id="abc">
<div #id id="123">
<p>Hide!</p>
</div>
<p>World</p>
</div>
<div id="def">
<p>Hello World</p>
</div>
`,
})
export class App {
name:string;
#ViewChild('id') el:ElementRef;
constructor() {
this.name = `Angular! v${VERSION.full}`
}
ngAfterViewInit()
{
this.el.nativeElement.style.display='none';
console.log(this.el.nativeElement);
}
}
#NgModule({
imports: [ BrowserModule ],
declarations: [ App ],
bootstrap: [ App ]
})
export class AppModule {}

#Component({
selector: 'my-app',
template: `
<div #id>
<p>Hide This!</p>
</div>
<div>
<p>Hello World</p>
</div>
`,
})
export class AppComponent {
#ViewChild('id') id:ElementRef;
constructor() {}
ngOnInit()
{
this.id.nativeElement.hidden=true;
}
}

The simplest way to hide elements using DOM is
document.getElementById('123').hidden = true;
in typescript.

Related

What is the purpose of <app-control-message> in angular 8 and how it is used?

I need to create a button for uploading a file in my form. I am using tag in my html but it is throwing an error : Can't bind to 'control' since it isn't a known property of 'app-contorl-message'.
Here is my html code -
<div class="col-lg-6">
<div class="form-group">
<div class="custom-file">
<input *ngIf="mode == 'CREATE'" type="file" (change)="onFileSelect($event)"
accept=".jpg,.jpeg,.png"/>
<app-contorl-message [control]="form.get('file')"></app-contorl-message>
</div>
</div>
</div>
here is def of onSelect($event) :
onFileSelect(event) {
this.form.get('file').setValue(event.srcElement.files);
this.fileData = event.srcElement.files;
console.log(event);
}
Thanks in advnace!
In your AppControlMessageComponent you need to create an #Input() named control. To learn more about inputs and output, visit: https://angular.io/guide/inputs-outputs
app-control-message.component.ts
import { Component, OnInit, Input } from "#angular/core";
#Component({
selector: "app-app-control-message",
templateUrl: "./app-control-message.component.html",
styleUrls: ["./app-control-message.component.css"]
})
export class AppControlMessageComponent implements OnInit {
#Input() control; // Input whose value parent component will provide
constructor() {}
ngOnInit() {}
}

How can we create modal pop-up in angular from scratch

Need to create a modal popup on button click,
is there any way to make it from scratch without adding any extra dependency for it,
with the below method, I am getting the fully functional modal, but have no confidence whether this is a good way in angular or not,
please suggest
HTML
<button class="hl-sort" (click)="openSortingModal()">
Sort
</button>
<div class="modal-container" *ngIf="modalContent">
<h1>i am modal content</h1>
<button (click)="closeModal()">Close</button>
</div>
components.ts
modalContent = false;
openSortingModal(){
this.modalContent = true;
console.log('clicked')
}
closeModal(){
this.modalContent = false;
}
If you don't want to add any extra dependency, I suggest you create a re-usable component using HTML + CSS as follows:
import { Component, OnInit, ViewChild, ElementRef } from '#angular/core';
#Component({
selector: 'app-modal',
template: `
<div #myModal class="container">
<div class="content">
<p>Some content here...</p>
<button (click)="close()">Close</button>
</div>
</div>
`,
styleUrls: ['./modal.component.css']
})
export class ModalComponent {
#ViewChild('myModal', {static: false}) modal: ElementRef;
open() {
this.modal.nativeElement.style.display = 'block';
}
close() {
this.modal.nativeElement.style.display = 'none';
}
}
Then use it in your container:
import { Component, ViewChild } from '#angular/core';
import { ModalComponent } from './modal/modal.component';
#Component({
selector: 'my-app',
template: `
<app-modal #modal></app-modal>
<p>
Open a Pure HTML + CSS with Angular
</p>
<button (click)="openModal()">Open Modal</button>
`,
styleUrls: []
})
export class AppComponent {
#ViewChild('modal', {static: false}) modal: ModalComponent
openModal() {
this.modal.open();
}
}
See a working example here: https://stackblitz.com/edit/angular-modal-html-css
I hope it helps!
If you do not want to reinvent the wheel, you can use this
https://ng-bootstrap.github.io/#/components/modal/examples
well, if you want to "re-invent the wheel", don't forget close the modal when you click outside
improving the Luixaviles's answer, the component modal can be like
<div #myModal class="container" (click)="tryClose()">
<div #content class="content">
<ng-content></ng-content>
</div>
</div>
Well, you see that I make a function "tryClose" if you click on the div "myModal", this function check if we click but we don't click inside "content"
tryClose() {
const clickTarget = event.target as HTMLElement;
if (!(this.content.nativeElement as HTMLElement).contains(clickTarget))
this.close();
}
Using <ng-content> allow us write in app.component some like
<app-modal #modal>
<p>Some content here...</p>
<button (click)="modal.close()">Close</button>
</app-modal>
<p>
Open a Pure HTML + CSS with Angular
</p>
<button (click)="modal.open()">Open Modal</button>
The rest of code in modal component is simple:
export class ModalComponent {
#ViewChild("myModal", { static: false }) modal: ElementRef;
#ViewChild("content", { static: false }) content: ElementRef;
open() {
this.modal.nativeElement.style.display = "block";
}
close() {
this.modal.nativeElement.style.display = "none";
}
}
See the Luixaviles's forked stackblitz
Update a simple stopPropagation makes the thinks easer
<div #myModal class="container" (click)="close()">
<div (click)="$event.stopPropagation()" class="content">
<ng-content></ng-content>
</div>
</div>
Obviously it is a good idea to create your own component rather using a third party. Just make sure, your popup must be a reusable or dynamic popup.

New Line not working properly in Angular 2 editable div

I have a contenteditable div that works great until I assign the changed text back into initial variable. When editing and I press enter, a new line appears properly in the editable div, but does not get stored into 'name'. The next character typed ends up at the end of the previous line, and the cursor goes to the beginning of the first line. If I remove the (input) line, the div behaves properly, but 'name' is not updated. How do I get the div to behave properly and update 'name'?
Plunk Demo
import {Component, NgModule} from '#angular/core'
import {BrowserModule} from '#angular/platform-browser'
#Component({
selector: 'my-app',
template: `
<div style="white-space: pre-wrap;"
[textContent]=name
(input)="name=$event.target.textContent"
contenteditable>
</div>
<div style="white-space: pre-wrap;">{{name}}</div>
`,
})
export class App {
name:string;
constructor() {
this.name = `TEST`
}
}
#NgModule({
imports: [ BrowserModule ],
declarations: [ App ],
bootstrap: [ App ]
})
export class AppModule {}
Expected Result:
Test
Test
Actual Result:
estTestT
With some little changes you can make it work.
Change textContent attribute to innerText.
Set the the innerText value value in ngOnInit and forgo ngModel.
Typescript:
#ViewChild('myEditable') private myEditable;
name:string;
constructor() {
this.name = 'I am editable';
}
ngOnInit(){
this.myEditable.nativeElement.innerText = this.name;
}
HTML:
<div #myEditable contentEditable (input)="name=$event.target.innerText"></div>
<div style="white-space:pre">{{name}}</div>
Demo

Show text when image is clicked

I'm trying to show some text underneath my header when the image I have is clicked. OnClick, it should show the paragraph of text underneath. However, I'm stuck on what is wrong with my current implementation.
Here's my html code so far:
I have a question and next to it is a plus sign for example. When I click on the plus sign, showAnswer goes from false to true and then it should showAnswer but the page loads with all the content already shown. How can I fix that?
<h1 class="question"> Foo?
<img (click)="showAnswer = !showAnswer" style="float:right;" src="images/ic-add.png"
class="ic_add"/></h1>
<p *ngIf="showAnswer" class="answer" > Bar</p>
<hr/>
<h1 class="question" >ABC
<img (click)="showAnswer = !showAnswer" style="float:right;" src="images/ic-add.png" class="ic_add"/>
</h1>
<p *ngIf="showAnswer" class="answer">123</p>
<hr/>
ts:
export class QuestionsComponent {
public showAnswer = false;
constructor(){
}
}
There is no problem in your code.
I have made an example.
You could check it.
UPDATED
Support multiple question by ngFor.
//our root app component
import {Component, View, CORE_DIRECTIVES, FORM_DIRECTIVES} from 'angular2/angular2'
import {Question} from './question'
#Component({
selector: 'my-app',
bindings: []
})
#View({
template: `
<question *ng-for="#el of questionArray; #idx = index"></question>
`,
directives: [CORE_DIRECTIVES, FORM_DIRECTIVES, Question]
})
export class App {
questionArray: Object[] = [1,2];
}
import {Component, View, CORE_DIRECTIVES} from 'angular2/angular2'
#Component({
selector: 'question',
bindings: []
})
#View({
template: `
<h1 class="question"> Foo?
<img (click)="clicked()" style="float:right;" src="images/ic-add.png"
class="ic_add"/></h1>
<p *ng-if="showAnswer" class="answer"> Bar</p>
<hr/>
`,
directives: [CORE_DIRECTIVES]
})
export class Question {
showAnswer: bool = false;
clicked() {
this.showAnswer = !this.showAnswer;
}
}

Building a wrapper directive (wrap some content / component) in angular2

I'm pretty new building directives with Angular2. What I want is to create a popup directive that will wrap the content with some css classes.
Content
Content can be pure text and headers like:
<div class="data">
<h2>Header</h2>
Content to be placed here.
</div>
Then I want to give this a directive attribute like: popup
<div class="data" popup>
<h2>Header</h2>
Content to be placed here.
</div>
What the directive should do, is to wrap the div inside, lets say:
<div class="some class">
<div class="some other class">
<div class="data">
<h2>Header</h2>
Content to be placed here.
</div>
</div>
</div>
The case i described so far, is this a attribute or structural directives.
import { Directive, ElementRef, HostListener, Input } from '#angular/core';
#Directive({
selector: `[popup]`
})
export class PopupDirective {
}
The other answer is related but different.
For something closer, see this: How to conditionally wrap a div around ng-content - my solution is for Angular 4, but the linked question has some hints about how this might be doable for Angular 2.
I solved this problem with a component and a directive combined. My component looks something like this:
import { Component, Input, TemplateRef } from '#angular/core';
#Component({
selector: 'my-wrapper-container',
template: `
<div class="whatever">
<ng-container *ngTemplateOutlet="template"></ng-container>
</div>
`
})
export class WrapperContainerComponent {
#Input() template: TemplateRef<any>;
}
and my directive like this:
import { Directive, OnInit, Input, TemplateRef, ComponentRef, ComponentFactoryResolver, ViewContainerRef } from '#angular/core';
#Directive({
selector: '[myWrapperDirective]'
})
export class WrapperDirective implements OnInit {
private wrapperContainer: ComponentRef<WrapperContainerComponent>;
constructor(
private templateRef: TemplateRef<any>,
private viewContainerRef: ViewContainerRef,
private componentFactoryResolver: ComponentFactoryResolver
) { }
ngOnInit() {
const containerFactory = this.componentFactoryResolver.resolveComponentFactory(WrapperContainerComponent);
this.wrapperContainer = this.viewContainerRef.createComponent(containerFactory);
this.wrapperContainer.instance.template = this.templateRef;
}
}
To be able to load your component dynamically, you need to list your component as an entryComponent inside your module :
#NgModule({
imports: [CommonModule],
declarations: [WrapperContainerComponent, WrapperDirective],
exports: [WrapperContainerComponent, WrapperDirective],
entryComponents: [WrapperContainerComponent]
})
export class MyModule{}
so the HTML in the end is:
<some_tag *myWrapperDirective />
Which renders as:
<my-wrapper-container>
<div class="whatever">
<some_tag />
</div>
</my-wrapper-container>
You can achieve this with a component attribute selector and Angular 2 Content Projection <ng-content>
#Component({
selector: 'my-app',
template: `
<div class="app">
<div class="data" myWrapper>
<h2>Header</h2>
Content to be placed here.
</div>
</div>
`
})
export class AppComponent {}
#Component({
selector: '[myWrapper]',
template: `
<div class="my-class">
<div class="my-sub-class">
<ng-content></ng-content>
</div>
</div>
`
})
export class MyComponent {
}