$scope.push failing to update after entering same value in Angular (bug!) - javascript

I am new to Angular and I was trying my hands on a few functions. I found this strange behavior when I try to re-enter the same value.
<!-- HTML -->
<body ng-app="angular-test">
<div ng-controller="FormController">
<ul>
<li ng-repeat="name in names">{{name}}</li>
</ul>
<form ng-submit="addName()">
<input type="text" ng-model="newName">
<input type="submit" value="Add">
</form>
</div>
</body>
/*** Angular Code ***/
(function() {
var app = angular.module("angular-test", []);
app.controller("FormController",formController);
function formController($scope){
$scope.names = ['Israel','Agyeman','Prempeh','Osei','Apea'];
$scope.addName = function(){
$scope.names.push($scope.newName);
$scope.newName = '';
}
}
})(angular);
![A list generated from the existing model in the HTML page][1]
Israel
Agyeman
Prempeh
Osei
Apea
King
king
______________ [Add] (input form)
"King" was added through the add button so was "king" but as I typed "king" again it failed to update and does not update afterwards no matter what I insert. Any ideas as to what is causing this?

Evening Israel,
You can't duplicate values in a repeater. To make it works, just add the following:
name in names track by $index
Or see it in action: http://codepen.io/anon/pen/xGzRKK
Hope it helps!

Related

on-click event does not make the other field editable in one-click?

