how to disable dropdown selection? - html

I have a dropdown with 2 options:
I want the user to be able to see both options (Cips, Projects); however, I do not want to allow the user to choose a different item.
How do we allow the user to click on the dropdown and see all the options, but disable choosing any other option?
This dropdown is defined like so:
<p-dropdown [(ngModel)]="editRagColumns.BaseObjectType"
name="RagBasicType"
type="text"
class="form-control"
id="RagBasicType"
[options]="baseObjectTypes"
optionLabel="BaseObjectTypeName"
[style]="{'width':'100%', 'border-color':'transparent'}"
>
</p-dropdown>

As per the documentation:
https://www.primefaces.org/primeng/showcase/#/dropdown
You can use this optionDisabled

You have to add the following property to your "p-dropdown" component.
optionDisabled="BaseObjectTypeName"
This is my ts and html file that I have done to confirm that it works.
ts file
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-question1',
templateUrl: './question1.component.html',
styleUrls: ['./question1.component.sass']
})
export class Question1Component implements OnInit {
BaseObjectTypeName: string = "BaseObjectTypeName";
baseObjectTypes: any[] = [
{ BaseObjectTypeName: "tab1" },
{ BaseObjectTypeName: "tab2" },
];
constructor() { }
ngOnInit(): void {
}
}
html file
<p-dropdown
name="RagBasicType"
type="text"
class="form-control"
id="RagBasicType"
[options]="baseObjectTypes"
optionLabel="BaseObjectTypeName"
[style]="{'width':'100%', 'border-color':'transparent'}"
optionDisabled="BaseObjectTypeName"
>
</p-dropdown>
I hope I've helped you.

If you are using primeng 11.0.0 and onwards, then optionDisabled property is the way to go, as others have already mentioned.
In case if you are using previous versions, then you have to ensure following points:
The value passed to options must be of SelectItem[ ] type or at least have label, value and disabled properties from SelectItem type.
label would be the dropdown option text
value can be of any type i.e an object or simply a string
disabled would be of boolean type, setting it to true will disable the dropdown option
p-dropdown optionLabel should not be used
In your case baseObjectTypes should be something as below:
baseObjectTypes = [
{ label: 'Projects', value: 'Projects', disabled: true }, // <--- value can be object too
{ label: 'Cips', value: 'Cips', disabled: true
]

Related

Change the value of checkbox to string

I already saw many questions but I still can't change the value of a checkbox to a string. I need to change the value according to true - false -> 'A' - 'B'. I am using reactive forms in angular.
I got this:
...
..*ngFor="let item of myForm.get('people')['controls'];
...
<mat-checkbox formControlName="check"
[checked]="item.get('check').value === 'A' ? true : false"
(change)="item.get('check').setValue($event.checked ? 'A' : 'B')">
</mat-checkbox>
It has to be in check true if the value that comes is 'A' and in false if it is 'B', I really don't see whydon't set that value on change. I need to send as a string the value of the checkbox
<form [formGroup]="form" (ngSubmit)="submit()">
{{form.value | json}} // just for to see the output
<ng-container formArrayName="people" *ngFor="let item of people.controls; let i = index">
<div [formGroupName]="i">
<mat-checkbox formControlName="check" [checked]="item.get('check').value === 'A' ? true : false"
(change)="setCheck($event.checked, i)">
</mat-checkbox>
</div>
</ng-container>
<button mat-button>submit</button>
</form>
import { FormArray } from '#angular/forms';
import { Component, OnInit } from "#angular/core";
import { FormBuilder, FormGroup } from '#angular/forms';
#Component({
selector: "app-test",
templateUrl: "./test.component.html",
styleUrls: ["./test.component.scss"],
})
export class TestComponent implements OnInit {
form: FormGroup
constructor(private formBuilder: FormBuilder) {}
ngOnInit() {
this.createForm();
}
createForm(){
this.form = this.formBuilder.group({
people: this.formBuilder.array([
this.createItem()
])
})
}
createItem(){
return this.formBuilder.group({
check: ''
})
}
addItem(){
this.people.push(this.createItem());
}
get people(){
return this.form.get("people") as FormArray;
}
setCheck(checked, index){
this.people.controls[index].get("check").setValue(checked ? 'A' : 'B');
}
submit(){
console.log(this.form.value);
}
}
and one more thing, try to use presentation logic in the component class.
style guide: Style 05-17.
link: https://angular.io/guide/styleguide#put-presentation-logic-in-the-component-class
First, if you create many many checkboxes inside a loop, and you set formControlName to a specific one, every checkbox will be bind to 1 control. (You will check and uncheck all of them with the same click.)
On second, you should use formControlName, in formGroup:
<div [formGroup]="myForm">
...
..*ngFor="let item of myForm.get('people')['controls'];"
...
<mat-checkbox formControlName="check"
[checked]="item.get('check').value === 'A' ? true : false"
(change)="item.get('check').setValue($event.checked ? 'A' : 'B')">
</mat-checkbox>
</div>
On Third, I suggest to use brackets in ngFor and '' to look for control name as string.
[formControlName]="'check'"
And finally, I suggest to use mat-checkbox's (change) event, and call a custom function, and do whatever you want on ts side:
<mat-checkbox [formControlName]="'check'" (change)="someFunction(item, $event)"></mat-checkbox>
And in ts:
someFunction(item, event){
...//Do your black magic here
}
By the way: If you use reactive form, and bind a controls to a checkbox, it's value always will be boolean, cuz it's logic... You should decide to map the value later to 'A' or 'B', but you shouldn't use the same time.
And backwards: The checkbox will always work with true or false, width FormControl.
Think about it: You want a Control to control true or false value, but you force 'A' or 'B' in it... It's illogic.
Please re-think your solution.

