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

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.

Related

Values not updating for dynamically added field in angular js

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" />

How to dynamically validation under ng-repeat in angularjs

Hello I am beginner of Angularjs and I want to build dynamic validations.Here is my code shortened as well as possible.
JS
$scope.inputValidates = [
{ 'name':'name',
'validate':'required',
},
{ 'name':'email',
'validate':'type = email',
}]
HTML
<div ng-repeat="vitem in vm.inputValidates">
<input name={{vitem.name}} ng-model="vm.useraccount[vitem.name]" {{item.validate}}>
</div>
I want this input result as
<input name=name ng-model="vm.useraccount[vitem.name] required>
<input name=name ng-model="vm.useraccount[vitem.name] type = email>
Thanks for taking time for this.
Use ng-required:
<div ng-repeat="vitem in vm.inputValidates">
<input name={{vitem.name}} ng-model="vm.useraccount[vitem.name]" ng-required="item.validate">
</div>
By the way, I see you assigned inputValidates to your $scope. So you should be accessing it in your view by inputValidates, not vm.inputValidates.
Sample is HERE
Sample contains both required and pattern validation applied on textbox rendered using ng-repeat and use ng-switch based on your validation type
<div ng-repeat="field in fields">
<div style="width:600px">
<div ng-form name="validMe" style="width:58%;float:left" ng-switch="field.validationType">
{{field.name}} :
<div ng-switch-when="required">
<input id="input{{$index}}" name="input{{$index}}" type="text" ng-model="field.value" required>
<span style="color: #a94442" ng-show="validMe['input\{\{$index\}\}'].$error.required ">Field Required!</span>
</div>
<div ng-switch-when="email">
<input type="email" id="input{{$index}}" name="input{{$index}}" ng-model="field.value" ng-pattern="/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/">
<span style="color: #a94442" ng-show="validMe['input\{\{$index\}\}'].$error.pattern">Not a valid email!</span>
</div>
</div>
</div>
</div>

How to use one model in ng-repeat using AngularJs?

This is my Fiddle.
http://jsfiddle.net/0c5p38dt/1/
In the above fiddle use ng-model in textfield and add save button
<input type="text" ng-model="eachItem.value"/>
<input type="button" value="save" ng-click="save()"/>
and i write code in js file :-
$scope.save=function(){
console.log($scope.data);
};
In the above code first i click add button when i enter data in first textfield(name) that will also effect on second textfield(name). I want to save the data . So how to differentiate these textboxes.
you should use a 'name' attribute in your input fields with angular
$index
on ng-repeat.
in your Fiddle:
<div ng-app>
<div ng-controller="Ctrl">
<div ng-repeat="eachItem in data">
<input type="button" value="add" ng-click="addFields(eachItem)"/>
<label>{{eachItem.label}}</label>
<input type="text" name="eachItem.label[$index]" />
</div>
</div>
</div>
The result would be like:
<input type="text" name="email[1]">
<input type="text" name="email[2]">
<input type="text" name="email[3]">
<input type="text" name="name[1]">
<input type="text" name="name[2]">
I'm not completely sure what you want, but I don't think you want the <input> in an ng-repeat, maybe what you want is in your .html:
<div ng-app>
<div ng-controller="Ctrl">
<label>Name</label>
<input type="text"ng-model="item.name"/>
<label>Email</label>
<input type="text"ng-model="item.email"/>
<input type="button" value="add" ng-click="addFields(item)"/>
<div ng-repeat="item in data">
<div ng-bind="item.name"></div>
<div ng-bind="item.email"></div>
</div>
</div>
</div>
and in your .js:
function Ctrl($scope) {
$scope.data=[];
$scope.addFields = function (item) {
$scope.data.push(item);
};
}
This will give you the inputs once and then keep track (and display) the data from the inputs

How to populate data in a twitter-bootstrap modal using angularjs

