Pushing values in Ng-model inside ng-repeat - javascript

I am trying to build a status comment type of system using angularJS. The first textbox allows the user to put the value in an array and thus display it on the page. On clicking also allows a textbox and a button to enter the comment. The value of comment however is not displaying inside the scope. The code is :
HTML
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="status.js"></script>
<body ng-app="myApp" ng-controller="userCtrl">
<div>
<h2>Status!</h2>
Post status here :<br>
<textarea rows="5" cols="50" ng-model="value"></textarea>
<button ng-click="addstatus()">Click to Add!</button>
<br><br><br>
<table>
<tr ng-repeat="add in statushow">
<td><h3>{{add.value}}</h3>
<input ng-model="commentvalue" type="text" size="40" placeholder="Enter your comment here!"></input>
<button ng-click="addcomment()">Add comment!</button>
<table>
<tr ng-repeat="comms in comments">
<td><h4>{{comms.commentvalue}}</h4></td></tr></table>
</td>
</tr>
</table>
{{commentvalue}}
</div>
STATUS.JS
var app = angular.module('myApp', [])
app.controller('userCtrl', function($scope) {
$scope.statushow = [];
$scope.comments = [];
$scope.addcomment= function(){
$scope.comments.push({
commentvalue: $scope.commentvalue
});
$scope.value="";
};
$scope.addstatus= function(){
$scope.statushow.push({
value: $scope.value
});
$scope.value="";
};
});

Try with this http://jsfiddle.net/rrfqaf9L/2/:
<div ng-app="myApp" ng-controller="userCtrl">
<h2>Status!</h2>
Post status here :
<br>
<textarea rows="5" cols="50" ng-model="value"></textarea>
<button ng-click="addstatus()">Click to Add!</button>
<br>
<br>
<br>
<table>
<tr ng-repeat="add in statushow">
<td>
<h3>{{add.value}}</h3>
<input ng-model="add.commentvalue" type="text" size="40" placeholder="Enter your comment here!"></input>
<button ng-click="addcomment(add)">Add comment!</button>
<table>
<tr ng-repeat="comms in add.comments">
<td>
<h4>{{comms.commentvalue}}</h4>
</td>
</tr>
</table>
</td>
</tr>
</table>{{commentvalue}}</div>
Javascript:
var app = angular.module('myApp', [])
app.controller('userCtrl', function($scope) {
$scope.statushow = [];
$scope.addcomment= function(add){
if (typeof add.comments == 'undefined') add.comments = [];
add.comments.push({
commentvalue: add.commentvalue
});
add.commentvalue="";
};
$scope.addstatus= function(){
$scope.statushow.push({
value: $scope.value
});
$scope.value="";
};
});

A suggestion would be not to use specific keywords such as add, value as model or variable names.
You could send the model through the function as a parameter:
<textarea rows="5" cols="50" ng-model="status"></textarea>
<button ng-click="addstatus(status)">Click to Add!</button>
<table>
<tr ng-repeat="stat in statushow">
<td><h3>{{stat.value}}</h3>
<input ng-model="commentvalue" type="text" size="40" placeholder="Enter your comment here!"></input>
<button ng-click="addcomment(commentvalue)">Add comment!</button>
<table>
<tr ng-repeat="comms in comments">
<td><h4>{{comms.commentvalue}}</h4></td></tr></table>
</td>
</tr>
</table>
{{commentvalue}}
</div>
Modify the controller as:
$scope.addcomment= function(comment){
$scope.comments.push({
commentvalue: comment
});
};
$scope.addstatus= function(status){
$scope.statushow.push({
statusvalue: status
});
};
See fiddle: http://jsfiddle.net/HB7LU/15033/

The quickest way to do it would be to change the following and add $parent. NG-Repeat creates child scopes, so the input box wasn't adding the correct scope.
<input ng-model="$parent.commentvalue" type="text" size="40" placeholder="Enter your comment here!"></input>
Here's the code pen.
http://codepen.io/shuffguy/pen/gpezOM?editors=101

Related

Javascript Form Validation, multiple functions on a single button not working correctly

