Have ion-input only accept 20 digit numbers? - ionic-framework

I've tried using
<ion-input formControlName="LPNumber" type="number">
LPNumber: ['', [Validators.required, Validators.minLength(20), Validators.maxLength(20)]]
but that doesn't seem to validate.... in chrome at least. Is there a better way to validate a 20 digit number in Ionic 4?

So by design if your input type is "number" the maxLength will be ignored.
There are many ways to workaround this. I used this approach (hacky a bit):
<ion-item>
<ion-label>MaxLength 4</ion-label>
<ion-input onKeyPress="if(this.value.length==4) return false;"
type="number"></ion-input>
</ion-item>

<ion-input formControlName="LPNumber" minlength="20" maxlength="20" type="number">

My way to do this is by:
<ion-input type="number" (ionChange)="onNumberChange($event)"></ion-input>
...
onNumberChange($event) {
// checks of number only. Doesn't allow + - . for in input
$event.target.value = $event.target.value.replace(/[^0-9]/g, '').replace(/(\..*)\./g, '$1');
// checks for maxlength doesn't allow greater than specified length
$event.target.value = $event.target.value.length > 20 ? $event.target.value.substring(0, 20) : $event.target.value;
}

you can give type="text" then allow, but you give type="number" then not allow Validation, so you can give below like
page.html
<ion-item lines="none">
<ion-label position="stacked">Input Number</ion-label>
<ion-input formControlName="LPNumber" type="tel"></ion-input>
</ion-item>
<ion-item no-padding lines="none" class="validator-error"
*ngIf="property_form_step3.controls.LPNumber.hasError('required') && property_form_step3.controls.LPNumber.touched">
<p class="content">Please Enter Required Field!</p>
</ion-item>
<ion-item no-padding lines="none" class="validator-error"
*ngIf="property_form_step3.controls.LPNumber.hasError('maxlength') && property_form_step3.controls.LPNumber.touched">
<p class="content">Allow Only 20 Digits Number!</p>
</ion-item>
page.ts
LPNumber: [null, Validators.compose([Validators.maxLength(20), Validators.required])],
page.scss
.validator-error{
--background: transparent;
color: #d44848;
--min-height: 30px;
.content{
margin-bottom: 0px;
margin-top: 0px;
font-size: 12px;
}
}

Related

How to change ion-label color while checking ion-radio on Ionic 6?

I have a following chunk of Ionic code,
<ion-radio-group>
<ion-item class="ship-method">
<ion-label>Flat Rate £0.00</ion-label>
<ion-radio slot="end" value="flat-rate"></ion-radio>
</ion-item>
<ion-item class="ship-method">
<ion-label>Free Shipping</ion-label>
<ion-radio slot="end" value="free-shipping"></ion-radio>
</ion-item>
</ion-radio-group>
and following part of SCSS code,
.ship-method {
margin: 25px;
ion-label { font-size: 16px; }
ion-radio {
--color-checked: #e22078;
}
}
What I want is to color <ion-label> to #e22078 while checking the respective <ion-radio>. How can I do that?
First, you need to bind the value of the selected radio button into a variable. So, declare a variable in your .ts file:
selectedShippingMethod:string=''; //Or change it to 'flat-rate' for default value
Next add a 2-way binding in your template file so that you can save the value of the selected radio button.
<ion-radio-group [(ngModel)]="selectedShippingMethod">
<ion-item class="ship-method">
<ion-label [class.selected]="selectedShippingMethod=='flat-rate'">Flat Rate £0.00</ion-label>
<ion-radio slot="end" value="flat-rate"></ion-radio>
</ion-item>
<ion-item class="ship-method">
<ion-label [class.selected]="selectedShippingMethod=='free-shipping'">Free Shipping</ion-label>
<ion-radio slot="end" value="free-shipping"></ion-radio>
</ion-item>
</ion-radio-group>
Add a class named selected in .SCSS file:
.selected{
color:#e22078;
}
Here you are assigning ion-label class 'selected' when the value of selectedShippingMethod matches the value of that radio-button
<ion-label [class.selected]="selectedShippingMethod=='free-shipping'">

