Angular.js: two-way binding inside ng-repeat - javascript

I'm working on an Angular application.
I want to generate a form with an arbitrary number of text input fields with two-way bindings for every individual input field. No buttons, no watchers. ng-model is not working correctly because of the scoping (if I'm not mistaken). The input fields are generated from an array with ng-repeat like this:
<div ng-repeat="item in items">
<label>{{item.name}}</label>
<input type="text" placeholder="{{item.default}}" ng-model="{{item.value}}"> <!-- this input should be bound -->
</div>
I just want a simple binding to update the items array in the controller on changes in the input.
Any help appreciated.

Just change input tag so it reads:
<input type="text" placeholder="{{item.default}}" ng-model="item.value">
Notice ng-model without curly braces.
Working plunk: http://plnkr.co/edit/CLdem9yIw2Sk1U52Iajl?p=preview

Related

ng-html-bind for label that contains checkbox

I have the following view.It's standard bootstrap for checkboxes,where input is located inside the label
<div class="checkbox">
<label ng-bind-html="vm.trustedHtml">
<input type="checkbox" ng-model="vm.isAcknowledged">
</label>
</div>
I need to bind my trustedHtml property,that contains html,on label.But this directive fully replace the content of the label,including the input.How can I avoid it?The only option I see is changing the html and moving the input out of label,but I don't like it.
No, ng-bind-html does not have anything like "place to insert". It's really straightforward.
add nested <span> and put ng-bind-html on it
include <input> into vm.trustedHtml
Don't use ng-bind-html if you know all variations possible and there are not so many of them: just describe all options with appropriate ng-if

AngularJS ng-repeat input

I am trying to make comments functionality using Angular js. The problem is that when i want to write a comment for a post, the text is also writing inside other input elements (comments). I write a text inside one input, but it writes it in all inputs
So for example same is happening with this code
<div class="comments" ng-repeat="articles in [1,2,[4,5,6]]">
<div ng-repeat="comments in articles">
<div>
<input type="text" ng-model="$parent.new">
</div>
</div>
if i use new instead of $parent.new i get undefined, but when i use $parent.new and i write in one input, it also writes in other inputs.
The issue is that you are assigning all of the inputs to the same model, so your inputs are all in sync with the same object.
What you need is to assign each input to a different model. I'm guessing you need these models to be dynamic, so you should use an array as your model and track your ng-repeat by $index like so:
<div ng-repeat="comments in articles track by $index">
<div>
<input type="text" ng-model="arr[$index]">
<span ng-if="arr[$index]">
{{arr[$index]}}
</span>
</div>
</div>
Now, in your controller, you can initialize the empty arr like so:
$scope.arr = [];
Now, your inputs will be in sync with $scope.arr depending on the index they were in.
Try out this jsfiddle for an example.
This is because you've giving same model (ng-model="$parent.new") for all of the inputs What you should do to avoid this problem is assign different model to each input element. Something like
<div class="comments" ng-repeat="articles in [1,2,[4,5,6]]">
<div ng-repeat="comments in articles">
<div>
<input type="text" ng-model="comments">
</div>
</div>
Change ng-model of input to
<input type="text" ng-model="comments.comment">

Angular1: How to reflect ng-model errors on another element?

I have a directive with the following template
<div>
<span class="label">My Label</span>
<input ng-model="name" required>
</div>
I want the label to be painted red when the input field is invalid.
How can I do that?
Currently I have another directive to sync all the errors from ngModelCtrl to the wrapping div
<div add-all-errors>
...
</div>
And the directive's link function does something like this:
const ngmodel = $element.find('[ng-model]').controller('ngModel');
$scope.$watch(()=>ngmodel.$error, addAllClasses, true);
Where addAllClasses simply makes sure the correct classes appear on the element..
I also tried just adding the same ng-model
<div ng-model="name">
...
</div>
But did not see the classes there..
any better way to do this?
This is why we use the angularjs form... I'm really not sure why people are against using a very handy feature.
I've made a plunker for you.
https://plnkr.co/edit/bGOcQjWzlRq2aTYZUYNm?p=preview
<form name="form">
<span ng-class="{red: form.name.$invalid}">Name:</span>
<input name="name" ng-model="name" required>
</form>
A little more insight of what's going on. form is added to the scope auto magically by angularjs by it's name. In this case, I named it form, however it can be any name.
Now form is an ngForm Object and adds all input field into it by their name attributes. This way we can do form.name to get another object similar to the ngForm Object. We can then use $invalid or $valid properties with ng-class.
ngForm is pretty powerful and is loaded with many cool properties and methods. Just call console.log(scope.form); You will need to put in a method and add it to ng-change to see updates.

Angular nested ng-form causes $modelValue to not be set

I'm having a little issue with an Angular project. Firstly the $digest value in a form wasn't set to true, in certain conditions. I fixed it via this post.
So in order to fix that problem I had to put a ng-form around some parts in my form. Making it look like the following:
<div class="fim-sub-input">
<ng-form name="gender" novalidate>
<label class="fim-radio" fim-radio ng-repeat="gender in genders">
<input type="radio" name="gender" value="{{ gender.id }}" ng-model="card.gender">
<span class="fim-sub-label">{{ gender.name }}</span>
</label>
</ng-form>
</div>
This fixed my $digest problem. However now in the form, the gender property never has a $modelValue property? All other form properties still do, except the gender property, which is in a nested form doesn't have it. Is this expected behaviour?
I currently fixed it by setting the form.gender.$modelValue to the value which is in the scope's model, before I process the form. It works, but it's ugly :)
Any ideas?
not sure what you are trying, but ng-model should be gender.gender instead of card.gender.
You might still eventually get some issues since you are using ng-repeat which creates a child scope (unless you use ng-model = $parent.gender.gender)

Gather a ng-model from several input fields

I am very new to angular and i am trying to display several input boxes and then gather the inputs of the user for each. The number or id of the input boxes depends on a json and its dynamic. I am trying to create the structure in a ng-repeat but it only displays one input box when i define the field ng-model for it.
This is what i have so far.
<td ng-repeat="(key, value) in personType.requirements">
<label for="{{key}}">{{key}}:</label> <input type="text" id="{{key}}" value="{{value}}" ng-model="newReg.{{key}}"></td>
<td><button id='finalizePerson' ng-click="register(newReg)">Register</button></td>
You need to explicitly define the $scope.newReg = {}; to your controller scope.
And to use dynamic ng-model properties, try newReg[key] instead.

Categories

Resources