Values not updating for dynamically added field in angular js - angularjs

I have created a form where fields are added dynamically.Adding works perfectly but the problem i am facing is when i am updating it.In the form there are two textboxes , a text area and a checkbox. Checkbox is checked depending upon the condition of a database field.At the time of editing all values are getting updated but the checkbox value is always getting set to true if i also unchecked the checkbox.
Below the code i am using
The Json i am receiving
$scope.choices = {"success":"yes","msg":"","data":{"checkListValues":[{"id":"81","checklist_id":"1","number":"1","short_text":"shorttext 12","long_text":"longtext12","is_photo":"1"},{"id":"82","checklist_id":"1","number":"2","short_text":"shorttext21","long_text":"longtext22","is_photo":"1"}]}}
In the html Part
<a ng-click="addNewChoice()" class="btn btn-success ng-scope" >Add More</a>
<tr data-ng-repeat="choice in choices track by $index">
<td>
<div class="number-part">
<input type="text" ng-model="choice.number" required />
</div>
</td>
<td>
<div class="shorttext-part">
<input type="text" ng-model="choice.short_text" ng-trim="false" maxlength="40" required/>
<div class="clearfix"></div>
<span class="character-count">{{40 - choice.short_text.length}} Characters left</span>
</div>
</td>
<td>
<div class="shorttext-part">
<textarea ng-model="choice.long_text" ng-trim="false" maxlength="255" required></textarea>
<div class="clearfix"></div>
<span class="character-count">{{255 - choice.long_text.length}} Characters left</span>
</div>
</td>
<td>
<input type="checkbox" ng-checked="choice.is_photo == 1" ng-model="choice.is_photo"/>
</td>
<td>
<a ng-if="!$first" ng-click="removeChoice($index)">
<i class="fa fa-minus"></i>
</a>
</td>
And In the angular js controller
$scope.removeChoice = function(z)
{
var lastItem = $scope.choices.length-1;
$scope.choices.splice(z,1);
};
$scope.addNewChoice = function()
{
var newItemNo = $scope.choices.length+1;
$scope.choices.push({'id':'choice'+newItemNo});
//console.log("=====",$scope.choices);
};
$scope.item = [];
var newItem = {};
for( var i in $scope.choices)
{
newItem= $scope.choices[i];
$scope.item.push(newItem);
}
So how to do that if a checkbox is selected at the time of editing and if i unchecked it the value should be updated in the $scope.choices.
Working for the text box and text area... problem is happening only with the checkbox

EDIT Maybe it is better that is_photo to be a boolean, instead of string:
Than you dont need to use ngChange at all, you just need ng-model and ng-checked
I left in this plunker ng-change so you can monitor the values of the checkbox models.
<input type="checkbox" ng-checked="choice.is_photo" ng-model="choice.is_photo" />

Related

Object not added to one $scope variable but to all others

