I'm building a client collection with the following information:
"name" : "Test client",
"email" : "test#test.com",
"position" : "Project Manger",
"contacts" : [
{
"name" : "asdf",
"email" : "asdf#adf",
"tel" : "7877877878",
"title" : "asdf"
},
{
"name" : "fdas",
"email" : "fdas#fdas",
"tel" : "7877877878",
"title" : "fdsa"
}
],
I want to be able to edit/update the contacts of the client but I'm not sure how to do so with angular since I have the form inside an ng-repeat repeating the contacts of a client.
<div ng-repeat="contact in contacts track by $index">
<label>Name</label>
<input type="tel" ng-model="contact.name">
<label>Telephone</label>
<input type="tel" ng-model="contact.tel">
<label>Email</label>
<input type="email" ng-model="contact.email">
<label>Title</label>
<input type="text" ng-model="contact.title">
<md-button ng-click="save(contact)">Save</md-button>
</div>
and my controller:
'use strict'
angular.module('myApp')
.controller('ContactsCtrl', function($scope, $mdDialog, $mdMedia, client) {
$scope.client = client;
$scope.contacts = client.contacts;
$scope.save = (contact) => {
Clients.update({_id: client._id},{
$set: {
contacts : contact
}
},function(err, data){
if(err) return console.log(err);
console.log(data + " " );
$mdDialog.hide(data);
});
}
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.hide = function() {
$mdDialog.hide();
};
});
But when I press save it replaces the array with a single object.
QUESTION
How can I update the existing objects in an array that are inside a document with a form that is inside an ng-repeat?
change html to :
<div ng-repeat="contact in contacts track by $index">
<label>Name</label>
<input type="tel" ng-model="contact.name">
<label>Telephone</label>
<input type="tel" ng-model="contact.tel">
<label>Email</label>
<input type="email" ng-model="contact.email">
<label>Title</label>
<input type="text" ng-model="contact.title">
<md-button ng-click="save($index,contact)">Save</md-button>
</div>
and save() function to
$scope.save = (index,contact) => {
Clients.update({_id: client._id},{
$set: {
contacts[index] : contact
}
},function(err, data){
if(err) return console.log(err);
console.log(data + " " );
$mdDialog.hide(data);
});
}
hope it does the trick.
Was able to do a work around but I'm not sure if this is the best option.
Just add $index when doing the save function:
<md-button ng-click="save($index, contact)">Save</md-button>
and in the controller the save function:
$scope.save = (index, contact) => {
$scope.client.contacts[index] = contact;
Clients.update({_id: client._id},{
$set: {
contacts : $scope.client.contacts
}
},function(err, data){
if(err) return console.log(err);
console.log(data + " " );
$mdDialog.hide(data);
});
}
Related
I have code to pass date and time to controller.
Here is HTML code,
<div class="page-content" ng-app="app">
<div ng-controller="postAppoinmentCtr as ctrl" class="panel-body">
<form ng-submit="submitForm()" id="form1">
<input name="time" ng-model="time" type="text" class="form-control" ng-model="time" data-plugin="timepicker" autocomplete="off"/>
<input name="date" ng-model="date" type="text" class="form-control" data-plugin="datepicker"/>
<input..ng-model="type"...></input>
<input..ng-model="Description"...></input>
<button ...>
</form>
</div>
</div>
Here is angular js part
var app = angular.module('app', []);
app.controller('postAppoinmentCtr', function($scope, $http, $location) {
$scope.submitForm = function(){
var url = $location.absUrl() + "/addAppoinment";
alert(url);
var config = {
headers : {
'Content-Type': 'application/json;charset=utf-8;'
}
}
var data = {
type: $scope.type,
date: $scope.date,
time: $scope.time,
description: $scope.description
};
$http.post(url, data, config).then(function (response) {
$scope.postResultMessage = "Sucessful!";
}, function (response) {
$scope.postResultMessage = "Fail!";
});
$scope.type = "";
$scope.date = "";
$scope.time ="";
$scope.description ="";
}
});
When click the button type and description pass to controller. But date and time not. I can do this using
<input id="date-birth" class="form-control" type="date" ng-model="date">
this line. But I need to use data-plugin="datepicker" .
I'm new one for the angularjs and I try to many ways for solve this problem.
Please give me some answer this. Thanks in advance.
am trying to add the value of input field to json object using angularjs i wrote some codes but it doesn't work, please i need help
script section
<script>
var app = angular.module("exampleApp", []);
app.controller("defaultCtrl", function ($scope, $http) {
$scope.loadData = function () {
$http.get("productData.json").then(function (response) {
console.log("Status: " + response.status);
console.log("Type: " + response.headers("content-type"));
console.log("Length: " + response.headers("content-length"));
$scope.products = response.data;
});
$scope.products = {name:'',age:'',isDead:''};
$scope.resurrect = function(item){
item.isDead = false;
};
$scope.addnew = function(){
$scope.products.mname = $scope.products.name;
$scope.products.mage = $scope.products.age;
$scope.products.misDead = $scope.products.isDead;
};
}
});
</script>
productData.json
[
{ "name": "Tommen Baratheon", "age": "23", "isDead": true },
{ "name": "Roose Bolton", "age": "32", "isDead": false },
{ "name": "Theon Greyjoy", "age": "27", "isDead": true},
{ "name": "Cersei Lannister", "age": "31", "isDead": false}
]
form section
<form>
<input type="text" placeholder="Enter Charater name" class="form- control" ng-model="products.mname">
<input type="number" placeholder="Enter Charater age" class="form-control" ng-model="products.mage">
<input type="text" placeholder="Enter True or false" class="form-control" ng-model="products.misDead">
<input type="submit" value="andNew" ng-submit="addnew()"></form>
So the first problem is that $scope.products is an array. Your markup is bound as if it's a single object though.
<form>
<div ng-repeat="p in products">
<input type="text" placeholder="Enter Charater name" class="form-control" ng-model="p.name">
<input type="number" placeholder="Enter Charater age" class="form-control" ng-model="p.age">
<input type="text" placeholder="Enter True or false" class="form-control" ng-model="p.isDead">
<input type="submit" value="andNew" ng-submit="addnew()">
</div>
</form>
The other problem was that you had bindings like products.mname, but the field is actually name. The next problem you have is you're initializing products as an object when you really should just initialize it as an empty array:
$scope.products = [];
The next problem you'll have is addnew. It needs to just push a new object on to the array:
$scope.addnew = function() {
$scope.products.push({});
};
That will cause a new div to be rendered inside the form.
here save the ng-model is newattendance saving to database. "newattendance._id" is not taken as a ng-model.how to make it "newattendance._id" is ng-model
<select class="form-control" ng-options="item.empcode as item.empcode for item in totemplist" ng-model="item.empcode">
</select>
<input type="text" ng-repeat="newattendance in totemplist" ng-model="newattendance._id" ng-show="item.empcode ==newattendance.empcode" style="width:200px;" ><br>
<input placeholder="Enter Attendacne Date" ng-model="newattendance.doa">
<button class="btn btn-primary" ng-click="checkOut()">checkOut</button>
Controller
EmpMasterController.controller("AttendanceController", ['$scope', 'AttendanceFactory',"EmpAddService", function($scope, AttendanceFactory,EmpAddService){
$scope.newattendance={};
$scope.totemplist=EmpAddService.getAllEmpAddItems();
console.log($scope.totemplist);
$scope.checkIn = function(){
AttendanceFactory.addAttendance($scope.newattendance);
$scope.newattendance = {}
}
$scope.getAllAttendance = function(){
console.log("$$$$$"+$scope.newattendance._id)
$scope.attendancedetails =AttendanceFactory.getAllAttendance($scope.newattendance._id);
}
}])
Factory
EmpFactModule.factory("AttendanceFactory", function($resource, RES_URL){
var attendanceResource = $resource(RES_URL+"attandence/:id/:attid",
{"id": "#id", "attid": "#attid"}, {update: {method: "PUT"}})
var attendanceDetails;
return {
addAttendance: function(newattendance){
console.log("..1.. " + newattendance._id)
attendanceResource.save({"id":newattendance._id}, newattendance, function(data){
console.log("Add Success ")
}, function(data, status){
console.log("Add Failed*****");
})
},
getAllAttendance: function(_id){
console.log("..#.. " + _id)
attendanceDetails = attendanceResource.query({"id": _id});
return attendanceDetails;
},
}
})
please help me how make it as ng-model and how to save this...
I've create a JSFiddle for you which hopefully will help you understand the 2 way binding in angular.
you dont need to pass the newattendance object to the check-out function, it is already saved on the scope.
HTML:
<div ng-app="app">
<div ng-controller="formValidation">
<div>
<div>
<span>User Name</span>
<input type="text" placeholder="John" ng-model="newattendance._id">
<span>
<button ng-click="submit()">
check out
</button>
</span>
</div>
</div>
<pre>{{newattendance._id}}</pre>
</div>
</div>
JS:
var app = angular.module('app', []);
app.controller('formValidation', function($scope) {
$scope.submit=function(){
var formPost = {
"Username":$scope.newattendance._id
};
console.log(formPost);
}
});
i know its very common and very easy thing but really i m very new to angularjs and need your help
My View Page:
<div ng-controller="AddressController">
<div class="form-part-title" ng-show="Caption">{{Caption}} <span ng-show="showSameAsBilling" class="spancheck"><input type="checkbox" id="SameAsBilling" ng-model="Address.SameAsBilling"><label class=" after">Same As Billing Address</label></span> </div>
<div ng-show="!readOnly">
<label class="required">#Resource.Country<span ng-show="showInvalidAddress" class="spancheck"><input type="checkbox" id="InvalidAddress" ng-model="Address.InvalidAddress"><label class="after">Invalid Address</label></span>
<span ng-show="showPostalOnly" class="spancheck"><input type="checkbox" id="PostalOnly" ng-model="Address.PostalOnly"><label class="after">Postal Only</label></span>
</label>
<select kendo-drop-down-list class="sdk-dropdown" ng-model="Address.CountryId" k-options="countries" k-on-change="onChange(kendoEvent)" />
<label>#Resource.Address</label>
<input class="block" type="text" name="Address" ng-model="Address.Address1" maxlength="100" />
<input class="block" type="text" ng-model="Address.Address2" maxlength="100" />
<input class="block" type="text" ng-model="Address.Address3" maxlength="100" />
<label id="lblState">{{StateLabel}}</label>
<select kendo-drop-down-list class="sdk-dropdown" ng-model="Address.StateProvinceId" k-options="states" k-rebind="states" />
<label>#Resource.City</label>
<input class="block" type="text" name="City" ng-model="Address.City" maxlength="50" />
<label>{{ZipCodeLabel}}</label>
<input class="block" type="text" name="ZipCode" ng-model="Address.ZipCode" maxlength="50" />
</div>
<div ng-show="readOnly">
<textarea style="min-height:120px!important" disabled>{{Address.Address}}{{Address.Address1}}
{{Address.Address2}}
{{Address.City}}
{{Address.State}}{{Address.CountryName}}
{{Address.ZipCode}}</textarea>
</div>
</div>
My Angular Controller:
var AddressController = function ($scope, $http, $routeParams, $location) {
$scope.StateLabel = "State";
$scope.ZipCodeLabel = "Zip Code";
$scope.countryDataSource = {
transport: {
read: {
dataType: "json",
url: "/ApplicationData/GetCountries",
}
}
};
$scope.countries = {
dataSource: $scope.countryDataSource,
dataTextField: "Name",
dataValueField: "Id",
optionLabel: "Select..."
};
this.showAlert = function () {
alert("this is test method");
};
$scope.onChange = function (e) {
var countryId = e.sender.value();
if (countryId == 2) {
$scope.StateLabel = "Province";
$scope.ZipCodeLabel = "Postal Code";
}
else {
$scope.StateLabel = "State";
$scope.ZipCodeLabel = "Zip Code";
}
$http.get('/ApplicationData/GetStates/' + countryId).
success(function (jsonData, status, headers, config) {
console.log(jsonData);
var data = {
dataSource: jsonData,
dataTextField: "Name",
dataValueField: "Id",
optionLabel: "Select..."
};
$scope.states = data;
}).
error(function (data, status, headers, config) {
console.log("error getting countries");
});
};
$scope.SameAsBilling = function (checked) {
alert(1);
if (SameAsBilling.checked = true) {
vmCustomer.BillingAddress = vmCustomer.ShippingAddress
}
};
};
AddressController.$inject = ['$scope', '$http', '$routeParams', '$location'];
i need you guys to help me with the below function
$scope.SameAsBilling = function (checked) {
alert(1);
if (SameAsBilling.checked = true) {
vmCustomer.BillingAddress = vmCustomer.ShippingAddress
}
};
i m tying but don't know why the check box is not talking to controller please help
I have a problem with the controller triggering the method defined on the $scope twice when the page first loads and when the form submits.
Here's the fiddle : http://jsfiddle.net/scabro/pQb6q/5/
<div data-ng-app="app" data-ng-controller="AppCtrl">
<form method="post" data-ng-submit="submitForm()">
<span data-ng-show="showWarning('email')">Please provide valid email address</span>
<input type="email" name="email" placeholder="Email address" data-ng-model="fields.email.value" />
<span data-ng-show="showWarning('telephone')">Please provide your telephone number</span>
<input type="text" name="telephone" placeholder="Telephone" data-ng-model="fields.telephone.value" />
<span data-ng-show="showWarning('name')">Please provide your name</span>
<input type="text" name="name" placeholder="Name" data-ng-model="fields.name.value" />
<button type="submit">Submit</button>
</form>
</div>
And here are two AngularJs modules - first with with controller and the other with 'isValid' factory service
angular.module('app', ['validation'])
.controller('AppCtrl', function($scope, $log, isValid) {
$scope.fields = {
email : {
type : 'email',
value : '',
required : true
},
telephone : {
type : 'number',
value : '',
required : true
},
name : {
type : 'string',
value : '',
required : true
}
};
$scope.warnings = [];
$scope.showWarning = function(field) {
$log.info($scope.warnings);
return ($scope.warnings.indexOf(field) !== -1);
};
$scope.submitForm = function() {
$scope.warnings = [];
isValid.run($scope.fields);
if (isValid.errors.length > 0) {
$scope.warnings = isValid.errors;
}
};
});
angular.module('validation', [])
.factory('isValid', function() {
return {
errors : [],
isEmail : function(emailValue) {
return (
emailValue.indexOf("#") != -1
);
},
isNumber : function(numberValue) {
return (
!isNaN(parseFloat(numberValue)) &&
isFinite(numberValue)
);
},
isEmpty : function(emptyValue) {
return (
emptyValue === '' ||
emptyValue === 'undefined'
);
},
validateEmail : function(fieldObject, fieldName) {
if (!this.isEmail(fieldObject.value)) {
this.errors.push(fieldName);
}
},
validateNumber : function(fieldObject, fieldName) {
if (!this.isNumber(fieldObject.value)) {
this.errors.push(fieldName);
}
},
validateEmpty : function(fieldObject, fieldName) {
if (this.isEmpty(fieldObject.value)) {
this.errors.push(fieldName);
}
},
type : function(fieldObject, fieldName) {
switch(fieldObject.type) {
case 'email':
if (fieldObject.required || !this.isEmpty(fieldObject.value)) {
this.validateEmail(fieldObject, fieldName);
}
break;
case 'number':
if (fieldObject.required || !this.isEmpty(fieldObject.value)) {
this.validateNumber(fieldObject, fieldName);
}
break;
default:
if (fieldObject.required) {
this.validateEmpty(fieldObject, fieldName);
}
break;
}
},
resetErrors : function() {
this.errors = [];
},
run : function(fields) {
this.resetErrors();
for (var fieldName in fields) {
if (fields.hasOwnProperty(fieldName)) {
this.type(fields[fieldName], fieldName);
}
}
}
};
});
Also - for some reason the validation only work for the first 2 fields and doesn't seem to validate an empty field.
Here's what I'm getting in the console when page first loads (empty arrays) and when the form is first submitted:
it also seem to be calling the showWarning() method with each 'keydown' event when typing inside of any of the fields.
Any idea what might be causing it?
validateEmpty has a spurious ! before this.isEmpty(....
As for why they're getting called twice, I'd guess a digest cycle is running when you submit, and Angular is checking its watches to decide whether to keep showing those spans, but I'm not entirely sure why it's doing that in this case.
You are not using the angular standard validation.
here is an example with a very crud telephone custom validation
<div data-ng-app="app" data-ng-controller="AppCtrl">
<form method="post" name="form" data-ng-submit="submitForm()">
<input required="" type="email" name="email" placeholder="Email address" data-ng-model="fields.email.value" />
<div data-ng-show="form.email.$dirty && form.email.$invalid">Please provide valid email address</div>
<br />
<input required="" valid-telephone type="text" name="telephone" placeholder="Telephone" data-ng-model="fields.telephone.value" />
<div data-ng-show="form.telephone.$dirty && form.telephone.$invalid">Please provide your telephone number</div>
<br />
<input required="" type="text" name="name" placeholder="Name" data-ng-model="fields.name.value" />
<div data-ng-show="form.name.$dirty && form.name.$invalid">Please provide your name</div>
<br />
<button type="submit">Submit</button>
</form>
</div>
angular.module('app', [])
.controller('AppCtrl', function($scope, $log) {
$scope.fields = {
email : {
value : ''
},
telephone : {
value : ''
},
name : {
value : ''
}
};
$scope.submitForm = function() {
};
})
.directive('validTelephone', [function() {
return {
require: 'ngModel',
link: function(scope, ele, attrs, c) {
scope.$watch(attrs.ngModel, function() {
c.$setValidity('unique', /^\d{10}$/.test(c.$viewValue));
});
}
};
}]);
input.ng-invalid {
border: 1px solid red;
}
input.ng-valid {
border: 1px solid green;
}
Here is the code
http://plnkr.co/edit/Y9DzmBNlu9wNiJ1Odljc?p=preview
here is some documentation
http://scotch.io/tutorials/javascript/angularjs-form-validation