Disable a button once clicked in Angular2 - html

I have a silly problem but i didn't know how to overcome it since i'm using Angular2 (Typescript) stuffs not JavaScript's tools. I have this HTML code
<div class=" uk-align-center" >
<a class="md-btn md-btn-success" >Start</a>
<!--<a class="md-btn disabled" *ngIf="">Start</a>-->
</div>
Simply , I want to change the button status to disabled once clicked, I found Javascript ways but none of them worked for me, any Help please ?

You can use following approach without touching your component,
<a class="md-btn md-btn-success"
[class.disabled]="isClickedOnce"
(click)="isClickedOnce = true">Start</a>

another solution with code side:
<button name="submitButton" #submitButton type="submit" class="btn btn-primary" (click)="onButtonClick()">Submit</button>
import { ViewChild, ElementRef } from '#angular/core';
#ViewChild('submitButton') submitButton:ElementRef;
onButtonClick()
{
this.submitButton.nativeElement.disabled = true;
//Do some other stuff, maybe call a service etc...
this.submitButton.nativeElement.disabled = false;
}

You could use ngClass directive to deal with classes:
import {Component} from '#angular/core';
#Component({
selector: 'my-app',
providers: [],
template: `
<div>
<div class=" uk-align-center" >
<a [ngClass]="{'md-btn md-btn-success': !isButtonDisabled,
'md-btn disabled': isButtonDisabled }"
(click)="isButtonDisabled = !isButtonDisabled;">Start</a>
</div>
</div>
`,
styles: [
`
.md-btn md-btn-success {
...
}
.md-btn disabled {
...
}
`
]
})
export class App {
isButtonDisabled: false;
constructor() {
}
}

i'm using Angular2-RC2. This is how i use *ngIf, maybe it helps.
NOTE: in this example, once the button is pressed, it will be disabled, so you cannot click it to call the function unpushMe() anymore.
text-area.component.ts
import {Component} from '#angular/core';
#Component({
selector: 'textarea-comp',
template: `
<div>
<div *ngIf="!isPushed" >
<p><button (click)="pushMe()">push2disable</button></p>
</div>
<div *ngIf="isPushed" >
<p><button (click)="unPushMe()" disabled >disabled</button></p>
</div>
`
})
export class TextAreaComponent {
isPushed: boolean = false;
pushMe() {
this.isPushed = true;
}
unPushMe() {
this.isPushed = false;
}
}

Related

initialize html tag from angular type-script