Everytime I want to add a form to fill out a new contact person of a customer company I call this function:
$scope.addContact = () => {
$scope.selectedCustomer.contacts.push({});
console.log(JSON.stringify($scope.selectedCustomer));
};
But I noticed there is one customer that magically loses that contact object at somepoint after the method is called and I don't know why, because in the debugger only some standard angularjs methods are executed that shouldn't play a role in this and I don't understand them.
Usually the console looks like this:
1st, 2nd and 3rd click on add contact button results in:
{"id":135,"masterData":{},"name":"Normal Test","contacts":[{}]}
{"id":135,"masterData":{},"name":"Normal Test","contacts":[{"$$hashKey":"object:2205"},{}]}
{"id":135,"masterData":{},"name":"Normal Test","contacts":[{"$$hashKey":"object:2205"},{"$$hashKey":"object:2207"},{}]}
But for one object (so far, but I think there are more) the same situation prints this:
{"id":150,"masterData":{},"name":"Test AG","contacts":[{}]}
{"id":150,"masterData":{},"name":"Test AG","contacts":[{}]}
{"id":150,"masterData":{},"name":"Test AG","contacts":[{}]}
As you see there is an empty object added but not saved, every time I click add contact again, the contacts array is empty at first.
In the mongo db those two customers look exactly the same:
What else can I analyze to find out where the problem is and what to do about it?
EDIT
By debugging I found the place where the workflow traverses a different path when it's not working:
contentscript.js, line 1114 var observerHandler = function(mutations) {... is traversed when it works, but not reached during the failing process - it is called after: return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply( elem, arguments ) : undefined; in jquery.js, line 5013.
My HTML:
<div class="form-group">
<label for="contacts" class="col-sm-3 control-label">Ansprechpartner</label>
<div class="col-sm-9">
<table id="contacts" ng-if="selectedCustomer.contacts.length"
class="table-condensed" cellpadding="10">
<tr>
<th>Name</th>
<th>Telefon</th>
<th>E-Mail</th>
</tr>
<tr ng-repeat="contact in selectedCustomer.contacts">
<td>
<a class="delete" ng-hide="readonly" ng-click="deleteContact(contact)">
<i class="fa fa-minus-circle"></i>
</a>
<input type="text" class="form-control"
ng-readonly="readonly" ng-model="contact.name"
placeholder="keine Angabe">
</td>
<td>
<input type="text" class="form-control" ng-readonly="readonly"
ng-model="contact.phone" placeholder="keine Angabe"/>
</td>
<td>
<input type="text" class="form-control" ng-hide="readonly"
ng-model="contact.email" placeholder="keine Angabe"/>
<a href="mailto:{{contact.email}}" ng-show="readonly">
<input type="text" class="form-control"
ng-readonly="readonly" ng-model="contact.email"
placeholder="keine Angabe"/>
</a>
</td>
</tr>
</table>
<div class="addContact" ng-hide="readonly">
<button class="btn btn-default btn-block btn-sm" ng-click="addContact()"
type="button">+ Ansprechpartner hinzufügen...
</button>
</div>
</div>
</div>

Atleast one field is mandatory in form: Form Validation in Angular

I have got three input fields on a form.
I am looking for a way in which a form is valid if either or any combination of inputs is required, It means atleast one is necessary .Also user may enter inputs in any combination even then also form is valid.
I have read ng-required but that will make my expression too long.
<td>Name</td>
<td><input type="text" class="form-control input-xs" name="name"
ng-model="ctrl.orderSearch.name" minlength="4">
</td>
<td>Class</td>
<td><input type="text" class="form-control input-xs" name="class"
ng-model="ctrl.orderSearch.Class" minlength="6">
</td>
<td>Roll No:</td>
<td><input type="text" class="form-control input-xs" name="rollNo"
ng-model="ctrl.orderSearch.RollNo" minlength="6">
</td>
Update: I don't want to diable submit button. The form is valid in either of these scenarios:
1)field one or two or three is filled
2) 1,2 or 1,3 or 2,3 is filled
3) 1,2,3 is filled.
Also, I tried to use:
ng-required="!(ctrl.orderSearch.name.length || ctrl.orderSearch.rollNo.length )" on fields. But when I submit my form ,an in built pop up from angular is presented on my name field saying "Please fill this required field" because whenever form.$valid is called on an empty form , field one would be checked first and hence pop up will be displayed on that field. But to user, it may seem field one is mandatory which is not the case.
Also , I don't want to write a custom method for validation. Is is it possible using ng-required? Please help.
Check this link
HTML
<form name="myForm">
<input type="text" ng-model="fields.one" name="firstField" ng-required="!(fields.one.length || fields.two.length || fields.three.length)" />
<br/>
<input type="text" name="secondField" ng-required="!(fields.one.length || fields.two.length || fields.three.length)" ng-model="fields.two" />
<br/>
<input type="text" ng-model="fields.three" name="thirdField" ng-required="!(fields.one.length || fields.two.length || fields.three.length)" />
<br/>
<button type="submit" ng-disabled="!myForm.$valid">Submit</button>
<br/>
<div>
<p>Submitted ? <span ng-bind="fields.submitted"></span>
</p>
<p>Form $valid: <span ng-bind="myForm.$valid"></span>
</p>
</div>
</form>
Js
angular.module("myApp", [])
.controller('myCtrl', ['$scope', function ($scope) {
$scope.fields = {
one: '',
two: '',
three: '',
submitted: 'Not Yet'
};
$scope.submit = function () {
$scope.fields.submitted = "Yahooo";
}
}]);
You can create a $scope variable that will do the "either or all of fields required checking". That $scope variable will be your flag on when a form is valid or not.
example:
Controller
function SampleController(){
$scope.isValidForm = function(){
//do the checking here.
//return true or false
}
}
View:
<button ng-disabled="!isValidForm()">Submit</button>
I have edited your code check your code... check the fiddle link Fiddle
Hope this will help you to understand validation..
<div ng-app ng-controller="myCtrl">
<table ng-form="checkForm">
<tr>
<td>Name</td>
<td>
<input type="text" class="form-control input-xs" required name="name"
ng-model="ctrl.orderSearch.name" minlength="4" >
</td>
<td>
<div ng-show="checkForm.name.$invalid">
name error
</div>
</td>
</tr>
<tr>
<td>Class</td>
<td>
<input type="text" class="form-control input-xs" required name="class"
ng-model="ctrl.orderSearch.Class" minlength="6" >
</td>
<td>
<div ng-show="checkForm.class.$invalid">
class error
</div>
</td>
</tr>
<tr>
<td>Roll No:</td>
<td>
<input type="text" class="form-control input-xs" required name="rollNo"
ng-model="ctrl.orderSearch.RollNo" minlength="6" >
</td>
<td>
<div ng-show="checkForm.rollNo.$invalid">
Roll no error
</div>
</td>
</tr>
<tr>
<td colspan="3" style="font-weight:bold; color:green">
<span ng-show="checkForm.name.$valid || checkForm.class.$valid || checkForm.rollNo.$valid">Valid Form</span>
</td>
</tr>
</table>
</div>
Below is the code it will validate on form submitting event.It will restrict while you submit the form and your form contains all the fields empty.
<html>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script>
angular.module('myApp', []).controller('myCtrl', function($scope) {
$scope.isOneFieldRequired = function (name,uclass,rollNo) {
return !(name|| uclass|| rollNo);
};
});
</script>
<div ng-app="myApp" ng-controller="myCtrl">
<form name="myForm">
<input type="text" ng-model="name" name="name" ng-required="isOneFieldRequired(name,uclass,rollNo)" />
<br/>
<input type="text" ng-model="uclass" name="uclass" ng-required="isOneFieldRequired(name,uclass,rollNo)" />
<br/>
<input type="text" ng-model="rollNo" name="rollNo" ng-required="isOneFieldRequired(name,uclass,rollNo)" />
<br/>
<button type="submit"> Submit</button>
</form>
</div>
</body>
</html>

