I have a code:
document.getElementById('loginInput').value = '123';
But while compiling the code I receive following error:
Property value does not exist on type HTMLElement.
I have declared a var: value: string;.
How can I avoid this error?
Thank you.
if you want to set value than you can do the same in some function on click or on some event fire.
also you can get value using ViewChild using local variable like this
<input type='text' id='loginInput' #abc/>
and get value like this
this.abc.nativeElement.value
here is working example
Update
okay got it , you have to use ngAfterViewInit method of angualr2 for the same like this
ngAfterViewInit(){
document.getElementById('loginInput').value = '123344565';
}
ngAfterViewInit will not throw any error because it will render after template loading
(<HTMLInputElement>document.getElementById('loginInput')).value = '123';
Angular cannot take HTML elements directly thereby you need to specify the element type by binding the above generic to it.
UPDATE::
This can also be done using ViewChild with #localvariable as shown here, as mentioned in here
<textarea #someVar id="tasknote"
name="tasknote"
[(ngModel)]="taskNote"
placeholder="{{ notePlaceholder }}"
style="background-color: pink"
(blur)="updateNote() ; noteEditMode = false " (click)="noteEditMode = false"> {{ todo.note }}
</textarea>
import {ElementRef,Renderer2} from '#angular/core';
#ViewChild('someVar') el:ElementRef;
constructor(private rd: Renderer2) {}
ngAfterViewInit() {
console.log(this.rd);
this.el.nativeElement.focus(); //<<<=====same as oldest way
}
A different approach, i.e: You could just do it 'the Angular way' and use ngModel and skip document.getElementById('loginInput').value = '123'; altogether. Instead:
<input type="text" [(ngModel)]="username"/>
<input type="text" [(ngModel)]="password"/>
and in your component you give these values:
username: 'whatever'
password: 'whatever'
this will preset the username and password upon navigating to page.
Complate Angular Way ( Set/Get value by Id ):
// In Html tag
<button (click) ="setValue()">Set Value</button>
<input type="text" #userNameId />
// In component .ts File
export class testUserClass {
#ViewChild('userNameId') userNameId: ElementRef;
ngAfterViewInit(){
console.log(this.userNameId.nativeElement.value );
}
setValue(){
this.userNameId.nativeElement.value = "Sample user Name";
}
}
Related
I have a custom dropdown in which i need to update or set default value using formControlName.
I am using ControlValueAccessors in the shared component so that I can attach formControls to them in parent component and update the formControl values of the form.
Right now I have a issue in setting the default value by using the below code.
this.parentForm = this.fb.group({
district: ['bangalore', Validators.required], // bangalore should be set as my default value.
distance: [''],
state:['']
});
HTML code :
<form [formGroup]="parentForm">
<app-common-dropdown placeHolder="select district" [dropDownId]="'districtLabel'" [dataList]="['bangalore','chennai','pune']" formControlName="district" ></app-common-dropdown>
<app-common-dropdown placeHolder="select distance" [dropDownId]="'distanceLabel'" [dataList]="[100,200,300,400]" formControlName="distance" ></app-common-dropdown>
<app-common-dropdown placeHolder="select state" [dropDownId]="'stateLabel'" [dataList]="['karnataka','tamil nadu','mumbai']" formControlName="state" ></app-common-dropdown>
I have attached the example code for this https://stackblitz.com/edit/angular-p2gvtm. Kindly look into the demo code and help me as I am feeling that code is being written more for just setting and getting values using formcontrols.
Hello here is a stackblitz with refactored fork of your code.
First thing first if you want to display the value of the control you must pass it to the place where you are going to visualize it.
app.component
<form [formGroup]="parentForm">
<app-common-dropdown [controlForDisplay]="parentForm.get('city')"
placeHolder="select district"
[dataList]="['bangalore','chennai','pune']"></app-common-dropdown>
<app-common-dropdown [controlForDisplay]="parentForm.get('state')"
placeHolder="select distance"
[dataList]="[100,200,300,400]"></app-common-dropdown>
<app-common-dropdown [controlForDisplay]="parentForm.get('country')"
placeHolder="select state"
[dataList]="['karnataka','tamil nadu','mumbai']"></app-common-dropdown>
</form>
<button type="submit" (click)="getFormValues()">submit</button>
In your case I had added new input to your app-common-dropdown, called controlForDisplay in order to pass reference of the desired formControl to the component. I also deleted the dropdownId, the reason for that action I will explain latter on.
common-dropdown.component.html
<div [ngClass]="{'cs-active': dropdownOpen}"
class="cs-select cs-skin-border"
tabindex="0">
<span (click)="selectClicked($event)" class="cs-placeholder">
{{!!controlForDisplay.value ? controlForDisplay.value : placeHolder }}
</span>
<div class="cs-options">
<ul>
<li *ngFor="let item of dataList" (click)="selectOption(item)">
<span>{{item}}</span></li>
</ul>
</div>
</div>
So now we are heading to the common-dropdown.component.html, where the important part is the following line
{{!!controlForDisplay.value ? controlForDisplay.value : placeHolder }}
Now through the added controlForDisplay input we can access the formControl reference that is holding the desired default value of the dropdown and visualize it if there is any default value or display the placeholder if the form control is empty.
commpon-dropdown.component.ts
#Component({
selector: 'app-common-dropdown',
templateUrl: './common-dropdown.component.html',
styleUrls: ['./common-dropdown.component.css']
})
export class CommonDropdownComponent {
#Input() placeHolder: string;
#Input() dataList: any;
#Input() controlForDisplay: FormControl = new FormControl()
dropdownOpen = false;
selectClicked(event: any) {
this.dropdownOpen = true
}
selectOption(value: string) {
this.controlForDisplay.patchValue(value)
this.closeDropDown('')
}
closeDropDown(event: any) {
this.dropdownOpen = false;
}
}
Here the major changes are that instead of using the native elements we are updating the formControl value trough the formControl API, called patch value, by doing so we are updating the whole form which is accessed both from the parent and the current component.
p.s.
You must add the CommonModule inside your app.module.
Pretty much that fixes your problem. Keep in mind that it's almost always preferable to use the Angular API-s when creating web pages with Angular instead the DOM API-s, I would suggest the you take the Tour of Heroes , which is the official angular tutorial.
I need to update the angular model on a js change event,
this is a simplified, isolated demo:
hero-form.component.html:
<button type="button" id='btn1'>change</button>
<input type="text" id="txt1" name="txt1" [(ngModel)]="str1" />{{str1}}
hero-form.component.ts:
...
import * as $ from "jquery";
...
export class HeroFormComponent implements OnInit {
str1 = "initval";
ngAfterViewInit(){
var txt1 = $('#txt1');
$('#btn1').on('click', function(){
txt1.val('new val').change();
// when js/jquery triggers a change on the input, I need the str1
// which was bound using [(ngModel)] to be updated
});
}
when clicking the button the value of the textbox changes to new val but the interpolation {{str1}} is not affected, however if I change the value of the textbox manually it works.
is it possible to update the model bound with ngmodel on a js change event ?
In angular project we should not implement your requirement like your way.
You can use (click) event and #txt1 to get value
In ts component implement change str1 value.
export class AppComponent {
name = 'Binding data in Angular';
str1 = "initval";
ngAfterViewInit() {
}
change(val) {
console.log(val)
this.str1 = val;
}
}
Updated HTML
<hello name="{{ name }}"></hello>
<button type="button" id='btn1' (click)="change(txt1.value)">change</button>
<input type="text" #txt1 id="txt1" name="txt1" />{{str1}}
Demo: https://stackblitz.com/edit/angular-click-change-value
I have an input field and add button in a component.
Button is disabled at first, when user enters valid format url, button becomes active, then button add this domain to db, refresh table(which is in another component). I want to achieve that, after button is clicked it makes input field empty (refresh like page is just opened)
My component template is
<form #addDomainForm="ngForm" (ngSubmit)="addClicked()">
<mat-card class="topia-box-shadow">
<mat-card-content fxLayout="row wrap" fxLayoutAlign="left" fxLayoutGap="16px">
<div>
<p>Enter domain name or copy and paste the full link to add its domain
to white list</p>
<mat-form-field>
<mat-label>Enter link here</mat-label>
<input type="url" matInput [(ngModel)]="domainName" #url="ngModel"
[class.is-invalid]="url.invalid && url.touched"
name="url" [pattern]="urlValidationRegexPattern" required>
</mat-form-field>
<mat-error *ngIf="url.invalid && (url.dirty || url.touched)">
Please enter the link in correct format
</mat-error>
</div>
</mat-card-content>
<button type="button" id="search" class="topia-btn topia-primary-btn action-buttons"
[disabled]="!addDomainForm.valid" (click)="addClicked()">Add
Domain
</button>
</mat-card>
</form>
My ts file for that component:
export class DomainWhiteListingAddComponent implements OnInit {
#Output()
domainAdded = new EventEmitter<true>();
domainName: string;
public urlValidationRegexPattern = /^((((https?)(:\/\/))?((www)\.)?)?|mailto:(\w+\.?\w+)\#)([a-z0-9]+\.[a-z0-9]+)+((\/([\w#]+|[\w#]+(([.\w#])*(-\w+|=\w+|\?\w+=\w+(&\w+=(\w)+)*)?)+)+))*$/;
constructor(private globalSettingService: GlobalSettingsService, private dialog: MatDialog) {
}
ngOnInit() {
}
addClicked() {
const newDomainModel = {
id: null, domain: this.domainName, disabled: false
} as Domain;
this.globalSettingService.addDomainToList(newDomainModel)
.subscribe((data: Domain) => {
this.domainAdded.emit(true);
}, (error: HttpErrorResponse) => {
this.showErrorDialog(error.error);
});
}
}
This code is working but after clicking button and adding the element, input box value still stays there.
if i add a single line code to .ts file addClicked() method
this.domainName = null;
this time, input field becomes empty as I wanted but it appears as invalid so it shows error. I just want it make as default like the page is opened at beginning. Like
But it shows as:
How can I do that ? (if it is needed i can add parent component codes and other component code also)
Or if it is needed; how can i reset just that component?
How about
#ViewChild(addDomainForm) formDirective: FormGroupDirective;
addClicked() {
this.formDirective.resetForm();
}
It'll reset your form as you are checking if the form is dirty
You are making the ngModel domainName as null so it throws error.
Change it like this.domainName = ''
Along with setting the ngModel to it's original value, empty or null. You should also set your form asPristine.
If you are using Template-Driven forms and you have something like this in your component: #ViewChild('myForm') myform: any;
You can use the markAsPristine() function on the form property of your form. So it would be this.myform.form.markAsPristine().
In your HTML you use url.invalid && url.touchedto add the invalid red class, perhaps try this instead:
[class.is-invalid]="url.invalid && url.dirty"
This way it's not flagged as invalid until the value as actually changed.
I want to print the value of textbox when i click of button. But it throws nullpointerexception. I also need to keep some value in the textbox i dont understand why?. Whatever i type in textbox and when i click on buttom i need to print the value of textbox What is the issue?
Below is my code:
ts file
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-mypage',
templateUrl: './mypage.component.html',
styleUrls: ['./mypage.component.scss']
})
export class mypageComponent implements OnInit {
constructor(private router: Router) {
}
ngOnInit() {
}
myFunc() {
var num1 = ((document.getElementById("exchageRateDate") as HTMLInputElement).value);
console.log(num1);
}
}
HTML File
<br>Welcome.<br>
Place - <input type="text" value="Sydney" ng-model="placeId" />
<button (click)="myFunc(placeId)" formtarget="_blank">Test</button>
Error:
ERROR TypeError: Cannot read property 'value' of null
Seems like you forgot to add id in input field
<input id="exchageRateDate" type="text" value="Sydney" ng-model="placeId" />
Edit: Angular way to do it
As you are using Angular so I will suggest you a better way to do this using NgModel
Try this
<br>Welcome.<br>
Place - <input type="text" value="Sydney" [(ngModel)]="placeId" />
<button (click)="myFunc(placeId)" formtarget="_blank">Test</button>
In component:
myFunc(num1) {
console.log(num1);//here you will get input value through ng-model
}
You need to set id of input tag remove ng-model because it's a angularjs(1.x.x) not angular(2/4/5/6/7/8)
In html
<br>Welcome.<br>
Place - <input id="exchageRateDate" type="text" value="Sydney" />
<button (click)="myFunc()" formtarget="_blank">Test</button>
In typescript:
myFunc() {
var num1 = ((document.getElementById("exchageRateDate") as HTMLInputElement).value);
console.log(num1);
}
Here is working example: Get value of input tag using HTMLInputElement
<input type="text" class="textbox" id="Summary" name="Summary"placeholder="Summary" value="{{Item.summary}}">
(document.getElementById("Summary") as HTMLInputElement).value;
In my Angular 4 application I have this input box in which I ONLY want numbers... 0-9 to be entered.. otherwise I want it to clear out onkeyup
HTML
<input type="number" (keyup)="numbersOnly($event)" placeholder="0000000000" formControlName="phone" maxlength="10"/>
Above works to call this function in the component
but it is not working to prevent letters.
numbersOnly(val) {
let y = this.trackerForm.controls['phone'].value
y.value = y.value.replace(/[^0-9.-]/g, '');
console.log('y', y);
}
Is .value the wrong approach?
Should I be using event preventdefault?
The console log for 'y' shows correctly.
What do I need to do?
Since you are using ReactiveForm, you should understand that FormConrtol's value only has a getter.
If you want to change formControl's value, use patchValue or setValue.
let y = this.trackerForm.controls['phone'];
this.trackerForm.controls['phone'].patchValue(y.value.replace(/[^0-9.-]/g, ''));
// OR
this.trackerForm.controls['phone'].setValue(y.value.replace(/[^0-9.-]/g, ''));
Refer demo.
You should probably have a model on the input and pass that into your function with the event. Change the model instead of the event value. Also your solution may not be working because the input probably has the value updated on the (keypress) event.
let y = this.trackerForm.controls['phone'].value
^^^^^
y.value = y.value.replace(/[^0-9.-]/g, '');
^^^^
You are already taking the value.
Change it to
let y = this.trackerForm.controls['phone'];
y.value = y.value.replace(/[^0-9.-]/g, '');
You use ngModel instead.
<input type="number" (keyup)="numbersOnly()" placeholder="0000000000" formControlName="phone" maxlength="10" [(ngModel)]="value"/>
value = "";
numbersOnly() {
this.value = this.value.replace(/[^0-9.-]/g, '');
}
To access the value of the input field, use ngModel (documentation)
For form validation, have a look at the built-in tools. If you use these, you can simply use the HTML attribute pattern to achieve a validation of an input field by a regular expression. (documentation)
Updated code:
<input type="number" name="phoneNumber" placeholder="0000000000" pattern="[0-9.-]*" maxlength="10" [(ngModel)]="phoneNumber" #phoneNumber="ngModel"/>
Please note that you need to define a new field named phoneNumber in your component.
For this kind of things angular has directives that listen to the events coming from components.
If you have your input mapped to a model then the way you assign the value will not be reflected into model. So that should be taken care of as well.
#Directive({
selector: '[restrict]',
})
export class RestrictDirective {
constructor(private control: NgControl) {}
#HostListener('keyup', ['$event.target'])
#HostListener('paste', ['$event.target'])
private onInputEvent(input) {
if (input.value) {
let truncated = input.value.replace(PATTERN, ''); //put your pattern here
// change value only if it contains disallowed characters
if (truncated !== input.value) {
this.control.valueAccessor.writeValue(truncated); //write to model
this.control.viewToModelUpdate(truncated); //write to view
}
}
}
}
Then just get to use the directive in the input
<input type="text" restrict/>
For integers the pattern would be
const PATTERN = /[\D]/g;
Improving Damask's answer. If we are using Reactive Forms, I's necesary the last line: "this.control.control.setValue(truncated); "
<input type="text" [restrict]="'[^0-9]'" />
The directive
#Directive({
selector: '[restrict]',
})
export class RestrictDirective {
regexp:any;
#Input('restrict')
set pattern(value)
{
this.regexp=new RegExp(value,"g");
}
constructor(private control: NgControl) {}
#HostListener('input', ['$event.target'])
#HostListener('paste', ['$event.target'])
private onInputEvent(input) {
if (input.value) {
let truncated = input.value.replace(this.regexp, '');
if (truncated !== input.value) {
this.control.valueAccessor.writeValue(truncated); //write to model
this.control.viewToModelUpdate(truncated); //write to view
this.control.control.setValue(truncated); //send to control
}
}
}
}
create a simple directive something like this
import { Directive, HostListener } from '#angular/core';
#Directive({
selector: '[appNumberOnly]'
})
export class NumberOnlyDirective {
constructor() { }
#HostListener('keypress', ['$event'])
onInput(event: any) {
const pattern = /[0-9]/;
const inputChar = String.fromCharCode(event.which ? event.which : event.keyCode);
if (!pattern.test(inputChar)) {
event.preventDefault();
return false;
}
return true;
}
}
import this in your module
and in HTML
<input type="number" appNumberOnly placeholder="0000000000" formControlName="phone" maxlength="10"/>
Also inside your component.ts, inside formBuilder you can have something like this
phone: ['', Validators.compose([Validators.maxLength(10), Validators.pattern('[6-9]\\d{9}'), Validators.required])],