Accessing ng-model from nested templates generated by ng-repeat - javascript

I'm having trouble accessing values from an ng-repeat directive inside a nested template. Hope I'm using the right terminology, but here's some code that may make it clearer.
outer-template.html
<div ng-repeat="test in $ctrl.test_list">
<div id="test-{{ $index }}" layout="row">
<inner-thing ng-model="test"></inner-thing>
</div>
</div>
inner-template.html
<div>
<md-input-container>
<label>ID</label>
<input type="text" ng-model="test.id">
</md-input-container>
</div>
This is what I was hoping would work. The reasons it doesn't seem fairly obvious even to me, but I'm wondering if something like this is possible. I'm already aware that I can, from the 2nd (inner) controller, access each test using $scope.parent.test_list, but what I really want is for the 2nd (inner) template to be aware of which test it was "given" from the ng-repeat directive.

Well in case anyone has this same question, the answer is quite simple:
inner-template.html
<div>
<md-input-container>
<label>ID</label>
<input type="text" ng-model="$parent.test.id">
</md-input-container>
</div>

Related

ngMessages not working correctly with nested input

I have an input field that is nested within another <div> element, and I am trying to use ngMessages on that inside input field, but I can't seem to get it to validate correctly.
<div class="form-group" ng-model="object.idnumber" ng-hide="condition.userObjectsHidden">
<label class="form-control-label col-lg-12">ID Number</label>
<div class="col-lg-12">
<input type="text" name="idnumber" placeholder="111001111"
ng-model="user.idnumber"
ng-pattern="idpattern"
class="form-control input-lg"
required="required"></input>
<div ng-messages="idnumber.$error" ng-if="idnumber.$dirty">
<p ng-message="pattern">You are wrong!</p>
</div>
</div>
</div>
I'm not sure if it matters in terms of functionality where the <div ng-messages...> tag is, but I have also tried having it completely outside of this element with the same results. If I understand Angular and ngMessages correctly, I need to assign ng-messages to a directive--$error in this case--that I get to by dot-walking across name assignments. As far as I know, I have done this with idnumber.$error, although to be fair, I have also tried a more extensive dot-walk by using kiosk-form.uin.$error, where kiosk-form is the name of the entire form.
I have tried both ng-message="pattern" as well as ng-message="required". Also, just for clarity, idpattern is defined in my Javascript file as a regex string. It is defined correctly.
Rename your form as kioskFormand then ng-messages ="kioskForm.idnumber.$error"

angular ng-model transclude transfer

I am trying to create custom elements which will convert my form elements to match bootstrap's form styling structure
Basically,
<my-input ng-model="myname">
should become
<div class="form-element">
<input ng-model="myname" />
</div>
The problem is that when I use transclude, the ng-model goes to the root element and the resulting DOM is
<div class="form-element" ng-model="myname">
<input>
</div>
Is it possible to choose which inner element the ng-model attribute is transferred to??
If I create another directive called my-model and use it instead of ng-model, how can I transfer this to the inner input element?
<my-input my-model="myname">
should become
<div class="form-element">
<input ng-model="myname" />
</div>
I think it is unnecessary to use ng-transclude here, you can simply have directive
<my-input model="myname">
and directive template
<div class="form-element">
<input ng-model="model" />
</div>
where directives scope is
scope: {
'model': '='
}
By using this you can have couple of models in directive and you can put them wherever you want.
Yes. I ran into this issue a little while ago.
You need to bind your ng-model as a property of an object such as.
<div class="form-element">
<input ng-model="user.myname" />
</div>
And in controller, make sure you do this.
$scope.user = {};
In this way, angular would be able to find the ng-model.

Can I concatenate within a directive declaration in AngularJS?