Angular-meteor use of ng-model inside ng-repeat

I am trying to use the repeated variable from an ng-repeat in as part of the ng-model, which is passed to the controller to be inserted into MongoDB.
In the html below, I have used
<input... ng-model="tablesList.person.lastName />
where I really want an input for each column field
<input... ng-model="tablesList.person.{{column.field}} />
however, this produces an error. Neither does
<input... ng-model="tablesList.person.column.field />
which takes column.field as a string.
Any ideas how to get this to work? I have tried to use getter/setter function, but am not sure how to do this properly, or if this is necessary.
HMTL:
<form name="newTableRowForm" novalidate ng-cloak>
<td ng-repeat="column in tablesList.ammiTables">
<md-input-container flex class="md-block">
<input type="text" ng-model="tablesList.person.lastName" />
</md-input-container>
</td>
<td>
<md-button ng-click="tablesList.submit()" class="md-primary" ng-disabled="newTableRowForm.$invalid" aria-label="send">
Submit <md-icon md-svg-icon="content:ic_send_24px"></md-icon>
</md-button>
</td>
</tr>
</form>
Submit part of controller:
submit() {
this.person.owner = Meteor.user()._id;
Persons.insert(this.person);
if(this.done) {
this.done();
}
this.reset();
}
ng-model should be an object.
$scope.lines = [
{
text: 'res1'
},
{
text: 'res2'
}
];
without ng-repeat:
<input type="text" ng-model="lines[0].text">
with ng-repeat:
<div ng-repeat="line in lines">
<input type="text" ng-model="line.text[$index]">
</div>
check this answer: https://stackoverflow.com/a/14411131/3967587
and this fiddle: https://jsfiddle.net/win_web/hrok3944/
update
you are still looking for answers to the question, please create a fiddle.

How to choose exact row in table while editing with angular?

