Currency masking in ionic - ionic-framework

I am trying to format the entry in currency format like 10,000.00 in a ion-input field with the below line of code but while entering the text it shows the output as 10,000.0010000. I have tried almost all of the alternate solutions in online and none of them helped me to overcome this situation. tried ng2-currency-mask and its not working
<ion-item>
<ion-input type="number" [(ngModel)]= Basic pattern="\d*" name="Basic"
#Basic="ngModel" clearInput placeholder="0.00">
<div>{{selectedCtcBasic | currency: '₹ '}}</div>
</ion-input>
<div class="error-form" *ngIf="Basic.invalid">
<div *ngIf="Basic.errors.pattern">* Text/symbols not allowed</div>
</div>
</ion-item>

Basically currency masks and directives are applied to input element, but when you use <ion-input>, then you can observe by inspecting element that its not input there's some other tags are also added. So you need to add these type of things on input element as shown below -
<ion-item>
<input type="number" [(ngModel)]="selectedCtcBasic" name="Basic"
#Basic="ngModel" clearInput placeholder="0.00" />
<div>{{selectedCtcBasic | currency: '₹ '}}</div>
</ion-item>
Happy Coding :)

Related

Only down arrow coming for ION-SELECT and blank for textbox in IONIC 4

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.

Ionic latest add item not display in the list top

Im using ionic 3 for my mobile application. I have an issue with my item list, my issue is when i add a new item it does not show up at the top of the list, it always appears at the bottom , how to do that correctly?
Thanks
example
add Item -
first -A
second-B
its display
A
B
I want to know how can display this type
B
A
item list
<ion-list class="ion-addexe">
<ion-item *ngFor="let bill of Details">
<ion-label>
<p class="ion-lbl" style="position: relative;top:-0.2rem;">{{bill.billdescription}}</p>
</ion-label>
<ion-label>
<p class="ion-lbl" text-right style="position: relative;top:-0.2rem;">$ {{bill.billtotal}}</p>
</ion-label>
</ion-item>
</ion-list>
add item
<div>
<ion-item >
<ion-label id="ion-lbls">Select you want</ion-label>
<ion-select [(ngModel)]="addnewBill_category" okText="Add" cancelText="Close">
<ion-option *ngFor="let bill of Category" value="{{bill.billCategoryID}}">{{bill.CategoryName}}</ion-option>
</ion-select>
</ion-item>
<ion-item >
<ion-label id="ion-lbls">Details</ion-label>
<ion-input type="text" value="" [(ngModel)] = "addnewBill_description" placeholder="Description" text-right></ion-input>
</ion-item>
<ion-item >
<ion-label id="ion-lbls">Date</ion-label>
<ion-datetime displayFormat="MMM DD YYYY" [(ngModel)]="event.addnewbill_Date" placeholder="MMM/DD/YYYY"></ion-datetime>
</ion-item>
<ion-item>
<ion-label id="ion-lbls">Total ($)</ion-label>
<ion-input type="number" [(ngModel)]="addnewBill_amount" value="" placeholder="$0.0" text-right></ion-input>
</ion-item>
</div>
</ion-list>
First of all that is the correct way in which a ngFor works it displays the first element first and the next items at the bottom, because whenever you insert new items inside an array it follows the top to bottom approach. So basically you want to display your array items in reverse order that should be your question
The most simple and easy solution to this is by just using reverse() on your *ngfor. In your case it would be something like this:
<ion-item *ngFor="let bill of Details.reverse()">
...
<ion-item>
or one more solution is using a custom angular pipe which you could apply on the *ngFor and sort your array in reverse order.
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'reverse'
})
export class ReversePipe implements PipeTransform {
transform(value) {
if (!value) return;
return value.reverse();
}
}
and then in your html you can use that pipe like this:
<ion-item *ngFor="let bill of Details | reverse">
...
<ion-item>

How to conditionally require form inputs in angular 4?

