Topic: MDB5 mdb-form-control ng-content

sjardine priority asked 1 year ago

Expected behavior

See below

Actual behavior

See below

Resources (screenshots, code snippets etc.)

I am currently working on creating a set of input components based on MDB5 Angular. I have created a reusable field component that is a parent of specific input components.

Here is the template for the field:

  <label mdbLabel *ngIf="label" class="form-label" [class.text-danger]="error" [for]="id"
  >{{ label }}<span *ngIf="required" class="required">
      <sup><i class="fa-solid fa-asterisk text-danger"></i></sup></span
  <mdb-error *ngIf="error">{{ errorMessage }}</mdb-error>
  <mdb-success *ngIf="success">{{ successMessage }}</mdb-success>
  <small *ngIf="helpText" class="help-message">{{ helpText }}</small>

Here is the template for the input:

      <ng-container [formGroup]="formGroup">
          class="form-control {{ extraClasses }}"

For some reason the MdbFormControlComponent does not set the _formControl variable correctly. I am assuming that @ContentChild is not getting set because my input is not a child of my field component but in order to avoid a bunch of duplicate code the field wrapper needs to be separated from the input element.

Is there a way around this behavior? Is there a way to manually set the _formControl variable or update @ContentChild to see the children in ?

Thanks! Steve

@sjardine mdb-form-control needs access to the input element on initalization to recalculate label position and border-top gap. Unfortunately, it is not possible to manually define the _formControl variable after the component init.

Edit: Possible workaround (I assume you created custom components for both mdb-form-control wrapper and input):

Custom input:

@ViewChild(MdbInputDirective, { static: true }) input: MdbInputDirective;

Custom form control:

  @ContentChild(CustomInputComponent, { static: true }) customInput: CustomInputComponent;
  @ViewChild(MdbFormControlComponent, { static: true }) _controlWrapper: MdbFormControlComponent;

  ngOnInit(): void {
    this._controlWrapper._formControl = this.customInput.input;

sjardine priority commented 1 year ago

This seems like a bug that should be addressed. It creates a lot of extra code in an environment that is supposed to promote reuse.

This has also been reported as a issue for angular with some potential workarounds:

Arkadiusz Idzikowski staff commented 1 year ago

@sjardine Thank you for the link. I did a bit more research and it looks this is a limitation of angular content projection: (still not fixed event in v14).

However, I tried to find a workaround based on the info given in these github issues and it seems there is a way to fix this problem. Please take a look at my edited answer and let me know if that helped.

I'm afraid this leads us to another problem with styles and this problem will be much harder to fix, especially without introducing breaking changes. The styles were prepared for a flat structure (form control, input, label) and they changes according to the input active state. It will be difficult to predict how to style these components when they are nested in other elements.

sjardine priority commented 1 year ago

Thank you for looking into this. Unfortunately, things didn't work well. I am just going to live with the duplicate code for the time being.

Thanks again!

Please insert min. 20 characters.


Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.



Specification of the issue

  • User: Priority
  • Premium support: Yes
  • Technology: MDB Angular
  • MDB Version: MDB5 2.2.0
  • Device: Desktop
  • Browser: Chrome
  • OS: Ubuntu
  • Provided sample code: No
  • Provided link: No