0
# Form Controls
1
2
Advanced form controls including datepickers, timepickers, typeahead, rating, and button controls for enhanced user input.
3
4
## Capabilities
5
6
### Datepicker
7
8
Bootstrap-styled date picker with comprehensive configuration options and localization support.
9
10
```typescript { .api }
11
/**
12
* Bootstrap date picker directive for single date selection
13
*/
14
@Directive({
15
selector: '[bsDatepicker]'
16
})
17
class BsDatepickerDirective implements OnInit, OnDestroy {
18
/** Configuration options */
19
@Input() bsConfig: Partial<BsDatepickerConfig>;
20
/** Selected date value */
21
@Input() bsValue: Date;
22
/** Minimum selectable date */
23
@Input() minDate: Date;
24
/** Maximum selectable date */
25
@Input() maxDate: Date;
26
/** Custom CSS classes for specific dates */
27
@Input() dateCustomClasses: DatepickerDateCustomClasses[];
28
/** Days of week to disable (0-6, Sunday-Saturday) */
29
@Input() daysDisabled: number[];
30
/** Specific dates to disable */
31
@Input() datesDisabled: Date[];
32
/** Datepicker placement */
33
@Input() placement: 'top' | 'bottom' | 'left' | 'right' = 'bottom';
34
/** Event triggers */
35
@Input() triggers: string = 'click';
36
/** Container for datepicker */
37
@Input() container: string = 'body';
38
/** Disable the datepicker */
39
@Input() isDisabled: boolean = false;
40
41
/** Event emitted when datepicker is shown */
42
@Output() onShown: EventEmitter<BsDatepickerDirective>;
43
/** Event emitted when datepicker is hidden */
44
@Output() onHidden: EventEmitter<BsDatepickerDirective>;
45
/** Event emitted when date value changes */
46
@Output() bsValueChange: EventEmitter<Date>;
47
48
/** Show the datepicker */
49
show(): void;
50
/** Hide the datepicker */
51
hide(): void;
52
/** Toggle datepicker visibility */
53
toggle(): void;
54
/** Set date value */
55
setConfig(): void;
56
}
57
58
/**
59
* Inline datepicker directive (always visible)
60
*/
61
@Directive({
62
selector: '[bsDatepickerInline]'
63
})
64
class BsDatepickerInlineDirective extends BsDatepickerDirective {}
65
66
/**
67
* Date range picker directive for selecting date ranges
68
*/
69
@Directive({
70
selector: '[bsDaterangepicker]'
71
})
72
class BsDaterangepickerDirective implements OnInit, OnDestroy {
73
/** Configuration options */
74
@Input() bsConfig: Partial<BsDaterangepickerConfig>;
75
/** Selected date range */
76
@Input() bsValue: Date[];
77
/** Minimum selectable date */
78
@Input() minDate: Date;
79
/** Maximum selectable date */
80
@Input() maxDate: Date;
81
/** Custom CSS classes for specific dates */
82
@Input() dateCustomClasses: DatepickerDateCustomClasses[];
83
/** Days to disable */
84
@Input() daysDisabled: number[];
85
/** Specific dates to disable */
86
@Input() datesDisabled: Date[];
87
/** Placement relative to trigger */
88
@Input() placement: 'top' | 'bottom' | 'left' | 'right' = 'bottom';
89
/** Event triggers */
90
@Input() triggers: string = 'click';
91
/** Container for datepicker */
92
@Input() container: string = 'body';
93
/** Disable the datepicker */
94
@Input() isDisabled: boolean = false;
95
96
/** Event emitted when shown */
97
@Output() onShown: EventEmitter<BsDaterangepickerDirective>;
98
/** Event emitted when hidden */
99
@Output() onHidden: EventEmitter<BsDaterangepickerDirective>;
100
/** Event emitted when date range changes */
101
@Output() bsValueChange: EventEmitter<Date[]>;
102
}
103
104
/**
105
* Configuration interface for datepicker
106
*/
107
interface BsDatepickerConfig {
108
/** Container CSS class */
109
containerClass: string;
110
/** Custom CSS class */
111
customClass: string;
112
/** Date input format */
113
dateInputFormat: string;
114
/** Use UTC dates */
115
useUtc: boolean;
116
/** Return focus to trigger after selection */
117
returnFocusToInput: boolean;
118
/** Show week numbers */
119
showWeekNumbers: boolean;
120
/** First day of week (0-6) */
121
startingDayOfWeek: number;
122
/** Adaptive position */
123
adaptivePosition: boolean;
124
/** Show today button */
125
showTodayButton: boolean;
126
/** Show clear button */
127
showClearButton: boolean;
128
/** Clear button label */
129
clearButtonLabel: string;
130
/** Today button label */
131
todayButtonLabel: string;
132
/** Clear position */
133
clearPosition: string;
134
/** Today position */
135
todayPosition: string;
136
/** Range separator for date ranges */
137
rangeSeparator: string;
138
/** Select week */
139
selectWeek: boolean;
140
/** Select from other month */
141
selectFromOtherMonth: boolean;
142
/** Display one month */
143
displayOneMonthRange: boolean;
144
/** Display months */
145
displayMonths: number;
146
}
147
148
/**
149
* Date custom classes interface
150
*/
151
interface DatepickerDateCustomClasses {
152
/** Target date */
153
date: Date;
154
/** CSS classes to apply */
155
classes: string[];
156
}
157
158
/**
159
* View modes for datepicker
160
*/
161
type BsDatepickerViewMode = 'day' | 'month' | 'year';
162
163
/**
164
* Localization service for datepicker
165
*/
166
@Injectable()
167
class BsLocaleService {
168
/** Current locale */
169
currentLocale: string;
170
171
/** Use specified locale */
172
use(locale: string): void;
173
/** Get current locale data */
174
getCurrentLocale(): string;
175
/** Get locale data */
176
getLocaleData(locale: string): any;
177
}
178
179
/**
180
* Angular module for datepicker functionality
181
*/
182
@NgModule({
183
declarations: [
184
BsDatepickerDirective,
185
BsDatepickerInlineDirective,
186
BsDaterangepickerDirective,
187
BsDaterangepickerInlineDirective,
188
BsDatepickerInputDirective,
189
BsDaterangepickerInputDirective
190
],
191
exports: [
192
BsDatepickerDirective,
193
BsDatepickerInlineDirective,
194
BsDaterangepickerDirective,
195
BsDaterangepickerInlineDirective,
196
BsDatepickerInputDirective,
197
BsDaterangepickerInputDirective
198
],
199
providers: [BsLocaleService]
200
})
201
class BsDatepickerModule {}
202
```
203
204
**Usage Example:**
205
206
```typescript
207
import { BsDatepickerModule, BsDatepickerConfig, BsLocaleService } from 'ngx-bootstrap/datepicker';
208
import { defineLocale } from 'ngx-bootstrap/chronos';
209
import { esLocale } from 'ngx-bootstrap/locale';
210
211
@Component({
212
template: `
213
<!-- Single date picker -->
214
<input
215
type="text"
216
class="form-control"
217
bsDatepicker
218
[bsValue]="selectedDate"
219
[bsConfig]="datePickerConfig"
220
(bsValueChange)="onDateChange($event)"
221
placeholder="Select date">
222
223
<!-- Date range picker -->
224
<input
225
type="text"
226
class="form-control"
227
bsDaterangepicker
228
[bsValue]="dateRange"
229
[minDate]="minDate"
230
[maxDate]="maxDate"
231
(bsValueChange)="onRangeChange($event)"
232
placeholder="Select date range">
233
234
<!-- Inline datepicker -->
235
<div
236
bsDatepickerInline
237
[bsValue]="selectedDate"
238
(bsValueChange)="onDateChange($event)">
239
</div>
240
`,
241
imports: [BsDatepickerModule]
242
})
243
export class MyComponent {
244
selectedDate = new Date();
245
dateRange: Date[] = [];
246
minDate = new Date();
247
maxDate = new Date();
248
249
datePickerConfig: Partial<BsDatepickerConfig> = {
250
showWeekNumbers: true,
251
dateInputFormat: 'YYYY-MM-DD',
252
containerClass: 'theme-dark-blue'
253
};
254
255
constructor(private localeService: BsLocaleService) {
256
// Set locale
257
defineLocale('es', esLocale);
258
this.localeService.use('es');
259
260
// Set date constraints
261
this.maxDate.setDate(this.maxDate.getDate() + 7);
262
}
263
264
onDateChange(date: Date) {
265
this.selectedDate = date;
266
}
267
268
onRangeChange(range: Date[]) {
269
this.dateRange = range;
270
}
271
}
272
```
273
274
### Timepicker
275
276
Time selection component with configurable step intervals and 12/24 hour formats.
277
278
```typescript { .api }
279
/**
280
* Time selection component
281
*/
282
@Component({
283
selector: 'timepicker'
284
})
285
class TimepickerComponent implements ControlValueAccessor, OnInit {
286
/** Hours step interval */
287
@Input() hourStep: number = 1;
288
/** Minutes step interval */
289
@Input() minuteStep: number = 5;
290
/** Seconds step interval */
291
@Input() secondsStep: number = 10;
292
/** Make inputs readonly */
293
@Input() readonlyInput: boolean = false;
294
/** Disable the component */
295
@Input() disabled: boolean = false;
296
/** Enable mousewheel support */
297
@Input() mousewheel: boolean = true;
298
/** Enable arrow key support */
299
@Input() arrowkeys: boolean = true;
300
/** Show spinner buttons */
301
@Input() showSpinners: boolean = true;
302
/** Show seconds input */
303
@Input() showSeconds: boolean = false;
304
/** Show minutes input */
305
@Input() showMinutes: boolean = true;
306
/** Show AM/PM selector */
307
@Input() showMeridian: boolean = true;
308
/** AM/PM labels */
309
@Input() meridians: string[] = ['AM', 'PM'];
310
/** Minimum time */
311
@Input() min: Date;
312
/** Maximum time */
313
@Input() max: Date;
314
/** Placeholder for hours */
315
@Input() hoursPlaceholder: string = 'HH';
316
/** Placeholder for minutes */
317
@Input() minutesPlaceholder: string = 'MM';
318
/** Placeholder for seconds */
319
@Input() secondsPlaceholder: string = 'SS';
320
/** Allow empty time values */
321
@Input() allowEmptyTime: boolean = false;
322
323
/** Increment hours */
324
incrementHours(): void;
325
/** Decrement hours */
326
decrementHours(): void;
327
/** Increment minutes */
328
incrementMinutes(): void;
329
/** Decrement minutes */
330
decrementMinutes(): void;
331
/** Increment seconds */
332
incrementSeconds(): void;
333
/** Decrement seconds */
334
decrementSeconds(): void;
335
/** Toggle meridian (AM/PM) */
336
toggleMeridian(): void;
337
}
338
339
/**
340
* Global configuration for timepicker
341
*/
342
@Injectable()
343
class TimepickerConfig {
344
/** Default hours step */
345
hourStep: number = 1;
346
/** Default minutes step */
347
minuteStep: number = 5;
348
/** Default seconds step */
349
secondsStep: number = 10;
350
/** Default meridian display */
351
showMeridian: boolean = true;
352
/** Default meridian labels */
353
meridians: string[] = ['AM', 'PM'];
354
/** Default readonly state */
355
readonlyInput: boolean = false;
356
/** Default disabled state */
357
disabled: boolean = false;
358
/** Default mousewheel support */
359
mousewheel: boolean = true;
360
/** Default arrow key support */
361
arrowkeys: boolean = true;
362
/** Default spinner display */
363
showSpinners: boolean = true;
364
/** Default seconds display */
365
showSeconds: boolean = false;
366
/** Default minutes display */
367
showMinutes: boolean = true;
368
/** Default empty time handling */
369
allowEmptyTime: boolean = false;
370
/** Default minimum time */
371
min?: Date;
372
/** Default maximum time */
373
max?: Date;
374
/** Default hours placeholder */
375
hoursPlaceholder: string = 'HH';
376
/** Default minutes placeholder */
377
minutesPlaceholder: string = 'MM';
378
/** Default seconds placeholder */
379
secondsPlaceholder: string = 'SS';
380
/** Default hours aria label */
381
ariaLabelHours: string = 'hours';
382
/** Default minutes aria label */
383
ariaLabelMinutes: string = 'minutes';
384
/** Default seconds aria label */
385
ariaLabelSeconds: string = 'seconds';
386
}
387
388
/**
389
* Angular module for timepicker functionality
390
*/
391
@NgModule({
392
declarations: [TimepickerComponent],
393
exports: [TimepickerComponent]
394
})
395
class TimepickerModule {}
396
```
397
398
**Usage Example:**
399
400
```typescript
401
import { TimepickerModule, TimepickerConfig } from 'ngx-bootstrap/timepicker';
402
403
@Component({
404
template: `
405
<timepicker
406
[(ngModel)]="selectedTime"
407
[hourStep]="1"
408
[minuteStep]="15"
409
[showMeridian]="true"
410
[showSeconds]="false"
411
[readonlyInput]="false"
412
[disabled]="isDisabled">
413
</timepicker>
414
415
<timepicker
416
[(ngModel)]="time24"
417
[showMeridian]="false"
418
[showSeconds]="true"
419
[min]="minTime"
420
[max]="maxTime">
421
</timepicker>
422
`,
423
imports: [TimepickerModule]
424
})
425
export class MyComponent {
426
selectedTime = new Date();
427
time24 = new Date();
428
isDisabled = false;
429
minTime = new Date();
430
maxTime = new Date();
431
432
constructor(timepickerConfig: TimepickerConfig) {
433
// Global configuration
434
timepickerConfig.showMeridian = false;
435
timepickerConfig.showSeconds = true;
436
437
// Set time constraints
438
this.minTime.setHours(9, 0, 0);
439
this.maxTime.setHours(17, 30, 0);
440
}
441
}
442
```
443
444
### Typeahead
445
446
Auto-complete functionality with flexible data sources and customizable matching.
447
448
```typescript { .api }
449
/**
450
* Typeahead directive for auto-complete functionality
451
*/
452
@Directive({
453
selector: '[typeahead]'
454
})
455
class TypeaheadDirective implements OnInit, OnDestroy {
456
/** Data source for suggestions */
457
@Input() typeahead: any;
458
/** Minimum characters to trigger search */
459
@Input() typeaheadMinLength: number = 1;
460
/** Wait time before triggering search */
461
@Input() typeaheadWaitMs: number = 0;
462
/** Maximum number of options to display */
463
@Input() typeaheadOptionsLimit: number = 20;
464
/** Custom option template */
465
@Input() typeaheadOptionField: string;
466
/** Async loading indicator */
467
@Input() typeaheadAsync: boolean;
468
/** Latinize characters for matching */
469
@Input() typeaheadLatinize: boolean = true;
470
/** Single words matching */
471
@Input() typeaheadSingleWords: boolean = true;
472
/** Word delimiters */
473
@Input() typeaheadWordDelimiters: string = ' ';
474
/** Phrase delimiters */
475
@Input() typeaheadPhraseDelimiters: string = '\'"';
476
/** Loading text */
477
@Input() typeaheadLoadingText: string = 'Loading...';
478
/** No results text */
479
@Input() typeaheadNoResultsText: string = 'No Results Found';
480
/** Hide results on blur */
481
@Input() typeaheadHideResultsOnBlur: boolean = true;
482
/** Cancel request on focus lost */
483
@Input() typeaheadCancelRequestOnFocusLost: boolean = false;
484
/** Select first item */
485
@Input() typeaheadSelectFirstItem: boolean = true;
486
/** Scroll to active option */
487
@Input() typeaheadScrollable: boolean = false;
488
/** Scroll height */
489
@Input() typeaheadOptionsInScrollableView: number = 5;
490
/** Container for dropdown */
491
@Input() container: string;
492
/** Dropdown up */
493
@Input() dropup: boolean = false;
494
495
/** Event emitted when loading starts */
496
@Output() typeaheadLoading: EventEmitter<boolean> = new EventEmitter();
497
/** Event emitted when no results found */
498
@Output() typeaheadNoResults: EventEmitter<boolean> = new EventEmitter();
499
/** Event emitted when option is selected */
500
@Output() typeaheadOnSelect: EventEmitter<TypeaheadMatch> = new EventEmitter();
501
/** Event emitted when preview changes */
502
@Output() typeaheadOnPreview: EventEmitter<TypeaheadMatch> = new EventEmitter();
503
/** Event emitted when blur occurs */
504
@Output() typeaheadOnBlur: EventEmitter<any> = new EventEmitter();
505
506
/** Change active option */
507
changeModel(match: TypeaheadMatch): void;
508
/** Get active option */
509
getActive(): TypeaheadMatch;
510
/** Select active option */
511
selectActiveMatch(): void;
512
/** Select match */
513
selectMatch(value: TypeaheadMatch): void;
514
/** Show matches */
515
show(): void;
516
/** Hide matches */
517
hide(): void;
518
}
519
520
/**
521
* Typeahead match result
522
*/
523
class TypeaheadMatch {
524
constructor(
525
public item: any,
526
public value?: string,
527
public header?: boolean
528
) {}
529
530
/** Check if option is header */
531
isHeader(): boolean;
532
/** String representation */
533
toString(): string;
534
}
535
536
/**
537
* Typeahead configuration options
538
*/
539
class TypeaheadOptions {
540
/** Placement of dropdown */
541
placement: string;
542
/** Animation enabled */
543
animation: boolean;
544
/** Typeahead container */
545
typeaheadRef: any;
546
}
547
548
/**
549
* Global configuration for typeahead
550
*/
551
@Injectable()
552
class TypeaheadConfig {
553
/** Default hide results on blur */
554
hideResultsOnBlur: boolean = true;
555
/** Default cancel request on focus lost */
556
cancelRequestOnFocusLost: boolean = false;
557
/** Default select first item */
558
selectFirstItem: boolean = true;
559
/** Default minimum length */
560
minLength: number = 1;
561
/** Default wait time */
562
waitMs: number = 0;
563
}
564
565
/**
566
* Utility functions for typeahead
567
*/
568
interface TypeaheadUtils {
569
/** Escape regex special characters */
570
escapeRegexp(text: string): string;
571
/** Get value from nested object property */
572
getValueFromObject(object: any, path: string): string;
573
/** Tokenize text for matching */
574
tokenize(text: string, wordRegexDelimiters?: string, phraseRegexDelimiters?: string): string[];
575
/** Convert text to latin characters */
576
latinize(text: string): string;
577
}
578
579
/** Character mapping for latinization */
580
declare const latinMap: { [key: string]: string };
581
582
/**
583
* Template context interfaces
584
*/
585
interface TypeaheadOptionItemContext {
586
/** Match object */
587
$implicit: TypeaheadMatch;
588
/** Match index */
589
index: number;
590
}
591
592
interface TypeaheadOptionListContext {
593
/** All matches */
594
$implicit: TypeaheadMatch[];
595
/** Query string */
596
query: string;
597
}
598
599
/**
600
* Angular module for typeahead functionality
601
*/
602
@NgModule({
603
declarations: [
604
TypeaheadDirective,
605
TypeaheadContainerComponent
606
],
607
exports: [TypeaheadDirective]
608
})
609
class TypeaheadModule {}
610
```
611
612
**Usage Example:**
613
614
```typescript
615
import { TypeaheadModule } from 'ngx-bootstrap/typeahead';
616
import { Observable, of } from 'rxjs';
617
import { map, mergeMap } from 'rxjs/operators';
618
619
@Component({
620
template: `
621
<!-- Static data source -->
622
<input
623
type="text"
624
class="form-control"
625
[(ngModel)]="selectedState"
626
[typeahead]="states"
627
placeholder="Type to search states">
628
629
<!-- Async data source -->
630
<input
631
type="text"
632
class="form-control"
633
[(ngModel)]="selectedUser"
634
[typeahead]="asyncUsers"
635
typeaheadOptionField="name"
636
[typeaheadMinLength]="2"
637
[typeaheadWaitMs]="300"
638
(typeaheadOnSelect)="onUserSelect($event)"
639
placeholder="Search users">
640
641
<!-- Custom template -->
642
<input
643
type="text"
644
class="form-control"
645
[(ngModel)]="selectedProduct"
646
[typeahead]="products"
647
typeaheadOptionField="name"
648
[typeaheadItemTemplate]="customTemplate"
649
placeholder="Search products">
650
651
<ng-template #customTemplate let-model="item" let-index="index">
652
<div>
653
<strong>{{model.name}}</strong> - ${{model.price}}
654
</div>
655
</ng-template>
656
`,
657
imports: [TypeaheadModule]
658
})
659
export class MyComponent {
660
selectedState: string;
661
selectedUser: string;
662
selectedProduct: string;
663
664
states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California'];
665
666
products = [
667
{ name: 'Laptop', price: 999 },
668
{ name: 'Mouse', price: 25 },
669
{ name: 'Keyboard', price: 75 }
670
];
671
672
asyncUsers = new Observable((observer: any) => {
673
// Simulate API call
674
observer.next([
675
{ id: 1, name: 'John Doe', email: 'john@example.com' },
676
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
677
]);
678
});
679
680
onUserSelect(event: any) {
681
console.log('Selected user:', event.item);
682
}
683
}
684
```
685
686
### Rating
687
688
Star rating component with configurable icons and half-star support.
689
690
```typescript { .api }
691
/**
692
* Star rating component
693
*/
694
@Component({
695
selector: 'rating'
696
})
697
class RatingComponent implements ControlValueAccessor, OnInit {
698
/** Maximum rating value */
699
@Input() max: number = 5;
700
/** Current rating value */
701
@Input() rate: number = 0;
702
/** Read-only mode */
703
@Input() readonly: boolean = false;
704
/** Custom titles for rating values */
705
@Input() titles: string[] = [];
706
/** Enable/disable rating */
707
@Input() disabled: boolean = false;
708
/** Custom template for rating display */
709
@Input() customTemplate: TemplateRef<any>;
710
711
/** Event emitted when rating changes */
712
@Output() onHover: EventEmitter<number> = new EventEmitter();
713
/** Event emitted when mouse leaves */
714
@Output() onLeave: EventEmitter<number> = new EventEmitter();
715
716
/** Rating range array */
717
range: number[] = [];
718
/** Current hover value */
719
preValue: number;
720
721
/** Enter rating item */
722
enter(value: number): void;
723
/** Reset to original value */
724
reset(): void;
725
/** Select rating value */
726
rate(value: number): void;
727
}
728
729
/**
730
* Global configuration for rating
731
*/
732
@Injectable()
733
class RatingConfig {
734
/** Default maximum rating */
735
max: number = 5;
736
/** Default readonly state */
737
readonly: boolean = false;
738
/** Default disabled state */
739
disabled: boolean = false;
740
}
741
742
/**
743
* Angular module for rating functionality
744
*/
745
@NgModule({
746
declarations: [RatingComponent],
747
exports: [RatingComponent]
748
})
749
class RatingModule {}
750
```
751
752
**Usage Example:**
753
754
```typescript
755
import { RatingModule } from 'ngx-bootstrap/rating';
756
757
@Component({
758
template: `
759
<!-- Basic rating -->
760
<rating
761
[(ngModel)]="currentRate"
762
[max]="maxRating"
763
[readonly]="false"
764
(onHover)="onRatingHover($event)"
765
(onLeave)="onRatingLeave($event)">
766
</rating>
767
768
<!-- Custom titles -->
769
<rating
770
[(ngModel)]="productRating"
771
[titles]="ratingTitles"
772
[disabled]="isDisabled">
773
</rating>
774
775
<!-- Readonly display -->
776
<rating
777
[ngModel]="averageRating"
778
[readonly]="true"
779
[max]="5">
780
</rating>
781
`,
782
imports: [RatingModule]
783
})
784
export class MyComponent {
785
currentRate = 3;
786
maxRating = 10;
787
productRating = 4;
788
averageRating = 4.5;
789
isDisabled = false;
790
791
ratingTitles = ['Poor', 'Fair', 'Good', 'Very Good', 'Excellent'];
792
793
onRatingHover(rating: number) {
794
console.log('Hovering over rating:', rating);
795
}
796
797
onRatingLeave(rating: number) {
798
console.log('Left rating:', rating);
799
}
800
}
801
```
802
803
### Button Controls
804
805
Button directives for checkbox and radio button behavior.
806
807
```typescript { .api }
808
/**
809
* Directive for checkbox-like button behavior
810
*/
811
@Directive({
812
selector: '[btnCheckbox]'
813
})
814
class ButtonCheckboxDirective implements ControlValueAccessor, OnInit {
815
/** Button active state */
816
@Input() btnCheckbox: boolean;
817
/** Uncheckable button */
818
@Input() uncheckable: boolean = true;
819
/** True value for checkbox */
820
@Input() trueValue: any = true;
821
/** False value for checkbox */
822
@Input() falseValue: any = false;
823
824
/** Toggle button state */
825
toggle(): void;
826
}
827
828
/**
829
* Directive for radio button behavior
830
*/
831
@Directive({
832
selector: '[btnRadio]'
833
})
834
class ButtonRadioDirective implements ControlValueAccessor, OnInit {
835
/** Radio button value */
836
@Input() btnRadio: any;
837
/** Uncheckable radio */
838
@Input() uncheckable: boolean = false;
839
/** Radio group value */
840
@Input() value: any;
841
842
/** Set button state */
843
onClick(): void;
844
}
845
846
/**
847
* Group directive for radio buttons
848
*/
849
@Directive({
850
selector: '[btnRadioGroup]'
851
})
852
class ButtonRadioGroupDirective implements ControlValueAccessor {
853
/** Radio group value */
854
value: any;
855
856
/** Write value */
857
writeValue(value: any): void;
858
}
859
860
/**
861
* Angular module for button controls
862
*/
863
@NgModule({
864
declarations: [
865
ButtonCheckboxDirective,
866
ButtonRadioDirective,
867
ButtonRadioGroupDirective
868
],
869
exports: [
870
ButtonCheckboxDirective,
871
ButtonRadioDirective,
872
ButtonRadioGroupDirective
873
]
874
})
875
class ButtonsModule {}
876
```
877
878
**Usage Example:**
879
880
```typescript
881
import { ButtonsModule } from 'ngx-bootstrap/buttons';
882
883
@Component({
884
template: `
885
<!-- Checkbox buttons -->
886
<div class="btn-group" role="group">
887
<button
888
type="button"
889
class="btn btn-primary"
890
[(ngModel)]="checkboxModel.left"
891
btnCheckbox>
892
Left
893
</button>
894
<button
895
type="button"
896
class="btn btn-primary"
897
[(ngModel)]="checkboxModel.right"
898
btnCheckbox>
899
Right
900
</button>
901
</div>
902
903
<!-- Radio buttons -->
904
<div class="btn-group" role="group" [(ngModel)]="radioModel" btnRadioGroup>
905
<button
906
type="button"
907
class="btn btn-success"
908
btnRadio="Left">
909
Left
910
</button>
911
<button
912
type="button"
913
class="btn btn-success"
914
btnRadio="Middle">
915
Middle
916
</button>
917
<button
918
type="button"
919
class="btn btn-success"
920
btnRadio="Right">
921
Right
922
</button>
923
</div>
924
`,
925
imports: [ButtonsModule]
926
})
927
export class MyComponent {
928
checkboxModel = { left: false, right: false };
929
radioModel = 'Middle';
930
}
931
```