Setting values on repeater scopes - javascript

I have an input within a repeater scope set up so that users can modify the value and see the calculated results on that value on that row - the intent is to have a spreadsheet like behavior.
I'd like to know what the best way to automatically populate the input box is, so that the field comes up set to a certain value with the model properly updated. I've set up a fiddle that tries to jam the number 4 into the value attribute here:
http://jsfiddle.net/BVRzh/
Where this is the template:
<div ng-app>
<ol ng-controller="TestCtrl">
<li ng-repeat="a in arr">
<input type="text" ng-model="testVal" value="4"></input>
<span>Value: {{testVal}}, Times {{a}}: {{testVal * a}}</span>
</li>
</ol>
</div>
And this is the javascript:
function TestCtrl($scope) {
$scope.arr = [1, 2, 3, 4];
}
Is there a better way to approach this?

ngInit can be useful :
<input type="text" ng-model="testVal" ng-init="testVal = a">
Example: http://jsfiddle.net/BVRzh/3/
If i understand correctly , this is the only case when you can use ngInit. Citation from documentation:
The only appropriate use of ngInit for aliasing special properties of
ngRepeat, as seen in the demo bellow. Besides this case, you should
use controllers rather than ngInit to initialize values on a scope.

Related

Setting ng-model value dynamically to the value of js variable in AngularJS

Similar questions have bee asked before and I have tried solutions given to them, but my problem is little different.
Lets say I have an array of objects like this in my controller
$scope.objArray = [
{
id:1,
name:"placeholder1"
},
{
id:2,
name:"placeholder2"
}
];
now based on this array I am generating a form dynamically like this
<div ng-repeat="field in fields">
{{field.field_name}} </br>
<input type="text" ng-model="field.field_name"><br>
</div>
here in this form i want ng-model value to be set as placeholder1 and placeholder2 and not like javascript variable like field.field_name because my targets are coming from another source which contains html like below.
<p>this is sample html {{placeholder1}}. again sample html {{placeholder2}} </p>
i don't have those JS variables in here. I could not find any solution which will work this way for me so far.
here is link to plunk:
http://plnkr.co/edit/ttaq0l3PDRu4piwSluUX?p=preview
In your case it will look like this:
<div ng-repeat="field in fields">
{{field.field_name}}
<br>
<input type="text" ng-model="$parent[field.field_name]">
<br>
</div>
Note, that you have to use $parent reference because in your case you want to set property of the outer scope (where objArray is defined), however ngRepeat creates child scopes per iteration, so you need one step up.
Demo: http://plnkr.co/edit/35hEihmxTdUs6IofHJHn?p=info

How to let Angular JS ng-init only under certain condition?