I'm working on a form validation project that requires multiple input fields connected to a single submit button. I more or less figured the button out, but I'm having an issue getting the functions themselves to work properly. I currently only have three of the eleven fields typed up for testing, but what the page should do is let you know which fields are invalid when there is nothing filled out in them (changing text/background colors, message below, etc).
The issue I'm having is that when the requirements for the first field (Gift Card Number) are met, it acts as though there isn't any issues anywhere, regardless of whether or not the other input fields (First name, Last name) have been filled. They all seem to function correctly if none of the fields are filled, but my concern is that the functions seem to be firing in order and first one to work negates all the ones after (for example, Gift Card prevents First and Last, First prevents Last, etc).
Any ideas where I've gone wrong here? I'll include my html and my javascript. (Yes, I know the html is a bit ugly, I plan to move the material over to a div table later, just trying to get it to function for now) Any help appreciated as always!
HTML
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<table>
<tbody>
<tr id="rONE">
<td><h4>Gift Card Amount</h4>
<form name="giftForm" onsubmit="return validateGiftCard()" method="post" id="GiftCardForm">
<input type="text" name="giftInput">
<h5 id="giftMessage"></h5></td>
<input type="submit" value="Submit" style="display:none" />
<td></td>
</tr>
</form>
<tr id="rTWO-1">
<td><h4>Recipient's name</h4>
</td>
<td> </td>
</tr>
<tr id="rTWO-2">
<td>
<form name="firstForm" onsubmit="return validateRecipient()" method="post">
<input type="text" name="firstInput">
<br>
<h4>First</h4>
</form>
</td>
<td><form name="lastForm" method="post">
<input type="text" name="lastInput">
<br>
<h4>Last</h4></td>
</form>
</tr>
<tr>
<td><h5 id="recipientMessage"></h5></td></td>
<td> </td>
</tr>
</tbody>
</table>
<button type="submit" id="btn" form="GiftCardForm" value="Submit">Submit</button>
</body>
<footer>
<script src="Form Validation.js"></script>
</footer>
</html>
Javascript
document.getElementById('btn').addEventListener('click', function(){
validateGiftCard();
validateRecipient();
});
function validateGiftCard() {
valid = true;
if ( document.giftForm.giftInput.value == "" )
{
giftMessage.innerHTML = "This field is required";
document.getElementById("rONE").style.backgroundColor="#fff7f7"
valid = false;
}
return valid;
}
function validateRecipient() {
valid = true;
if ( document.firstForm.firstInput.value == "" )
{
recipientMessage.innerHTML = "This field is required";
document.getElementById("rTWO-1").style.backgroundColor="#fff7f7"
document.getElementById("rTWO-2").style.backgroundColor="#fff7f7"
valid = false;
}
return valid;
}
document.getElementById('btn').addEventListener('click', function(e) {
var v1 = validateGiftCard();
var v2 = validateRecipient();
console.log(v1, v2);
if (!v1 || !v2)
e.preventDefault();
});
function validateGiftCard() {
valid = true;
if (document.giftForm.giftInput.value == "") {
giftMessage.innerHTML = "This field is required";
document.getElementById("rONE").style.backgroundColor = "#fff7f7"
valid = false;
}
return valid;
}
function validateRecipient() {
valid = true;
if (document.firstForm.firstInput.value == "") {
recipientMessage.innerHTML = "This field is required";
document.getElementById("rTWO-1").style.backgroundColor = "#fff7f7"
document.getElementById("rTWO-2").style.backgroundColor = "#fff7f7"
valid = false;
}
return valid;
}
<table>
<tbody>
<tr id="rONE">
<td>
<h4>Gift Card Amount</h4>
<form name="giftForm" onsubmit="return validateGiftCard()" method="post" id="GiftCardForm">
<input type="text" name="giftInput">
<h5 id="giftMessage"></h5>
</form>
</td>
<input type="submit" value="Submit" style="display:none" />
<td></td>
</tr>
<tr id="rTWO-1">
<td>
<h4>Recipient's name</h4>
</td>
<td> </td>
</tr>
<tr id="rTWO-2">
<td>
<form name="firstForm" onsubmit="return validateRecipient()" method="post">
<input type="text" name="firstInput">
<br>
<h4>First</h4>
</form>
</td>
<td>
<form name="lastForm" method="post">
<input type="text" name="lastInput">
<br>
<h4>Last</h4>
</form>
</td>
</tr>
<tr>
<td>
<h5 id="recipientMessage"></h5>
</td>
<td> </td>
</tr>
</tbody>
</table>
<button type="submit" id="btn" form="GiftCardForm" value="Submit">Submit</button>

for loop not working in JavaScript while Second Attempt

