angular icon indicating copy to clipboard operation
angular copied to clipboard

Binding on input [type] is broken

Open GuyShaanan opened this issue 8 years ago • 39 comments

I'm submitting a ...

[x] bug report => search github for a similar issue or PR before submitting

Current behavior Try to bind the type attribute of input:

// in Class
inputType="number"

// in html
<input [type]="inputType" formControlName="integerB" />

Initially, the value is presented as number when doing form.value:

{"integerB": 5}

Now, try to change the input's value.

Its type has changed to string:

{"integerB": "5"}

while it seems the html attributes haven't changed:

// chrome dev console
<input formcontrolname="integerB" ng-reflect-name="integerB" ng-reflect-type="number" type="number" class="ng-valid ng-dirty ng-touched">

Expected behavior If we are able to bind to [type], the input type should have stayed "number", so does the value.

Minimal reproduction of the problem with instructions http://plnkr.co/edit/kp0xoDbZmJnD5orOTZUj?p=preview

What is the motivation / use case for changing the behavior? I'm dynamiclly generating forms from given JSON, so binding to [type] can save a lot of copy-paste code.

Please tell us about your environment: Not sure this is relevant as it is reproducible in plnkr.

Thanks.

Edit: same goes if binding [type] to inputType="checkbox". Edit2: this is also broken in the Dynamic Forms demo if you change "email" type to number (for example)

GuyShaanan avatar Dec 05 '16 16:12 GuyShaanan

Duplicate of https://github.com/angular/angular/issues/7329

DzmitryShylovich avatar Dec 14 '16 10:12 DzmitryShylovich

Looks like a dup indeed, although my issue is not restricted to ngModel only but also for ReactiveForms.

The Dynamic Forms demo still demonstrates this behaviour (the ability to bind to [type]) and is misleading.

GuyShaanan avatar Dec 14 '16 11:12 GuyShaanan

<input formControlName="integerB" [type]="'number'"/> 
<input formControlName="integerB" [attr.type]="'number'"/>

doesn't trigger creation of NumberValueAccessor https://plnkr.co/edit/u9RAULnbb4lGTR6JJhos?p=preview So it's blocked by https://github.com/angular/angular/issues/11716

DzmitryShylovich avatar Jan 04 '17 10:01 DzmitryShylovich

Is this being fixed any time soon? It's a real gapping hole in a "big" feature of angular.

Check #21418 for a workaround I use.

Would be nice too if the docs say you don't support reactive forms completely and that it's state is actually incomplete...

michael-letcher avatar Jan 26 '18 14:01 michael-letcher

Wonder why this still hasn't been fixed. It seems like a common use case and see many requests to have this support.

AngularDevMrs avatar Apr 03 '18 05:04 AngularDevMrs

It's very surprising, I guess not many use reactive forms or were smart enough not to use an incomplete "feature"

michael-letcher avatar Apr 03 '18 05:04 michael-letcher

Is there another Angular way of doing forms?

ceor avatar Jun 20 '18 16:06 ceor

Wow, I am also wondering why this still hasn't been fixed. This bug makes it really hard to create a dynamic form.

gorkemyontem avatar Jul 04 '18 15:07 gorkemyontem

@gorkemyontem You have no idea, our dynamic form field component is huge so that we can cover each broken outlier.

michael-letcher avatar Jul 05 '18 00:07 michael-letcher

@ceor there is a workaround referenced here #21418, still works in Angular 6

michael-letcher avatar Jul 05 '18 00:07 michael-letcher

I have done several dynamic input fields, and I have learn that each type of input field is different, and even when you seem to only check for the input type, the fact that the browser renders a different element for each makes you appreciate this kind of behaviors.

michaeljota avatar Jul 05 '18 16:07 michaeljota

The deprecation warning you get with ng-model makes the workaround really confusing.

gitbnw avatar Jul 11 '18 15:07 gitbnw

@michael-letcher Could you please provide an example of code with WA?

I can find only this workaround, but it is working without of changing ngModel:

