I want to bind 3 buttons to 3 different lists. I could use ion-segmentbut since I like the design over the segments I just do it with custom buttons. But now when I implement the *ngSwitchCase the lists are simply not displayed when I click on a button and I get this error Error: No value accessor for form control with unspecified name attribute
page.html
<ion-row [(ngModel)]="pre" [(ngModel)]="type" class="bg">
<ion-col col-4><ion-button value="own"</ion-button></ion-col>
<ion-col col-4><ion-button value="friends"</ion-button></ion-col>
<ion-col col-4><ion-button value="all" </ion-button></ion-col>
</ion-row>
<div [ngSwitch]="pre">
<ion-list *ngSwitchCase="'own'">
</ion-list>
<ion-list *ngSwitchCase="'friends'">
</ion-list>
<ion-list *ngSwitchCase="'all'">
</ion-list>
</div>
the issue here is that ion-row doesn't implement value accessor, which is required for using ngModel, you need to use an element that does implement value accessor.
for instance ion-segment
<ion-segment [(ngModel)]="type" [(ngModel)]="pre">
<ion-segment-button value="own">
Own
</ion-segment-button>
<ion-segment-button value="friends">
Friends
</ion-segment-button>
<ion-segment-button value="all">
All
</ion-segment-button>
</ion-segment>
it's weird to have two ngModels on one element, but you can if you'd like.
Related
This question was also asked here, but the solution was several years old and not well-suited for me since it's an earlier version of Ionic. I want to put City and State next to each other as an ion-input (with a floating label) and an ion-select (no label). Below is my HTML and the resulting display:
[![Result][1]][1]
<ion-row>
<ion-col size="8">
<ion-item lines="full">
<ion-label position="floating">City</ion-label>
<ion-input type="text"></ion-input>
</ion-item>
</ion-col>
<ion-col size="4">
<ion-item lines="full">
<ion-select placeholder="State">
<ion-select-option [value]="st" *ngFor="let st of [{ name: 'Louisiana'},{name: 'Texas'}]">{{st.name}}
</ion-select-option>
</ion-select>
</ion-item>
</ion-col>
</ion-row>
</ion-grid>```
[1]: https://i.stack.imgur.com/q5Hqj.png
You can use ion-label with stacked position on your select options.
<ion-grid>
<ion-row>
<ion-col size="8">
<ion-item lines="full">
<ion-label position="floating">City</ion-label>
<ion-input type="text"></ion-input>
</ion-item>
</ion-col>
<ion-col size="4">
<ion-item lines="full">
<ion-label position="stacked">City</ion-label>
<ion-select placeholder="State">
<ion-select-option [value]="st" *ngFor="let st of [{ name: 'Louisiana'},{name: 'Texas'}]">{{st.name}}
</ion-select-option>
</ion-select>
</ion-item>
</ion-col>
</ion-row>
</ion-grid>
<ion-card *ngFor="let house of (houses | async)">
<ion-list *ngIf="house.members[0] === currentUserId">
<ion-item button (click)="goToHouseDetailsPage(this.house)">
<ion-icon class="listIcon" item-left name="exit"></ion-icon>
{{ house.name }}
</ion-item>
</ion-list>
</ion-card>
This code is working and is displaying only the houses that the current user is a member of. I want to be able to iterate through this array, for when there are many members of one house.
Thanks
If you want to access the value of each item in house.members, then replace ngIf with ngFor like this:
<ion-card *ngFor="let house of (houses | async)">
<ion-list *ngFor="let member of house.members">
<ion-item button (click)="goToHouseDetailsPage(house)">
<ion-icon class="listIcon" item-left name="exit"></ion-icon>
{{ house.name }}
</ion-item>
</ion-list>
</ion-card>
I am trying to align two radio buttons in single row or horizontally in Ionic 3 as shown in below image.
html
<ion-item>
<ion-row radio-group >
<ion-col>
<ion-item>
Batch Medium
</ion-item>
</ion-col>
<ion-col>
<ion-item>
<ion-label>English</ion-label>
<ion-radio >English</ion-radio>
</ion-item>
</ion-col>
<ion-col>
<ion-item>
<ion-label>Bilingual</ion-label>
<ion-radio>Bilingual</ion-radio>
</ion-item>
</ion-col>
</ion-row>
</ion-item>
After trying this code I am getting blank screen.
That's like verbose ugly :)
Here is my take
The Looks
or
The HTML
The CSS
The code behind
There is more tweaking you can do like with flexbox
The least you invest in any framework the better :)
Enjoy!
Tryout like below code.
<ion-row radio-group [(ngModel)]="batchmedium">
<ion-col>
<ion-item>
Batch Medium*
</ion-item>
</ion-col>
<ion-col>
<ion-item>
<ion-label> English </ion-label>
<ion-radio value="English"></ion-radio>
</ion-item>
</ion-col>
<ion-col>
<ion-item>
<ion-label> Bilingual </ion-label>
<ion-radio value="Bilingual"></ion-radio>
</ion-item>
</ion-col>
</ion-row>
review this link for more details http://plnkr.co/edit/AdFPOUaufyFYXqBxNiGg?p=preview
<ion-grid>
<ion-item>
<ion-label col-5 inline>Building Type</ion-label>
<ion-select type="text" formControlName="ml_build_type">
<ion-option value="VILLA">Villa</ion-option>
<ion-option value="BLGD">Building</ion-option>
</ion-select>
</ion-item>
<ion-row>
<ion-item col-6 inline>
<ion-label >Name/Number</ion-label>
<ion-input type="text" formControlName="ml_build" ></ion-input>
</ion-item>
<ion-item col-6 inline >
<ion-label >Flat No</ion-label>
<ion-input type="number" formControlName="ml_flat" ></ion-input>
</ion-item>
</ion-row>
<ion-row>
<ion-item col-6>
<ion-label inline> Floor No</ion-label>
<ion-input type="number" min="0" formControlName="ml_floor" ></ion-input>
</ion-item>
<ion-item col-6>
<ion-label inline>Room No</ion-label>
<ion-input type="number" min="0" formControlName="ml_room_no" ></ion-input>
</ion-item>
</ion-row>
<ion-row>
<ion-item col-6>
<ion-label inline>Room Type</ion-label>
<ion-select type="text" formControlName="ml_unit" >
<ion-option *ngFor="let room of room_type" let i=i ndex [value]="room.code">{{room.room_type}}</ion-option>
</ion-select>
</ion-item>
<ion-item col-6>
<ion-label inline> Wall Number</ion-label>
<ion-input type="number" min="0" formControlName="ml_wall_no" ></ion-input>
</ion-item>
</ion-row>
<ion-row>
<ion-item col-6>
<ion-label inline> Wall Width</ion-label>
<ion-input type="number" formControlName="ml_width" ></ion-input>
</ion-item>
<ion-item col-6>
<ion-label inline> Wall Height</ion-label>
<ion-input type="number" formControlName="ml_height" ></ion-input>
</ion-item>
</ion-row>
<ion-item>
<ion-label col-5 inline>Window Exists</ion-label>
<ion-select formControlName="window_exists" type="text">
<ion-option value="Y">Yes</ion-option>
<ion-option value="N">No</ion-option>
</ion-select>
</ion-item>
</ion-grid>
this HTML code , the data is displaying according to lable size, i want them to look good and arranged in one line, All data must be display in horizontal alignment . i am trying to use as much as ionic component to make it look perfect but the data is displaying here and there.
In the .scss file for your page, you can override the Ionic label style thus to make the labels all the same width:
.item-input ion-label {
width: 150px;
}
You just have to choose a width that suits your layout and accommodates all label widths.
Ionic provides several attributes that allow you to control the styling for inputs. You probably want to use the Fixed Inline Labels.
Excerpted from Input Component Documentation emphasis added
Use fixed to place a label to the left of the input element. The label does not hide when text is entered. The input will align on the same position, regardless of the length of the label. Placeholder text can be used in conjunction with a fixed label.
Replace inline in your code with fixed.
<ion-item col-6>
<ion-label fixed> Wall Width</ion-label>
<ion-input type="number" formControlName="ml_width"></ion-input>
</ion-item>
EDIT
If you have very long labels and you can't shorten them, your options are:
1. Override the label width:
If you have static labels, you can override the label width of the fixed width labels. Fixed width labels by default are 100px wide. To set them to 200px for example, add the following to your scss file:
ion-label[fixed] {
width: 200px;
flex: 0 0 200px;
//max-width defaults to 200px
//if you're setting your label width wider than 200px
//remember to adjust the max-width as well.
}
2. Toggle the overflow property of the ion-label.
The ion-label has its overflow property set to overflow: hidden. You could set the value to visible, and then programmatically change it to hidden when the respective input is in focus or has a value that is not empty. This way the ellipsis for the label will only appear once the input has been entered and given a value.
A simple way to do this is with ngStyle. To determine if the input as focus, you could add a property to your class, setting its initial value to false, and then toggle the value by adding focus/blur events to the corresponding input as follows:
<ion-input (focus)="inFocus = true" (blur)="inFocus = false" ...>...</input>
Then you can use ngStyle to toggle the overflow value by determining whether the inFocus property is true or the input is not empty (by observing the ngModel for the input). So, you'd have something like:
<ion-label [ngStyle]="{'overflow': inFocus || myForm.myinputvalue != '' ? 'hidden' : 'visible' }">
3. Use floating labels instead.
Floating labels will fill the entire width of the input. When the user touches/clicks inside the input, the label "floats" out of the way but remains visible for reference.
Similarly, a 'stacked' label will be placed above the input, but is fixed in place:
In addition to AndrWeisR's answer I couldn't get it working without the following (Ionic 4).
.item-input ion-label {
width: 150px;
flex: 0 0 150px;
}
What should the [(ngModel)] in the following case be,such that I can persist the state of the checkbox in the slide ? I need to slide from one slide to another upon selecting the checkboxes but when I click previous the state needs to be persisted.
Here is what I've for radio buttons. I just changed the radio buttons code into checkbox but it is not working.So I removed the [value] property and now if I select one checkbox, all of them are getting checked.
<ion-content padding>
<ion-slides>
<ion-slide *ngFor="let question of questions; let i = index">
<h1>{{ question.text }}</h1>
<span *ngIf="question.type=='singlecorrect'>
<ion-list radio-group [(ngModel)]="question.answer">
<ion-item no-lines no-padding *ngFor="let choice of question.choices">
<ion-label>{{ choice.choiceText }}</ion-label>
<ion-radio [value]="choice"></ion-radio>
</ion-item>
</ion-list>
</span>
<span *ngIf="question.type=='singlecorrect'>
<ion-list checkbox-group [(ngModel)]="question.answer">
<ion-item no-lines no-padding *ngFor="let choice of question.choices">
<ion-label>{{ choice.choiceText }}</ion-label>
<ion-checkbox></checkbox> // ERROR : no value accessor found.
</ion-item>
</ion-list>
</span>
<ion-row margin-top>
<ion-col>
<button (click)="showPrevious()" ion-button text-only [disabled]="i === 0" >Previous</button>
</ion-col>
<ion-col>
<button [disabled]="!question.answer" *ngIf="i < questions.length - 1" (click)="showNext()" ion-button text-only >Next</button>
<button [disabled]="!question.answer" *ngIf="i === questions.length - 1" (click)="showNext()" ion-button text-only >Submit</button>
</ion-col>
</ion-row>
</ion-slide>
</ion-slides>
</ion-content>
I'm storing the selected choices in an array called "answer".Refer this:Angular2,Typescript: How to put the radio button checked when in an array which displays one element per page?
Can someone help me? Thanks in advance.
I'm not sure if all questions should use checkboxes, or just some of them. I've modified the previous plunker to set some questions as a multiple choice question and left the rest as single choice questions. Please take a look at the new version of the plunker
This is the end result:
In the demo, now each question has the following properties:
{
text: 'Question 1',
multiple: false,
choices: [...],
answer: null
}
If the question allows multiple answers, then the answer property is initialized with an array, with one item per available choice of that question.
// Initialize the answers
this.questions.forEach(question => {
if(question.multiple) {
// Initialize an array with as many elements as the number of choices
question.answer = new Array(question.choices.length);
}
});
Then in the view we render radio items or checkbox items accordingly:
<ion-slides>
<ion-slide *ngFor="let question of questions; let i = index">
<h1>{{ question.text }}</h1>
<!-- Single choice: radio items -->
<div *ngIf="!question.multiple">
<ion-list radio-group [(ngModel)]="question.answer">
<ion-item no-lines no-padding *ngFor="let choice of question.choices">
<ion-label>{{ choice.choiceText }}</ion-label>
<ion-radio [value]="choice"></ion-radio>
</ion-item>
</ion-list>
</div>
<!-- Multiple choice: checkbox items -->
<div *ngIf="question.multiple">
<ion-item no-lines no-padding *ngFor="let choice of question.choices; let i = index">
<ion-label>{{ choice.choiceText }}</ion-label>
<ion-checkbox [(ngModel)]="question.answer[i]"></ion-checkbox>
</ion-item>
</div>
<span style="font-size: 1.2rem;">Selected answer: {{ question.answer | json }}</span>
<ion-row margin-top>
<ion-col>
<button (click)="showPrevious()" ion-button text-only [disabled]="i === 0" >Previous</button>
</ion-col>
<ion-col>
<button [disabled]="!question.answer" *ngIf="i < questions.length - 1" (click)="showNext()" ion-button text-only >Next</button>
<button [disabled]="!question.answer" *ngIf="i === questions.length - 1" (click)="showNext()" ion-button text-only >Submit</button>
</ion-col>
</ion-row>
</ion-slide>
</ion-slides>