import { ChangeDetectorRef , ContentChild , Directive , ElementRef , EventEmitter , Input , Output , Renderer } from '@angular/core' ; import { NG_VALUE_ACCESSOR } from '@angular/forms' ; import { ListHeader } from '../list/list-header' ; import { isCheckedProperty , isTrueProperty } from '../../util/util' ; import { RadioButton } from './radio-button' ; name description usage demo see {@link /docs/components#radio Radio Component Docs} see {@link ../RadioButton RadioButton API Docs} @ Directive ( { selector : '[radio-group]' , host : { 'role' : 'radiogroup' } , providers : [ { provide : NG_VALUE_ACCESSOR , useExisting : RadioGroup , multi : true } ] , } ) export class RadioGroup { internal _disabled : boolean = false ; hidden _btns : RadioButton [ ] = [ ] ; hidden _fn : Function ; hidden _ids : number = - 1 ; hidden _init : boolean = false ; hidden value : any ; hidden id : number ; input @ Input ( ) get disabled ( ) : boolean { return this . _disabled ; } set disabled ( val ) { this . _disabled = isTrueProperty ( val ) ; } output @ Output ( ) ionChange : EventEmitter < RadioGroup > = new EventEmitter < RadioGroup > ( ) ; constructor ( private _renderer , private _elementRef , private _cd ) { this . id = ++ radioGroupIds ; } hidden ngAfterContentInit ( ) { let activeButton = this . _btns . find ( b => b . checked ) ; if ( activeButton ) { this . _setActive ( activeButton ) ; } } hidden writeValue ( val ) { console . debug ( 'radio group, writeValue' , val ) ; this . value = val ; if ( this . _init ) { this . _update ( ) ; this . onTouched ( ) ; this . ionChange . emit ( val ) ; } this . _init = true ; } hidden registerOnChange ( fn ) { this . _fn = fn ; this . onChange = ( val ) => { console . debug ( 'radio group, onChange' , val ) ; fn ( val ) ; this . value = val ; this . _update ( ) ; this . onTouched ( ) ; this . ionChange . emit ( val ) ; } ; } hidden registerOnTouched ( fn ) { this . onTouched = fn ; } hidden _update ( ) { let hasChecked = false ; this . _btns . forEach ( radioButton => { radioButton . checked = isCheckedProperty ( this . value , radioButton . value ) && ! hasChecked ; if ( radioButton . checked ) { this . _setActive ( radioButton ) ; hasChecked = true ; } } ) ; } hidden _setActive ( radioButton ) { this . _renderer . setElementAttribute ( this . _elementRef . nativeElement , 'aria-activedescendant' , radioButton . id ) ; } hidden add ( button ) { this . _btns . push ( button ) ; button . ionSelect . subscribe ( ( val ) => { this . onChange ( val ) ; } ) ; return this . id + '-' + ( ++ this . _ids ) ; } hidden remove ( button ) { let index = this . _btns . indexOf ( button ) ; if ( index > - 1 ) { if ( button . value === this . value ) { this . value = null ; } this . _btns . splice ( index , 1 ) ; } } hidden @ ContentChild ( ListHeader ) set _header ( header ) { if ( header ) { if ( ! header . id ) { header . id = 'rg-hdr-' + this . id ; } this . _renderer . setElementAttribute ( this . _elementRef . nativeElement , 'aria-describedby' , header . id ) ; } } hidden onChange ( val ) { console . debug ( 'radio group, onChange w/out formControlName' , val ) ; this . value = val ; this . _update ( ) ; this . onTouched ( ) ; this . ionChange . emit ( val ) ; this . _cd . detectChanges ( ) ; } hidden onTouched ( ) { } hidden setDisabledState ( isDisabled ) { this . disabled = isDisabled ; } } let radioGroupIds = - 1 ;