Angular 11 fill input in HTML - html

I'm facing a problem, mainly I cannot fill a value in input but in the HTML. I searched but nothing seems to work. I tried value, (value), [(value)], "k.bag.ConstructionYear", "{{k.bag.ConstructionYear}}" and other combinations and nothing seems to work.
mycomponent.html
<ng-container
*ngIf="{
// other stuff
firstStepState: firstStepState$ | async
} as o"
>
//........
<ng-container *ngIf="{
bag : testService.getData(o.firstStepState.value1, o.firstStepState.value2) | async
} as k">
<ng-container *ngIf="k.bag !== undefined && k.bag !== null">
{{k.bag.ConstructionYear}} // <-- this is showing
<input
type="text"
name="constructionYear"
formControlName="constructionYear"
id="constructionYear"
data-test="constructionYear"
placeholder=""
[value]="k.bag.ConstructionYear" <-- this is the problem
/>

by assigning formControlName="constructionYear" to the input, you delegate value control of this input to your formControl. from this point of time you should update the logical form from your ts code whenever you want, not the value of the input. for example through method control.setValue(newValue)

<input
type="text"
name="constructionYear"
formControlName="constructionYear"
id="constructionYear"
data-test="constructionYear"
placeholder=""
[(ngModel)]="k.bag.ConstructionYear"
/>
for binding with your data

Related

Angular data bind on div not working on update list value

I have this div that I need to take the text value from to use in my doubleClicks function. Since ngmodel does not work on div, I tried to use the solution on this link (ngModel is not working on <div> tag using contenteditable and have html as an input)
I get the error "object is possibly null" when using "event.target.textContent".
After the list is loaded I need to be able to update any value from the list, but for that, I need the input text from the user in the div id=newProjectName to pass to the backend service.
<li
*ngFor="let i of listing; let idx = index; let isLast = last"
class="company"
(click)="selectedLine($event, idx)"
(dblclick)="doubleClicks($event, idx)"
[ngClass]="{ selected: idx == selectedItem }"
[ngClass]="{ lastAdded: isLast && isProjects && newProjectEntry }"
id="listing"
>
<div
*ngIf="!isProjects"
class="name"
id="newProjectName"
name="newProjectName"
[innerHTML]="content"
(input)="contentNew = $event.target.textContent"
>
{{ i.name }}
</div>
</li>
doubleClicks(event, idx) {
if (this.isProjects) {
// USE DIV (Id=newProjectName) TEXT VALUE HERE
name = ....
}
}

How can I set a form field as invalid?

I want to validate the length of a field, after removing it's mask. I'm using https://github.com/text-mask/text-mask, and because of that, I can't just use the property "minLength". With the mask that doesn't work. Always has the size expected, even the user just typed one character. Therefore, the need of calling a method in "ngModelChange", clear the mask, and then see the length of the text.
So the question is, how can I set this form field as invalid, if it fails my method validation?
checkDigitosCPF() {
const qtdDigitos = _.replace(this.advogado.cpf, /\D/g, '').length;
this.isCPFNotOk = _.isEqual(qtdDigitos, 11);
}
<div class="form-group">
<label class="form-control-label" for="field_cpf">CPF</label>
<input type="text" class="form-control" name="cpf" id="field_cpf" [(ngModel)]="advogado.cpf" required [textMask]="{mask: cpfMask}" (ngModelChange)="checkDigitosCPF()" minlength="11" />
<div [hidden]="!(editForm.controls.cpf?.dirty && editForm.controls.cpf?.invalid)">
<small class="form-text text-danger" [hidden]="!editForm.controls.cpf?.errors?.required" jhiTranslate="entity.validation.required">
This field is required.
</small>
<small class="form-text text-danger" [hidden]="isCPFNotOk">
Esse campo deve ter no minímo 11 carácteres.
</small>
</div>
</div>
In the component the validator method should look like this:
// this function should be triggered each time the value change or the form submit
validateField(form): void {
if (conditionOfError) {
form.controls.yourFieldName.setErrors({'customLengthError': true})
} else {
form.controls.yourFieldName.updateValueAndValidity()
}
}
In the form html error list:
<small *ngIf="yourFieldName?.errors?.customLengthError">
The error text.
</small>
I solved the question. I got the desired behavior by creating a custom directive.

Angular2 Form datepicker not detecting as touched as soon as it is focused