I'm creating editable table, and while editing all rows became input fields, how to choose only one row that I'm clicking on?
This is a piece of my table
<table>
<tr ng-repeat="item in data track by $index">
<td>
<span ng-if="!editing">{{item.username}}</span>
<span ng-if="editing">
<!-- If I use ng-if="editing && index == $index" than all other fields disappear -->
<input type="text" name="name" class="form-control" ng-model="item.username">
</span>
</td>
<td>
<div ng-if="!editing">
<button ng-click="edit()" >Edit</button>
</div>
</td>
</tr>
<table>
Controller:
.controller('formCtrl', function($scope) {
$scope.editing = false;
$scope.index = "";
$scope.edit = function(index) {
$scope.editing = true;
$scope.index = index;
};
You have to check that the index of the current item is not the item in edition while in editing mode:
<span ng-if="!editing || index!=$index">{{item.username}}</span>
<span ng-if="editing && index==$index">
<input type="text" name="name" class="form-control" ng-model="item.username">
</span>
See working JsFiddle: http://jsfiddle.net/805rt1wd/1/
pass index on click
try like this
<button ng-click="edit($index)" >Edit</button>
Or the object itself
<button ng-click="edit(item)" >Edit</button>
JSFIDDLE

Issue with ng-model and ng-repeat, input value is duplicated on each form field on the page

I have a page where multiple forms are created based on ng-repeat. everything works fine until write something into the input and everything gets duplicated on all the other repeated forms input elements. I have used ng-model="Notify.message" which is nothing but object which takes the value from the input and sends to control on button submit and hence rest of the logic.
I am looking for when if one form is been filled, other forms should keep quite and shouldnt duplicate the values written in input text of form 1.
Here is the code:
<div data-ng-show="alluserposts.length > 0">
<div id="b{{userpost.id}}" data-ng-repeat="userpost in alluserposts" >
<div class="row" style="margin-left: -5px">
<form class="text-center" role="form" id=f1{{userpost.id}} name="userForm"
ng-submit="notify(userForm.$valid, userpost, apiMe)" novalidate>
<div class="row">
<div class="col-xs-8 col-md-4">
<div class="form-group">
<input data-container="body" data-toggle="popover" data-placement="top"
data-content="Any message which you would like to convey to post owner"
type="text" ng-model="Notify.message" data-ng-init="Notify.message=''"
id="u{{userpost.id}}"
placeholder="Enter a Message or Phone number" class="form-control"
required>
<p ng-show="userForm.name.$invalid && !userForm.name.$pristine" class="help-block">It is
required.</p>
<script>$(function () {
$("[data-toggle='popover']").popover();
});
</script>
<input type="hidden" ng-model="Notify.loggedInEmail"
ng-init="Notify.loggedInEmail = result.email"/>
<input type="hidden" ng-model="Notify.postId" ng-init="Notify.postId = userpost.id"/>
<input type="hidden" ng-model="Notify.destEmail"
ng-init="Notify.destEmail = userpost.userEmail"/>
</div>
</div>
<div ng-show="loginStatus.status == 'connected'" class="col-xs-4 col-md-2">
<button class="btn btn-primary" ng-disabled="userForm.$invalid || !userForm.$dirty"
type="submit">
Notify Post Owner
</button>
</div>
</div>
</form>
</p>
</div>
</div>
</div>
</div>
I will attempt following solution to implement it.
create a nested json object with number of forms to display in angularjs controller.
for example
$scope.FormsCollection = {
"Form1" : [
{"title" : "Rockband", "details" : "1hr"},
],
"Form2" : [
{"title" : "The Old You", "details" : "Dr. Smith"}
]
}
obviously, you can use loop to build it or whatever approach suits you best in your context to build the forms collection in angularjs controller.
then in html page you can use following convention to correctly populate each form data
you need two ng-repeat, first for index of each form, and then to iterate nested form object.
<input type="text" ng-model="form[index].firstName"/>
as result you will have $scope.FormsCollection with correct form object data
Please check the example code in following jsfiddle
http://jsfiddle.net/CMnxW/4/
jsfiddle should contain following code.
<div ng-app>
<div ng-controller="controller">
<ul ng-repeat="post in posts">
<li>{{$index}}
<input type="text" ng-model="post.userEmail" />
<button class="btn btn-danger" ng-click="notify(post)" type="button">Notify</button>
</li>
</ul>
<table>
<tr>
<td>destEmail is: </td>
<td>{{Notify.destEmail}}</td>
</tr>
</table>
</div>
</div>
JS:
function controller($scope) {
$scope.Notify = {
destEmail: ''
};
$scope.posts = [{userEmail: 'e#mail.com'}, {userEmail: 'f#mail.com'}];
$scope.notify = function(post) {
$scope.Notify.destEmail = post.userEmail;
//set other $scope.Notify properties from post
//your other notify code...
}
}

Resources