Ionic 3 to Ionic 4 SCSS migration

Lately I am trying to migrate my Ionic 3 project to Ionic 4. Most of the migration is going successful but I keep having problems with my styling.
After some reading I changed a few things to my styling, listed below:
Moved global styling from app.scss to global.scss
Changed theme styling $colors for example to :root { ion-color- ... }
Changed naming of (some) components (ion-navbar to ion-toolbar, button to ion-button, etc.)
Removed page selectors in page-specific styling (so removed page-login { ... } in login.scss)
Though the styling is still not quite right. I am probably still missing some things.
As example I am using my page-specific style for my login page.
In Ionic 3 the style file looked as follows for this page:
page-login {
.content {
background: url('../assets/img/background.png') no-repeat;
background-size: cover;
#logo {
padding-top: 5rem;
}
form {
position: absolute;
bottom: 0;
width: 100%;
.logo-row {
margin-bottom: 40%;
}
.form-inputs {
.label-ios {
width: 60px;
max-width: 60px;
}
ion-icon, .select-ios, ::-webkit-input-placeholder {
color: color($colors, lightGray);
max-width: 100%;
}
.item-ios {
background: transparent;
padding-left: 0;
&:first-child {
border-top: none;
}
.input-wrapper {
padding-left: 50px;
input.text-input.text-input-ios {
color: color($colors, lightGray);
}
}
}
[icon-only] ion-icon {
line-height: 1;
}
}
}
}
}
In my Ionic 4 app I changed it to the following:
ion-content {
--background: url('../../../assets/img/background.png') no-repeat;
--background-size: cover;
#logo {
padding-top: 5rem;
}
ion-form {
--position: absolute;
--bottom: 0;
--width: 100%;
.logo-row {
margin-bottom: 40%;
}
ion-inputs {
.ios ion-label {
--width: 60px;
--max-width: 60px;
}
ion-icon, .select-ios, ::-webkit-input-placeholder {
--color: var(--ion-color-lightGray); //color($colors, lightGray);
--max-width: 100%;
}
.ios ion-item {
--background: transparent;
--padding-left: 0;
&:first-child {
--border-top: none;
}
.input-wrapper {
--padding-left: 50px;
input.text-input.text-input-ios {
--color: var(--ion-color-lightGray); //color($colors, lightGray);
}
}
}
[icon-only] ion-icon {
--line-height: 1;
}
}
}
}
There are a few things which are not styled correctly:
I thought I had to replace the most Ion specific components with ion- in front of it, for content this seems to work but the form targeting this does not seem to work (ion-form), while form (liek it used to be) also doesn't work. Any clues with what I should replace this? Or should I omit the form targeting and just keep it in ion-content?
There is also some html inline styling going on, I don't know if all these styles are still correctly used in Ionic 4? For example, I have read somewhere that I should replace padding text-center with class="ion-padding ion-text-center" but what about the inline col-x and offset-x styles?
My Ionic html login page looks as following:
<ion-header [ngClass]="'no-shadow'">
<ion-toolbar transparent>
<ion-buttons start>
<button ion-button icon-only menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-row class="logo-row" *ngIf="isKeyboardHidden">
<ion-col col-8 offset-2 class="ion-padding ion-text-center">
<img id="logo" src="assets/img/logo-dia-positive.png">
</ion-col>
</ion-row>
<form #f="ngForm" (ngSubmit)="onSubmit()">
<ion-row>
<ion-col>
<p style="height: 16px"></p>
</ion-col>
</ion-row>
<ion-list no-lines class="form-inputs">
<ion-item>
<ion-label icon-only>
<ion-icon name="person"></ion-icon>
</ion-label>
<ion-input
type="text"
name="username"
[(ngModel)]="account.username"
[placeholder]="'USERNAME' | translate"
required></ion-input>
</ion-item>
<ion-item>
<ion-label icon-only>
<ion-icon name="unlock"></ion-icon>
</ion-label>
<ion-input
type="password"
name="password"
[(ngModel)]="account.password"
[placeholder]="'PASSWORD' | translate"
required></ion-input>
</ion-item>
</ion-list>
<ion-row>
<ion-col col-10 offset-1>
<ion-button
block
[disabled]="!f.valid || isLoading">
{{'LOGIN' | translate}}
</ion-button>
</ion-col>
</ion-row>
</form>
</ion-content>
<ion-footer *ngIf="isKeyboardHidden">
<ion-row>
<ion-col class="ion-text-center">
<p class="light-gray">
{{'DEVELOPED_BY' | translate}}
<span class="bold">
<a class="default-text"
href="https://www.my-company.com/"
target="_blank">
My Company
</a>
</span>
</p>
</ion-col>
</ion-row>
</ion-footer>
Any ideas or pointers what I am (still) missing?
Here you can find official migration guide. They have listed all controls which they updated and Breaking changes:
https://github.com/ionic-team/ionic/blob/master/angular/BREAKING.md#breaking-changes

