I have a Stepper from #Angular/Material and it looks great. However, I see many example that have only the current step opened up. I would like this functionality. All inactive steps should be closed.
[EDIT]: Just added in the HTML and TS file.
Component HTML File
<img width="350px" align="middle" mat-card-image src="../assets/Icon_Rev8.png" alt="Logo">
<mat-card-content>
<mat-tab-group mat-stretch-tabs [selectedIndex]="0" dynamicHeight=true>
<mat-tab label="Login">
<form>
<mat-form-field class="sameWidth">
<input matInput style="width:100%;" placeholder="Username">
</mat-form-field>
<mat-form-field class="sameWidth">
<input matInput style="width:100%;" placeholder="Password">
</mat-form-field>
</form>
<button class="sameWidth" mat-raised-button color="primary">Login</button>
<button class="sameWidth" mat-button color="primary">Forgot Password?</button>
</mat-tab>
<mat-tab label="Register">
<mat-progress-spinner mode="indeterminate"></mat-progress-spinner>
<mat-vertical-stepper [linear]=true>
<mat-step [stepControl]="firstFormGroup">
<form [formGroup]="firstFormGroup">
<ng-template matStepLabel>Fill out your name</ng-template>
<mat-form-field>
<input matInput placeholder="Last name, First name" formControlName="firstCtrl" required>
</mat-form-field>
<div>
<button mat-button matStepperNext>Next</button>
</div>
</form>
</mat-step>
<mat-step [active]="true" [stepControl]="secondFormGroup">
<form [formGroup]="secondFormGroup">
<ng-template matStepLabel>Fill out your address</ng-template>
<mat-form-field>
<input matInput placeholder="Address" formControlName="secondCtrl" required>
</mat-form-field>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button matStepperNext>Next</button>
</div>
</form>
</mat-step>
<mat-step>
<ng-template matStepLabel>Done</ng-template>
You are now done.
<div>
<button mat-button matStepperPrevious>Back</button>
</div>
</mat-step>
</mat-vertical-stepper>
<!--<form>
<table cellspacing="0">
<tr>
<td>
<mat-form-field>
<input style="width: 40%;" matInput placeholder="First Name">
</mat-form-field>
</td>
<td>
<mat-form-field>
<input style="width: 40%;" matInput placeholder="Last name">
</mat-form-field>
</td>
</tr>
</table>
<mat-form-field style="width:100%;">
<input matInput placeholder="Password">
</mat-form-field>
</form>-->
<mat-checkbox style="z-index: 1000;" color="primary">I Agree to the Terms and Conditions</mat-checkbox>
<button class="sameWidth" mat-raised-button color="primary">Register</button>
</mat-tab>
</mat-tab-group>
</mat-card-content>
Component TS File
import { Component, OnInit, ViewEncapsulation, Inject } from "#angular/core";
import {
MatIconRegistry,
MatDialog,
MatDialogRef,
MAT_DIALOG_DATA
} from "#angular/material";
import { DomSanitizer } from "#angular/platform-browser";
import { HttpClientModule, HttpClient } from "#angular/common/http";
import { FormBuilder, FormGroup, Validators } from "#angular/forms";
#Component({
selector: "app-login",
templateUrl: "login.component.html",
styleUrls: ["login.component.css"]
})
export class LoginComponent {
animal: string;
name: string;
constructor(
private _formBuilder: FormBuilder,
iconRegistry: MatIconRegistry,
sanitizer: DomSanitizer,
public dialog: MatDialog
) {
iconRegistry.addSvgIcon(
"close",
sanitizer.bypassSecurityTrustResourceUrl(
"assets/icons/ic_close_48px.svg"
)
);
}
openDialog(): void {
let dialogRef = this.dialog.open(LoginDialogComponent, {
width: "400px",
data: { name: this.name, animal: this.animal }
});
dialogRef.afterClosed().subscribe(result => {
console.log("The dialog was closed");
this.animal = result;
});
}
}
#Component({
selector: "dialog-login",
templateUrl: "loginDialog.component.html",
styleUrls: ["loginDialog.component.css"]
})
export class LoginDialogComponent {
constructor(
private _formBuilder: FormBuilder,
public dialogRef: MatDialogRef<LoginDialogComponent>,
#Inject(MAT_DIALOG_DATA) public data: any
) {}
onNoClick(): void {
this.dialogRef.close();
}
ngOnInit() {
this.firstFormGroup = this._formBuilder.group({
firstCtrl: ["", Validators.required]
});
this.secondFormGroup = this._formBuilder.group({
secondCtrl: ["", Validators.required]
});
}
}
My Current Status:
My Goal:
There is no official fix yet. I have submitted a bug-report and it is being looked into. For now I have researched and found a workaround for this issue. I had to add (selectionChange)="cambiaStep($event)" as an attribute to my <mat-vertical-stepper> tag. Then I had to add a <ng-container> under all of my <mat-step> tags. In each corresponding <ng-container>, I had to set an attribute based on which position it had in the stepper order. In each <ng-container> I had to add *ngIf="stepIndex === 0" but the 0 was based on its order in the steps (0: first, 1: second, 2: third, etc.)
My stepper ended up having code as such:
<mat-vertical-stepper (selectionChange)="cambiaStep($event)">
<mat-step>
<ng-container *ngIf="stepIndex === 0">
</ng-container>
</mat-step>
<mat-step>
<ng-container *ngIf="stepIndex === 1">
</ng-container>
</mat-step>
<mat-step >
<ng-container *ngIf="stepIndex === 2">
</ng-container>
</mat-step>
</mat-vertical-stepper>
I also had to add the event function in my component's *.ts file.
export class LoginDialogComponent {
stepIndex: number = 0;
cambiaStep(e) {
this.stepIndex = e.selectedIndex;
}
constructor() {}
}
I just copy pasted your code in default angular-material stepper code and it's showing like your goal
https://stackblitz.com/edit/angular-tpeo6s?embed=1&file=app/stepper-overview-example.html
Edit
It seems angular material bug to me.
if stepper is put out of tabs, it is working but inside tab, though aria-expanded="false" for inactive steps , material is not adding style="height: 0px; visibility: hidden;" to hide inactive steps.
you can log issues related to angular material 2 HERE
Related
I am trying to push edited form data from edit-customers-dialog.ts to an array of objects in my datasource. The form.data.value comes back correctly, but it is not being inserted into the array properly.
I am having trouble finding the correct syntax on pushing to an interface data type. Please help as I'm new to angular. Thanks!
customers.html
<mat-card-title>
<button id="invite" mat-raised-button color="primary" type="button" (click)="addCustomer()">
Add Customer
</button>
</mat-card-title>
<mat-card-content>
<table mat-table [dataSource]="dataSource.data" class="mat-elevation-z8">
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let row"> {{row.name}} </td>
</ng-container>
<!-- Address Column -->
<ng-container matColumnDef="address">
<th mat-header-cell *matHeaderCellDef> Address </th>
<td mat-cell *matCellDef="let row"> {{row.address}}</td>
</ng-container>
<!-- Actions Column -->
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef> Actions </th>
<td mat-cell *matCellDef="let row">
<ng-container>
<button id="edit" mat-icon-button color="primary" title="Update Customer" (click)="editCustomer(row)" >
<mat-icon>edit</mat-icon>
</button>
<button id="delete" mat-icon-button color="warn" title="Delete Customer" (click)="deleteCustomer(row)">
<mat-icon>delete</mat-icon>
</button>
</ng-container>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator
showFirstLastButtons
[length] = "0"
[pageSizeOptions]="[25, 50, 75]"
>
</mat-paginator>
</mat-card-content>
</mat-card>
customers.component.ts
import {MatTableDataSource} from '#angular/material/table';
import { MatPaginator } from '#angular/material/paginator';
import { MatSort } from '#angular/material/sort';
import { MatDialog, MatDialogConfig, MatDialogRef} from '#angular/material/dialog/';
import { AddCustomerDialogComponent } from '../customers/add-customer-dialog/add-customer-dialog.component';
import { EditCustomerDialogComponent } from '../customers/edit-customer-dialog/edit-customer-dialog.component';
import {CustomerDataSource, CustomerListItem } from './customer.datasource';
#Component({
selector: 'app-customers',
templateUrl: './customers.component.html',
styleUrls: ['./customers.component.css']
})
export class CustomersComponent implements OnInit {
#ViewChild(MatPaginator) paginator: MatPaginator;
#ViewChild (MatSort) sort: MatSort;
dataSource: CustomerDataSource;
customer: CustomerListItem [];
displayedColumns: string[]
constructor(
public dialog: MatDialog) {}
ngOnInit() {
this.displayedColumns = ['name', 'address', 'actions'];
this.dataSource = new CustomerDataSource (this.paginator, this.sort,
);
}
editCustomer(customer: CustomerListItem){
const dialogRef = this.dialog.open(EditCustomerDialogComponent, <MatDialogConfig> {
data: customer,
});
dialogRef.afterClosed()
.subscribe(result => {
this.dataSource.data.push({name, address: ''})
console.log('The dialog was closed');
console.log(this.dataSource.data);
});
}
deleteCustomer(customer: CustomerListItem){
if(confirm('Are you sure you want to delete this customer?'))
{
this.dataSource.data = this.dataSource.data.filter(person => person.name != customer.name);
}
}
}
edit-customer-dialog.html
<h2 mat-dialog-title>
Edit Customer
</h2>
<form *ngIf="form" [formGroup]="form" (ngSubmit)="onSubmitForm()">
<mat-dialog-content class="container">
<mat-form-field>
<input matInput placeholder="Name" formControlName ="name" required/>
</mat-form-field>
<mat-form-field class="input">
<input id="placeholder" matInput placeholder="Address" formControlName ="address" required/>
</mat-form-field>
</mat-dialog-content>
<mat-dialog-actions>
<button
id="add"
mat-button
mat-raised-button
color="primary"
type="submit"
>
Update
</button>
<button id="cancel" mat-button mat-raised-button color="warn" mat-dialog-close>Cancel</button>
</mat-dialog-actions>
</form>
edit-customer-dialog-comptent.ts
import { Component, OnInit, Inject } from '#angular/core';
import { FormBuilder, FormGroup, FormControl, Validators } from '#angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef} from '#angular/material/dialog/';
import {MatTableDataSource} from '#angular/material/table';
import { MatPaginator } from '#angular/material/paginator';
import { CustomerDataSource, CustomerListItem } from '../customer.datasource';
#Component({
selector: 'app-edit-customer-dialog',
templateUrl: './edit-customer-dialog.component.html',
styleUrls: ['./edit-customer-dialog.component.css']
})
export class EditCustomerDialogComponent implements OnInit {
form: FormGroup;
customer: CustomerListItem [];
constructor(
#Inject (MAT_DIALOG_DATA) public data: any,
private dialogRef: MatDialogRef<EditCustomerDialogComponent>,
private formBuilder: FormBuilder
) {}
ngOnInit() {
// Intitlaize the form
this.form = this.formBuilder.group({
name: this.data.name,
address: this.data.address
})
console.log(this.form.value);
}
onSubmitForm(){
// Update Customer
console.log(this.form.value);
this.dialogRef.close(this.form.value);
}
}
datasource array:
export interface CustomerListItem {
name: string;
address: string;
}
// TODO: replace this with real data from server
const EXAMPLE_DATA: CustomerListItem[] = [
{ name: 'Michael Jordan', address: '1111 Grail St. Concord MI 98076' },
{ name: 'Jeremy Scott', address: '7690 Wing Drive. Adidas, MI' },
{ name: 'Hiroki Nakamura', address: '980 Air Force Rd. Jubilee, MI' },
{ name: 'James Bond', address: '654 Depop Dr. Chicago, MI' },
{ name: 'Bill Bowerman', address: '1811 Hill St. Converse, MI' },
{ name: 'Clyde Frazier', address: '3333 Cement Ln. Jordan, MI'},
{ name: 'Jeff Staple', address: '4444 Black Cat Ct. Jordan,MI' },
{ name: 'Sophia Chang', address: '2006 Citrus Rd. Seven, MI'},
];
Add let i = index and pass i to the edit function
<td mat-cell *matCellDef="let row; let i = index;">
<ng-container>
<button id="edit" mat-icon-button color="primary" title="Update Customer" (click)="editCustomer(row, i)" >
<mat-icon>edit</mat-icon>
</button>
</ng-container>
</td>
editCustomer(customer: CustomerListItem, i: number){
}
Try reinitializing the data after the edit.
this.dataSource.data[i] = result;
this.dataSource.data = this.dataSource.data;
OR
const temp = this.dataSource.data;
temp[i] = result;
this.dataSource.data = temp;
I have angular in front end and node.js in back end
I used angular material form stepper, it has 3 forms form1, form2, form3 for each step, on the last step
I need to join all objects in to one and post it to Node.js, I am new any help will be appreciated thanks.
bellow is my code:
<mat-horizontal-stepper linear #stepper>
<mat-step [stepControl]="firstFormGroup">
<form [formGroup]="firstFormGroup" #personalInfo="ngForm" (ngSubmit)="form1()">
<ng-template matStepLabel>Personal Information</ng-template>
<mat-form-field>
<input matInput placeholder="Surname/Family name" formControlName="lastnameCtrl" required>
</mat-form-field>
<br />
<mat-form-field>
<input matInput placeholder="First name" formControlName="firstnameCtrl" required>
</mat-form-field>
<br />
<mat-form-field>
<mat-label>Gender</mat-label>
<mat-select [formControl]="genderControl" required>
<mat-option></mat-option>
<mat-option *ngFor="let gender of genders" [value]="gender">
{{gender.value}}
</mat-option>
</mat-select>
<mat-error *ngIf="genderControl.hasError('required')">Please choose gender</mat-error>
</mat-form-field>
<div>
<!-- <button [disabled]="personalInfo.invalid" mat-raised-button color="warn" matStepperNext type="submit" >Save & continue</button> -->
<button mat-raised-button color="primary" matStepperNext>Next</button>
</div>
</form>
</mat-step>
<mat-step [stepControl]="secondFormGroup" [optional]="isOptional">
<form [formGroup]="secondFormGroup" #programAvailability="ngForm" (ngSubmit)="form2()">
<ng-template matStepLabel>Program Availability</ng-template>
<mat-form-field>
<input matInput placeholder="Email" formControlName="emailCtrl" required>
</mat-form-field>
<div>
<button mat-raised-button matStepperPrevious>Back</button>
<button mat-raised-button color="primary" matStepperNext>Next</button>
</div>
</form>
</mat-step>
<mat-step>
<form [formGroup]="thirdFormGroup" #programAvailability="ngForm" (ngSubmit)="form3()">
<ng-template matStepLabel>Confirm & submit</ng-template>
<mat-checkbox formControlName="agreementCtrl" (change)="changeCheck($event)"> I agree to....</mat-checkbox>
<div>
<button mat-raised-button matStepperPrevious>Back</button>
<button mat-raised-button [disabled]="disabledAgreement" color="primary" matStepperNext type="submit" >Submit</button>
<button mat-raised-button color="warn" (click)="stepper.reset()">Reset</button>
</div>
</form>
</mat-step>
and my component code is here:
import { Component, OnInit} from '#angular/core';
import { merge } from 'rxjs';
import {FormBuilder,FormControl, FormGroup, Validators} from '#angular/forms';
import{AgentService} from '../../services/agent.service';
import {PersonalData,ContactRequest, Agent} from '../../models/applicant.model';
import {ApplicantService} from '../../services/applicant.service';
#Component({
selector: 'app-manage-agent',
templateUrl: './manage-agent.component.html',
styleUrls: ['./manage-agent.component.css']
})
export class ManageAgentComponent implements OnInit {
firstFormGroup: FormGroup;
secondFormGroup: FormGroup;
thirdFormGroup:FormGroup;
selectedValue: string;
isEditable = false;
constructor(private agentService:AgentService,private _formBuilder: FormBuilder,private service:ApplicantService) { }
genderControl = new FormControl('', [Validators.required]);
genders: Gender[] = [
{value: 'Male', viewValue: 'Male'},
{value: 'Female', viewValue: 'Female'}
];
ngOnInit() {
//this.agentService.getNode();
this.firstFormGroup = this._formBuilder.group({
lastnameCtrl: ['', Validators.required],
firstnameCtrl: ['', Validators.required]
//genderCtrl: ['', Validators.required]
});
this.secondFormGroup = this._formBuilder.group({
emailCtrl: ['', Validators.required]
});
this.thirdFormGroup = this._formBuilder.group({
agreementCtrl: ['', Validators.required]
});
}
disabledAgreement: boolean = true;
changeCheck(event){
this.disabledAgreement = !event.checked;
}
form1(){
console.log(this.firstFormGroup.value);
}
form2(){
console.log(this.secondFormGroup.value);
}
form3(){
if(this.firstFormGroup.valid && this.secondFormGroup.valid && this.thirdFormGroup.valid){
console.log('----form is valid----');
console.log(this.firstFormGroup.value);
console.log(this.secondFormGroup.value);
console.log(this.thirdFormGroup.value);
const f1 = this.firstFormGroup.value;
const f2 = this.secondFormGroup.value;
const f3 = this.thirdFormGroup.value;
if(this.service.formData.Id==0){
this.insertRecord(form);
}
//---------Update Record---------//
else{
this.UpdateRecord(form);
this.resetForm();
}
}else{
console.log('--- form is invalid');
}
}
You can merge values from forms at the moment you are "commiting" the changes.
if(this.firstFormGroup.valid && this.secondFormGroup.valid && this.thirdFormGroup.valid){
const result = Object.assign({}, this.firstFormGroup.value, this.secondFormGroup.value, this.thirdFormGroup.value);
if(this.service.formData.Id==0){
this.insertRecord(result);
} else {
this.UpdateRecord(result);
this.resetForm();
}
}else{
console.log('--- form is invalid');
}
please look image description hereI need to create a multi step form without using Angular UI Router & angular material.
could any one help me.
<div class="wizard">
<a routerLinkActive="active" [routerLink]="['/customer-dashboard/customer-information/information-form']" [routerLinkActiveOptions]="{exact: true}">
Submit Information
</a>
<a [class.disabled]="idTab" routerLinkActive="active" [routerLink]="['/customer-dashboard/customer-information/id-form']" [routerLinkActiveOptions]="{exact: false}">
Submit Id
</a>
<a routerLinkActive="active" [routerLink]="['/customer-dashboard/customer-information/verify-identity']" [routerLinkActiveOptions]="{exact: false}">
Verify Identity
</a>
<a routerLinkActive="active" [routerLink]="['/customer-dashboard/customer-information/final-validation']" [routerLinkActiveOptions]="{exact: false}">
Final Validation
</a>
<a routerLinkActive="active" [routerLink]="['/customer-dashboard/customer-information/approval']" [routerLinkActiveOptions]="{exact: false}">
Approval
</a>
</div>
working CodesandBox
app.component.html
<div>
<span class="state-container" [ngStyle]="state === 1 && {'color': 'red'}"
>state 1</span
>
<span class="state-container" [ngStyle]="state === 2 && {'color': 'red'}"
>state 2</span
>
<span class="state-container" [ngStyle]="state === 3 && {'color': 'red'}"
>state 3</span
>
</div>
<div *ngIf="state === 1">
<form #f1="ngForm" (ngSubmit)="onSubmit(user)" novalidate>
<label for="name">Name</label>
<input name="name" id="name" [(ngModel)]="user.name" />
<label for="family">Family</label>
<input name="family" id="family" [(ngModel)]="user.family" />
<button (click)="next(user)">Next</button>
</form>
</div>
<div *ngIf="state === 2">
<form #f2="ngForm" (ngSubmit)="onSubmit(user)" novalidate>
<label for="address">Address</label>
<input name="address" id="family" [(ngModel)]="user.address" />
<button (click)="back()">Back</button>
<button (click)="next(user)">Next</button>
</form>
</div>
<div *ngIf="state === 3">
<p>The End</p>
<button (click)="back()">Back</button>
<button (click)="reset()">Reset</button>
<button (click)="save(user)">Save</button>
</div>
app.component.ts
import { Component, OnInit } from "#angular/core";
interface User {
name: string;
family: string;
address: string;
}
#Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
title = "CodeSandbox";
state = 1;
user: User;
ngOnInit() {
this.user = {
name: "",
family: "",
address: ""
};
}
save(user: User) {
alert("Final Result:\n\n" + JSON.stringify(user));
}
next(user: User) {
++this.state;
alert(JSON.stringify(user));
}
back() {
--this.state;
}
reset() {
this.state = 1;
this.user = {
name: "",
family: "",
address: ""
};
}
}
app.module.ts
import { BrowserModule } from "#angular/platform-browser";
import { NgModule } from "#angular/core";
import { AppComponent } from "./app.component";
import { FormsModule } from "#angular/forms";
#NgModule({
declarations: [AppComponent],
imports: [BrowserModule, FormsModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
I personally don't recommend this approach. Just remember, If you don't save the data and refresh the page your data is gone.
Have the below ngx-datatable where I want to have the first row expanded on view load. I have tried to call the toggleExpandRow(this.table.row[0]) on the angular lifecycle hook ngAfterViewChecked and the template is not getting updated with the row expanding. Has anyone accomplished this before with ngx-datatable? The below code does not run and is there for information purposes only.
import {
Component,
Input,
Output,
EventEmitter,
OnInit,
ChangeDetectionStrategy,
ViewEncapsulation,
ViewChild
} from '#angular/core';
import { defaultTrackByFn } from '#shared/utils';
import { Datatable } from '#app/stores/dashboard-store/models/datatable.model';
import { DatatableComponent as ngxDatatableComponent } from '#swimlane/ngx-datatable';
import { Observable } from 'rxjs';
import { ActiveToggleService } from '#dashboard/services/ActiveToggle.service';
#Component({
selector: 'fmsl-datatable',
templateUrl: './datatable.component.html',
styleUrls: ['./datatable.component.scss'],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DatatableComponent implements OnInit {
#Input()
datatable: Datatable;
#Input()
isBorrower: boolean;
#ViewChild('loanTable')
table: ngxDatatableComponent;
#Input()
showLegend: boolean = true;
trackByFn: Function = defaultTrackByFn;
// TODO: Implement Datatable Actions
actions = ['replace with logic later'];
isBorrower$: Observable<boolean>;
constructor(private _toggleService: ActiveToggleService) {}
ngOnInit() {
// console.log('table:', this.table)
// console.log('table row detail', this.table.rowDetail)
// this.table.rowDetail.expandAllRows();
}
ngAfterViewChecked() {
console.log('table:', this.table)
console.log('table row detail', this.table.rowDetail)
console.log('table row:', this.table._rows[0])
this.table.rowDetail.toggleExpandRow(this.table._rows[0]);
}
toggleExpandRow(row) {
console.log('row toggled', row);
console.log('row table', this.table);
this.table.rowDetail.toggleExpandRow(row);
}
onDetailToggle(event) {
// on row detail expand we can do something
}
toggleActiveInactive(row) {
const { uuid, loanStatusTypeName } = row;
this._toggleService.toggleActiveInactive({ uuid, loanStatusTypeName });
}
}
<div class="row datatable-row">
<div class="col">
<!--mdc-replace datatable-->
<div [ngClass]="datatable.tableClass">
<!-- {{ datatable | json }} -->
<ngx-datatable
#loanTable
class="material expandable"
[rows]="datatable.rows"
[columnMode]="'flex'"
rowHeight="auto"
sortType="single"
[headerHeight]="42"
[footerHeight]="0"
[scrollbarH]="true"
[footerHeight]="0"
[loadingIndicator]="datatable.loading"
[messages]="datatable.messages"
>
<ngx-datatable-row-detail [rowHeight]="44" (toggle)="onDetailToggle($event)">
<ng-template
let-row="row"
let-expanded="expanded"
ngx-datatable-row-detail-template
>
<div class="expansion-row" style="padding-left:35px;">
<mdc-icon class="material-icons" aria-hidden="true">info_outline</mdc-icon>
<span
[innerHTML]="row.statusProperties.statusDetail"
class="datatable__expansion-row-message"
></span>
</div>
</ng-template>
</ngx-datatable-row-detail>
<ngx-datatable-column
[width]="50"
[resizeable]="false"
[sortable]="false"
[draggable]="false"
[canAutoResize]="false"
>
<ng-template let-row="row" let-expanded="expanded" ngx-datatable-cell-template>
<a
href="javascript:void(0)"
[class.datatable-icon-right]="!expanded"
[class.datatable-icon-down]="expanded"
title="Expand/Collapse Row"
(click)="toggleExpandRow(row)"
>
</a>
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column
*ngFor="let col of datatable.columns; index as i; trackBy: trackByFn"
[name]="col.name"
resizeable="false"
[flexGrow]="col.flex"
[prop]="col.prop"
[pipe]="col.pipe"
>
<ng-template let-column="column" ngx-datatable-header-template let-expanded="true">
{{ col.name }}
</ng-template>
<ng-template let-row="row" let-value="value" ngx-datatable-cell-template>
<div class="table-cell justify-content-start" [attr.data-heading]="col.name">
<span *ngIf="col.isIcon; else progressCell">
<fmsl-datatable-icon
*ngIf="value"
[actionRequiredBy]="value"
[legend]="datatable.legend"
[currentRole]="datatable.currentRole"
></fmsl-datatable-icon>
</span>
<div *ngIf="col.isActions" class="rowActions">
<button mdc-button (click)="toggleActiveInactive(row)">
Mark {{ row.loanStatusTypeName === 'active' ? 'Inactive' : 'Active' }}
</button>
</div>
<ng-template #progressCell>
<div *ngIf="col.isProgress; else linkCell" class="progress-container">
<mdc-linear-progress
class="progress-bar loan-status-progress-bar"
[determinate]="true"
[progress]="value"
></mdc-linear-progress>
</div>
</ng-template>
<ng-template #linkCell>
<span *ngIf="col.isLink; else valueCell">
<a
*ngIf="row.sharePointURL; else internalLink"
target="_blank"
href="{{ row.sharePointURL }}"
>{{ value }}
</a>
<ng-template #internalLink>
<a [routerLink]="['/dashboard/deal', 'loan-request-info', row.uuid]">{{
value
}}</a>
</ng-template>
</span>
</ng-template>
<ng-template #valueCell>
<span>{{ value }}</span>
</ng-template>
</div>
</ng-template>
</ngx-datatable-column>
</ngx-datatable>
</div>
</div>
</div>
There is an open issue https://github.com/swimlane/ngx-datatable/issues/929 while using toggle functions with onInit and afterViewInit hooks.
To call toggle function inside ngAfterViewChecked is not a good idea, as this hook will be called multiple times. And once you get it expanded, you cannot collapse it.
Still there is a dirty workaround to call the toggle function inside AfterViewInit within setTimeout:
#ViewChild(DatatableComponent) private table: DatatableComponent;
constructor(private cdRef: ChangeDetectorRef) {}
setTimeout(() => {
this.table.rowDetails.toggleExpandedRow(ROW);
this.cdRef.detectChanges();
}, 1000);
The Ionic 2 Documentation doesn't really explain on how to use ion-toggle. I would like to take the values from the On Checkbox/Toggle to next page/state.
Please help in understanding.
TypeScript
import { Component } from '#angular/core';
import { NavController, NavParams, LoadingController } from 'ionic-angular';
import { Apis } from '../../app/apis';
import { BookingConfirmationPage } from '../booking-confirmation/booking-confirmation';
#Component({
selector: 'page-booking-enhancement',
templateUrl: 'booking-enhancement.html',
providers: [Apis]
})
export class BookingEnhancementPage {
constructor(public navCtrl: NavController, public navParams: NavParams, public loadingCtrl: LoadingController, public Apis: Apis ) {
}
}
HTML
<ion-grid>
<ion-row *ngFor="let item of extra" class="row-extra">
<ion-col width-10>
<ion-toggle class="switcher display-block" color="secondary"></ion-toggle>
</ion-col>
<ion-col width-67 class="description">{{ item.description }}</ion-col>
<ion-col width-23 style="text-align: right;">
<div class="rate text-center display-block">${{ item.rate }}</div>
<div class="qty text-center display-block"><input type="number" class="text-center"/></div>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-col width-100 class="text-center"><button type="submit" class="continue" (click)="ContinueBookingConfirmation()">Continue</button></ion-col>
</ion-col>
</ion-row>
</ion-grid>