Using:
-Twitter-Bootstrap
-AngularJs
Here's the story
Created table: rows are dynamically created using "ng-repeat". The data item inside the first cell (in a row) has an on-click event triggering a Twitter-Bootstrap modal to appear. The input fields in the modal match the columns in the [table] row. The user edits the necessary data in that row. This should update database and changes reflect immediately in the table.
However, I cannot get the data from the table to populate inside the modal fields.
Here's the weird thing... If I use a Twitter-Bootstrap (TBS) popup instead of a TBS modal, everything works. EVERYTHING. All the data populates inside the popup fields, it's editable, it actually saves to the database, AND updates the table row! But popups suck and I am restricted from using them.
Using the EXACT SAME code, why won't the data populate inside a modal?
Obviously, this leads me to believe using syntactically identical code, a popup and modal do not function the same way. But why?
The research I've done, and documentation I've perused on here as well as both TBS and AngularJS, has been either too overwhelming or altogether unhelpful.
In Summary, this is the functionality I'm looking to achieve:
User clicks the data inside the first cell of a table row
(on-click) Modal appears populated with the data in the row (particularly this).
User can edit the fields
Save/Update. The trigger event can be "enter" or button "on-click" I don't care, I just want it to work.
Here's the gist of the code (with the popup which works, and the modal which doesn't).
Disclaimer: I couldn't get it to work in here (SO or jfiddle) I'm probably missing a reference. But I know you all are smarter than me, and with what I've given, I have the utmost confidence in this community to be able to figure out what it is I'm doing wrong.
I thank you all in advance for your help.
<!DOCTYPE html>
<html ng-app="person">
<head>
<title>HELP ME WITH MODALS</title>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div ng-controller="PersonCtrl">
<table style="border:1px solid black; padding:3px;">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Favorit Color</th>
<th>Favorit Food</th>
<th>Favorite Season</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="person in persons" ng-click="updatePerson(person)">
<td data-toggle="modal" data-target="#editModal">{{person.firstName}}</td>
<td>{{person.lastName}}</td>
<td>{{person.favoriteColor}}</td>
<td>{{person.favoriteFood}}</td>
<td>{{person.favoriteSeason}}</td>
<td>
<button popover-template="dynamicPopover.templateUrl" popover-placement="left" popover-title="Edit" ng-click="current.person=person">Edit</button>
</td>
</tr>
</tbody>
</table>
<!-- Modal -->
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="editModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true" style="color:#513011;">×</span>
</button>
<h4 class="modal-title" id="editModalLabel">Edit Person</h4>
</div>
<!--/HEADER-->
<div class="modal-body">
<form ng-submit="update(current.person)">
<div class="form-group">
<label for="firstname">First Name:</label>
<input name="firstname" type="text" ng-model=current.person.firstName class="form-control" required>
</div>
<div class="form-group">
<label for="lastname">Last Name:</label>
<input name="lastname" type="text" ng-model=current.person.lastName class="form-control" required>
</div>
<div class="form-group">
<label for="favoritecolor">Favorite Color:</label>
<input name="favoritecolor" type="text" ng-model=current.perosn.favoriteColor class="form-control">
</div>
<div class="form-group">
<label for="favoritefood">Favorite Food:</label>
<input name="favoritefood" type="text" ng-model=current.perosn.favoriteFood class="form-control">
</div>
<div class="form-group">
<label for="favoriteseason">Favorite Season:</label>
<input name="favoriteseason" type="text" ng-model=current.perosn.favoriteSeason class="form-control">
</div>
</form>
</div>
<!--/MODAL-BODY-->
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<input type="submit" ng-click="update(current.person)" class="btn btn-primary" value="Save" />
</div>
<!--/MODAL-FOOTER-->
</div>
<!--/MODAL-CONTENT-->
</div>
<!--/MODAL-DIALOG-->
</div>
<!--/MODAL-->
</div>
<!--/CONTROLLER-->
</body>
</html>
<!-- script for edit popover-->
<script type="text/ng-template" id="popoverTemplate.html">
<div>
<form ng-submit="update(current.person)">
<div class="form-group">
<label for="firstname">First Name:</label>
<input name="firstname" type="text" ng-model=current.person.firstName class="form-control">
</div>
<div class="form-group">
<label for="lastname">LastName:</label>
<input name="lastname" type="text" ng-model=current.person.lastName class="form-control">
</div>
<div class="form-group">
<label for="favoritecolor">Favorite Color:</label>
<input name="favoritecolor" type="text" ng-model=current.person.favoritecolor class="form-control">
</div>
<div class="form-group">
<label for="favoritefood">Favorite Food:</label>
<input name="favoritefood" type="text" ng-model=current.person.favoritecolor class="form-control">
</div>
<div class="form-group">
<label for="favoriteseason">Favorite Season:</label>
<input name="favoriteseason" type="text" ng-model=current.person.favoritecolor class="form-control">
</div>
<input type="submit" class="btn btn-default" value="Submit">
<input type="button" class="btn btn-default pull-right" ng-click="delete(current.schoolTerm)" value="Delete">
</form>
</div>
</script>
<script>
var person = angular.module('person', []);
personApp.controller('PersonCtrl', [
function ($scope) {
var person = [
{
'firstName': 'Christine',
'lastName': 'Smith',
'favoriteColor': 'Pink',
'favoriteFood': 'Sushi',
'favoriteSeason': 'Summer'
},
{
'firstName': 'Dana',
'lastName': 'Carvey',
'favoriteColor': 'Yellow',
'favoriteFood': 'Tomatoes',
'favoriteSeason': 'Summer'
},
{
'firstName': 'Terry',
'lastName': 'Gross',
'favoriteColor': 'Chartreuse',
'favoriteFood': 'Lasagna',
'favoriteSeason': 'Spring'
}
];
}]);
</script>
If you want to use the modal in the twitter bootstrap and pass data back and forth, you have to extend/wrap it around with your own directives, and I don't recommend doing that since there are already directives that do just that.
If you are new to Angular, and Have to use bootstrap consider using Angular Ui Bootstrap , which is a set of custom directives written using the twitter bootstrap.
If you are not supporting IE8 and haven't committed to twitter bootstrap, I strongly encourage you checkout lumx.
Note: These two are both still in beta, so use with caution.
Okay, now lets get back to your question. If you decide to stay with twitter bootstrap and once you have the angular ui bootstrap installed - it's easy, just follow this steps https://github.com/angular-ui/bootstrap#installation - , the only thing that probably will be a little confusing at first would be how to pass your scope properties from the caller controller up to the modal.
In a nutshell you have to do something like this in the caller controller:
var modalInstance = $modal.open({
templateUrl: 'yourModalTemplate.html',
controller: 'yourModalController',
resolve: {
itemsFromCallerController: function () {
return [{ i: 1, i: 2 }];
}
}
and your modal's controller should look something like this:
angular.module("app").controller('yourModalInstanceController', function ($scope, $modalInstance, itemsFromCallerController, action) {
$scope.modalHeader = "your modal header";
$scope.items = itemsFromCallerController;
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
Take a look at this Plunker

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