ion-item reduce width of end slot

I need to make the end slot of my list item take up less width so I can make the name in the first slot longer.
Currently it takes up around 50% of the width and is wasting space.
<ion-list *ngIf="!isLoading">
<ion-item *ngFor="let trail of trails" #defectReport (click)="onViewTrailDetails(trail)">
<fa-icon class="icon icon-center status-open-icon" *ngIf="trail.status === trailStatus.Open" slot="start" [icon]="['fas', 'check-circle']" size="2x"></fa-icon>
<fa-icon class="icon icon-center status-closed-icon" *ngIf="trail.status === trailStatus.Closed" slot="start" [icon]="['fas', 'times-circle']" size="2x"></fa-icon>
<fa-icon class="icon icon-center status-new-icon" *ngIf="trail.status === trailStatus.New" slot="start" [icon]="['fas', 'burn']" size="2x"></fa-icon>
<fa-icon class="icon icon-center status-under-construction-icon" *ngIf="trail.status === trailStatus.UnderConstruction" slot="start" [icon]="['fas', 'exclamation-triangle']" size="2x"></fa-icon>
<ion-label class="first-item-label">
<span><h2 class="heading">{{trail.name}}</h2></span>
<p class="label-text">{{trail.status}}</p>
</ion-label>
<ion-label slot="end" class="second-item-label">
<p class="sub-heading">{{trail.statusNotes}}</p>
<p class="label-text-small">{{trail.lastUpdated | timeAgo}}</p>
</ion-label>
</ion-item>
</ion-list>
I ended up using ion-note. It caused some formatting issues but resolved my problem.
https://ionicframework.com/docs/api/note
<ion-note slot="end" class="second-item-label" [ngClass]="{'margin-top-auto': !trail.statusNotes}">
<p class="sub-heading">{{trail.statusNotes}}</p>
<p class="label-text-small">{{trail.lastUpdated | timeAgo}}</p>
</ion-note>
ion-item is a flex container and ion-label has the style flex-grow: 1.
What I did is setting the first to flex-grow: 2, resulting in 2/3, 1/3 responsive proportions for labels.
In your case just add this to the CSS:
.first-item-label {
flex-grow: 2;
}
If you want the last label to have a fixed width, do this instead:
.second-item-label {
flex: 0 0 80px;
}
I recommend to use the following. Just change / reset the flex style of the label element, since it's a flex layout.
ion-label[slot='end'] {
flex: unset;
text-align: end;
}
The property text-align: end is optional and has nothing to do with the question. But in my opinion the right slot of an item should be right aligned. Especially input field.
You could use every element you want. But ion-label has some predefined styles which harmonize with the framework. And ion-note changes e.g. the font-size (in md style).
Update: This will be fixed in upcoming Ionic version (maybe Ionic 6). With this change flex: 1 is not longer set on slot="end".

How can I resize the length of an card in ionic?