Let say I have the following short input form:
<form ng-controller="parentController" action="testing.php" method="post">
<input name="parentInputField" ng-model="x">
<div ng-controller="childController">
<div ng-repeat="item in itemList">
<input name="childInputField[]" ng-model="x">
</div>
</div>
</form>
As you may already know, the model x in childController will follow the value of of model x in parentController until the user type in something in the childController input field, so the user can simply change the value in parent for bulk input and then fine tune in child.
Now, after the user have submitted the form, I want to call the same form for editing function. To keep the bulk input function on new items, is there a way I can ng-init model x in childController only when there is a previous value?
Haven't tried but I believe you can achieve with:
<div ng-init="ctrl.value && (ctrl.value=1)">
BUT if you want an advice, avoid both ng-init and nesting controllers like this: it would be a pain to maintain this program. Prefer to use controllerAs syntax (https://docs.angularjs.org/api/ng/directive/ngController) and put init logic on controller/service.

How to pass anything from DOM-element into function defined in $scope

Example:
<div ng-repeat="obj in objList">
<input type="text" id="obj_{{obj.id}}"/>
<button ng-click="removeRow(NEED PARAM HERE)">Remove</button>
</div>
I could use button's id or maybe parent's, but I dont know exactly how.
And second similar case: when I want get some value from input, for example. How can I do it?
Just pass obj in your function, and then remove the object obj from objList in your controller, it will disappear from your view, that's how angular's data binding works :
<div ng-repeat="obj in objList">
<input type="text" id="obj_{{obj.id}}"/>
<button ng-click="removeRow(obj)">Remove</button>
</div>
And in you controller:
$scope.removeRow = function(obj) {
var index = $scope.objList.indexOf(obj);
$scope.objList.splice(index, 1);
}
A little hard to follow your question, but are you trying to pass the value from the text field to the function so you can remove the row from the list?
If that is true then the you want to do something like this.
You'll want to use the ngRepeat track by functionality. See https://docs.angularjs.org/api/ng/directive/ngRepeat
HTML
<div ng-repeat="obj in objList track by $index">
<input type="text" id="obj_{{obj.id}}" />
<button ng-click="removeRow($index)">Remove</button>
</div>
At that point you're just using basic Javascript splice functionality to remove an item from an Array by index. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
JS
$scope.removeRow = function($index) {
$scope.objList.splice($index, 1);
};
See also AngularJS How to remove an Item from scope

Why can I bind a form to $index, but not interpolate names?

I'm trying to create ng-forms based on the population of an array. The array has elements N through M, and looks similar to this.
[ { name: 'MyForm N'}, { name: 'MyForm N+1' }, ...., { name: 'MyForm M' }]
I'm using the ng-repeat directive to create this list of forms. I would like to publish this list of forms inside of the scope object MyForms - to do this, I encapsulate the repeated forms within another form named accordingly.
<div ng-form='MyForms'>
<div ng-repeat='form in forms'>
<div ng-form='form.name'>
<input type='text' name='Foo'>Bar</input>
</div>
</div>
</div>
Obviously, this example fails, because ng-form expects a string, and takes form.name a little more literally than I would like, publishing each form in turn to form.name (overwriting the previous form).
My question is - why does this occur with form.name, however I can use $index (from ng-repeat) in the exact same place and I get my desired result (albeit without MyForms being denoted with form.name)? I understand that ng-form expects a string, and not an expression, but isn't $index part of an expression?
Since 1.3.0-rc.3 it is possible to assign an expression as the attribute name value of a form or input element.
So this should work:
<div ng-form="MyForms">
<div ng-repeat="form in forms">
<div ng-form="{{form.name}}">
<input type="text" name="Foo">Bar</input>
</div>
</div>
</div>
This is the commit that added the support: link

Using input field for both default and user-defined filter with AngularJS

There must be a simple answer to this, but I'm not getting it. I'm using the following input element to filter the results in a table through AngularJS. If I manually type "foo" into the input field, the table will filter for "foo". But my hard-coded value of "foo" (in the input's value attribute) will neither show up in the browser nor filter the results upon page load. How can I make this input field provide both a default filter and a user-defined filter? Thanks in advance.
<input ng-model="search" id="search" type="text" placeholder="Search" value="foo">
<div ng-controller="eventsController")>
<table>
<tr ng-repeat="event in events | filter:search">
<td><span ng-bind="event.title"></span></td>
<td><span ng-bind="event.date_start"></span></td>
</tr>
</table>
</div>
<script>
function EventsController($scope, $http) {
$http.get('/api/all-events').success(function(events) {
$scope.events = events;
});
}
</script>
If you are using ng-model then you shouldn't set your value in html. Instead you should be setting you model value in Angular. So get rid of you value="foo" and do this.
function EventsController($scope, $http) {
$http.get('/api/all-events').success(function(events) {
$scope.events = events;
$scope.search = "foo"; //This will set the models search to foo
});
}
Edited, initial response is an option but not recommended.
According to the documentation for ng-init
The only appropriate use of ngInit is for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
The link is a working example of the "proper" way to go about it.
http://plnkr.co/edit/EyV1R4WUyu2TEMTue3jT

Categories

Resources