Instant validation for datepicker in angular 2. As soon as the Date is entered it has to detect the min or max date. Right now after a click event it is detecting as touched.Is there anything else that has to be changed for it to detect.
<form #Details1="ngForm">
<div class="form-group" fxLayout="column" style="width:531px;">
<md2-datepicker mdInput
id="rDate"
name="rDate"
[(ngModel)]="component.rDate"
#receivedDate="ngModel"
placeholder="rDate"
format = 'MM/dd/y'
min="minDate"
max="maxDate"
type="date"></md2-datepicker>
<md-error *ngIf="rDate.invalid && (rDate.dirty || rDate.touched)">Please select a valid R Date</md-error>
<md-error *ngIf="(rDate.hasError('md2DatepickerMin') || rDate.hasError('md2DatepickerMax'))">Year between 1800-2099</md-error>
</div>
</form>

Angular 4 Material 2 - How to change tabbing from being vertical to horizontal with MD-Gridlist?

I'm currently attempting to switch the tabbing inside of an MD-Gridlist to tab hoizontally rather than vertically. I have tried using tab indexes and had no luck. I want to be able to tab through this dynamically growing or shrinking grid list horizontally.
<ng-container *ngFor="let field of fieldsTable; let i = index">
<!--condition in the grid-list tag checks if the key filed can be shown -->
<md-grid-list class="static-column" cols="1" rowHeight="25px" *ngIf="field.$type == GlobalVariables.typeClasses.Static && (field.Name !== '' || showKey)">
<md-grid-tile class="field-name-tile theme-primary" *ngIf="!field.IsKey;">
{{field.Name}}
</md-grid-tile>
<md-grid-tile class="field-name-tile theme-primary" *ngIf="field.IsKey && showKey" mdTooltip="Key field used to update data for this row via the api, values must be unique.">
<md-icon>vpn_key</md-icon>
</md-grid-tile>
<md-grid-tile class="static-field-tile theme-accent-alternating " *ngFor="let content of field.ContentData; let i = index">
<md-input-container class="content-data-input">
<input class="field-input" mdInput (keyup)="content.Value=$event.target.value" value="{{content.Value}}">
</md-input-container>
</md-grid-tile>
</md-grid-list>
</ng-container>
Any help would be greatly appreciated because I've hit a roadblock.
Thank you in advance!
I managed to remedy this by:
Adding this to the input container html which live in the grid tiles of the grid list
tabindex={{setTabIndex(i,j)}}
and this in the TypeScript
setTabIndex(outerIndex: number, innerIndex: number): number {
return (outerIndex + 1) + (innerIndex * this.staticTableLength);
}

angular 2 validation on dynamic generated fields in loop

I have a list of input fields that are generated with a model. I am trying to add validation to them.
The requirement is they should not be empty or less than 2 characters.
problem is in the documentation only shows validation with non-dynamically generated variable Name. My fields are all generated dynamically. So there is no tempVariableName I can hardcode (otherwise they conflict), so I created temp variable from the name of the property I binded the field to. So I came up with something like this :
<div *ngFor="let field of connector.configFields">
<label>{{field.name}}</label>
<input [(ngModel)]="field.value" [type]="field.name === 'Password' ? 'password' : 'text'"
placeholder="{{field.name}} (required)"
ngControl="[fieldName+field.name]"
required minlength="2"
#fieldName+[field.name]="ngModel" />
<div *ngIf="(fieldName+[field.name]).errors && ((fieldName+[field.name]).dirty || (fieldName+[field.name]).touched)">
<span *ngIf="(fieldName+[field.name]).errors.required">Enter Name</span>
<span *ngIf="(fieldName+[field.name]).errors.minlength">Name minimum at 2 characters</span>
</div>
</div>
and the configFields in typescript look like this :
export class FieldModel {
public name: string;
public type: string;
public value: any;
}
But this simply would not work. I am new to angular 2 so I am not exactly sure what I did wrong.
You can use the unique index for each field in the array. Use this together with the name attribute (and ngModel) which will evaluate each form controls separately. So each input field gets the unique name, eg:
name="f{{i}}"
where we get {{i}} from the iteration:
<div *ngFor="let field of connector.configFields; let i = index">
So finally, your template could look like this:
<form #myForm="ngForm">
<div *ngFor="let field of connector.configFields; let i = index">
<input name="f{{i}}" [(ngModel)]="field.value" [type]="field.name === 'Password' ? 'password' : 'text'" required #f="ngModel" minlength="2"/>
<div *ngIf="f.errors && (f.dirty || f.touched)">
<div *ngIf="f.errors.required"> This field is required </div>
<div *ngIf="f.errors.minlength"> Min 2 chars </div>
</div>
</div>
</form>
Here's a live
Demo
Prepare data in model and return to angular. Angular and hard logic in the template = bad friends.
But if you have a select option and if has *ngFor for option then error message loses its mapping, due second *ngFor loop
better to define custom class for error message and use css display: none or **block*
.custom-valid-box{
display: none;
}
.form-control-danger + .custom-valid-box{
display: block;
}