I got stuck in a very strange problem need help.
Actually i am trying to assign some value to dynamically generated input fields. So i tried the following code snippet. I mean to say in first step i only need to assign value for first 10 IDs and then again if assigning some other values to rest of IDs then it fails
JavaScript
<script type="text/javascript">
function callAssignMark() {
var rightMarkVal = $("#rightMarkVal").val();
var wrongMarkVal = $("#wrongMarkVal").val();
var initial= $("#from").val();
var last= $("#to").val();
console.log('fromWhere--'+initial);
console.log('to---'+last);
alert('Before Loop');
for (var i = initial; i <= last; i++) {
$('#rightMark_' + i ).val(rightMarkVal);
$('#wrongMark_' + i ).val(wrongMarkVal);
$('#selectData_' + i).prop('checked', 'checked');
}
$("#from").val('');
$("#to").val('');
}
</script>
The above JavaScript code working fine in first attempt means when I assign some value to initial and last variable then the loop iterates and works as expected and assign desired values to dynamically generated input fields, But now the problem is when I assign new value to initial and last variable then the loop not able to iterate any more.
And one more thing I want tell you all that all the dynamic IDs of input fields are generated correctly and I'm also getting the values which is going to be assigned to the input fields on second attempt and my HTML looks like following.
HTML
<div>
<div>
<ul>
<li>
<label>From</label>
<input name="" id="from" type="text" placeholder="from" value="" />
<label>To</label>
<input name="" id="to" type="text" placeholder="to" value="" />
<input name="rightMarkVal" id="rightMarkVal" type="text" placeholder="positive Value" value="" />
<input name="wrongMarkVal" id="wrongMarkVal" type="text" placeholder="Negative value" value="" />
<input type="button" class="btn btn-success" value="Assign Marks" onclick="callAssignMark()">
</li>
</ul>
</div>
<c:set var="counter" value="0" scope="page" />
<div>
<table>
<th>S.No</th>
<th>
<input type="checkbox" id="selectAllCheckBox">
</th>
<th>Right Marks</th>
<th>Wrong Marks</th>
<tbody>
<c:forEach var="list" items="${List}" varStatus="loop">
<tr>
<td>
<c:out value="${counter = counter+1 }" />
</td>
<td>
<form:checkbox path="qId" id="selectData_${counter}" value="${list.id}">
</form:checkbox>
</td>
<td>
<form:input path="rightMark" id="rightMark_${counter}" value="" />
</td>
<td>
<form:input path="wrongMark" id="wrongMark_${counter}" value="" />
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
I am unable to find out where is the problem so please help me.
Any help will be appreciated. Thanks

How to using angular ng-view keeps content in input field

