I'm new to Ionic and I would like to know how I can pass data that is in between the <p></p> HTML tag to my home.ts file. I have tried doing getElementById but that doesn't seem to work. Also ViewChild but with zero results. I'd like to have some help concerning this question.
From .ts -> html :
.ts-> varString : String = "Hallo world";
html-> {{varString}}
From html -> .ts depends of html tag
Ex. <input type=“text” name=“username” [(ngModel)]=“username”>
username is username : String = ""; and it changes avry time you update the input. Similar to other html tags. You can also get elements by id or class using Element of ionic angular
there is many way to pass data between html and ts, but you must have good understand about MVC design pattern. the MVC is the reason of why google introduced angular.
in angular (engine of ionic), your View(html in your project) knows everything about controller(ts file).
***** home.ts********
public MyName:string="jon";
MyFunc1()
{
alert(this.MyName);
}
MyFunc2()
{
this.MyName="other name";
alert(this.MyName);
}
*****home.html*******
<input type="text" [(ngModel)]="MyName" >
<p>{{MyName}}</p>
<button ion-button (click)="MyFunc1()" >MyFunc1</button>
<button ion-button (click)="MyFunc2()" >MyFunc2</button>
.
.
.
if you change the value of MyName in ts, then it will change automatically in html and also if you change you input value (that it is binded to MyName) it will change the MyName value in model (in ts).
Selecting DOM in ionic isn't a right way to change models value.
Taking the simple example of a Login page,
<ion-item>
<ion-label floating color="primary">Registered Email ID</ion-label>
<ion-input [(ngModel)]="login.email" name="email" type="text" #email="ngModel" spellcheck="false" autocapitalize="off"
required>
</ion-input>
</ion-item>
<ion-item>
<ion-label floating color="primary">Passcode</ion-label>
<ion-input [(ngModel)]="login.passcode" name="password" type="password" #password="ngModel" required>
</ion-input>
</ion-item>
The .ts code for this would be:
login= { username: '', email:'', mobile:'', passcode:'' };
That is literally it!
You can also go about without the login object and can declare variables like
username: any
email: any
and so on; and directly reference them in the html as
[(ngModel)]="username"
Hope it helps!
First try to understand that when you are working on Ionic, you are working on Angular but not Core Javascript.
and here is simple example that may help
home.html
import {Component} from '#angular/core';
import {NavController, AlertController} from 'ionic-angular';
#Component({
templateUrl: 'build/pages/home/home.html'
})
export class HomePage {
name: string;
constructor(public navCtrl: NavController, private alertController: AlertController) {
}
showName() {
console.log(this.name);
let alert = this.alertController.create({
title: 'Hello ' + this.name + '!',
buttons: ['OK']
});
alert.present();
}
}
home.ts
<ion-header>
<ion-navbar>
<ion-title>
Ionic Blank
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-label>{{ name }}</ion-label>
<ion-input [(ngModel)]="name"></ion-input>
<button (click)="showName()">Click Me</button>
</ion-content>
Related
I am trying to take amount to be transacted as input from user deduct it from the wallet of the user and then display the updated wallet. The wallet already is pre-loaded with 100 units of money. But when I run the app only 100 is displayed and the changes are not reflected. what do I do ?
Here is my html code
<ion-row>
<ion-col class="txt2" size="6" text-left >Company<br><ion-text class="bal">Balance & gms</ion-text>
</ion-col>
<ion-col class="text2" size="6" text-right ><ion-item><ion-input type="number" value="{{ wallet }}" [(ngModel)]="wallet" class="ion-text-end"></ion-input>
</ion-item>
</ion-col>
</ion-row>
<ion-item class="transact-display">
<ion-input type="number" placeholder="Enter amount" [(ngModel)]="amount" name="amount"></ion-input>
</ion-item>
<ion-button class="transact" type="submit" expand="block" (click)="transact()">Transact</ion-button>
The ts file
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
#Component({
selector: 'app-transaction',
templateUrl: './transaction.page.html',
styleUrls: ['./transaction.page.scss'],
})
export class TransactionPage implements OnInit {
constructor(public router : Router) {}
wallet: number = 100;
amount: number ;
ngOnInit() {
}
transact() {
this.router.navigateByUrl('/congratulation');
this.wallet = this.wallet - this.amount;
return this.wallet;
}
}
Actual behaviour:
No change in the displayed amount. 100 is only displayed even after the Transact button is clicked.
Expected behaviour:
when the user logs in for the 1st time, 100 should be displayed. When the user transacts amount, say 20, 20 should be deducted from 100 and 80 should be displayed.
Angular is 2 way data binding framwwork:
Use Angular interpolation:
.html
<ion-item>
{{wallet}}
</ion-item>
<ion-item class="transact-display">
<ion-input type="number" placeholder="Enter amount" [(ngModel)]="amount" name="amount"></ion-input>
</ion-item>
<ion-button class="transact" type="submit" expand="block" (click)="transact()">Transact</ion-button>
.ts
wallet: number = 100;
amount: number ;
ngOnInit() {
}
transact() {
this.wallet = this.wallet - this.amount; // this will update wallet automatically.
this.router.navigateByUrl('/congratulation');
}
I am getting the number values from the ion-select and input a number in the ion-input. How can I display the selected value and the input value from the original page to another page?
I am using ionic 4
<ion-item>
<ion-input #user2 type="tel" maxlength="14" minlength="4" [(ngModel)]="numpad"
name="userCount" (keypress)="numberOnlyValidation($event)"></ion-input>
</ion-item>
<ion-item (click)="openSelect()">
<ion-input [(ngModel)]="selectedCode"></ion-input>
</ion-item>
<ion-item style="display: none">
<ion-select #select1 [(ngModel)]="selectedCode">
</ion-select>
</ion-item>
Here's one solution. Assume the input is in home.page and the values will be routed to page2.page.
Update app-routing.module.ts and add a new route
{
path: 'page2/:code/:numpad',
loadChildren: () => import('./page2/page2.module').then( m => m.Page2PageModule)
},
Then you will want to take the values from home.page and navigate to page 2. There are a few different way to do this. In the example below I'm just using ionChange to call a function to route to page2.
home.page.ts
<ion-item>
<ion-input #user2 type="tel" maxlength="14" minlength="4" [(ngModel)]="numpad" name="userCount"></ion-input>
</ion-item>
<ion-item>
<ion-select [(ngModel)]="selectedCode" (ionChange)="valueChangedSoRouteToPage2()">
<ion-select-option *ngFor="let user of users" [value]="user.id">{{user.first + ' ' + user.last}}</ion-select-option>
</ion-select>
</ion-item>
Then in home.page.ts you can do something like this
valueChangedSoRouteToPage2() {
console.log('changed');
console.log(this.selectedCode);
console.log(this.numpad);
this.router.navigateByUrl('/page2/' + this.selectedCode + '/' + this.numpad);
}
Last step - update page2.page.ts
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-page2',
templateUrl: './page2.page.html',
styleUrls: ['./page2.page.scss'],
})
export class Page2Page implements OnInit {
page2Code;
page2Numpad;
constructor(private activatedRoute: ActivatedRoute) { }
ngOnInit() {
this.page2Code = this.activatedRoute.snapshot.paramMap.get("code");
this.page2Numpad = this.activatedRoute.snapshot.paramMap.get("numpad");
console.log('code: ' + this.page2Code);
console.log('numpad: ' + this.page2Numpad);
}
}
Hope this helps.
In my ionic select i got output like small down arrow rather than a full select tag and for input tag just a blank space. I can enter data but UI not looks good. Is there any css i need to add.
<ion-card class='sc-ion-card-md-h'>
<ion-card-header>
<ion-card-subtitle>Name:</ion-card-subtitle>
<ion-card-title>
<ion-select #inputName id="username" class="form-control">
<ion-select-option>SELECT</ion-select-option>
<ion-select-option>Monicka</ion-select-option>
<ion-select-option>Hema</ion-select-option>
<ion-select-option>Ramesh</ion-select-option>
<ion-select-option>Madhavan</ion-select-option>
<ion-select-option>Aadhavan</ion-select-option>
<ion-select-option>Madhan</ion-select-option>
<ion-select-option>Prasanth</ion-select-option>
</ion-select>
</ion-card-title>
</ion-card-header>
<ion-card-header>
<ion-card-subtitle>Date:</ion-card-subtitle>
<ion-card-title>
<ion-input type="text" #inputDate id="date" class="form-control"></ion-input>
</ion-card-title>
</ion-card-header>
</ion-card>
Output looks like this...
It seems like you are trying to convert a Bootstrap form over to Ionic and you are bringing some jQuery thinking along with it.
This is how you would do it with an Ionic page:
page.html
<ion-header>
<ion-toolbar>
<ion-title>card-select</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-card>
<ion-list>
<ion-item>
<ion-label position="stacked">Name:</ion-label>
<ion-select [(ngModel)]="username" placeholder="SELECT">
<ion-select-option>Monicka</ion-select-option>
<ion-select-option>Hema</ion-select-option>
<ion-select-option>Ramesh</ion-select-option>
<ion-select-option>Madhavan</ion-select-option>
<ion-select-option>Aadhavan</ion-select-option>
<ion-select-option>Madhan</ion-select-option>
<ion-select-option>Prasanth</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label position="stacked">Date:</ion-label>
<ion-input [(ngModel)]="date"></ion-input>
</ion-item>
</ion-list>
</ion-card>
</ion-content>
page.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-card-select',
templateUrl: './card-select.page.html',
styleUrls: ['./card-select.page.scss'],
})
export class CardSelectPage implements OnInit {
username: string;
date: string;
constructor() { }
ngOnInit() {
}
}
notes
You don't need all those classes you put on.
Using label position="stacked" puts it above the input.
You dont need to bind the name like #username or id="username". What you do is put a variable on the page behind it and then use ngModel to bind to it. Any change that is made to the user interface (typing into a box, selecting an option) is then automatically set to the variable in the page. This works both ways because of the [()] syntax, so if you change username with something like this.username = "superman"in the code then the input box on the page will automatically update to match that value as well.
You don't need type="text" on the input, its the default.
You can use the placeholder attrib to pass some SELECT text instead of having an extra select option.
I'm an ionic beginner, I'm trying to push user input to Firebase,
in my html file:
<ion-item>
<ion-label>E-mail </ion-label>
<ion-input type="email" value="" placeholder="Type your e-mail"></ion-input>
</ion-item>
I have the inputtext field, but I handle firebase operations in my ts file, how can I send this input value to my ts file so I can push it?
In the component class file (what you call ts file), you can add a class member, let's call it email:
#Component({
...
})
export class MyComponent {
private email: string;
}
And you can bind it in your template with ngModel:
<ion-item>
<ion-label>E-mail </ion-label>
<ion-input [(ngModel)]="email" type="email" value="" placeholder="Type your e-mail"></ion-input>
</ion-item>
I have a very simple page with a couple of controls.
My issue is that the page does not pickup changes to the model when the icon in upper right corner is clicked. This toggles the showFilterPane variable, which again should show or hide a div based on *ngIf="showFilterPane".
I have another page just like this one working, and I can not figure out why this isn't.
Any tips?
(I've tried using the ChangeDetectorRef.detectChanges(); which works, but then the rangeslider will not work. The draggable point doesn't update, or does not move to where you tap.)
The page:
<ion-header>
<ion-navbar>
<ion-title>MY AO</ion-title>
<ion-buttons end>
<button ion-button (click)="toggleFilterPane()" icon-only>
<ion-icon name="options"></ion-icon>
</button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content>
<div class="container">
<div class="left">
<div *ngIf="isSearching" class="spinner-container">
<ion-spinner></ion-spinner>
</div>
<!-- put content here -->
</div>
<div class="right" *ngIf="showFilterPane">
<ion-list inset>
<ion-list-header>BANA</ion-list-header>
<ion-item>
<ion-select multiple="true" [(ngModel)]="woTrackFilter">
<ion-option>1</ion-option>
<ion-option>2</ion-option>
<ion-option>3</ion-option>
<ion-option>4</ion-option>
<ion-option>5</ion-option>
</ion-select>
</ion-item>
</ion-list>
<ion-list inset>
<ion-list-header>TEKNIKSLAG</ion-list-header>
<ion-item>
<ion-select multiple="true" [(ngModel)]="woDisciplineFilter">
<ion-option>Signal</ion-option>
<ion-option>Bana</ion-option>
<ion-option>EL</ion-option>
<ion-option>Tele</ion-option>
</ion-select>
</ion-item>
</ion-list>
<ion-list inset>
<ion-list-header>DAGAR</ion-list-header>
<ion-item>
<ion-range min="10" max="80" step="4" [(ngModel)]="woDaysFilter">
<ion-label range-left>10</ion-label>
<ion-label range-right>80</ion-label>>
</ion-range>
</ion-item>
</ion-list>
<button ion-button (click)="doSearch()">Search</button>
</div>
</div>
</ion-content>
The component:
import { Component } from '#angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { WorkOrderDashboardPage } from "../work-order-dashboard/work-order-dashboard";
#Component({
selector: 'page-work-order-list',
templateUrl: 'work-order-list.html'
})
export class WorkOrderListPage {
private isSearching: boolean = false;
private showFilterPane: boolean=false;
private woTrackFilter: string[];
private woDisciplineFilter: string[];
private woDaysFilter: number;
constructor(public navCtrl: NavController, public navParams: NavParams) {
// Initialize storage providers here
}
ionViewDidLoad() {
console.log('ionViewDidLoad WorkOrderListPage');
}
toggleFilterPane(): void {
this.showFilterPane = !this.showFilterPane;
}
viewWorkOrder(event, workOrder): void {
this.navCtrl.push(WorkOrderDashboardPage, { workOrder: workOrder });
}
doSearch(): void {
console.log(this.woTrackFilter);
console.log(this.woDisciplineFilter);
console.log(this.woDaysFilter);
}
}
UPDATE: Found workaround
I tried creating a separate app, where the exact same code is working. That lead me to think something wasn't right on the LoginPage, the page that called setRoot() to the above page.
The login code looked like this:
WLAuthorizationManager.login("UserLogin", data).then(() => {
// Success
console.log("Logged in");
this.navCtrl.setRoot(WorkOrderListPage);
},
(err) => {
// failed
console.error(err);
this.showError("Username or password is incorrect");
})
I then figured it might be some Zone issue, and wrapped the setRoot call in zone.run() like this:
WLAuthorizationManager.login("UserLogin", data).then(() => {
// Success
console.log("Logged in");
this.zone.run(() =>
this.navCtrl.setRoot(WorkOrderListPage)
);
},
(err) => {
// failed
console.error(err);
this.showError("Username or password is incorrect");
})
After that the view started to respond as expected. I feel this is a bit of a hack. Can someone shed some light as to what is happening here?
Seems like you are basically using ngZone to make sure Angular knows you changed things so it will reload that part of the DOM to reflect the changes. I don't feel like it's a hack, because you are just making sure that it works as intended.
Angular 2 has some optimization features that help make your app run smoother and one of those is avoiding DOM updates whenever and wherever possible. By using zones (or ngZones) you are basically telling Angular "pay attention to this part, it changes and I need that change to be reflected in the DOM".
I've run into that sort of problem before myself and using zones is usually your best bet. Got into situations where a part of the interface would be stuck unless you touched a button or somesuch.
Another workaround (at least for range sliders) is using the AppllicationRef tick() method, which forces a DOM update. More info about it here.