thingsboard icon indicating copy to clipboard operation
thingsboard copied to clipboard

Mat-select in form is broken in 3.8.0

Open devaskim opened this issue 1 year ago • 2 comments

Describe the bug

It is a regression bug and blocker for custom widget development and usage. On 3.7.1 the same widget, actuall mat-select component works as expected, i.e. drowdown is auto closed after clicking on one of its options.

https://github.com/user-attachments/assets/e4045aae-8e2d-4c68-ad87-90fa3039094e

Widget test.json

HTML

<form [formGroup]="form" *ngIf="form" fxFill fxLayout="column" fxLayoutAlign="start stretch">
<mat-form-field>
  <mat-label>Choose an option</mat-label>
  <mat-select>
    <mat-option value="option1">Option 1</mat-option>
    <mat-option value="option2">Option 2</mat-option>
    <mat-option value="option3">Option 2</mat-option>
  </mat-select>
</mat-form-field>
</form>

JS

let $scope;

self.onInit = function() {
    $scope = self.ctx.$scope;
    $scope.form = $scope.fb.group({
        'Test': [null, [ $scope.validators.required ]]
    });
}

Your Server Environment

  • Deployment: monolith
  • Deployment type: docker-compose
  • ThingsBoard 3.8.0
  • Community

devaskim avatar Oct 17 '24 06:10 devaskim

Hi @devaskim, for the correct work, you need to add this code:

self.ctx.ngZone.run(function() {
   self.ctx.detectChanges(true);
});

It allows you to track and display changes.

So, the whole code should look like this:

<form [formGroup]="form" *ngIf="form" fxFill fxLayout="column" fxLayoutAlign="start stretch">
<mat-form-field>
  <mat-label>Choose an option</mat-label>
  <mat-select formControlName="Test">
    <mat-option value="option1">Option 1</mat-option>
    <mat-option value="option2">Option 2</mat-option>
    <mat-option value="option3">Option 3</mat-option>
  </mat-select>
</mat-form-field>
</form>
let $scope;

self.onInit = function() {
    $scope = self.ctx.$scope;
    $scope.form = $scope.fb.group({
        Test: ['Option 1', [ $scope.validators.required ]]
    });
    
    self.ctx.ngZone.run(function() {
       self.ctx.detectChanges(true);
    });
}

d2eight avatar Oct 18 '24 09:10 d2eight

@d2eight Many thanks!!! This solved the my issue.

Just curious, why wrapping in ngZone.run(...) matters from 3.8.0 ?

devaskim avatar Oct 18 '24 11:10 devaskim

@devaskim I want to ask the same. We have a lots of widgets we need to change now, which isnt bothering us, but we'd like to know why if anyone could spare the time explaining this.

X1folta avatar Jan 09 '25 17:01 X1folta

If above solution not working, can try to add setTimeout() like:

  setTimeout(() => {
    ctx.ngZone.run(() => {
      ctx.detectChanges(true);
    });
  }, 10);

Applicable for custom widget action (HTML+JS) too.

jource08 avatar Aug 06 '25 05:08 jource08