I want to concatenate 2 values into 1 label using Reactive Forms.
In this case i'm not using ngModel binding.
<label
id="identificationCode"
name="identificationCode"
formControlName="lblIdCode">______</label>
<input type="text"
id="reference"
name="reference"
formControlName="txtReference"
maxlength="250"
(change)="handleIdCode($event)">
<input type="text"
id="publicacion"
name="publicacion"
formControlName="txtPublicacion"
maxlength="250"
(change)="handleIdCode($event)">
I want to concatenate those 2 input text when user is writing and automatically reflect the value into the label. Is there any way like we do it with model binding without change event??
Use label to display the information. The label is not meant to bind with Reactive Form. If you need concatenate values to pass to API or for any use then try on TS. User cannot change the value of Label so there is no point to bind it, but just display the concatenated value.
Remove formControlName="lblIdCode" from your label and add for attribute.
<label>{{form.get('txtReference').value}} - {{form.get('txtPublicacion').value}}</label>
And concatenate on TS:
const lblIdCode = this.form.get('txtReference').value + this.form.get('txtPublicacion').value
The definition of label:
The HTML element represents a caption for an item in a user interface.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label
Although given answers work fine. There could be another declarative approach which will take advantage of valueChanges observables of the input text. We can combine the input texts' valuechanges observables and map to the desired output i.e. concatenate the Reference + Publicacion like this:
Component.ts:
export class FormreactiveComponent implements OnInit {
lblIdCode$: Observable<string>;
form = new FormGroup({
txtReference: new FormControl(''),
txtPublicacion: new FormControl('')
});
constructor() { }
ngOnInit() {
const refCtrl = this.form.get('txtReference');
const pubCtrl = this.form.get('txtPublicacion');
this.lblIdCode$ = combineLatest(refCtrl.valueChanges.pipe(startWith(refCtrl.value)),
pubCtrl.valueChanges.pipe(startWith(pubCtrl.value)))
.pipe(map(([firstName, lastName]) => {
return `${firstName} ${lastName}`;
}));
}
}
Template:
<form name="form" [formGroup]="form">
<div class="form-group">
<label for="txtReference">Reference</label>
<input type="text" class="form-control" formControlName="txtReference"/>
</div>
<div class="form-group">
<label for="txtPublicacion">Publicacion</label>
<input type="text" class="form-control" formControlName="txtPublicacion"/>
</div>
<div class="form-group">
<label for="lblIdCode">{{lblIdCode$ | async}}</label>
</div>
</form>
Working example
One approach is that you can use reference variables to refer to controls within the template. Like so
<label
id="identificationCode"
name="identificationCode">{{reference.value + " - " + publicacion.value}}</label>
<input type="text"
id="reference"
name="reference"
formControlName="txtReference"
maxlength="250"
#reference>
<input type="text"
id="publicacion"
name="publicacion"
formControlName="txtPublicacion"
maxlength="250"
#publicacion>
The important parts are the #reference and #publicacion on each of the inputs. This links the controls to the variables.
You can then use these variables within an Angular interpolation block like {{reference.value + " - " + publicacion.value}}. You can combine the values however you want inside this block.
Try using the form values, just like you'd use in the .ts file.
<label
id="identificationCode"
name="identificationCode"
formControlName="lblIdCode">
{{form.value.reference + ' ' + form.value.publicacion}}
</label>
you can create a get property base of these values like in
componenpe ts
get referencePublicacionValues() : string {
return `${this.form.get(txtReference).value} ${this.form.get('txtPublicacion').value}`
}
template
<label
id="identificationCode"
name="identificationCode">
{{referencePublicacionValues}}
</label>
now you have the value in reference Publicacion Values property any change the value will reflect to the ui
you can't use formControlName directive on labels if you want to set
the formcontrol lblIdCode you can use form valueChanges
this.form.valueChanges.subscribe( () => {
this.form.get('lblIdCode').setValue(this.referencePublicacionValues,{emitEvent: false})
})
demo 🔥🔥
Related
How To Get Value Of Input tag in typescript.
<input type="checkbox" id="demo111" (click)="chk(this)" name="schoolFactors" value="Yes" >Yes
I'm using the below code but not sure how to get & set the input box value using typescript in angular.
chk(this){
console.log(this);
}
If you dont want to use two way data binding. You can do this.
In HTML
<form (ngSubmit)="onSubmit($event)">
<input name="player" value="Name">
</form>
In component
onSubmit(event: any) {
return event.target.player.value;
}
Depends on the circumstances, another way that does not have to involve a <form> is by using ViewChild and elementRef. A very simplistic example:
HTML:
<input #cb type="checkbox" id="demo111" (change)="chk(cb.value)" name="schoolFactors" value="Yes" >Yes
Class code:
Demonstrates getting (via parameter from the HTML and directly in code) and setting the value:
#ViewChild('cb') cb: ElementRef;
chk(e): void {
const nativeCb = this.cb.nativeElement as HTMLInputElement;
console.log(e, nativeCb.value);
nativeCb.value = 'no';
}
I have 2 input fileds lets say input1 and input2. I have event such that everything I type in input1 it shows in input2.
Now the condition is if i manually change or type something in input2 , the event i had created above should not work.
I guess need to use count loop but I am confused.
html code:
<input placeholder="Organization Name" [(ngModel)] = "orgName" (ngModelChange)="setdomain($event)">
<input placeholder="Business + Sub Domain" [(ngModel)] = "subdomain">
fragment of TypeScript file:
subdomain : string;
setdomain(name) {
this.subdomain = name.toLowerCase().replace(/ /g ,'');
}
I guess that the simplest way is creating temporary variable, which will store unique subdomain name and create method, which will be passing to the variable appropriate value. For example:
in *.component.ts :
defaultSubdomain: string;
uniqueSubdomain: string;
setdomain(name) {
let expectedResult = name.toLowerCase().replace(/ /g ,'');
this.defaultSubdomain = expectedResult;
}
setUniqueDomain(name) {
this.uniqueSubdomain = expectedResult;
}
and in *.component.html :
<input type="text" placeholder="Organization Name" [ngModel] = "orgName" (ngModelChange)="setdomain($event)">
<input type="text" placeholder="Business + Sub Domain" [ngModel] = "uniqueSubdomain || defaultSubdomain" (ngModelChange)="setUniqueDomain($event)">
I created Plunker for you. Tell me if that's what you meant.
cant you just the defaut value of input2 to that of input1. I think it should work.
<input placeholder="Organization Name" #input1>
<input value=input1.value placeholder="Business + Sub Domain">
I'm using the ajduke:bootstrap-tagsinput` package and I'm trying to store the array in:
$('#dealTags').tagsinput('items')
in my deals collection, but the value of:
$(e.target).find('[name=dealTags]').val()
comes back as undefined. I'm a newbie to Meteor and Javascript, so sorry if this is a dumb question. Here is the form field:
<div class ="controls">
<input id="dealTags" type="text" class="form-control" value="" placeholder="Add some tags..." data-role="tagsinput">
</div>
And here I try to insert the data to my collection in the Template
var deal = {
dealTitle: $(e.target).find('[name=dealTitle]').val(),
venueName: $(e.target).find('[name=venueName]').val(),
when: $(e.target).find('[name=when]').val(),
dealTags: $(e.target).find('[name=dealTags]').val()
};
And my collection method doing the actual writing to DB
Meteor.methods({
dealInsert: function(dealAttributes) {
check(Meteor.userId(), String);
check(dealAttributes, {
dealTitle: String,
venueName: String,
when: String,
dealTags: String
});
Thanks!
I think you need to use the select element instead of input to have val() return an array. (see documentation)
<div class ="controls">
<select multiple id="dealTags" type="text" class="form-control" value="" placeholder="Add some tags..." data-role="tagsinput" />
</div>
Another solution is to keep using the input element, but call .tagsinput('items') instead of val()
var deal = {
dealTitle: $(e.target).find('[name=dealTitle]').val(),
venueName: $(e.target).find('[name=venueName]').val(),
when: $(e.target).find('[name=when]').val(),
dealTags: $(e.target).find('[name=dealTags]').tagsinput('items')
};
I have an Angular app with a list of F1 drivers. I want to put a filter on the table, so I can get drivers by their first or by their last name.
To make this I use following design:
Normally the label and the line of the input are black. I want to check if the input value only is a String value (a-zA-Z). I use following code in my partial view:
<div class="form-group col-xs-5 col-md-3">
<label class="control-label" for="inputError">input must be [a-zA-Z]</label>
<div class="form-control-wrapper">
<input ng-model="nameFilter" type="text" name="nameFilter" class="form-control empty" placeholder="Search Driver name...">
<span class="material-input"></span>
</div>
</div>
This input value is bound with following filter (declared in my controller.js)
$scope.searchFilter = function (driver) {
var re = new RegExp($scope.nameFilter, 'i');
if(! (/[^a-zA-Z]+/).test($scope.nameFilter)){
$scope.nameFilter.class ='control-label';
}
return !$scope.nameFilter || re.test(driver.Driver.givenName) || re.test(driver.Driver.familyName);
};
But this doesn't work.. What am I missing?
Regex
Your Regular expression is wrong, check out its validity here
change it from
/[^a-zA-Z]+/
to
/^[A-Za-z]+$/
I need to create a datetime object to store in MySQL, but I need it to be entered with multiple inputs (one for date, one for time, one for timezone). So right now my code is like this:
<input type="datetime-local", ng-model="workshop_date">
But what I want is something more like this:
<input type="date", ng-model="date">
<input type="time", ng-model="time">
<select ng-model="zone">
<option>Pacific</option>
<option>Eastern</option>
<input value='{{date + time + zone}}', ng-model="workshop_date", style="display:none">
However, this solution seems to confuse Angular. Is there any way I can take multiple inputs and make that the value of the ng-model?
Something like that ?
HTML
<input type="date" ng-model="tmp.date">
<input type="time" ng-model="tmp.time">
<select ng-model="tmp.timezone">...</select>
<strong>{{ workshop_date }}</strong>
Javascript
// into controller
$scope.tmp = {
date: '',
time: '',
timezone: ''
};
$scope.workshop_date = '';
$scope.$watch('[tmp.date, tmp.time, tmp.timezone]', function (tmp) {
// you may need to add some logic here...
$scope.workshop_date = date + time + zone;
});
On way would be to use 3 distinct values and create a getter for workshop_date to get the concatenation of the 3 when requested and if using angular 1.3 you can also use ng-model-options.
<input type="date", ng-model="date">
<input type="time", ng-model="time">
<select ng-model="zone">
<option>Pacific</option>
<option>Eastern</option>
</select>
If you need a field display it (or even editing it)
<input ng-model="myObj.getWorkShopDate" ng-model-options="getterSetter: true">
And in your controller you can defined a getter/setter (or just getter)
$scope.myObj = {
getWorkShopDate: function(value){
if(value)
// split into date,time,zone
else
return $scope.date + $scope.time + $scope.zone;
}
}
here is the official documentation plnkr DEMO