Passing values to ng-model from ng-repeat - angularjs

I have a form that passes its inputs to ng-model before storing to the database. One of which is a dynamic value (pre-generated code) that is taken from its database table.
<div class="form-group" ng-repeat="codes in response | filter: {branch: formData.branches.alias, taken: 0} | limitTo: 1">
<input class="form-control" type="text" name="code" ng-model="formData.code" ng-value="codes.code" readonly="" />
</div>
Theoretically, once the ng-model gets the value, it then passes it to the insert call for the database to store it along with the rest of the fields.
scope.processForm = function(isValid){
scope.$submitted = true;
if(isValid && state.$current=='registration.signupapp') {
http.post("server/insert.php",{'code': scope.codes.code, 'fullname': scope.formData.name, 'instagram': scope.formData.igname, 'email': scope.formData.email, 'mobile': scope.formData.mobile, 'location': scope.formData.location.type, 'branch': scope.formData.branches.branch}).success(function(data, status, headers, config){
console.log("inserted successfully");
});
state.go('registration.success');
} else if(!isValid) {
//alert("Please make sure that you entered everything correctly.");
}
};
Unfortunately, this does not work. 1) I was told that you cannot simply pass an ng-value to an ng-model inside an input[text]. 2) Even if in the case that the value is passed to ng-model, I am not sure what to call inside the controller as scope.codes.code nor scope.formData.code do not seem to work and gets either a not defined error or 404.
In a nutshell, how do I:
Get the value generated by ng-repeat as set to limitTo:1.
Store it to ng-model in real-time (as this is very dependent on a
dynamic dropdown).
Pass the value of ng-model back to the controller.
Send it back to the server and store it to the database.

I guess ng-init should help you out here.
Change your code segment from:
<div class="form-group" ng-repeat="codes in response | filter: {branch: formData.branches.alias, taken: 0} | limitTo: 1">
<input class="form-control" type="text" name="code" ng-model="formData.code" ng-value="codes.code" readonly="" />
</div>
to:
<div class="form-group" ng-repeat="codes in response | filter: {branch: formData.branches.alias, taken: 0} | limitTo: 1" ng-init="formData.code=codes.code">
<input class="form-control" type="text" name="code" ng-model="formData.code" readonly="" />
</div>

This is really contrived, but here's a very simplified demo:
var app = angular.module('demo', []);
app.filter('myFilter', function(){
return function(data){
return data[0];
};
});
app.controller('MainCtrl', ['$scope', '$filter', function($scope, $filter){
var myfilter = $filter('myFilter');
$scope.response = ['001', '002', '003', '004', '005'];
$scope.items = ['Item 1', 'Item 2', 'Item 3']
$scope.formData = {};
$scope.$watch('formData.select', function(newval){
if (newval === 'Item 1') {
$scope.formData.code = myfilter($scope.response);
} else {
$scope.formData.code = '';
}
});
}]);
#import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css";
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="container" ng-app="demo" ng-controller="MainCtrl">
<pre>formData.code = {{formData.code || "No Code for this Item"}}</pre>
<div class="form-group">
<label>Select a Value: <em>Choose Item 1 to update formData.code</em></label>
<select class="form-control" ng-model="formData.select" ng-options="item as item for item in items"></select>
</div>
<div class="form-group">
<label>formData.code:</label>
<input class="form-control" type="text" name="code" ng-model="formData.code" />
</div>
</div>
You have the response already, so rather than use ng-repeat, just add the value to the formData.code on the controller. If you need to use a custom filter, you can pass in the $filter service as a dependency to your controller.
Edit:
I didn't notice the part about the formData.code being dependent on another form value, so I updated the demo to include a $watch function.

Related

form validation using angularjs