Angular 2+: Input decorator not reflecting checkbox

I have a component
timeBoxSelector
HTML:
<input type="checkbox" [(ngModel)]="selected">
TS:
#Component({
...
})
export class TimeboxComponent implements OnInit {
#Input() selected: boolean;
constructor() {}
ngOnInit() {
console.log('Selected: ', this.selected);
}
}
Now, when I create
<app-timebox selected="false"><app-timebox/>
<app-timebox selected="true"><app-timebox/>
In both cases, the checkbox initially appears as selected. Why is this the case, and how can I fix it?
In both cases, you are binding non empty strings, which are truthy values. Use the brackets notation to tell Angular that the bound value is to be evaluated as a Javascript expression:
<app-timebox [selected]="false"><app-timebox/>
<app-timebox [selected]="true"><app-timebox/>

Angular:How to set aria-selected for option in select control for Angular

I have a select control with multi select true and option elements in ngFor. Now I want to set aria-selected to true if option is selected other wise to false.
A possible solution consists in using the loop to check for each option if it is part of selected options and if yes, set aria-selected to true using angular [attr.attribute-name] template syntax.
Here is a simple Stackblitz example demonstrating this solution.
Select options and see that elements are properly postfixed (meaning that aria-selected is set to true).
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `
<p>Pick values and see that aria-selected is set to true</p>
<select [(ngModel)]="selectedValues" multiple>
<option *ngFor="let value of values" [ngValue]="value" [attr.aria-selected]="selectedValues.indexOf(value) >= 0">{{value}}</option>
</select>
`,
styles: [
`
/* use CSS to add postfix to elements with aria-selected set to true */
option[aria-selected="true"]::after {
content : ' aria-selected';
}
`,
],
})
export class AppComponent {
values = [
'value 1',
'value 2',
'value 3',
];
selectedValues = [];
constructor() {
}
}

Angular 4 firebase dropdown select tag option

I am using Angular 4 and firebase. I'm trying to build a dropdown selector for a list of properties.
Once a property is selected from the dropdown list, the property location should appear in another input field below.
properties.component.html
<select [(ngModel)]="selectedProperty" (change)="onSelect($event, property)">
<option>--select property--</option>
<option *ngFor="let property of properties">{{property.propertyName}}</option>
</select>
<div *ngIf="selectedProperty">
<label >Location </label>
<input type="text" value="{{selectedProperty.location}}">
</div>
properties.component.ts
import { Component, OnInit } from '#angular/core';
import { PropertyService } from './../services/property.service';
import { Property } from './../models/property';
import { Observable } from 'rxjs/Observable';
#Component({
selector: 'app-property-list',
templateUrl: './property-list.component.html',
styleUrls: ['./property-list.component.scss']
})
export class PropertyListComponent implements OnInit {
properties: Observable<Property[]>;
selectedProperty: Property;
constructor(private propertyService: PropertyService) {}
ngOnInit() {
this.propertyService.getProperties().subscribe(properties => {
this.properties = properties;
})
}
onSelect(event, property: Property){
this.selectedProperty = property;
}
}
I am able to select the property from the dropdown list but the property location does not appear on the input field. I'll appreciate your help.
Instead of value use ngModel
<div *ngIf="selectedProperty">
<label >Location </label>
<input type="text" [(ngModel)]="selectedProperty.location">
</div>
By default selecting option from dropdown selects whatever value provided in selected option tag. So when you select any value in dropdown it putspropertyName inside respective ngModel.
As you want to select the whole object use ngValue in option, what that will do is, when user selects an option it will take down ngValue object value and assigned it to ngModel of select field.
<option [ngValue]="property" *ngFor="let property of properties">
{{property.propertyName}}
</option>

Value not showing for input field using one way binding angular2

Objective: Get a collection of values based on the dropdown selection and place them in hidden input fields to be included in my model;
The relative html:
<select class="selectFoo" (change)="onSelect($event.target.value)" name="FooName" ngModel>
<option selected="selected">--Select--</option>
<option *ngFor="let foo of foos" [value]="foo.ID">{{foo.Name}}
</option>
</select>
<input type="hidden" [value]="fooAddress" name="FooAddress" ngModel/>
In the code above I called a function named OnSelect to get the data about the selected foo. The foos are populated using a webservice call. Here is the snippet from my ts file.
import { Component, OnInit } from '#angular/core';
import { Foo } from './model';
import { DataService } from './data.service';
#Component({
moduleId: module.id,
selector: 'add-on',
templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
foos : Foo[];
selectedFoo: Foo;
fooAddress: string;
onSelect(fooID){
this.selectedFoo = null;
for(var i = 0; i < this.foos.length; i++)
{
console.log(this.foos[i].ID);
if(this.foos[i].ID == fooID){
this.selectedFoo = this.foos[i];
this.fooAddress = this.selectedFoo.Address.toString();
}
}
}
}
I originally tried one way binding my value to the selectedFoo but I was getting an error indicating my Address value wasn't defined. I noticed I could set the value equal to selectedFoo and it didn't error. So i created a new variable that was set to the fooAddress based on the selected foo. I get no value even though while stepping through the code I see it has a value.
How can I get my value to populate so I can use it in my model? Let me know if I need to provide anything else.
Thanks!
If I am correctly understanding what you are after then something like this would work:
<select name="FooName" [(ngModel)]="selectedFoo">
<option>--Select--</option>
<option *ngFor="let foo of foos" [ngValue]="foo" >{{foo.Name}}</option>
</select>
<input type="hidden" [value]="selectedFoo?.Address" name="FooAddress" />
//Assuming your 'foo' items are e.g. { ID: 1, Name: 'Hello', Address: '123 Hello St'}
Here you can bind the Address property of the selectedFoo directly to your hidden input field, rather than needing to handle the (change) event.