Expression in ng-model AngularJS - javascript

I need to execute an expression inside ng-model.
I have an array of integers which is shown in a list and input fields needs be generated on click of each item. All input fields should carry a generated value of ratio having base as 1. I also need to get the sum of numbers in the input field since the user can change the value.
My Code for this is
<div class="row" ng-repeat="kpi in SelectedKpiModel">
<div class="small-2 columns" ng-click="View.RemoveSelectedKPI($index)" style="margin-top:0.5em;border:ridge;padding-bottom: 1em; padding-top:0.5em; text-align:center"><span class="fa fa-scissors"></span></div>
<div class="small-4 columns" style="margin-top:0.5em;border:ridge;padding-bottom: 1em; padding-top:0.5em; text-align:center">
{{kpi.id}}
</div>
<div class="small-4 columns" style="float:left;margin-top:0.5em;border:ridge; padding:0em">
<input type="number" value="{{1/SelectedKpiModel.length}}" />
</div>
</div>
How do I get the count of all the field values if user changes or how do I store the value of each field and retrieve if need ?
I tried like ng-model="{{1/SelectedKpiModel.length}}" but it gave me error.
Thanks.

You can use something like this -
<input type="number" ng-model="getLength()" />
and your function -
$scope.getLength = () => {
return 1 / $scope.SelectedKpiModel;
}

Related

Bind input to only one text input in angular

There is a scenario where I use ngfor and adding the text box for each iteration. When I type anything in the text box it binds to every text box but I want to give input to that text box only which I click to enter a value.
<div class="comment" *ngFor="let comment of blog.comments">
<p>posts...</p>
<input type="text" [(ngModel)]="newComment.content" [ngModelOptions]="{standalone: true}">
</div>
You are referring same ngModel to every text box.
You need to have a array of newComment Objects.
<div class="comment" *ngFor="let comment of blog.comments;let i = index">
<p>posts...</p>
<input type="text" [(ngModel)]="newComment[i].content" [ngModelOptions]="{standalone: true}">
</div>
This should be like this: event -> target-> value will give you current input value
Html:
<input (keyup)="onKey($event)">
Component TS
onKey(event: any) {
console.log(event.target.value)
}

How to restrict ngModel changes effect to other inside ng-template in angular7?

This is my code
<ng-template #rowDetailsTmpl let-row="row">
<div class="row" style="padding: 10px 30px;">
<div class="col-sm-5 form-group">
<label> Add Operator </label>
<input type="string" id={{row.DeskId}} name={{row.DeskId}} (ngModelChange)="onChangeOperator($event)" class="form-control"
placeholder="Search Operator" [(ngModel)]="selectedOperatorEmail">
</div>
#ViewChild('rowDetailsTmpl', { static: true }) rowDetailsTmpl: TemplateRef<any>;
this._dataTableService.rowDetailsTemplate = this.rowDetailsTmpl;
In my code input text field using inside ng-template , i set id and name dynamically , but when i change value in textbox it automatically reflect to other input fields. so how to solve this problem in angular7.
in component define the model like array:
selectedOperatorEmail: Array<any> = [];
in html define ngModel define like this:
[(ngModel)]="selectedOperatorEmail[row.DeskId]"

Validate a form field with a dynamically given name in angular

I create a form dynamically in the view by iterating through an object that has the different questions to be asked to the user. One of the attributes of every question is formFieldName which is a a random string I use to give each form field a different name.
<form name="includedForm.newRequestForm" class="form-horizontal" role="form" novalidate>
<div ng-if="message.question.attributes.structure.type == 'object'">
<div ng-repeat="(index,objField) in message.question.attributes.structure.properties">
<div ng-if="objField.type == 'array'" class="form-group" show-errors>
<label for="{{objField.formFieldName}}" class="control-label col-sm-6">{{objField.title}}
<br /><i><small>{{objField.description}}</small></i></label>
<div class="col-sm-6">
<select class="form-control" name="{{objField.formFieldName}}" multiple ng-model="objField.userValue" ng-required="objField.required">
<option ng-repeat="option in objField.items.enum" value="{{option}}">{{option}}</option>
</select>
</div>
</div>
<div ng-if="objField.type == 'boolean'" class="form-group" show-errors>
<label for="{{objField.formFieldName}}" class="control-label col-sm-6">{{objField.title}}</label>
<div class="col-sm-6">
<input class="form-control" name="{{objField.formFieldName}}" ng-model="objField.userValue" type="checkbox" ng-value="option" ng-checked="message.question.attributes" />
</div>
</div>
</div>
</div>
<div class="col-sm-12">
<button ng-click="markAsDone(message)" class="btn btn-primary">Done</button>
</div>
<form>
In the controller I'm able to get the formFieldName attribute but I can't figure out how to use it to do the validation.
var MarkAsDone = function(message) {
$scope.includedForm = {};
var formField = message.question.attributes.formFieldName;
if ($scope.includedForm.newRequestForm.{{formField}}.$valid){
//submit the form
}
}
to answer you question:
first, {{}} is === $scope so you don't use that anywhere other than HTML. You use $scope in your JS and {{}} in HTML which creates a pipe (2-way binding) so that $scope.variable.property has bidirectional binding to {{variable.property }} in HTML.
$scope.includeForm.email === {{ includeForm.email }} === ng-model="includeForm.email" === ng-bind="includeForm.email"
if you set anyone of those all are set so if you set $scope it will show up in HTML and obviously as user input gets captured it is already in $scope ... all connected
when attempting to get the value from HTML back into JS you would need create and set a $scope i.e so if you create $scope.dataModel.dataProperty and use that in ng-model=dataModel.dataProperty (example) you again have two way binding ... you don't need to do anything as angular is taking care of the data pipeline. So if you want to extract the value to var, which is probably a waste as the $scope is already set as soon as the user checks the box
var formField = $scope.dataModel.dataProperty;
// but like I said no need as $scope.dataModel.dataProperty; is your var
In JS if you want to use a dynamic property as an object property key you would place the dynamic value in [] e.g.
$scope.variable[dynamicProperty].method;
// you can set a static property as a key with dot notation i.e.
$scope.variable.staticProperty = val;
Hope that helps