I have a form with an ng-repeat directive. I'm using ng-show to display validation error messages. I'm attempting to add a validation message within the ng-repeat directive, but I'm having trouble. This is what I have so far:
<form name="rentalApp" ng-controller="RentalAppCtrl">
<label for="name">Full Name</label>
<input id="name" name="name" ng-model="app.name">
<div ng-show="rentalApp.name.$invalid">Please enter your name</div>
<div ng-repeat="history in app.history">
<label for="address{{ $index }}">Street Address</label>
<input id="address{{ $index }}" name="address{{ $index }}" ng-model="history.address">
<div ng-show="rentalApp.('address' + $index).$invalid">Please enter an address</div>
</div>
</form>
As you can see, I am using the $index variable to make sure my IDs and names are unique.
In the rest of my form I'm doing something along the lines of:
<div ng-show="rentalApp.whatever.$invald">Error Message</div>
What I'm having trouble with is that within the ng-repeat directive, the indexes are dynamic. I've been fiddling around with this for a while, and the closest I think I've gotten to a solution is this line:
<div ng-show="rentalApp.('address' + $index).$invalid">Please enter an address</div>
However that doesn't work.
How can I properly concatenate the word "address" with the $index variable, to create a string along the lines of address0, which can then be used in my ng-show directive to determine if the form element is invalid? Or, alternatively, am I going about this completely wrong (not the "Angular way")?
EDIT
I'm looking at the rentalApp object from the console, and AngularJS is not evaluating the name attribute as I would expect. Specifically, the rentalApp object contains a address{{ $index }} object, instead of address0. So it looks like I can't use the expression {{ $index }} within the name attribute.
UPDATE
I make a research and find out it is not possible to give dynamic value to name besides create a custom directive for it...
but there is a solution for you to validate dynamic form with ng-form directive for each individual ng-repeat element...
<div ng-repeat="history in app.history">
<ng-form name="addressForm">
<label>Street Address</label>
<input name="address" ng-model="history.address" ng-required="true">
<div ng-show="rentalApp['address' + $index].$invalid">Please enter an address</div>
<span class="alert error" ng-show="addressForm.address.$invalid">Please enter an address</span>
</ng-form>
</div>
and here is your PLUNKER...
Just put:
<input name="{{input.name}}"></input>

Error: [$compile:multidir] Multiple directives [form, form] asking for 'form' controller on: <form ng-form="">

I am getting this error on a form I am building in angularjs.
`Error: [$compile:multidir] Multiple directives [form, form] asking for 'form' controller on:
<div data-ng-controller="shortlistController">
<ul>
<li data-ng-repeat="job in jobs">
<div>{{ job.role }}</div><div>{{ job.salary }}</div><div>{{ job.company }}</div>
</li>
</ul>
</div>
<form ng-form>
<input type="text" ng-model="newRole">
<input type="text" ng-model="newSalary">
<input type="text" ng-model="newCompany">
<input type="text" ng-model="newUrl">
<button>Submit</button>
</form>
Initially I had the form within data-ng-controller, I took it out to see if the controller might have been the issue..
Please ask if you think I need to post more code, I am using angulars native routing system
Each of these is more or less identical and refers to the form directive:
<form></form>
<div form></div>
<div x-form></div>
<div data-form></div>
So you can do either <div form></div> or simply <form></form>, and in both cases they refer to the same form directive. But <form form></form> would be redundant.
The ngForm directive which you mention is actually an alias for the form directive above, and can be referenced using any of these:
<ng-form></ng-form>
<div ng-form></div>
<div x-ng-form></div>
<div data-ng-form></div>
So in your case, you were doing <form ng-form></form>, which is really the same as <form form></form>, which is why you're getting that error.
This page explains in more detail all the different ways to reference directives:
http://docs.angularjs.org/guide/directive
BTW, a benefit (sometimes) to using the <div ng-form></div> format is that you can do nested forms, whereas you can't do nested forms using just the <form> tag.
You don't need the ng-form if you're using <form> as it automatically is hooked up to the ng-form directive. You use either or, not both.
I encountered the same problem when I set my component name to form.
angular.module("testApp").component("form", {
...
});
Effect was the similar as in #user553086 answer. Change component's name solves the problem.

Is using ng-init for bind once valid in angular js?

i have a collection of values whose structure lets assume to be
var a = [{id:1, value:12, name="one"}, {id:2, value:34, name="two"},...]
i wanted to display this in a series of controls so that user can change the values. but with that i also wanted to display original values which obviously shoudn't change.
i found out a way that is working and my code is something like this using ng-init
<div ng-repeat="p in a">
<div class="control-group" ng-if="p.value>0">
<label class="control-label" ng-bind="p.name"></label>
<div class="controls controls-row" ng-init="v=p.value">
<input class="span1" value="{{v}}"/>
<input type="number" ng-model="p.value" class="span2" />
</div>
</div>
</div>
being a complete newbie in angularjs i dont know what implications this might have as i have very little experience in thinking about $watch and performance.
Is it ok to do so?
but with that i also wanted to display original values which obviously shoudn't change.
Use angular.copy(/* array */). It will create new copy (instance) of old array.
BTW a collection must be defined as $scope.a
Demo Fiddle

Categories

Resources