I am using template driven forms for adding the task, and there are 2 input fields of type number for estimated mins to complete task,
one field is for estimated number of hrs and
another is for estimated minutes to complete the task
since the task estimate can be done either in hours like 1hrs , or in hours and minutes like 1Hrs 30Mins , so i want to set attribute required to inputs conditionally. So one of the 2 inputs must be set or form validation error will occur if both inputs are empty when submitting form.
so far i have done this but validation is not working
<form class="add-task" (ngSubmit)="onSubmit(newtask)" #newtask="ngForm">
<div class="estimate-container">
<input
type="number"
min="0"
max="10"
id="estimate_hrs"
ngModel
name="estimate_hrs"
mdInput
[required]="!estimateMins.valid"
placeholder="Estimated Hours"
#estimateHrs="ngModel"
>
<div class="error-msg" *ngIf="!estimateHrs.valid && !estimateMins.valid">
Please enter estimated hours
</div>
<input
type="number"
min="0"
max="60"
id="estimate_min"
ngModel
name="estimate_min"
mdInput
[required]="!estimateHrs.valid"
placeholder="Estimated Minutes"
#estimateMins="ngModel"
>
<div class="error-msg" *ngIf="!estimateMins.valid && !estimateHrs.valid">
Please enter estimated minutes
</div>
</div>
<button type='submit' [disabled]="!newtask.valid" >Submit</button>
</form>
Try using [attr.required] instead.
<input
type="number"
min="0"
max="10"
id="estimate_hrs"
ngModel
name="estimate_hrs"
mdInput
[attr.required]="!estimateMins.valid"
placeholder="Estimated Hours"
#estimateHrs="ngModel"
>
This is my working solution for Angular 5:
In component:
#Input()
required: boolean;
In template on the input (or select) element that:
[required]="required"
On the selector:
[required]="true"
Like #DeborahK double checked, no need for single quotes :-)
You need to put your !estimateMins.valid in single quotes like:
[required]="'!estimateMins.valid'" and [required]="'!estimateHrs.valid'"
See this plunkr
I spent some time trying this out because the basic syntax should have worked. I initially did a simply plunker just to test the syntax and the syntax does indeed work as defined.
After expanding the plunker to more closely match the OP's code: https://plnkr.co/edit/QAqeBYrg19dXcqbubVZ8?p=preview
<Links to plunker must be accompanied by code>
It became apparent that it is not a syntax error. Rather it is a logic error.
When the form first appears, both controls are valid so neither of them have the required attribute. So then neither are required and it appears that it does not work.
There are several possible ways to resolve this. One is to build a custom validator that does the cross field validation.
You can use [required]=boolean.
In angular2 or above you can use ngNativeValidate directive for template driven form. And also object to reserved and sending data(though it's your personal choice but i love this way) to api.
<form class="add-task" #newtask="ngForm" ngNativeValidate (ngSubmit)="onSubmit()">
<div class="estimate-container">
<input
type="number"
min="0"
max="10"
id="estimate_hrs"
name="estimate_hrs"
mdInput
[required]="!taskModel.estimateMins"
placeholder="Estimated Hours"
[(ngModel)]="taskModel.estimateHrs">
<div class="error-msg" *ngIf="!taskModel.estimateHrs && !taskModel.estimateMins">
Please enter estimated hours
</div>
<input
type="number"
min="0"
max="60"
id="estimate_min"
name="estimate_min"
mdInput
[required]="!taskModel.estimateHrs"
placeholder="Estimated Minutes"
[(ngModel)]="taskModel.estimateMins">
<div class="error-msg" *ngIf="!taskModel.estimateMins && !taskModel.estimateHrs">
Please enter estimated minutes
</div>
</div>
<button type='submit' [disabled]="!newtask.valid" [isFormValid]="!newtask.valid">Submit</button>
</form>
In .ts file
taskModel: any;
onSubmit(){
console.log(this.taskModel) // this object has all data.
}
You can also achieve the same with in AngularJS (version 1.x)
<form id="form" name="form" class="add-task" ng-init="taskModel={}">
<div class="estimate-container">
<input
type="number"
min="0"
max="10"
id="estimate_hrs"
name="estimate_hrs"
mdInput
ng-required="!taskModel.estimateMins"
placeholder="Estimated Hours"
ng-model="taskModel.estimateHrs">
<div class="error-msg" ng-if="!taskModel.estimateHrs && !taskModel.estimateMins">
Please enter estimated hours
</div>
<input
type="number"
min="0"
max="60"
id="estimate_min"
name="estimate_min"
mdInput
ng-required="!taskModel.estimateHrs"
placeholder="Estimated Minutes"
ng-model="taskModel.estimateMins">
<div class="error-msg" ng-if="!taskModel.estimateMins && !taskModel.estimateHrs">
Please enter estimated minutes
</div>
</div>
<button ng-disabled="form.$valid" ng-click="form.$valid && onSubmit()" >Submit</button>
</form>
Hope it's helpful to you!

Ionic2 - Error - If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone'

I'm not sure to understand the error I'm getting while looping through an array of options to populate my select list.
Here is the error I get
Error in ./PhonePage class PhonePage - caused by:
If ngModel is used within a form tag, either the name attribute must be set or the
form control must be defined as 'standalone' in ngModelOptions.
Example 1: <input [(ngModel)]="person.firstName" name="first">
Example 2: <input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}">
Here is my html code
<form>
<h2>Quel est votre numéro de téléphone?</h2>
<ion-list>
<ion-grid>
<ion-row>
<ion-col width-33>
<ion-item>
<ion-select [(ngModel)]="optionList">
<ion-option *ngFor="let item of optionList" value="{{item.text}}">{{item.text}}</ion-option>
</ion-select>
</ion-item>
</ion-col>
<ion-col>
<ion-item>
<ion-input type="text"></ion-input>
</ion-item>
</ion-col>
</ion-row>
</ion-grid>
</ion-list>
</form>
Prerak Tiwari's answer is correct.
Here is just a little tip: I see you bind your ion-select to "optionList" but this is just the list of options you want to show and need to create all ion-options.
You should bind the ion-select to a new parameter, because aftewards it will hold the selected ion-option.
If ngForm is used, all the input fields which has [(ngModel)]="" must have a attribute name with a value.