as shown in the below angular type script code, i would like to refer to the divisions mentioned in the below posted .html code using document.getElementById
the result of the log statement is null
please let me know how correctly to referece an html-tag in type-script
.ts:
export class GridCellPopupOverlayComponent implements OnInit {
isVisible = true
container: any
content
closer: any
overlay: any
AoC: any
AvgH: any
Dist: any
I: any
constructor() {
}
initHTMLElements() {
console.log("html init")
this.container = document.getElementById('idGridCellInfoPopupDiv');
this.AoC = document.getElementById('idGridCellInfoAoCValueDiv');
this.AvgH = document.getElementById('idGridCellInfoAvgHValueDiv');
this.Dist = document.getElementById('idGridCellInfoDistValueDiv');
this.I = document.getElementById('idGridCellInfoIValueDiv');
this.closer = document.getElementById('gridCellInfoPopup-closer');
console.log("this.AoC:",this.AoC)
}
}
html:
<div *ngIf="isVisible" id="idGridCellInfoPopupDiv" class="ol-popup">
<!-- <span id="idGridCellLabel" class="label label-success">dsfdsfsa</span> -->
<div class="alert alert-success alert-sm" role="alert">
<div class="alert-items">
<div class="alert-item static">
<div class="alert-icon-wrapper">
<clr-icon class="alert-icon" shape="check-circle"></clr-icon>
</div>
<div id="idGridCellAlertText"class="alert-text">
</div>
</div>
</div>
<!-- <button type="button" class="close" aria-label="Close">
<clr-icon aria-hidden="true" shape="close"></clr-icon>
</button> -->
</div>
<div id="idGridCellInfoAoCValueDiv"></div>
<div id="idGridCellInfoAvgHValueDiv"></div>
<div id="idGridCellInfoDistValueDiv"></div>
<div id="idGridCellInfoIValueDiv"></div>
You can get the elements from the .html by using #ViewChild/#ViewChildren decorators. Behind the scenes they are using document.getElementById. This is the correct way in Angular.
Also watch out for ngAfterViewInit lifeycle method in which you can access your references. View queries are set before the ngAfterViewInit callback is called. (form Angular documentation)
Here is the reference: https://angular.io/api/core/ViewChild
Btw, you can omit static: false since it's default.
TS file
import { HelloComponent } from './hello.component';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit {
name = 'Angular';
#ViewChild('pRef', {static: false}) pRef: ElementRef;
ngAfterViewInit() {
console.log(this.pRef.nativeElement.innerHTML);
this.pRef.nativeElement.innerHTML = "DOM updated succesfully!!!";
}
}
Template file
<hello name="{{ name }}" ></hello>
<p #pRef>
Start editing to see some magic happen :)
</p>```

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.

Is there an onHidden event for the ngb-datepicker? If there isn't how do we add events to custom components in angular?

I am using the datepicker from this source: https://ng-bootstrap.github.io/#/components/datepicker/api
And I would like to check if the ngb-datepicker is closed because I need to change the text of the button where it is triggered.
template:
<button (click)="dp.open(); changeText();">{{buttonText}}</button>
<ngb-datepicker #dp
[(ngModel)]="model"
(onHidden)="changeButtonText2()" <<---is this possible? >
/>
ts:
import {Component} from '#angular/core';
import {NgbCalendar} from '#ng-bootstrap/ng-bootstrap';
#Component({
selector: 'ngbd-datepicker-basic',
templateUrl: './datepicker-basic.html'
})
export class NgbdDatepickerBasic {
buttonText: string = 'Open Calendar'
constructor(private calendar: NgbCalendar) {
}
changeText() {
this.buttonText = 'The Calendar is Open';
}
changeButtonText2() {
this.buttonText = 'Open Calendar'
}
}
The ngx-bootstrap datepick have this but it seems the ngb-datepicker does not implement this feature. Can someone help me create a workaround so I don't have to use the ngx-bootstrap just for this? I already added some styling so...
Thanks :)
If you are using popup datepicker and only want to change text button
<form class="form-inline">
<button (click)="dpk.toggle()">{{ dpk.isOpen() ? 'The Calendar is Open' : 'Open Calendar' }}</button>
<div class="form-group">
<input class="form-control" placeholder="yyyy-mm-dd"
name="dp" [(ngModel)]="model" ngbDatepicker #dpk="ngbDatepicker">
</div>
</form>
if you want to custom more code, use this:
#ViewChild('dpk') dpk: NgbDatepicker;
ngAfterViewInit() {
this.dpk['close'] = () => {
if (this.dpk['isOpen']) {
// super origin event
this.dpk['_vcRef'].remove(this.dpk['_vcRef'].indexOf(this.dpk['_cRef'].hostView));
this.dpk['_cRef'] = null;
this.dpk['_closed$'].next();
// custom code
console.log('closed');
}
};
}

Computationally bind styles in Angular

Using Angular5 - I know how it is possible to bind an HTML element's style to a Boolean value, but I can't find an explanation to do this for multiple styles at the same time.
ie. I have found something like this works fine:
[style.background]="r.favourite === true ? '#3f51b5' : 'white'"
However I am also wanting to change the color of my text to white at this point also... And I don't want to clutter my components with lots of [style.xxx] tags.
Is there a way I can dynamically bind to a CSS class to apply when r.favourite === true?
I have seen ways in which this can be done... However this assumes you are binding within the same file as such:
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `
<button class="my-btn" [class.extraclass]="someProperty">Call to Action</button>
`,
styles: [`
.my-btn { font-size:1.7em; }
.extraclass { background: black; color: white; }
`]
})
export class AppComponent {
someProperty = true;
}
However my CSS is being stored in a shared file - such that I have a file structure like:
import { Component } from '#angular/core';
#Component({
selector: 'my-component',
styleUrls: ['./css/shared-styles.css']
template: `
<button class="my-btn" [class.extraclass]="someProperty">Call to Action</button>
`
})
export class MyComponent {
someProperty = true;
}
You can use NgClass.
<div [ngClass]="{'text-success':r.favourite ,'text-danger':!r.favourite}">
Where 'text-success' and 'text-danger' are classes you define.
Please refer to this great article about NgClass and NgStyle:
https://codecraft.tv/courses/angular/built-in-directives/ngstyle-and-ngclass/
Hope this helps