I am new to AngularJS and working on a small project. I want to build an editable table for courses including course Id and course Name. Users are able to click edit button and then they can edit content.
Howwever,I met a problem that when user clicks edit button, all the content just gone, like delete, but I want to keep the content editable. I try ng-value, but didn't work.
Here is my code and codepen link: http://codepen.io/marong125/pen/JRBQdo
Thank you so much!
<html>
<head>
<title>Online Learning</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-route.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-resource.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script>
var app = angular.module('app', []);
app.controller('courseController', function ($scope) {
$scope.courses = [
{
courseID: "CS602",
courseName: "Web Development",
isEditing:false
},
{
courseID: "CS502",
courseName: "Foundation of Java",
isEditing:false
}
];
$scope.addCourse = ()=>{
$scope.courses.push({
courseID: $scope.createIdInput,
courseName: $scope.createCourseInput
});
$scope.createIdInput = '';
$scope.createCourseInput = '';
console.log(1);
}
$scope.onEditClick = (course)=>{
course.isEditing = true;
}
});
</script>
</head>
<body ng-app="app">
<<h1>Course Manager</h1>
<div ng-controller = "courseController">
<form name="courseForm">
<input id="c_id_input" placeholder="Add course ID" ng-model="createIdInput" />
<input id= "c_name_input" placeholder="Add course name" ng-model="createCourseInput" />
<button class="btn btn-success pull-right" ng-click="addCourse()">Add Course</button>
</form>
<table class="table table-striped table-bordered table-condensed table-hover">
<tr>
<th>Course ID</th>
<th>Course Name</th>
<th>Actions</th>
</tr>
<tr ng-repeat = "course in courses">
<td>
<span ng-if="!course.isEditing" >{{course.courseID}}</span>
<form ng-submit="updateTask(course)">
<input type="text" ng-if="course.isEditing" class="form-control"
ng-value="course.courseID" ng-model="updatedCourseId" />
</form>
</td>
<td>
<span ng-if="!course.isEditing">{{course.courseName}}</span>
<form >
<input ng-if="course.isEditing" class="form-control"
ng-value="course.courseName" ng-model="updatedCourseName" />
</form>
</td>
<td>
<button class="btn btn-info" ng-click="onEditClick(course)" >Edit</button>
<button class="btn btn-danger">Delete</button>
</td>
</tr>
</table>
</div>
</body>
</html>
This is happening because of your ng-model in the edit fields. If you look closely you will find that ng-model for your ID field in updatedCourseId and Name is updatedCourseName. However your actual values are stored in course.courseID and course.courseName. Change your ng-model and point to the correct variables.
<input type="text" ng-if="course.isEditing" class="form-control"
ng-value="course.courseID" ng-model="updatedCourseId" />
<input ng-if="course.isEditing" class="form-control"
ng-value="course.courseName" ng-model="updatedCourseName" />
Alternatively
If you don't want to mix up the updated value and the non-updated value you can do that by copying the current value to another field when the user clicks on edit. I have created a codepen to demonstrate this, you can see it here.
JavaScript (Controller)
$scope.onEditClick = (course) => {
course.isEditing = true;
course.updatedCourseId = course.courseID;
course.updatedCourseName = course.courseName;
}
HTML
<input type="text" ng-if="course.isEditing" class="form-control"
ng-model="course.updatedCourseId" />
<input ng-if="course.isEditing" class="form-control"
ng-model="course.updatedCourseName" />
I think you are misunderstanding how ng-model works. ng-model represents the variable that your data is saved in, and it's a two way binding. You don't need a separate variable to store the "updated" values.
Instead of:
<input type="text" ng-if="course.isEditing" class="form-control"
ng-value="course.courseID" ng-model="updatedCourseId" />
you should use:
<input type="text" ng-if="course.isEditing" class="form-control"
ng-model="course.courseID" />
The changes will automatically be reflected, in real time, back to the array.

AngularJS Form Validation: $valid Always True

I'm having trouble with AngularJS form validation. Below is a simple two-field form with the only requirements being that data for each field is required, one of which is of "email" type.
The trouble is, no matter what I put as the value for either of the two fields, Angular's .$valid always returns the value of true and $invalid returns the value of false. It can be an empty field, a valid/invalid email address, or as long a string as I choose. The result is the same.
Therefore, the submit button is never disabled because I'm using
ng-disabled="FormLogin.$invalid"
However, if I use a variable from the controller, the submit button is disabled
ng-disabled="disableSubmit"
This suggests that Angular is working, but I haven't set up the directives correctly in the form controls. Note that ng-model directives appear to applied correctly.
I've tried many different variations of code on them, some pretty desperate, to no avail. There are other SO questions regarding this same subject, but I didn't find any that applied. Any suggestions you may have would be great. Thanks.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="formCtrl" align="center" style="width:400px;padding: 10px 10px 10px 10px;">
<table class="table table-stripe"><form name="FormLogin" ng-submit="submitForm(FormLogin.$valid)" novalidate>
<tr>
<td>User:</td>
<td>
<input type="email" name="email" class="form-control" ng-model="email" required />
</td>
</tr>
<tr>
<td>Pwd:</td>
<td><input type="password" name="password" class="form-control" ng-model="password" required /></td>
</tr>
<tr>
<td colspan="2" align="center">
<button type="submit" class="form-control" style="width:200px;" ng-disabled="FormLogin.$invalid">Log In</button>
</td>
</tr></form>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) {
$scope.disableSubmit = true;
$scope.email = 'testUser#testDomain.com';
$scope.password = 'y!keZ';
$scope.submitForm = function(isValid) {
alert($scope.email + ':' + $scope.password + ':' + isValid);
};
});
</script>
</body>
</html>
Your issue is due to invalid html, you have nested the form directly under table which is incorrect and the browser will throw it out of the table (or whatever it decides to do) as it renders (before even angular processes the DOM) and the angular validations does not work properly.
Demo wrapping the table inside the form
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) {
$scope.disableSubmit = true;
$scope.email = 'testUser#testDomain.com';
$scope.password = 'y!keZ';
$scope.submitForm = function(isValid) {
console.log($scope.email + ':' + $scope.password + ':' + isValid);
};
});
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="formCtrl" align="center" style="width:400px;padding: 10px 10px 10px 10px;">
<form name="FormLogin" ng-submit="submitForm(FormLogin.$valid)" novalidate>
<table class="table table-stripe">
<tr>
<td>User:</td>
<td>
<input type="email" name="email" class="form-control" ng-model="email" required />
</td>
</tr>
<tr>
<td>Pwd:</td>
<td>
<input type="password" name="password" class="form-control" ng-model="password" required />
</td>
</tr>
<tr>
<td colspan="2" align="center">
<button type="submit" class="form-control" style="width:200px;" ng-disabled="FormLogin.$invalid">Log In</button>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>