Invisible input-label with item-floating-label and set input value

In this sample I expected the Email label to be visible above the email input. It appears if I start to edit the input data.
Am I doing something wrong here?
<label class="item item-input item-floating-label">
<span class="input-label">Email</span>
<input type="email" value="me#example.com">
</label>
With ng-model in stead of value it will have the expected behaviour. So change your code to
<label class="item item-input item-floating-label">
<span class="input-label">Email</span>
<input type="email" ng-model="account.email">
</label>
and add something like the following in your controller
$scope.account = {
email: 'me#example.com'
};
I had a similar problem using AppGyver Supersonic.
I solved controlling the has-input class on my input-label using ng-class, like this:
<label class="item item-input item-floating-label">
<span class="input-label" ng-class="{'has-input': username}">Choose a username</span>
<input type="text" placeholder="Choose a username" ng-model="username">
</label>
The item-floating-label class animates the label as the user types in the input field. Refer documentation for more details.
http://ionicframework.com/docs/components/#forms-floating-labels
For your requirement to always show the label above the input field, you have to use the item-stacked-label
http://ionicframework.com/docs/components/#forms-stacked-labels
Set the placeholder with the same text as the label. In this case placeholder="Email".
The Floating item label works this way.. Until the field is filled, the label will not be visible, instead the placeholder will be visible. Just as you type in the field, the label will appear.The animation is sleek and nice. Just make sure the text is same.(case sensitive.)