I want to create a simple shopping list app with the price.
This is my shopping.html
<ion-header>
<ion-navbar color="secondary">
<ion-title align="center">
My Shopping Tracker
</ion-title>
<ion-buttons end>
<button ion-button icon-only (click)="addItem()"><ion-icon name="cart"></ion-icon></button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item *ngFor="let item of items" (click)="viewItem(item)">{{item.type}}</ion-item>
</ion-list>
</ion-content>
<ion-content>
<ion-list>
<ion-item-sliding *ngFor="let item of items">
<ion-item>
<h2>{{item.today}}</h2>
<p>{{item.type}}</p>
<p>{{item.total}}</p>
</ion-item>
<ion-item-options side="right">
<button ion-button (click)="delete(item)">
<ion-icon name="trash"></ion-icon>Delete
</button>
<button ion-button (click)="edit(item)">
<ion-icon name="redo"></ion-icon>Edit
</button>
</ion-item-options>
</ion-item-sliding>
</ion-list>
</ion-content>
<ion-footer>
<ion-toolbar >
<ion-title>{{total}}</ion-title>
</ion-toolbar>
</ion-footer>
This is the addshopping.html
<ion-header>
<ion-toolbar color="secondary">
<ion-title>
Add Shopping List
</ion-title>
<ion-buttons end>
<button ion-button icon-only (click)="close()"><ion-icon name="close"></ion-icon></button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item>
<ion-label>Date:</ion-label>
<ion-datetime displayFormat="DD-MM-YYYY HH:mm" [(ngModel)]="today"></ion-datetime>
</ion-item>
<ion-item>
<ion-label floating>Type:</ion-label>
<ion-input type="text" [(ngModel)]="type"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Description:</ion-label>
<ion-input type="text" [(ngModel)]="description"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Total Amount:</ion-label>
<ion-input type="text" [(ngModel)]="total"></ion-input>
</ion-item>
</ion-list>
<button full ion-button color="secondary" (click)="saveItem()">Save</button>
</ion-content>
This is my addlist.ts
import { Component } from '#angular/core';
import { NavController, ViewController } from 'ionic-angular';
#Component({
selector: 'page-addlist',
templateUrl: 'addlist.html'
})
export class AddListPage {
type: string;
description: string;
today: Date;
total: price;
constructor(public navCtrl: NavController, public view: ViewController) {
}
saveItem(){
let newItem = {
type: this.type,
today: this.today,
description: this.description,
total: this.total,
};
this.view.dismiss(newItem);
}
close(){
this.view.dismiss();
}
}
How do I calculate the total price for each time I add up new item? and display it on the footer? I uploaded the image.
Do I need to change from string to number values? Or stay it as string?
You can use a function that returns the total price, like this
private getTotalPrice() {
let totalPrice = 0;
for (let item of itens) {
totalPrice += Number.parseFloat(item.total);
}
return totalPrice;
}
and then u can call it in the footer
[(ngModel)]="getTotalPrice()"
Related
I have a settings screen with 4 radio buttons. If I click on any of the radio button a success message should be displayed and if I click anywhere else the message should be hidden.
Here is the code:
settings.component.html:
<ion-content>
<div class="flex-container">
<ion-card>
<div class="message">
<div class="message-inner" *ngIf="isMessageDisplay">
<ion-icon name="checkmark"></ion-icon>
<p>Success message</p>
</div>
</div>
<div class="home-screen">
<ion-card-header>
<ion-card-title class="ion-text-center">Select the home page to display</ion-card-title>
</ion-card-header>
<ion-card-content class="home-screen-buttons">
<ion-list class="radio-buttons">
<ion-radio-group name="homeButtons"
>
<ion-row>
<ion-col size="6">
<ion-item lines="none">
<ion-label>home 1</ion-label>
<ion-radio [value]="home.home1"
(ionSelect)="home1()"
color="secondary"
></ion-radio>
</ion-item>
</ion-col>
<ion-col size="6">
<ion-item lines="none">
<ion-label color="lightgray">home 2</ion-label>
<ion-radio [value]="home.home2"
(ionSelect)="home2()"
color="secondary"
></ion-radio>
</ion-item>
</ion-col>
</ion-row>
</ion-radio-group>
</ion-list>
</ion-card-content>
</div>
<div class="products">
<ion-card-header>
<ion-card-title class="ion-text-center">Select the product to display</ion-card-title>
</ion-card-header>
<ion-card-content class="products-buttons">
<ion-list class="radio-buttons">
<ion-radio-group name="productButtons">
<ion-row>
<ion-col size="6">
<ion-item lines="none">
<ion-label>Product 1</ion-label>
<ion-radio [value]="product.product1"
(ionSelect)="product1()"
color="secondary"></ion-radio>
</ion-item>
</ion-col>
<ion-col size="6">
<ion-item lines="none">
<ion-label color="lightgray">Product 2</ion-label>
<ion-radio [value]="product.product2"
(ionSelect)="product2()"
color="secondary"></ion-radio>
</ion-item>
</ion-col>
</ion-row>
</ion-radio-group>
</ion-list>
</ion-card-content>
</div>
</ion-card>
</div>
</ion-content>
settings.component.ts:
import { Component, ElementRef, HostListener, OnDestroy, OnInit } from '#angular/core';
import { Store } from '#ngrx/store';
import { Subscription } from 'rxjs';
#Component({
selector: 'app-settings-menu',
templateUrl: './settings-menu.page.html',
styleUrls: ['./settings-menu.page.scss'],
})
export class SettingsMenuPage implements OnInit, OnDestroy {
isMessageDisplay: boolean = false;
subscriptions$: Subscription[] = [];
constructor(
private store: Store<any>,
private elemRef: ElementRef
) {
}
ngOnInit() {
}
#HostListener('document:click', ['$event.target'])
onClickOutside(targetElement) {
const target = this.elemRef.nativeElement.querySelector('ion-radio');
if (targetElement.tagName != target.tagName)
this.isMessageDisplay= false;
}
home1() {
// some other logic
this.isMessageDisplay= true;
}
home2() {
// some other logic
this.isMessageDisplay= true;
}
product1() {
// some other logic
this.isMessageDisplay= true;
}
product2() {
// some other logic
this.isMessageDisplay = true;
}
ngOnDestroy() {
this.subscriptions$.forEach(subscription => subscription.unsubscribe());
}
}
The above code does the task well during development when I run ionic serve command. But once I build the code for browser using ionic cordova build browser --prod --release and deploy it in some server then success message does not toggle right away, it takes much time when I click anywhere else in the screen.
Please help!
The porblem was in the HostListener. Instead of using #HostListener('document:click', ['$event.target']) I used #HostListener('click', ['$event.target']) and removed document. This solved the problem I had during the production. I don't know the exact reason why this happened.
My checkbox code:
<ion-item>
<ion-label stacked>Beverage Size</ion-label>
</ion-item>
<ion-item>
<ion-label>Small</ion-label>
<ion-checkbox [(ngModel)]="drinkSmall" color="blue" checked="true"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Regular</ion-label>
<ion-checkbox [(ngModel)]="drinkRegular" color="blue" checked="true"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Large</ion-label>
<ion-checkbox [(ngModel)]="drinkLarge" color="blue" checked="true"></ion-checkbox>
</ion-item>
My submit button:
<button ion-button color="primary" block (click)="addBeverage(
drinkName,
drinkmenuDesc,
drinkPrice,
drinkCategory,
drinkSmall,
drinkRegular,
drinkLarge
)" [disabled]="!menuName">
Add Beverage
</button>
Edited:
I want to pass all the checkbox status as a parameter of a function. The drinkSmall, drinkRegular, drinkLarge should be the status of checkbox.
You should create a object that holds the checkbox values. Then you can pass that object to your submit function. See below for a example using a model called "checkboxes"
TS:
// A achecboxes object in your controller:
checkboxes: any = {
drinkSmall: true,
drinkRegular: true,
drinkLarge: true
}
HTML:
<ion-item>
<ion-label stacked>Beverage Size</ion-label>
</ion-item>
<ion-item>
<ion-label>Small</ion-label>
<ion-checkbox [(ngModel)]="checkboxes.drinkSmall" color="blue"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Regular</ion-label>
<ion-checkbox [(ngModel)]="checkboxes.drinkRegular" color="blue"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Large</ion-label>
<ion-checkbox [(ngModel)]="checkboxes.drinkLarge" color="blue"></ion-checkbox>
</ion-item>
<button ion-button color="primary" block (click)="addBeverage(checkboxes)" [disabled]="!menuName">
Add Beverage
</button>
In .ts you need to create an object.
checkboxes: any = {
drinkSmall: true,
drinkRegular: true,
drinkLarge: true
};
data: any = {
checkboxes:this.checkboxes,
para1:'',
para2:'',
para3:''
};
In .html you need to change like
<ion-item>
<ion-label stacked>Beverage Size</ion-label>
</ion-item>
<ion-item>
<ion-label>Small</ion-label>
<ion-checkbox [(ngModel)]="data.checkboxes.drinkSmall" color="blue"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Regular</ion-label>
<ion-checkbox [(ngModel)]="data.checkboxes.drinkRegular" color="blue"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Large</ion-label>
<ion-checkbox [(ngModel)]="data.checkboxes.drinkLarge" color="blue"></ion-checkbox>
</ion-item>
<button ion-button color="primary" block (click)="addBeverage(data)" [disabled]="!menuName">
Add Beverage
</button>
Here one object data holds multiple checkbox as well as para1,para2,para3
Output of console.log
I have a component which takes in a dynamic template which looks like this:
<ion-list>
<ion-item-sliding *ngFor="let entity of entityList" #item>
<ion-item (click)="navigateToDetail(entity.id)">
<template [ngTemplateOutlet]="template" [ngOutletContext]="{entity: entity}"></template>
</ion-item>
<ion-item-options side="right">
<button ion-button color="danger" *ngIf="config && config.canDelete" (click)="delete(entity.id)">
<ion-icon name="trash"></ion-icon>Delete
</button>
<button ion-button color="dark" >
<ion-icon name="more"></ion-icon>More
</button>
</ion-item-options>
</ion-item-sliding>
<ion-list-header>
<button *ngIf="config && config.canCreate" (click)="create()"
ion-button full color="secondary">
Create New<ion-icon name="add"></ion-icon>
</button>
</ion-list-header>
</ion-list>
and the typescript looks like so:
export class PageListBaseComponent<T extends IHasId> {
#Input() template: TemplateRef<any>;
#Input() detailPageType: any;
#Input() config: PageListConfiguration
#Input() set baseProvider(provider: ProviderBase<T>) {
provider.getList().subscribe(entities => {
this.entityList = entities;
console.log(entities);
});
}
public entityList: T[];
constructor(public navCtrl: NavController, public navParams: NavParams) {
console.log("ctor");
}
create() {
if (this.config && this.config.canCreate) {
//TODO: initialize entity
let entity = {}
this.navCtrl.push(this.detailPageType, { entity });
}
}
delete(id: number) {
console.log(id);
if(this.config && this.config.canDelete)
{
this.baseProvider.deleteById(id).subscribe(result => {
console.log(result);
});
}
}
navigateToDetail(id: number) {
this.navCtrl.push(this.detailPageType, { id })
}
}
And then I have a template that looks like so:
<template #myTemplate let-entity="entity">
<ion-item>
<ion-avatar item-left>
<img src="http://modexenergy.com/wp-content/themes/modex_wp/img/avatar.png">
</ion-avatar>
<h2>{{ entity.email }}</h2>
<ion-icon name="arrow-forward" item-right></ion-icon>
</ion-item>
</template>
My issue is the <ion-item> Right now I need to use it twice which I do not want to do, For some reason if i try and render the items dynamically they do not appear in the list, so I need to leave <ion-item> wrapping the template, that would be fine, except the directives don't respect there parent. Meaning if I use the item-left directive in a template, and the template does not include an <ion-item> my directives are ignored.
What can I do to fix this, if I can get away with out using both that would be nice, but if not is there a way render the first <ion-item> with no style?
I am new in Ionic2 and Angular2 trying to update my array at front side but its not updating.Moreover its updating perfectly at backend (ts),checked using console. need your help
My Component:
import { Component } from '#angular/core';
import { NavController, NavParams, ViewController } from 'ionic-angular';
#Component({
selector: 'page-modal-filter',
templateUrl: 'modal-filter.html'
})
export class ModalFilterPage {
public fil=[];
public BRANDNAME: any;
public srts:any;
constructor(public nav: NavController, public viewCtrl: ViewController, public navParams: NavParams) {
this.fil = [];
this.srts="ABCD";
if (navParams.get('tabName') == 'filter') {
let data = navParams.get('data');
data.map(d => {
for (let op in d.OPTIONGROUP) {
for (let x in d.OPTIONGROUP[op]) {
if (x != "UPC") {
if (!this.fil[x]) {
this.fil[x] = [];
}
if (this.fil[x].indexOf(d.OPTIONGROUP[op][x]) == -1) {
this.fil[x].push(d.OPTIONGROUP[op][x]);
}
}
}
}
})
console.log(this.fil);
}
}
closeModal() {
// this.nav.pop();
this.viewCtrl.dismiss(true);
}
}
"fil" array not showing on frontside of html but console show its perfectly.
My html code:
fil array not showing
<ion-header>
<ion-navbar color="primary">
<ion-buttons start>
<button ion-button (click)="closeModal()">
<ion-icon name="close"></ion-icon>
</button>
</ion-buttons>
<ion-title>Search Result(105)</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding class="tab-filter">
<!--filter list-->
<pre>{{fil}}</pre>
<pre>{{srts}}</pre>
<ion-list class="list-no-border">
<ion-item>
<ion-label> PLACE</ion-label>
<ion-select>
<ion-option value="">All Regions</ion-option>
<ion-option value="vn">Vietnam</ion-option>
</ion-select>
</ion-item>
<ion-item class="price-ranger">
<ion-label>Price</ion-label>
<ion-input type="text" placeholder="Min"></ion-input>
-
<ion-input type="text" placeholder="Max"></ion-input>
</ion-item>
<ion-item>
<ion-label>Free shipping</ion-label>
<ion-toggle checked="false"></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Once pice only</ion-label>
<ion-toggle checked="false"></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Sale items</ion-label>
<ion-toggle checked="false"></ion-toggle>
</ion-item>
</ion-list>
</ion-content>
<!--Footer buttons-->
<ion-footer class="category">
<ion-toolbar position="bottom">
<ion-buttons end>
<button ion-button (click)="closeModal()">
CANCEL
</button>
<button ion-button (click)="closeModal()">
<span ion-text color="gray">APPLY</span>
</button>
</ion-buttons>
</ion-toolbar>
</ion-footer>
Your {{fil}} is an array yet you are declaring it on the view as a simple property. Angular does not automatically interpret an array with string interpolation.
For arrays you need to use *ngFor
So if you want like you have stated is being displayed in your console.log you could write something like
<div *ngFor="let item of fil">
<ion-item *ngFor="let color of item.COLOR">
{{color.propertyName}}
<ion-item>
<ion-item *ngFor="let size of item.SIZE">
{{color.propertyName}}
<ion-item>
</div>
I resolved my issue by using
this.fil = [];
to
this.fil={}
I have an array of objects that I want to loop through in my template and output as cards. I have it working currently using *ngfor and now I want to change it to use collection repeat instead.
Here is my code:
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { TowersModel } from '../../app/models/towers-model';
#Component({
selector: 'page-towers',
templateUrl: 'towers.html'
})
export class TowersPage {
towers: any;
constructor(public navCtrl: NavController){
this.towers = [
{
"name" : "Tower 1",
"image" : "http://placehold.it/350x150"
},
{
"name" : "Tower 2",
"image" : "http://placehold.it/350x150"
},
{
"name" : "Tower 3",
"image" : "http://placehold.it/350x150"
}
];
}
}
Template:
<ion-header>
<ion-navbar>
<ion-title>
Towers
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-content>
<ion-card *ngFor="let tower of towers">
<img src="{{ tower.image }}" alt="{{tower.name}}">
<ion-item>
<h2>{{tower.name}}</h2>
<p>11 N. Way St, Madison, WI 53703</p>
</ion-item>
<ion-item>
<span item-left>18 min</span>
<span item-left>(2.6 mi)</span>
<button ion-button icon-left clear item-right>
<ion-icon name="navigate"></ion-icon>
Start
</button>
</ion-item>
</ion-card>
</ion-content>
</ion-content>
So as mentioned this approach works fine. If I try and change it though to use a collection repeat instead like so:
<ion-header>
<ion-navbar>
<ion-title>
Towers
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-content>
<ion-item collection-repeat="let tower of towers">
<h1>Tower {{tower.name}}</h1>
</ion-item>
</ion-content>
</ion-content>
Then I get the following error:
Runtime Error
Error in ./TowersPage class TowersPage - caused by: Cannot read property 'name' of undefined
I think you are using ionic 2 and you need to use vitualScroll instead of collection-repeat.
<ion-list [virtualScroll]="towers">
<ion-item *virtualItem="let tower">
{{ tower.name }}
</ion-item>
</ion-list>