src/app/core/basic-datatypes/string/edit-url/edit-url.component.ts
CustomFormControlDirective<string>
| changeDetection | ChangeDetectionStrategy.OnPush |
| providers |
EditUrlComponent
|
| selector | app-edit-url |
| standalone | true |
| imports |
MatInputModule
MatTooltipModule
|
| styleUrls | ./edit-url.component.scss |
| templateUrl | ./edit-url.component.html |
No results matching.
MatInputModule
FormsModule
ReactiveFormsModule
MatTooltipModule
CustomFormControlDirective<string>
EditComponent
OnInit
Properties |
|
Methods |
Inputs |
Outputs |
| formFieldConfig | |
Type : FormFieldConfig
|
|
| aria-describedby | |
Type : string
|
|
|
Inherited from
CustomFormControlDirective
|
|
| disabled | |
Type : boolean
|
|
|
Inherited from
CustomFormControlDirective
|
|
| ngControl | |
Type : any
|
|
Default value : inject(NgControl, { optional: true, self: true })
|
|
|
Inherited from
CustomFormControlDirective
|
|
| placeholder | |
Type : string
|
|
|
Inherited from
CustomFormControlDirective
|
|
| required | |
Type : boolean
|
|
|
Inherited from
CustomFormControlDirective
|
|
| value | |
Type : T
|
|
|
Inherited from
CustomFormControlDirective
|
|
| valueChange | |
Type : EventEmitter
|
|
|
Inherited from
CustomFormControlDirective
|
|
| openLinkIfDisabled | ||||||
openLinkIfDisabled(event?: Event)
|
||||||
|
Opens the URL in a new tab if the input field is disabled.
Parameters :
Returns :
void
|
| blur |
blur()
|
|
Inherited from
CustomFormControlDirective
|
|
Returns :
void
|
| focus |
focus()
|
|
Inherited from
CustomFormControlDirective
|
|
Returns :
void
|
| onContainerClick | ||||||
onContainerClick(event: MouseEvent)
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| registerOnChange | ||||||
registerOnChange(fn: any)
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| registerOnTouched | ||||||
registerOnTouched(fn: any)
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| setDescribedByIds | ||||||
setDescribedByIds(ids: string[])
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| setDisabledState | ||||||
setDisabledState(isDisabled: boolean)
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| writeValue | |||||||||||||||
writeValue(value: T, notifyFormControl: unknown)
|
|||||||||||||||
|
Inherited from
CustomFormControlDirective
|
|||||||||||||||
|
Implementation for Angular ControlValueAccessor interface that links the form control value to the component value
Parameters :
Returns :
void
|
| controlType |
Type : string
|
Default value : "custom-control"
|
|
Inherited from
CustomFormControlDirective
|
| elementRef |
Type : unknown
|
Default value : inject<ElementRef<HTMLElement>>(ElementRef)
|
|
Inherited from
CustomFormControlDirective
|
| Readonly enabled |
Type : Signal<boolean>
|
Default value : computed(() => !this._disabled())
|
|
Inherited from
CustomFormControlDirective
|
|
Whether the control is currently enabled, as a signal (tracks disabled). |
| errorStateMatcher |
Type : unknown
|
Default value : inject(ErrorStateMatcher)
|
|
Inherited from
CustomFormControlDirective
|
| id |
Type : unknown
|
Default value : `custom-form-control-${CustomFormControlDirective.nextId++}`
|
|
Inherited from
CustomFormControlDirective
|
| Static nextId |
Type : number
|
Default value : 0
|
|
Inherited from
CustomFormControlDirective
|
| onChange |
Type : unknown
|
Default value : () => {...}
|
|
Inherited from
CustomFormControlDirective
|
| onTouched |
Type : unknown
|
Default value : () => {...}
|
|
Inherited from
CustomFormControlDirective
|
| parentForm |
Type : unknown
|
Default value : inject(NgForm, { optional: true })
|
|
Inherited from
CustomFormControlDirective
|
| parentFormGroup |
Type : unknown
|
Default value : inject(FormGroupDirective, { optional: true })
|
|
Inherited from
CustomFormControlDirective
|
| stateChanges |
Type : unknown
|
Default value : new Subject<void>()
|
|
Inherited from
CustomFormControlDirective
|
| Readonly valueSignal |
Type : Signal<T>
|
Default value : computed(() => this._value())
|
|
Inherited from
CustomFormControlDirective
|
|
The current value of the control as a signal.
Authoritative in both modes: it reflects the bound |
import { CustomFormControlDirective } from "#src/app/core/common-components/basic-autocomplete/custom-form-control.directive";
import {
ChangeDetectionStrategy,
Component,
input,
OnInit,
} from "@angular/core";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { MatFormFieldControl } from "@angular/material/form-field";
import { MatInputModule } from "@angular/material/input";
import { MatTooltipModule } from "@angular/material/tooltip";
import { FormFieldConfig } from "../../../common-components/entity-form/FormConfig";
import { DynamicComponent } from "../../../config/dynamic-components/dynamic-component.decorator";
import { EditComponent } from "../../../entity/entity-field-edit/dynamic-edit/edit-component.interface";
@DynamicComponent("EditUrl")
@Component({
selector: "app-edit-url",
templateUrl: "./edit-url.component.html",
styleUrls: ["./edit-url.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [MatInputModule, FormsModule, ReactiveFormsModule, MatTooltipModule],
providers: [{ provide: MatFormFieldControl, useExisting: EditUrlComponent }],
})
export class EditUrlComponent
extends CustomFormControlDirective<string>
implements EditComponent, OnInit
{
formFieldConfig = input<FormFieldConfig>();
ngOnInit() {
this.formControl.valueChanges.subscribe((value) =>
this.processUrlInput(value),
);
}
/**
* Ensures the URL starts with 'http://' or 'https://' while preventing duplication.
*/
private processUrlInput(value: string): void {
if (!value) return;
let newValue = value.trim();
if (newValue.startsWith("http://") || newValue.startsWith("https://")) {
// if newValue has valid prefix, don't modify
} else if (newValue.includes("://")) {
// replace the prefix 'https://'
newValue = "https://" + newValue.substring(newValue.indexOf("://") + 3);
} else if ("https://".startsWith(newValue) && newValue.length > 1) {
// delete the whole prefix if the user is deleting the prefix
newValue = "";
} else {
newValue = "https://" + newValue;
}
if (this.formControl.value === newValue) {
// nothing changed, don't update the form control
return;
}
this.formControl.setValue(newValue, { emitEvent: false });
const urlPattern =
/^(https?:\/\/)?([\w.-]+)\.([a-z]{2,6}\.?)(\/[\w.-]*)*\/?$/i;
this.formControl.setErrors(
urlPattern.test(newValue) ? null : { invalid: true },
);
}
/**
* Opens the URL in a new tab if the input field is disabled.
*/
openLinkIfDisabled(event?: Event) {
if (this.formControl.disabled && this.formControl.value) {
// Prevent any default behavior and stop propagation
event?.preventDefault();
event?.stopPropagation();
window.open(this.formControl.value, "_blank");
}
}
}
<div
(click)="openLinkIfDisabled()"
[class.clickable]="!enabled() && valueSignal()"
>
<input [formControl]="formControl" matInput type="url" />
</div>
./edit-url.component.scss
/* Keep the input disabled but visible */
input[disabled] {
pointer-events: none;
}
.clickable {
cursor: pointer;
text-decoration: underline;
}