Ionic 4 - include a component based on property value - ionic-framework

How can I include a component in a loop, based on a property value.
Something like:
<ion-item *ngFor="let item of items">
?if item.type == 1? <item1 [data]="item"></item1>
?if item.type == 2? <item2 [data]="item"></item1>
</ion-item>
I would like to avoid:
<item1 *ngIf="item.type == 1" [data]="item"></item1>
<item2 *ngIf="item.type == 2" [data]="item"></item2>
If it is possible at all.

Related

how to show the selected value in radio button as checked when opening the ion-lost again after selection in ionic

I have a field which opens a list having ion-radio.On selection of an option it shows the selected value as checked and when i open the list again, the checked value is not shown.
here is my code:
code to show the options in modal controller :
let modal = this.modalCtrl.create(ListComponent, { selectEmpType: type, selectValue: value, customiseColor: this.customiseColor , formMrType :formMrType, limitedRoleList : this.limitedRoleList, formType:this.formType,defaultOU1:this.defaultOus[0],defaultOU2:this.defaultOus[1],defaultOU3:this.defaultOus[2]});
modal.onDidDismiss(data => {
if (data.type == 'single') {
this.setEmpValue(data.data, name); //data.data is the value that is selected from the list
}
}
in listcomponent.html:
<div *ngIf= "formMrType =='employee'">
<ion-list radio-group [(ngModel)]="relationship">
<ion-item *ngFor="let option of inputDatas">
<ion-label>{{option.EMPFullName}}</ion-label>
<ion-radio [checked]="option.checked" value="{{option.EMPFullName}}"></ion-radio>
</ion-item>
</ion-list>
</div>
how to show the selected option as checked when opening the list for second time.
Preferably, you should be using ion-select for such functionality..
If you are using latest ionic versions ion-radio-group
But even in your case..you can try something like this...
<ion-radio [checked]="option.checked" value="{{option.EMPFullName}}" (ionBlur)="optionBlur(option)"></ion-radio>
optionBlur(option){
if(!option['checked']){
option['checked'] = true;
}
else{
option['checked'] = !option['checked']
}
}

Ionic 4: How to update or refresh a ion-select from script?

I created an app with a register form in ionic 4 and angular. I want to do the following:
I have two ion-selects, one is for a countries list and that another is for phone codes list. The behavior i am looking for is: when a country is selected in the ion-select for countries, the corresponding telephone code must be selected automatically in the phone code ion-select.
This is my code:
ion-select for countries
<ion-select id="paisselect" formControlName="pais" (ionChange)="changeselect($event)" interface="popover">
<ion-select-option *ngFor="let c of countries" value="{{c.cod}}">{{c.name}}</ion-select-option>
</ion-select>
ion-select for phone code
<ion-select formControlName="phonecode" placeholder="Cod." interface="popover">
<ion-select-option *ngFor="let c of codetele" value="{{c.code}}" selected="{{codigoselected == c.code}}">{{c.code}}</ion-select-option>
</ion-select>
Here is the function i am using to update the phone code ion-select
changeselect($event){
console.log($event.target.value) ;
let item1 = this.countries.find(i => i.cod === $event.target.value);
console.log(item1) ;
this.codigoselected = item1.code;
console.log(this.codigoselected) ;
}
I am using the variable "codigoselected" to determine which country is selected. for this, in the ion-select-option i am using a condition to change the selected status of the option like this:
<ion-select-option *ngFor="let c of codetele" value="{{c.code}}" selected="{{codigoselected == c.code}}">{{c.code}}</ion-select-option>
The current behavior is like this:
I selected a country:
But the ion-select for phone codes seems not to be updated
But when I click on the field, the specific code is selected
I need to do clic under option is selected in order to field be refreshed:
So, how can I make the field for phone codes update automatically in the interface without the user clicking?
Try this, pass the phone code select element to your changeselect(event, phoneCodeSelect) function.
<ion-select id="paisselect" formControlName="pais" (ionChange)="changeselect($event, phoneCodeSelect)" interface="popover">
<ion-select-option *ngFor="let c of countries" value="{{c.cod}}">{{c.name}}</ion-select-option>
</ion-select>
Add #phoneCodeSelect to your phone code select element.
<ion-select #phoneCodeSelect formControlName="phonecode" placeholder="Cod." interface="popover">
<ion-select-option *ngFor="let c of codetele" value="{{c.code}}" selected="{{codigoselected == c.code}}">{{c.code}}</ion-select-option>
</ion-select>
Then in your function change the value of the select element manually, while also updating the phoneCode form control value.
changeselect($event, phoneCodeSelect){
console.log($event.target.value) ;
let item1 = this.countries.find(i => i.cod === $event.target.value);
console.log(item1) ;
this.yourFormGroup.value.phonecode = item1.code; // change yourFormGroup to what your variable's name is
phoneCodeSelect.value = item1.code;
}

Problem refreshing ion-select-options when data is updated

I am developing an Ionic application (v.4 final release)...
My problem:
I have an <ion-select> and this select has a list of <ion-select-option>, and this options was created doing *ngFor... the problem is: when I change the array, remove an element, for example, the ionc-select-options cannot re-render the new status of this array.
<ion-select>
<ion-select-option *ngFor="let question of questions">{{ question }}</ion-select-option>
</ion-select>
(I am updating questions array)
Any ideas?
UPDATE:
If a put the *ngFor in other element, like a div, it works fine:
example:
(It is no updating when I delete the first element)
<ion-select>
<ion-select-option *ngFor="let question of questions">{{ question }}</ion-select-option>
</ion-select>
<button (click)="deleteFirst()>Delete first!</button>
(It is updating when I delete the first element)
<div *ngFor="let question of questions"></div>
<button (click)="deleteFirst()>Delete first!</button>
class MyComponent() {
public questions = ['question1','question2','question3'];
deleteFirst() {
this.questions.splice(0, 1);
}
}
You are using splice method alters the content of an array but doesn't change its reference.
In other words, you should work with immutable objects/Array, and create new instances when you need to make a change.
In your case :
deleteFirst() {
if (this.questions.length) {
this.questions = this.questions.filter((el, index) => index > 0);
}
}
Here filter returns a new reference to an array containing objs that fulfill a condition

Prevent default (ionChange) ion-checkbox

What i´m trying to do is to prevent default event on (ionChange).
I want to be able to set the checkbox checked= true or checked= false
If a condition is true or false.
<ion-item *ngFor="let classroom of teachersClassrooms">
<ion-label>{{classroom.name}}</ion-label>
<ion-checkbox color="royal" [checked]="classroom.is_set" (ionChange)="updateClassroom(classroom, $event)"></ion-checkbox>
</ion-item>
updateClassroom(item, cbox: Checkbox){
//cbox.preventDefault(); ------> Not Work
if(something){
cbox.checked = true
}else{
cbox.checked = false
}
}
The comments above are a better approach to the ultimate problem. But to answer the question "what i'm trying to do is to prevent default event on ionChange", the following works in an Ionic 4 template:
<ion-checkbox (click)="$event.stopPropagation()" (ionChange)="doSomething()"></ion-checkbox>

How to check ion-checkbox from database

I have this ionic tag already populated and with all items unchecked:
<ion-checkbox ng-repeat="categoria in listaCategorias"
ng-model="categoria.checked"
ng-checked="categoria.checked"
ng-change="recuperarServicos(categoria)">
{{ categoria.nmCategoria }}
</ion-checkbox>
And here my controller code that has a list of 'categoria ids':
//here I have the ids recovered from database that I split into an array of ids
var idsCategoria = $scope.meuanuncio.idsCategoria.trim().split(',');
if($scope.listaCategorias.length > 0)
{
//for each item in my listaCategorias (used in ng-repeat)
for (var i = 0; i < $scope.listaCategorias.length; i++) {
var item = $scope.listaCategorias[i];
//I compare id from each item with my list recovered from database
if(idsCategoria.indexOf($scope.listaCategorias[i].idCategoria) != -1)
{
//If the item id exist in database list, I check the item
item.checked = true;
// Below there are other ways that I tried to use
// $scope.listaCategorias[i].Selected = true;
// $scope.listaCategorias[i].checked = true;
$scope.listaCategorias[0].checked = true;
}
}
};
But I can´t do my ion-checkbox item checked.
What am I doing wrong ?
Thanks.
ng-model="categoria.checked"
looks fine, don't think you need the ng-checked though.
var item = $scope.listaCategorias[i];
item.checked = true;
Nope, the item gets lost through the loop. I see you were trying with:
$scope.listaCategorias[i].checked = true;
Did you get an error or something? Because this looks like the way to do it.
Maybe try looping on a div around the ion-checkbox? aka
<div ng-repeat="categoria in listaCategorias">
<ion-checkbox ng-model="categoria.checked"
ng-change="recuperarServicos(categoria)">
{{ categoria.nmCategoria }}
</ion-checkbox>
</div>
try this :
<div ng-repeat="categoria in listaCategorias track by $index">
<ion-item class="item item-checkbox">
<label class="checkbox">
<input type="checkbox" ng-model="categoria.checked" ng-change="recuperarServicos(categoria)">
</label>
{{categoria.nmCategoria}}
</ion-item>
</div>
Controller:
$scope.recuperarServicos = function(categoria){
if(categoria.selected && ($scope.selectedItems.indexOf(categoria.name) < 0)){
$scope.selectedItems.push(categoria.name);
}else{
$scope.selectedItems.splice($scope.selectedItems.indexOf(categoria.name), 1);
}
};
hope this helps you..in someway..!
My problem was when I attribute my array of items to the $scope.listaCategorias.
I was doing that:
$scope.listaCategorias = listaCategorias;
But I need to do that:
$scope.listaCategorias.push.apply($scope.listaCategorias, listaCategorias);
I was building an array with the checked attribute inside, but when I associate my built list, I was associating the first one, which has not the checked attribute setted.
Let me show my code now.
My view :
<div ng-repeat="item in listaCategorias track by $index">
<ion-item class="item item-checkbox">
<label class="checkbox">
<input type="checkbox" ng-model="item.checked" ng-checked="item.checked" ng-change="recuperarServicos(item)">
</label>
{{ item.nmCategoria }}
</ion-item>
</div>
My controller:
//here I get all my 'categorias' from datatable
listaCategorias = appFactory.recuperarCategorias();
//If list is not null go ahead
if(listaCategorias != null) {
//split into an array all my 'categoria' ids
var idsCategoria = $scope.meuanuncio.idsCategoria.split(',');
//if list has items go ahead
if(listaCategorias.length > 0) {
for (var i = 0; i < listaCategorias.length; i++) {
//if 'categoria' id exists in datatable list set true, else false
if(idsCategoria.indexOf(listaCategorias[i].idCategoria) != -1) {
listaCategorias[i].checked = true;
}
else {
listaCategorias[i].checked = false;
}
}
};
//Here is the point !!! I need to load my $scope variable this way to build all my items correctly
$scope.listaCategorias.push.apply($scope.listaCategorias, listaCategorias);
}