Im trying to validate my form, if the fields are valid then it should post the data to the DB if not prevent from posting the data to DB. when I submit the form Im getting an error TypeError: Cannot read property '$valid' of undefined, I don't know how to overcome it, need help in this.
html:
<form name="formvalidation">
<ion-view ng-controller="ValidationCheck">
<ion-content>
<div>
<strong>User:</strong> <br/>
<input ng-model="name" type="text" name="name" required/>
<ng-messages for="formvalidation.name.$error" ng-if="formvalidation.name.$invalid">
<div ng-messages-include="error/validation.html"></div>
<ng-messages>
</div>
</from>
<button ng-click="check()">
controller:
myApp.controller('ValidationCheck',function($scope, applicationService)
{
$scope.check=function(formvalidation){
var name={'name'=$scope.name};
$scope.submitted=true;
if(formvalidation.$valid){
applicationService.save(name,$scope.home);
}}});
Just change your if condition formvalidation.$valid to formvalidation
. because you already pass formvalidation.$valid in your function via ng-click
if(formvalidation){
...
...
...
}
Remove ng-click and add a ng-submit:
<form name="formvalidation" ng-submit="check()" novalidate>
Try this : ( controller before form )
<ion-view ng-controller="ValidationCheck">
<form name="formvalidation">
In your html you have:
<button ng-click="check(formvalidation.$valid)">
which calls the check function with either a true or false value (a boolean), depending on whether or not the form is valid.
In your controller you have the check function with the following if-statement:
if(formvalidation.$valid)
but formvalidation is a boolean (true or false)
I recommend removing the argument from check and simply access the formvalidation properties from the $scope variable.
so the html becomes
<button ng-click="check()">
and the controller becomes
$scope.check=function(){
var name={'name'=$scope.name};
$scope.submitted=true;
if($scope.formvalidation.$valid) {
applicationService.save(name,$scope.home);
}
}
<form> should come after controller declaration
<div ng-app="app">
<ion-view ng-controller="ValidationCheck">
<form name="formvalidation">
<ion-content>
var app = angular.module("app", []);
app.controller('ValidationCheck', function($scope) {
$scope.check = function(formvalidationBoolean) {
alert(formvalidationBoolean);
var name = {
'name': $scope.name
};
$scope.submitted = true;
if (formvalidationBoolean) {
//applicationService.save(name, $scope.home);
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<ion-view ng-controller="ValidationCheck">
<form name="formvalidation">
<ion-content>
<div>
<strong>User:</strong>
<br/>
<input ng-model="name" type="text" name="name" required/>
<ng-messages for="formvalidation.name.$error" ng-if="formvalidation.name.$invalid">
<div ng-messages-include="templates/admin/validation.html"></div>
<ng-messages>
</div>
</from>
<button ng-click="check(formvalidation.$valid)">Submit</button>
</div>
You are sending boolean value "ng-click="check(formvalidation.$valid)", So your statement if(formvalidation.$valid){ inside controller is wrong.
And You need to change "=" to ":" in var name = {'name': $scope.name };

how to make dropdown with input field in angular.js

i am making dropdown list with input field in angular.js but got no success
the code which i using..
<div ng-app="" ng-controller="namesCtrl">
<h2>filter input</h2>
<input type="text" ng-model="test"/>
<ul>
<li ng-repeat="x in names | filter:test | orderBy : 'name'">
{{ x.name + ',' + x.country }}
</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstName= "";
$scope.lastName= "";
});
</script>
<script src="namescontrol.js"></script>
Check the working demo: JSFiddle.
Use a customized filter to perform the filtering. Since ng-model binds to the value key. Whenever key is changed, the items will be filtered and the view will be changed.
angular.module('Joy',[])
.controller('JoyCtrl', ['$scope', function ($scope) {
$scope.items = ['one', 'two', 'three', 'four', 'five'];
$scope.key = '';
$scope.search = function (value) {
return value.indexOf($scope.key) >= 0;
}
}]);
HTML:
<div ng-app="Joy" ng-controller="JoyCtrl">
<input type="text" ng-model="key">
<div>
<li ng-repeat="item in (items | filter:search)" ng-bind="item"></li>
</div>
</div>
Update 1
If you want to hide the list initially: JSFiddle:
$scope.search = function (value) {
return $scope.key !== '' && value.indexOf($scope.key) >= 0;
};
Update 2
I have developed an open source project angular-sui based on Angular and Semantic-UI. There is a directive sui-select, which is exactly what you want. Please check the Demo.
I think what you are looking for is autocomplete functionality. AngularUI offers this through their Typeahead directive. https://angular-ui.github.io/bootstrap/#/typeahead
You want to have something like this:
<input type="text" ng-model="test" typeahead="name for name in names"/>
The directive will dynamically generate the list so you don't need to create that explicitly yourself.

Mutual effect of model variables

I have a simple GUI I would like to implement via pure AngularJS - there are two (or more) groups of checkboxes like here: http://jsbin.com/cemitubo/2/edit
Here is the code from the link below:
HTML:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js"></script>
<div ng-app="myApp" ng-controller="MyController">
<div class="group">
<input type="checkbox" ng-model="tag.aaa"/>
<input type="checkbox" ng-model="tag.ccc"/>
</div>
<div class="group">
<input type="checkbox" ng-model="tag.zzz"/>
</div>
{{tag}}
</div>
JS:
angular.module('myApp', [])
.controller('MyController', function($scope){
$scope.tag = {aaa: true};
});
Once A checkbox of one of the groups is checked all the checkboxes of the other groups should be unchecked (and the change obviously should be reflected in the model).
I tried to $watch the tag model variable and setting false to the variables of the other groups in $watch callback. The problem is that it fires the $watch callback each time tag is changed by $watch callback.
What is the proper AngularJS solution?
Thanks in advance!
Use ng-change instead $watch:
Something like:
$scope.changed = function(item, type){
console.log(item);
if((type == 'aaa' || type == 'ccc') ){
$scope.tag.zzz = !item;
}
else if(type == 'zzz'){
$scope.tag.aaa = !item;
$scope.tag.ccc = !item;
}
}
HTML
<div class="group">
<input type="checkbox" ng-model="tag.aaa" ng-change="changed(tag.aaa,'aaa')"/>
<input type="checkbox" ng-model="tag.ccc" ng-change="changed(tag.ccc,'ccc')"/>
</div>
<div class="group">
<input type="checkbox" ng-model="tag.zzz" ng-change="changed(tag.zzz, 'zzz')"/>
</div>
Demo JSBIN

How to assign value to ng-model definition

I am using ui-bootstrap for typeahead in my application.
<input type="text" ng-model="newItem.id" class="form-control">
<pre>Model: {{customSelected | json}}</pre>
<input type="text" ng-model="customSelected" typeahead="asset as asset.asset_name for asset in assets | filter:{asset_name:$viewValue}" class="form-control">
When I select the autocompleted value, I can see my objects printed. But the problem is I am using newItem object to set form values and passing to $http requests, So how can I set customSelected.id to newItem.id ?
Getting error when I use something like this,
<input type="text" ng-model="newItem.id=customSelected.id" class="form-control">
Demo
If you want to assign the selected asset id to newItem.id:
<input type="text" ng-model="newItem.id" typeahead="asset.id as asset.asset_name for asset in assets | filter:{asset_name:$viewValue}" class="form-control">
UPDATE (FIDDLE)
View:
<div ng-app="App">
<div ng-controller="ctrl">
<input type="text" ng-model="newItem.id" class="form-control" />
<input
type="text"
ng-model="customSelected"
typeahead="asset as asset.asset_name for asset in assets | filter:{asset_name:$viewValue}"
class="form-control" />
</div>
</div>
Ctrl:
function ctrl($scope){
$scope.newItem = {};
$scope.assets = [
{
"id":"1",
"asset_reg_no":"AST1",
"asset_name":"Omega Shopping Complex"
},
{
"id":"2",
"asset_reg_no":"AST2",
"asset_name":"Keedam Chicken Farm"
}
];
$scope.$watch('customSelected', function(asset, oldAsset){
if(!asset && !oldAsset){
return;
}
if(oldAsset && !asset){
delete $scope.newItem.id;
delete $scope.newItem.asset_reg_no;
return;
}
$scope.newItem.id = asset.id;
$scope.newItem.asset_reg_no = asset.asset_reg_no;
});
}
If I understand you, this demo is what you want
function ctrl($scope){
$scope.assets = [{"id":"1","asset_reg_no":"AST1","asset_name":"Omega Shopping Complex","asset_type_id":"2","description":"Shopping Complex in Calicut","created_on":"2014-01-28 16:03:23","asset_type_name":"Building"},{"id":"2","asset_reg_no":"AST2","asset_name":"Keedam Chicken Farm","asset_type_id":"2","description":"Chicken farm in Valivida","created_on":"2014-01-28 16:04:06","asset_type_name":"Building"}];
$scope.newItem = {};
$scope.$watch('customSelected', function(asset, oldAsset){
$scope.newItem.id = asset.id;
$scope.newItem.text = asset.asset_name;
});
}

How to get data from ngform in angularjs?

HTML:
<div ng-controller="TestController" >
<form name="test_form" ng-submit="submit()">
<input type="text" name="some_name" ng-model="form_data.some_name" required>
<ng-form ng-repeat="key in keys" name="keyForm">
<input type="text" name="data_input" ng-model="form_data.data_input" required>
</ng-form>
<a ng-click="addKey()">NEW KEY</a>
</form>
</div>
JS:
app.controller('TestController', function TestController($scope){
$scope.keys = [];
$scope.addKey = function() {
$scope.keys.push({});
}
$scope.submit = function() {
console.log($scope);
}
});
In submit function I can get the value of "some_name" input:
$scope.submit = function() {
console.log($scope.form_data.some_name);
}
But I can't get the values of "data_input" inputs (they are inside ngform tag). How to do that?
(ngform tag is using for ability to validate each new added input separately)
Each input inside the ng-repeat needs its own unique ng-model property -- they all can't use form_data.data_input. Here is one way to solve your problem:
<ng-form ng-repeat="key in keys" name="keyForm">
<input type="text" name="data_input" ng-model="key.data" required>
</ng-form>
$scope.addKey = function () {
$scope.keys.push({ data: ''});
}
Fiddle.
See also https://stackoverflow.com/a/14379763/215945

Resources