Custom component for beta11 form

Hi everyone. After update to beta 11 my previous code return error
Error: No value accessor for ‘bankCountry’

My form

<form class="standard-content-wrapper standard-no-pt" [formGroup]="bankDetailsForm">
            <ion-item>
                <ion-label floating>{{'BANK_DETAILS.FORM.LABEL.BANK_ADDRESS' | translate}}</ion-label>
                <ion-input type="text"
                           formControlName="bankAddress"
                           [(ngModel)]="bankData.bank_address">
                </ion-input>
            </ion-item>

            <country-selector [(ngModel)]="bankData.bank_country"
                              formControlName="bankCountry"
                              placeholder="{{'BANK_DETAILS.FORM.LABEL.BANK_COUNTRY' | translate}}">
            </country-selector>
        </ion-list>
    </form>

For form I include REACTIVE_FORM_DIRECTIVES

Country-selector html

<ion-item class="country-selector-ion-input">
    <ion-label floating>{{placeholder}}</ion-label>
    <ion-input type="text"
               class="country-selector"
               disabled
               [(ngModel)]="_value">
    </ion-input>
</ion-item>

Country-selector.ts (sorry for eye-bleeding code, this part was written by our newbie developer)

import {Component, ElementRef, EventEmitter, forwardRef, Input, HostListener, Optional, Output, Provider, Renderer, QueryList, ViewEncapsulation } from '@angular/core';
import {NG_VALUE_ACCESSOR} from '@angular/common';
import {Form, Item, NavController, ModalController} from 'ionic-angular';
import {CountryListModal} from '../country-selector/country-list/country-list.modal';

const SELECT_VALUE_ACCESSOR = new Provider(
    NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => CountrySelectorComponent), multi: true});

@Component({
    selector: 'country-selector',
    templateUrl: 'build/shared/directives/country-selector/country-selector.html',
    providers: [SELECT_VALUE_ACCESSOR, ModalController],
    encapsulation: ViewEncapsulation.None,
})
export class CountrySelectorComponent {
    private _fn: Function;
    private _value: string;

    @Input() placeholder: string;

    constructor(
        private _form: Form,
        private _elementRef: ElementRef,
        private _renderer: Renderer,
        private _modal: ModalController,
        @Optional() private _item: Item,
        @Optional() private _nav: NavController
    ) {
        this._form.register(this);
    }

    @HostListener('click', ['$event'])
    private _click(ev: UIEvent) {
        if (ev.detail === 0) {
            // do not continue if the click event came from a form submit
            return;
        }
        ev.preventDefault();
        ev.stopPropagation();
        this._open();
    }

    private _open() {
        var modal = this._modal.create(CountryListModal);
        modal.onDidDismiss(data => {
            this.writeValue(data.country);
            this.onChange(data.country);
        });
        modal.present();
    }

    writeValue(val: any) { this._value = val; }

    ngAfterContentInit() { }

    registerOnChange(fn: Function): void {
        this._fn = fn;
        this.onChange = (val: any) => {
            fn(val);
            this.onTouched();
        };
    }

    registerOnTouched(fn: any) { this.onTouched = fn; }

    onChange(val: any) {
        this.writeValue(val);
        this.onTouched();
    }

    onTouched() { }

    ngOnDestroy() { this._form.deregister(this); }
}

Any ideas how solve my problem ? Native ionic ion-select is unsuitable (pixel perfect design).
Thanks for your answer in advice.

I don’t know if this would help, but have you tried building the custom component with native html instead of the Ionic input. I think then you would want use a value accessor from angular, not sure how thought. Just some thoughts.

1 Like

@El_Dee565, Thanks. I take your idea and rewrite my component according this guide. All works