<label><input [type]="'checkbox'" [ngModel]="option" [checked]="option" (change)="option = $event.target.checked">Option</label>

Here is live example: https://stackblitz.com/edit/angular-checkbox-2way-binding

belyan avatar Feb 27 '19 13:02 belyan

I've been searching for days for this. Are there any plans to fix this? Here's another example:

https://stackblitz.com/edit/angular-rzttpk?file=src/app/app.component.ts

dinohorvat avatar Nov 25 '19 08:11 dinohorvat

Still an issue with Angular 9...

🔬 Minimal Reproduction

https://stackblitz.com/edit/angular-number-input-bug

tremppu avatar Mar 30 '20 14:03 tremppu

No wonder... why the entire World is changing for React.

PedroFerr avatar May 07 '20 01:05 PedroFerr

@PedroFerr It is rather sad.

michael-letcher avatar May 07 '20 05:05 michael-letcher

Still an issue? Yup, still an issue.

yoh-m avatar Aug 12 '20 22:08 yoh-m

This problem has been existed for four years

paul61843 avatar Sep 26 '20 08:09 paul61843

No wonder... why the entire World is changing for React.

every framework/libarary has bugs

ekabelly avatar Jan 06 '21 11:01 ekabelly

No wonder... why the entire World is changing for React.

@PedroFerr it's because they don't that react was built on angular 😉

HackPoint avatar Feb 21 '21 19:02 HackPoint

Giving this a bump because I think it's still an important issue to fix.

inorganik avatar Aug 30 '21 22:08 inorganik

Not fixed since 2016? Seriously?

haskelcurry avatar Nov 03 '21 11:11 haskelcurry

It's 2022 already. Is this gonna be noticed anytime this year?

Anutrix avatar Jan 11 '22 08:01 Anutrix

Not fixed?

Almostsagar avatar Jan 20 '22 18:01 Almostsagar

April 2022, still no fix in sight?

Ghandie avatar Apr 25 '22 09:04 Ghandie

Until this is fixed, you can set a [ngSwitch] on a parent element to the variable holding the input type, and use multiple input tags each with *ngSwitchCase. Not as clean, but it works.

<ng-container [ngSwitch]="inputTypeVariable">
  <input *ngSwitchCase="'text'" type="text" ...>
  <input *ngSwitchCase="'number'" type="number" ...>
  ...
</ng-container>

DFG-kjtroll avatar Jul 14 '22 19:07 DFG-kjtroll

Until this is fixed, you can set a [ngSwitch] on a parent element to the variable holding the input type, and use multiple input tags each with *ngSwitchCase. Not as clean, but it works.

<ng-container [ngSwitch]="inputTypeVariable">
  <input *ngSwitchCase="'text'" type="text" ...>
  <input *ngSwitchCase="'number'" type="number" ...>
  ...
</ng-container>

It didn't work for me. I will have to make a duplicate that only differ by the input

royeradames avatar Jul 20 '22 18:07 royeradames

It didn't work for me. I will have to make a duplicate that only differ by the input

It does work, you must be doing something else wrong. You have to put multiple input tags within the [ngSwitch] container, one for each possible case, explicitly declare the type in each tag, and repeat everything. Which is why it's just a sloppy workaround, if this type binding issue gets fixed you could accomplish it with just one input tag.

So to dynamically generate multiple form fields, you could have something like this in the component model:

private formFields: {
  inputType: 'text' | 'number' | 'date'...
  value: any
}[]

Then something like this in the template:

<ng-container *ngFor="let field of formFields"
  <ng-container [ngSwitch]="field.inputType">
    <input *ngSwitchCase="'text'" type="text"  [value]="field.value"...>
    <input *ngSwitchCase="'number'" type="number" [value]="field.value"...>
  ...
  </ng-container>
</ng-container>

DFG-kjtroll avatar Jul 21 '22 18:07 DFG-kjtroll

Still doesn't work - 06.12.2022 6 years lmao

Asphiii avatar Dec 06 '22 17:12 Asphiii