Well, I want to standardize the width equal to the above, but I'm not getting any way ... I've tried margin's, width and others, but none if you want to change the size of the card. I want to leave default, do you recommend me some command or am I doing wrong? all the css commands I did was in home.scss, thank you all.
Watch the print of my app here
page-home {
.bg{
background: linear-gradient(to bottom, #00A399 0%, #fafafa 400%);
}
.bg-ions{
background:#000;
opacity:0.2;
}
.btn{
background:#000;
opacity:0.2;
color:white;
}
ion-input{
color:#FAFAFA;
}
ion-textarea{
color:#FAFAFA;
}
ion-card{
display: flex;
flex-direction: column;
width: 100%;
}
ion-card-content{
margin-left:-2%;
}
ion-item{
width:50%;
}
.summ{
color:#000;
}
::placeholder {
color: white;
opacity: 1; /* Firefox */
}
:-ms-input-placeholder { /* Internet Explorer 10-11 */
color: white;
}
::-ms-input-placeholder { /* Microsoft Edge */
color: white;
}
}
<br>
<ion-header>
<ion-navbar>
<ion-title>
HybridSumm
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding class="bg">
<ion-item class="bg-ions">
<ion-label class="div-pai" color="primary" stacked>Title</ion-label>
<ion-input placeholder="Ex: The Bio-informatics" style="color:white;"></ion-input>
</ion-item>
<br>
<ion-item class="bg-ions">
<ion-label color="primary" stacked >Text</ion-label>
<ion-textarea placeholder="Place the text that you want to summarize." ngDefaultControl [(ngModel)]="test"></ion-textarea>
</ion-item>
<br>
<button ion-button outline style="background: white">Summarize</button>
<button ion-button>Test</button>
<br><br>
<ion-card>
<ion-card-header>
Card Header
</ion-card-header>
<ion-card-content>
{{test}}
</ion-card-content>
</ion-card>
</ion-content>
Ionic set some properties by default, and the only way to override them, is by giving them the !important rule.
It is maybe not the best practice, but it works, and ionic gives us not very much sass variables to overwrite some things.
It works for me adding this in the following SCSS rules in your code:
ion-card{
display: flex;
flex-direction: column;
width: 100% !important;
margin: 0 !important;
}
I hope it works for you.

Ionic App view content move upside when keyboard comes up for typing inside text field

I am using Ionic 2 for building an app, I have created a login page which looks like this
Now When I try to type something in username fieild the keyboard pops out and the whole page scrolls upside like this
Now I am not able to see the text fields.
I have seen some solutions on google to stop scroll when keyboard come out.Even I have tried the same but then it behaves weird in landscape mode.
my login page code is.
<ion-content class="background">
<ion-card>
<ion-card-header>
<ion-icon name="ios-log-in"></ion-icon>
Login
</ion-card-header>
<ion-card-content>
<ion-list noline >
<ion-item>
<ion-label floating>Username</ion-label>
<ion-input class="inpt" type="text"></ion-input>
</ion-item>
<ion-item >
<ion-label floating>Password</ion-label>
<ion-input type="password"></ion-input>
</ion-item>
</ion-list>
<div padding>
<button ion-button block outline color="light">
<ion-icon name="ios-log-in"></ion-icon>
Sign In
</button><br />
<!-- <button ion-button block color="fb">
<ion-icon name="logo-facebook"></ion-icon>
Login with Facebook
</button> -->
</div>
<a href="">
Forgot Login Details?
<b>Get Help Signing IN</b>
</a>
</ion-card-content>
</ion-card>
<button ion-button block color="primary">Don't have an Account? Sign Up</button>
</ion-content>
This is my sass code:
page-login {
.background{
background-image:url('../assets/bg.jpg');
background-repeat: none;
}
.scroll-content{
align-content:center;
display:flex;
flex-direction:column;
}
ion-card.card{
box-shadow:none;
background:rgba(0,0,0,0.6);
border-radius:8px;
}
a, p, ion-card-header.card-header {
color:#fff;
}
.list > item-block:first-child{
border:medium none
}
.item{
margin-bottom:10px;
background:rgba(255,255,255,0.7);
border:medium none;
.text-input,{
color:green;
}
*:-moz-placeholder{
color:black !important;
}
*:-moz-input-placeholder{
color:black !important;
}
}
}
I have gone through some links which says that this is a bug in ionic beta version.
this link
Is there any standard solution on this issue ? because this functionality is common thing in all apps .
Bit confused to take a call to go with ionic or not .