How to validate input field inside ng-repeat

I want to validate an input field where i want to be able to check whether the current input is greater than the previous input.
Here is what i mean
<div class="col-xs-10" ng-repeat="period in trim.rent_period" >
<div class="col-xs-6">
<div class="form-group">
<label class="col-xs-5 control-label" for="rentperiod">Rental Period
<span class="colon--label">:</span>
</label>
<div class="col-xs-6">
<input id="rentperiod" name="rentperiod" type="text" class="form-control" ng-model="rent.period" ng-change="checkRentPeriod($index);" required>
</div>
</div>
</div>
</div>
<div class="col-xs-2">
<i class="pull-left fa fa-plus-circle add-rent--icon" ng-click="addRent(currentIndex);"></i>
</div>
Here the add button adds an input into the list , and i want to make sure that the current input is greater than the previous input.
Try to wrap your code with form tag. And then check for validation of form if everything is okay. You can do this by following this guide here as a way to solve your question
https://docs.angularjs.org/guide/forms
change your ng-model="rent.period" to correct, something starting from "period", like ng-model="period.rent"
no need for extra method ng-change="checkRentPeriod($index);"
add that simple block after input:
<span ng-if="$index > 0 && period.rent && period.rent > trim.rent_period[$index - 1].rent">
Rent is greater than {{trim.rent_period[$index - 1]}}
</span>

Get the value of an element inside ng-repeat

Here is my html snippet:
<tr ng-repeat="row in rowCollection">
<td><h6 id="{{$index}}">{{row.inventory_serialno}}</h6></td>
</tr>
<div class="form-group">
<label for="inventory_serialno">SL No:</label>
<input class="form-control" value="//I need the value of h6 here//" id="inventory_serialno" placeholder="Enter serial number">
</div>
Goal:
Get the value of an element inside ng-repeat (In this case the 'h6' tag value of each row)
Use that corresponding value to autofill the value of respective text box input present in each row.
The input text box is out of the ng-repeat scope.
For some reason i cant access the value of the h6 tag if i do this (gives a value null)
document.getElementById("1").innerHTML; //or even text()
Weirdly i noticed the above JavaScript code runs fine on the browser console but not on my script (which means its something to do with the angular element generation time.. May be i'm accessing it before it even got generated).
Nonetheless can someone please shed some light on the solution. Thanks in advance.
******** Updated with controller code *****
app.controller('InventoryCtrl', function ($scope) {
var x = document.getElementById("1").innerHTML; // giving a null value
console.log(x);
$scope.rowCollection = [{
id: 100,
inventory_serialno: 'HW13FGL'
}, {
id: 101,
inventory_serialno: 'SM123GH'
}, {
id: 102,
inventory_serialno: 'LK90100'
}];
});
You could do it like this:
<input value="{{rowCollection[2].inventory_serialno}}" />
Example
However I would place the input inside the ng-repeat to keep it clean, and achieve the layout you like inside a big wrapper, something like this:
<div class="grid" ng-repeat="row in rowCollection">
<div class="col">
<h6 id="{{$index}}">{{row.inventory_serialno}}</h6>
<hr>
<div class="form-group">
<form>
<input value="{{row.inventory_serialno}}"/>
</form>
</div>
</div>
</div>
If you need an input for each item, use ng-repeat.

Categories