I'm having the same problem as in this question, but the solutions there do not work for me.
I'm learning AngularJS and I am struggling to submit form data using ng-model inside of ng-repeat. I have a list of members of a group and the date they last attended:
[{"name": "Bob", "attended": "01/01/16"},
{"name":"Steve", "attended": "02/01/16"}]
I'm listing out all members using ng-repeat, and would like to be able to update the "attended" field from a form in each line. However, I cannot get "attended" to bind properly. Here's the code:
<div ng-repeat="member in members">
{{member.name}}
<input type="text" ng-model="attended"></input>
Save
</div>
$scope.setAttended = function(attended){
alert( 'Date: ' + attended);
};
The alert shows "Date: undefined". I've also tried using objects instead of primitives:
<div ng-repeat="member in members">
{{member.name}}
<input type="text" ng-model="member.attended"></input>
Save
</div>
$scope.setAttended = function(member){
alert( 'Date: ' + member.attended);
};
I get that ng-repeat will create a new scope for each object, and those scopes inherit setAttended from the parent scope. I get that the parent scope doesn't know what is happening in the child scopes, and so the parameter must let it know.
Why doesn't my parameter contain my input value?
Is the input not being bound to the model correctly before I run setAttended?
Actually it is working for me. See the snippet below.
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.9/angular-route.min.js"></script>
<style>
</style>
</head>
<body ng-controller="myController">
<div ng-repeat="member in members">
{{member.name}}
<input type="text" ng-model="member.attended"/>
Save
</div>
<script>
var app = angular.module("myApp", []);
app.controller("myController", function($scope) {
$scope.members = [{
"name": "Bob",
"attended": "01/01/16"
}, {
"name": "Steve",
"attended": "02/01/16"
}];
$scope.setAttended = function(member) {
alert('Date: ' + member.attended);
}
});
</script>
</body>
</html>
Please try below code and feedback me:
<div ng-repeat="member in members">
{{member.name}}
<input type="text" ng-model="members[$index].attended"></input>
Save
</div>
$scope.setAttended = function(attended){
alert( 'Date: ' + attended);
};
Use this , It refers to the correct scope object from ng-repeat function
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.members = [{"name": "Bob", "attended": "01/01/16"},
{"name":"Steve", "attended": "02/01/16"}];
$scope.setAttended = function(member){
alert( 'Date: ' + this.attended);
};
});
<script data-semver="1.4.9" src="https://code.angularjs.org/1.4.9/angular.js" data-require="angular.js#1.4.x"></script>
<body ng-app="plunker" ng-controller="MainCtrl">
<div ng-repeat="member in members">
{{member.name}}
<input type="text" ng-model="attended">
Save
</div>
</body>
Related
Im working on a project where I input a user's Id, first name and last name. Once input, I create a user object which is stored inside the logins array.
What I'm trying to do is display each new user as the next item in an unordered list each time the login button is clicked. Right now, I'm trying to get the user input from the text boxes, this works for the first item, until I try to clear the text boxes. How can I correctly bind my input to the user object while still being able to display each new user? I.e, add more than one user and have them both show up. They seem to be added to the array fine, but I can't figure out where the display is going wrong.
I'm thinking that because of the way I'm trying to get the data input to the text boxes, my variables are set as I enter them, but I'm not sure what else I can try. Quite new to angular. Any help is appreciated.
Code:
<!DOCTYPE html>
<html ng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.js"></script>
<script type='text/javascript'>
function LoginController($scope) {
$scope.user = {
id: "",
firstName: "",
lastName: ""
};
$scope.logins = [];
$scope.login = function () {
$scope.logins.push($scope.user);
console.log($scope.logins);
};
}
</script>
</head>
<body>
<div ng-controller="LoginController">
<div>Hello {{ user.firstName }}</div>
<input id="id" ng-model="user.id"></input>
<input id="first" ng-model="user.firstName"></input>
<input id="last" ng-model="user.lastName"></input>
<input type="submit" ng-click="login()" value="Login"></input>
<ul>
<li ng-repeat="login in logins" >{{user.id + ', ' + user.firstName + ', ' + user.lastName}}</li>
</ul>
</div>
</body>
</html>
you cannot add same object (duplicate) that you have used for repeater,
you want some like this,
check below or check on https://jsbin.com/pulinetari/1/edit?html,console,output
check
$scope.logins.push({id:$scope.user.id, firstName: $scope.user.firstName, lastName: $scope.user.lastName});
you need to create new object to add on array, which uses by repeater.
<!DOCTYPE html>
<html ng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.js"></script>
<script type='text/javascript'>
function LoginController($scope) {
$scope.user = {
id: "",
firstName: "",
lastName: ""
};
$scope.logins = [];
$scope.login = function () {
$scope.logins.push({id:$scope.user.id, firstName: $scope.user.firstName, lastName: $scope.user.lastName});
console.log($scope.logins);
};
$scope.selectUser= function(user){
$scope.user = user;
}
}
</script>
</head>
<body>
<div ng-app ng-controller="LoginController">
<div>Hello {{ user.firstName }}</div>
<input id="id" ng-model="user.id"></input>
<input id="first" ng-model="user.firstName"></input>
<input id="last" ng-model="user.lastName"></input>
<input type="submit" ng-click="login()" value="Login"></input>
<ul>
<li ng-repeat="login in logins" ng-click="selectUser(login)">{{login.id + ', ' + login.firstName + ', ' + login.lastName}}</li>
</ul>
</div>
</body>
</html>
In my HTML Page i am setting an input text box value not by typing but through JavaScript and then when I am fetching that value using AngularJS inside the controller using scope, then it's showing undefined....
Below is my code:-->
<!DOCTYPE html>
<html lang="en">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="formCtrl">
<form id="someForm" name="someForm">
First Name: <input type="text" id="fname" ng-model="user.firstname" ng-model-options="{updateOn: 'change'}" />
Last Name: <input type="text" id="lname" ng-model="user.lastname" ng-model-options="{updateOn: 'change'}" />
<input id="getUser" type="submit" ng-click="getUserName(user)" value="Get User" />
<button ng-click="resetForm(user)">RESET</button>
</form>
</div>
<script>
$('#getUser').on('click', function(){
//$("getUser").on('click', function(){
//alert("First Name "+$("#fname").val());
$("#lname").val($("#fname").val());
alert("Last Name set to "+$("#lname").val());
// });
});
</script>
<script>
//angular.element(document).ready(function () {});
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) {
$scope.getUserName = function(user)
{
alert("Last Name in Angular Controller: "+$scope.user.lastname)
}
$scope.resetForm = function(user) {
//Even when you use form = {} it does not work
angular.copy({},user);
}
});
</script>
</body>
</html>
After clicking Get User Button, first the lastname field value is set through JQuery then AngularJS controller is called in which the ng-model value is undefined. I am unable to understand this. What is the solution or workaround for this type of scenario where the input text field value is set dynamically through JavaScript or JQuery and fetched and used using AngularJS Model and Controller.
Looks like you have a typo at ng-model="user.lasttname"
<!DOCTYPE html>
<html lang="en">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="formCtrl">
<form id="someForm" name="someForm">
First Name: <input type="text" id="fname" ng-model="user.firstname" ng-model-options="{updateOn: 'change'}" />
Last Name: <input type="text" id="lname" ng-model="user.lastname" ng-model-options="{updateOn: 'change blur'}" />
<input id="getUser" type="button" ng-click="getUserName(user)" value="Get User" />
<input id="getUser2" type="button" ng-click="getUserName(user)" value="Get User" />
<button ng-click="resetForm(user)">RESET</button>
</form>
</div>
<script>
$('#getUser').on('click', function(){
var element = angular.element($('#someForm'));
element.scope().user.lastname = $("#fname").val();
});
</script>
<script>
//angular.element(document).ready(function () {});
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) {
$scope.user = {};
$scope.getUserName = function()
{
console.log("User: "+ JSON.stringify($scope.user));
alert("Last Name in Angular Controller: "+$scope.user.lastname)
}
$scope.resetForm = function(user) {
//Even when you use form = {} it does not work
// angular.copy({},user);
}
});
</script>
</body>
</html>
Add this in angularjs code:-
<script>
//angular.element(document).ready(function () {});
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) {
$scope.user = {}; // Initiate this
$scope.getUserName = function(user)
{
alert("Last Name in Angular Controller: "+$scope.user.lastname)
}
});
Of course!!! If you want the binding (HTML <--> JavaScript) you must respect the rules of Angular. What you need to do is to update the ng-model being defined for the input box. So, add to your input box: ng-model="blabla" and within your JavaScript: $scope.blabla = <value>.
Correction: You do have the ng-model in the input, but still miss the assignment within your javascript code.
In my webpage, when the user focusses on the last <input>, I want a set of a <input> and a <select> added dynamically.
If I do it with ng-click on a <button>, it works fine but not with focus event on the last <input>.
var Note = function($scope){
$scope.items = [];
$scope.options = [{name: 'x'}, {name: 'y'}];
$scope.add = function () {
console.log('adding..');
$scope.items.push({
question: "",
questionPlaceholder: "foo",
});
//console.dir($scope.items);
};
$scope.add();
$('input:last-child').on('focus', function(){ // does not work
console.log('adding elements dynamically');
$scope.add();
$scope.$apply();
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js"></script>
<div ng-app>
<div ng-controller="Note" id='itemsPool'>
<form ng-submit="submitHandler()">
<div ng-repeat="item in items">
<input type="text" placeholder="URL" ng-model="item.question">
<select ng-init="item.type = options[0]"
ng-model='item.type'
ng-options="option.name for option in options">
</select>
</div>
</form>
<button ng-click='add()'>Add</button> <!-- works! -->
<span><-- button will be removed eventually</span>
</div>
</div>
How do I fix this?
Is it possible to fix this without using jQuery? How?
Don't use jQuery like you are using now, use dedicated Angular directives. In your case you need ngFocus.
This attribute will work well for you:
ng-focus="$last && add()"
Check the demo:
var Note = function($scope){
$scope.items = [];
$scope.options = [{name: 'x'}, {name: 'y'}];
$scope.add = function () {
console.log('adding..');
$scope.items.push({
question: "",
questionPlaceholder: "foo",
});
//console.dir($scope.items);
};
$scope.add();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js"></script>
<div ng-app>
<div ng-controller="Note" id='itemsPool'>
<form ng-submit="submitHandler()">
<div ng-repeat="item in items">
<input type="text"
placeholder="URL"
ng-model="item.question"
ng-focus="$last && add()">
<select ng-init="item.type = options[0]"
ng-model='item.type'
ng-options="option.name for option in options">
</select>
</div>
</form>
<button ng-click='add()'>Add</button> <!-- works! -->
<span><-- button will be removed eventually</span>
</div>
</div>
The problem with your original approach is that there is nothing to bind focus event to, when you are using jQuery in controller, because ngRepeat has not yet rendered anything. Of course, you could workaround it easily with delegated event on the parent container, but you see how clumsy it is getting and not clear.
I tried to implement two-way data binding in two text boxes using AngularJS, however it is not working.
Here is my code:
<html ng-app="myApp">
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.3/angular-route.min.js"></script>
<script>
var app = angular.module('myApp', []);
</script>
</head>
<body ng-controller="tasksController">
<input type="text" ng-model="username" value="{{userage}}">
<input type="text" ng-model="userage" value="{{username}}">
</body>
Can anyone help me on this?
You haven't defined tasksController in your Angular code:
<script>
var app = angular.module('myApp', []);
app.controller('tasksController', function($scope){
$scope.username = "John Doe";
$scope.userage = 45;
});
</script>
The model scope will then work. Also, you don't need to bind the model to the input value. ng-model binds the value automatically :
<input type="text" ng-model="username">
<input type="text" ng-model="userage">
I am new to Angular and I am trying to obtain the value of the radio button that the user has selected using ng-model. But I am not getting any output in "selected contact".
Here is My HTML
<!doctype html>
<html ng-app>
<head>
<script src="http://code.angularjs.org/1.2.0rc1/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<form name="myForm" ng-controller="Ctrl">
<table border="0">
<th>Contact Type</th>
<tr ng-repeat="contact in contacttype"><td>
<input type="radio" ng-model="contactname" name="group1" value="{{contact.name}}">{{contact.name}}
</td>
</td></tr></table>
<tt>selected contact = {{contactname}}</tt><br/>
</form>
</body>
</html>
Below is my main.js
function Ctrl($scope) {
$scope.contacttype = [
{name: 'Both' },
{name: 'User'},
{name: 'Admin'}
];
}
What am I doing wrong here? Not able to figure out !!!
Because ng-repeat creates its own scope and what you are trying to do is assign the value to the parent scope from the child scope. So you can do
<input type="radio" ng-model="$parent.contactname" name="group1" value="{{contact.name}}">
So I had this same problem and using $parent with ng-model didn't appear to be working. My problem was that I had groups of checkboxes but used the same name attribute for each of them. It ended up hiding the default checked radio button in the last group.
Make sure you are using distinct name attributes for each distinct group.
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) {
$scope.devices = [{
nameD: "Device 1"
}, {
nameD: "Device 2"
}, {
nameD: "Device 3"
}, {
nameD: "Device 4"
}];
});
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="app-controller-r.js"></script>
<body>
<div ng-app="myApp" ng-controller="formCtrl">
<form>
<ul>
<li ng-repeat="device in devices">
<label>{{device.nameD}}
<input type="radio" ng-model="$parent.deviceType" value="{{device.nameD}}" />
</label>
</li>
</ul>
<button>Submit</button>
</form>
{{deviceType}}
</div>
</body>
</html>
if you are using the directive multiple times and you are using the for and id with labels ... Make sure to use a reference to the scope's $id
<li ng-repeat='add_type in types'>
<input id="addtester_{{ add_type.k }}_{{ $parent.$id }}" type="radio" ng-model="$parent.addType" ng-value='add_type.k' class="tb-form__input--custom" /
<label for="addtester_{{ add_type.k }}_{{ $parent.$id }}">{{ add_type.v }}</label>
</li>
Otherwise you will have been directives sharing the same inputs and make it possibly appear as if not working.