I am trying to create a select that will resize to the width of the selected item.
Here's the implementation in jQuery/Javascript: Drop down list width fit selected item text
The problem I'm having is that the styles are always empty. If I try to set the mainSelectElement to hiddenSelectElement, it almost disappears. The reason is that nativeElement.style.width is blank. I logged the style property to the console, and every property is blank. We also have global styles applied to select, and those are not appearing either.
Does anyone know why my styles are blank? Does this have something to do with the shadow DOM? And best of all, any solutions?
import { Component, Input, Output, EventEmitter, forwardRef, ViewChild, ElementRef, Renderer } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
const SELECT_RESIZE_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useClass: forwardRef(() => SamSelectResizableComponent),
multi: true
}
@Component({
selector: 'sam-select-resizable',
template: `
<select #mainSelectElement [ngModel]="selected" (ngModelChange)="updateSelected($event)">
<ng-content></ng-content>
</select>
<select #hiddenSelectElement>
<option >{{selected}}</option>
</select>
`,
providers: [
SELECT_RESIZE_VALUE_ACCESSOR
]
})
export class SamSelectResizableComponent implements ControlValueAccessor {
@ViewChild('hiddenSelectElement') hiddenSelectElement: ElementRef;
@ViewChild('mainSelectElement') mainSelectElement: ElementRef;
public selected: any;
private onChangeCallback: (_: any) => void = (_: any) => {};
private onTouchedCallback: () => void = () => {};
get value(): any {
return this.selected;
}
set value(val: any) {
if (val !== this.selected) {
this.selected = val;
this.onChangeCallback(this.selected);
}
}
constructor(private renderer: Renderer) {}
updateSelected(event) {
this.selected = event;
const hiddenWidth = this.hiddenSelectElement.nativeElement.style.width;
this.renderer.setElementStyle(this.mainSelectElement.nativeElement, 'width', hiddenWidth);
}
writeValue(value: any) {
if (value !== this.selected) {
this.selected = value;
this.onChangeCallback(this.selected);
}
}
registerOnChange(fn: any) {
this.onChangeCallback = fn;
}
registerOnTouched(fn: any) {
this.onTouchedCallback = fn;
}
}
Here is some nice way to fetch the styles once they are applied. Initially all the style properties are empty for any HTML element.
window.getComputedStyle() may resolve your issue.
// fetch styles for an element
style = window.getComputedStyle(hiddenSelectElement.nativeElement, null);
// fetch the property values for any style attribute
console.log(style.getPropertyValue("width"));
For pseudo elements like ::before
and ::after
// fetch styles for an element
style = window.getComputedStyle(hiddenSelectElement.nativeElement, ':before');
// fetch the property values for any style attribute
console.log(style.getPropertyValue("width"));
Reference : https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With