I am using p-button
and togglemask="true"
from PrimeNG. But they do not render in the html initially until clicked. I want to know why and how to fix this! Thank you!
// user-login.component.html
<main>
<form #loginForm="ngForm" (ngSubmit)="login(loginForm)">
<h2>Sign in</h2>
<div>
<span >
<input id="username" type="text" pInputText
[(ngModel)]="username">
<label for="username">Username</label>
</span>
</div>
<div>
<span >
<p-password id="password" [toggleMask]="true"
[(ngModel)]="password"></p-password>
<label for="password">Password</label>
</span>
</div>
<div>
<button pButton type="submit" label="Sign in"></button>
</div>
</form>
<div>
<span>New User?</span>
<button pButton type="button" [routerLink]="'/signup'" label="Create account" ></button>
</div>
</main>
This is the initial page I have without clicking any button in the page.
- The togglemask in password input box is not showing.
- The button is also not showing in desired styling.
// password input without togglemask
<p-password _ngcontent-sqf-c60="" id="password" ><div><input pinputtext="" ><!--container--><!--container--><!--container--></div></p-password>
// button
<button _ngcontent-dxo-c60="" pbutton="" type="submit" label="Sign in" ng-reflect-label="Sign in"></button>
Only after clicking the input box, ng-untouched ng-pristine ng-valid
added to the <form>
would the button show with styling, like this.
- The togglemask appears but in the wrong position.
// password input with togglemask in wrong position
<p-password _ngcontent-sqf-c60="" id="password" ng-reflect-toggle-mask="true">
<div ng-reflect-ng- >
<input pinputtext="" ng-reflect-ng- type="password">
<!--bindings={
"ng-reflect-ng-if": "false"
}--><i ng-reflect-ng- ></i><!--bindings={
"ng-reflect-ng-if": "true"
}--><!--bindings={
"ng-reflect-ng-if": "false"
}-->
</div>
</p-password>
// button
<button _ngcontent-ale-c60="" pbutton="" type="submit" label="Sign in" ng-reflect-label="Sign in">
<span >Sign in</span>
</button>
After clicking the password input box I get the desired styling like this.
// password input with desired togglemask
<p-password _ngcontent-sqf-c60="" id="password" ng-reflect-toggle-mask="true">
<div ng-reflect-ng- >
<input pinputtext="" ng-reflect-ng- type="password">
<!--bindings={
"ng-reflect-ng-if": "false"
}--><i ng-reflect-ng- ></i><!--bindings={
"ng-reflect-ng-if": "true"
}--><!--bindings={
"ng-reflect-ng-if": "false"
}-->
</div>
</p-password>
CodePudding user response:
Based on the error mentioned by skink, I fixed the problem by simply adding name
attribute in <input>
as follow:
<input id="username" type="text" pInputText
[(ngModel)]="username" name="username"required>
The reason using name
attribute is specified in angular doc.
CodePudding user response:
I've reproduced the issue on StackBlitz, and there seems to be a quite unambiguous error (that you don't see?):
Error: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions.
Example 1: <input [(ngModel)]="person.firstName" name="first">
Example 2: <input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}">
Which is totally right, you're mixing reactive forms with normal forms. If you meant to use normal forms, then the form
element should be removed from the DOM and the form submission should be handled at the button level:
<!--<form #loginForm="ngForm" (ngSubmit)="login(loginForm)">-->
<button pButton type="submit" (onClick)="login()" label="Sign in"></button>
<!--</form>-->
If you meant to use reactive forms, the ngModel
bindings should be replaced with the formControlName
attributes:
<input
id="username"
type="text"
pInputText
formControlName="username"
/>
<p-password
id="password"
[toggleMask]="true"
formControlName="password"
></p-password>