Javascript validating multiple fields

I want to validate multiple fields in my form. For that i don't want to write separate condition for all the fields. So i have assigned the error messages like a key and value pair.
If i leave all the fields without typing any value then it should populate error message.
This is my html code.
<head>
<title></title>
<script src="Scripts/validate_register.js"></script>
</head>
<body>
<table class="valid">
<tr>
<td>id:</td>
<td><input type="text" id="id1" placeHolder="Enter your name"/></td></tr>
<tr><td>email:</td>
<td><input type="text" id="id2" placeHolder="Enter your email"/></td></tr>
<tr><td>password:</td>
<td><input type="text" id="id3" placeHolder="Enter your password"/></td></tr>
<tr><td>address:</td>
<td><input type="text" id="id4" placeHolder="Enter your address"/></td></tr>
<tr><td>contact no:</td>
<td><input type="text" id="id5" placeHolder="Enter your contact no"/></td>
</tr>
<tr><td><input type="submit" onclick="validate()" value="submit"> </td></tr></table>
</body>
This is my javascript code.
function validate () {
var error={
id1:'name Cannot be empty',
id2:'email cannot be empty',
id3:'password cannot be empty',
id4:'address Cannot be empty',
id5:'contactno cannot be empty'
}
var elements=document.querySelectorAll('input');
for(var i=0;i<elements.length;i++){
if(elements[i]['value']=="")
{
var id=elements[i]['id'];
document.querySelector("."+id).innerHTML=error[id];
}
}
}
This shows an error on the document.querySelector("."+id).innerHTML=error[id]; line about something being null.
document.querySelector("."+id).innerHTML=error[id];
That expects you to have an element with a class corresponding to the input's id (e.g.,
class="id2" and such). You haven't shown any of those in your question. querySelector returns null if it can't find a matching element.
If you add a series of things like this in appropriate locations:
<span class="id1"></span>
...then that element will get the error message for your <input id="id1">. Or of course, as these elements are unique, you could use ids like error_id1, error_id2, and such.
Here's a complete example using classes: Live Copy
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Example</title>
</head>
<body>
<table class="valid">
<tr>
<td>id:</td>
<td><input type="text" id="id1" placeHolder="Enter your name"/><span class="id1"></span></td></tr>
<tr><td>email:</td>
<td><input type="text" id="id2" placeHolder="Enter your email"/><span class="id2"></span></td></tr>
<tr><td>password:</td>
<td><input type="text" id="id3" placeHolder="Enter your password"/><span class="id3"></span></td></tr>
<tr><td>address:</td>
<td><input type="text" id="id4" placeHolder="Enter your address"/><span class="id4"></span></td></tr>
<tr><td>contact no:</td>
<td><input type="text" id="id5" placeHolder="Enter your contact no"/><span class="id5"></span></td>
</tr>
<tr><td><input type="button" onclick="validate()" value="submit"> </td></tr></table>
</body>
<script>
"use strict";
function validate () {
var error={
id1:'name Cannot be empty',
id2:'email cannot be empty',
id3:'password cannot be empty',
id4:'address Cannot be empty',
id5:'contactno cannot be empty'
}
var elements=document.querySelectorAll('input');
for(var i=0;i<elements.length;i++){
var id=elements[i]['id'];
document.querySelector("."+id).innerHTML=elements[i].value ? "" : error[id];
}
}
</script>
</body>
</html>
In the above, I've also cleared the errors when the field had a value, so that the second time it runs, the error disappears. (I also changed the submit button to just a button, but that's only so the form doesn't get submitted nowhere in the example.)
Side note: I'd move validate to an onsubmit on the form, and have it return false if there are any errors.
. is for classes. If you want to detect ids, you need to use #. Moreover, you need to use value, not innerHTML. So, correct
document.querySelector("."+id).innerHTML=error[id];
to
document.querySelector("#"+id).value=error[id];

Categories