<!--Below is the html code-->
<div ng-init="InitializeFields()">
<input type="text" on-click="makeOtherReadOnly('1')"
readonly="show_or_not_first"/>
<input type="text" on-click="makeOtherReadOnly('2')" readonly="show_or_not_second"/>
</div>
// Now inside javascript
$scope.makeOtherReadOnly=function(number){
if(number==='1'){
show_or_not_second=true;
show_or_not_first=false;
show_or_not_second=true;
}else if(number==='2'){
show_or_not_first=true;
show_or_not_second=false;
}
};
$scope.Initializer=function(){
show_or_not_first=false;
show_or_not_second=false;
}
$scope.Initializer();
the problem that I am facing is as I click on the input field, it should turn the other field to readonly after pafe gets loaded and we have either field clicked, but it requires two click...
Every help is appreciated.
Try changing on-click to ng-click.
You need to correct few things ion your code :
change on-click to ng-click, So your function can be called from HTML.
Change readonly to ng-readonly, So you can utilize $scope property
In your ng-init, I guess you need to call Initializer() method to initialize default value.
Further just to make 2 input box readonly, you can chieve this by 1 flag. and no string comparison.
Simple Demo :
angular.module('myApp', []).controller('myCtrl', function($scope) {
$scope.makeOtherReadOnly = function(boolValue) {
console.log(boolValue);
$scope.data.first = boolValue;
};
$scope.Initializer = function() {
$scope.data = {
first: false
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-init="Initializer()">
First: <input type="text" ng-click="makeOtherReadOnly(false)"
ng-readonly="data.first" />
Second: <input type="text" ng-click="makeOtherReadOnly(true)"
ng-readonly="!data.first" />
</div>
</div>
There are two scopes here
javascript and angular
sometimes inside ng-click, javqascript function don't work
so change on-click to ng-click.

Node.js generated text boxes are filled simultaneously

I'm building a dynamically generated form from a database using ng-repeat in Node.js and Angular. All of the text boxes are replicating the text entered on any one of the text boxes. So, if I type "xyz" in one text box, all of them have "xyz". But, if I submit the results, it only updates that one form reference.
This is the HTML:
<div class="container">
<div class="todo-form">
<form class="form-inline" ng-repeat="todo in todoData">
<li>
<h4>Country Code: {{ todo.country_code }} <input id="{{ todo.country_code }}" type="text" class="form-control input-sm" placeholder="{{ todo.country_name }}" ng-model="formData.text">
<button type="submit" class="btn btn-default" ng-click="updateTodo(todo.country_code)">Update</button></h4><br>
</li>
</form>
</div>
This is the JS it refers to:
angular.module('editTodo', [])
.controller('editController', ($scope, $http) => {
$scope.formData = {};
$scope.todoData = {};
// Get Org Details
$http.get('ref_country_code_get')
.success((data) => {
$scope.todoData = data;
console.log(data);
})
.error((error) => {
console.log('Error: ' + error);
});
Clearly, I need to disable this. I've tried to add a name= or ID={{ todo.country_code }} into the form to make it unique, but that doesn't work. Why are the all acting like they are the same text box? I'm new to Node.js and very rusty with my HTML, but I can't find any reference to this phenomena. Maybe it is too basic that nobody makes this mistake? %)
Andy F solved the issue. Simply replace the ng-model="formdata.txt" to ng-model="todo.txt". Now, none of the text boxes replicate what is typed in any other text box.

AngularJS: Target a form with Controller As syntax in an object

Note: I did look around here on SO for solutions, yet no one had the additional issue of the function being in an object.
I have a form in my Angular JS app:
<div ng-app="plunker">
<div ng-controller="PMTController as pmt">
<form name="myForm">
<div class="form-group">
<input type="text" class="form-control" />
</div>
<button class="btn btn-primary" ng-click="pmt.search.resetSearchForm()">Reset</button>
</form>
</div>
</div>
Further, I have a controller with an object:
app.controller('PMTController', function($log) {
var _this = this;
_this.search = {
resetSearchForm: function () {
$log.debug('test');
// how to target the form?
}
};
})
My ng-click works, as the log.debug works. But no amount of tweaking to target the form so that I can reset the entire thing (empty all the fields) works.
I can do $window.myForm.reset(); but how could I do this from angular?
Note please my main issue/question is how to correctly target the form from inside that resetSearchForm function in the search object.
Note I tried changing the form name to pmt.myForm or pmt.search.myForm to no avail.
I tried $setPristine and $setUntouched() but they don't seem to clear the fields.
I know I can assign a model and assign it to all the form controls, but this is for a prototype so I'd rather do a simple reset.
I made a pen: https://codepen.io/smlombardi/pen/YWOPPq?editors=1011#0
Here is my take on your codepen that will hopefully resolve the issue:
https://codepen.io/watsoncn/pen/YWOXqZ?editors=1011
Explanation:
Angular's documentation provides an example of a "Form Reset" button, but you can apply the same logic towards resetting after submission:
Documentation:https://docs.angularjs.org/guide/forms
with a plunker:
Live Example:https://plnkr.co/edit/?p=preview
The example shows the use of Angular's copy method that creates a deep copy of whatever you pass it as a parameter and assigns it to the ng-model that is put on a particular input field. In this case they simply pass it an empty master object.
You need to make sure to add an ng-model attribute to your inputs, then create a reset function that can run after submission. Another common option would be to simply set each input's ng-model to empty strings in the submission function, such as $scope.inputModel = ""
Is this what you were hoping for? I might have misunderstood the question. I will happily take another crack at it if there is still confusion.
To get the form in your controller you just need to name your form this way:
<form name="pmt.myForm">
Here's a complete demo:
(function() {
"use strict";
angular
.module('plunker', [])
.controller('PMTController', PMTController);
PMTController.$inject = ['$log'];
function PMTController($log) {
var _this = this;
_this.model = {};
_this.search = {
resetSearchForm: function() {
console.log(_this.myForm); // -> Form reference
_this.model = {};
}
};
}
})();
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body ng-controller="PMTController as pmt">
<div class="col-md-12">
<form name="pmt.myForm">
<div class="form-group">
<input type="text" ng-model="pmt.model.example" class="form-control" />
<input type="text" ng-model="pmt.model.example2" class="form-control" />
<input type="text" ng-model="pmt.model.example3" class="form-control" />
</div>
<button class="btn btn-primary" ng-click="pmt.search.resetSearchForm()">Reset</button>
</form>
<hr> All fields:
<pre ng-bind="pmt.model | json"></pre>
</div>
</body>
</html>

Validate inputs in table row with angular

I use this lib to create table on page.
Every row in this table can be edited. So if editMode is on, I show inputs at each column of row. Some of this inputs is required. I want to show red text "Required" or just red border if required field is empty.
But problem - it's simple when I use form. But in my case I can't use forms.
This answer isn't good for me, cause every row must have unique form-name for correct validation.
Example : https://jsfiddle.net/r8d1uq0L/147/
<div ng-repeat="user in users">
<div name="myform-{{user.name}}" ng-form>
<input type="text" ng-model='user.name' required name="field"/>
<span class="error" ng-show="myform.field.$error.required">Too long!</span>
</div>
</div>
<div>
<button ng-click="add()">
Add
</button>
</div>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.users = [{name:"1"}, {name:"2"}];
$scope.add = function(){
$scope.users.push({});
}
});
No need to create a dynamic form name, as ng-repeat does create new child scope on each iteration while drawing template on browser. So just keep name as name="innerForm" and use innerForm.field.$error.required to have validation over it.
<div ng-repeat="user in users">
<div name="innerForm" ng-form>
<input type="text" ng-model='user.name' required name="field"/>
{{myform[$index]}}
<span class="error" ng-show="innerForm.field.$error.required">Too long!</span>
</div>
</div>
Forked Fiddle

Binding using ng-model inside ng-repeat in angularjs

I'm trying to bind a model 'User' to a list of input fields. I do not know the fields beforehand, so i've to write a generic code to setup the form based on the fields.
<script>
function MyController($scope){
$scope.fields = ['name','password','dob'];
$scope.user1 = {name:"Shahal",password:"secret"}
};
</script>
<div ng-app ng-controller="MyController">
<ul>
<li ng-repeat="field in fields">
<label>{{field}}</label><input type="text" ng-model="user1.{{field}}">
</li>
</ul>
<pre>{{fields}}</pre>
</div>
I'm trying to loop through the fields and show a input field for each fields (available in scope). But the binding is not proper as i'm trying to evaluate an expression inside ng-model.
Basically i'm trying to show 3 input fields (name,password,dob) with the object user1 attached to the corresponding field.
Here's the fiddle
Any help?
Below will solve your problem
<script>
function MyController($scope){
$scope.fields = ['name','password','dob'];
$scope.user1 = {name:"Shahal",password:"secret"}
};
</script>
<div ng-app ng-controller="MyController">
<ul>
<li ng-repeat="field in fields">
<label>{{field}}</label><input type="text" ng-model="user1[field]">
</li>
</ul>
<pre>{{fields}}</pre>
</div>

Categories