AngularJS - ng-disabled directive acting weird - angularjs

I'm using few modals in my angular project, in every modal which is a form I'm using button with ng-disabled directive and each modal has its own controller.
The issue is that when I debugging the code I can see that when I'm opening one modal the debugger run on all the ng-disabled directives in the code although it should run only on the ng-disabled function in the current modal that I use.
On each ng-disabled I run some verification function in its own controller,
like ng-disabled='somefunction()'
and somefunction() in the controller is somefunction() = x || y;
Do I miss something ?
controller:
app.controller('NewHolidayModalController', function ($scope, close, HolidaysService) {
var centerList = $scope.$parent.$$childHead.centers;
var currCenterDN = $scope.$parent.$$childHead.currentCenter.DN;
var indexOfCurrentCenter = _.indexOf(_.pluck(centerList, 'DN'), currCenterDN);
centerList[indexOfCurrentCenter].ticked = true;
var selectedDNs;
$scope.dt = k = new Date();
$scope.close = function (result) {
centerList[indexOfCurrentCenter].ticked = false;
close(result, 500);
};
$scope.conditionsForSendNewHoliday = function () {
selectedDNs = _.select(centerList, { ticked: true });
return (($scope.starttime >= $scope.endtime) || ($scope.dt < k) || (angular.isDate($scope.dt) == false) || (angular.isDate($scope.starttime) == false) || (angular.isDate($scope.endtime) == false) || ($scope.HolidayName.length == 0) || (selectedDNs.length == 0));
};
$scope.addHoliday = function () {
holiday = HolidaysService.formatDateAndTime($scope);
for (i = 0; i < selectedDNs.length; i++)
{
newHoliday = { DN: selectedDNs[i].DN, HolidayName: $scope.HolidayName, HolidayDate: holiday.Date, BeginHour: holiday.start, EndHour: holiday.end }
HolidaysService.addHoliday(newHoliday)
.success(function (data, status, headers, config) {
if ((_.select($scope.$parent.$$childHead.holidays, { BeginHour: data.BeginHour }).length == 0) && (_.select($scope.$parent.$$childHead.holidays, { EndHour: data.EndHour }).length == 0) && (_.select($scope.$parent.$$childHead.holidays, { HolidayDate: data.HolidayDate }).length == 0) && (_.select($scope.$parent.$$childHead.holidays, { EndHour: data.EndHour }).length == 0) && (_.select($scope.$parent.$$childHead.holidays, { HolidayName: data.HolidayName }).length == 0))
$scope.$parent.$$childHead.holidays.push(data);
centerList[indexOfCurrentCenter].ticked = false;
alert("holiday was created");
})
.error(function (data, status, headers, config) {
if (status == 409)
alert("Holiday " + data.HolidayName + " Cannot be created for " + data.DN + " BECAUSE OF OVERLAPPED HOLIDAYS.")
})
}
}
})
HTML:
<div class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" ng-click="close(false)" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<form>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div isteven-multi-select
input-model="$parent.$$childHead.centers"
output-model="outputCenters"
button-label="Name"
item-label="Name (Route)"
tick-property="ticked"
max-labels="5" max-height="150px">
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="form-group">
<div class="input-group date">
<input ng-model="HolidayName" type="text" placeholder="Holiday Name" class="form-control">
<span class="input-group-addon">
<span class="glyphicon glyphicon-pencil"></span>
</span>
</div>
</div>
</div>
</div>
<div ng-controller="DatepickerCtrl">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="$parent.dt" is-open="opened" min-date="minDate" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
</div>
<div class="row">
<div class='col-md-8 col-md-offset-2'>
<timepicker-pop input-time="starttime" class="input-group"
show-meridian='showMeridian'>
</timepicker-pop>
</div>
</div>
<div class="row">
<div class='col-md-8 col-md-offset-2'>
<timepicker-pop input-time="endtime" class="input-group"
show-meridian='showMeridian'>
</timepicker-pop>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" ng-click="close(false)" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" ng-click="addHoliday()" class="btn btn-primary" data-dismiss="modal" ng-disabled="conditionsForSendNewHoliday()">Send</button>
</div>
</div>
</div>
Should I add the other controller and the html?

Related

AngularJS Form - How to create and update several emails with ng-switch

I have a form in order to add / update one or several emails. The first email field is mandatory. After filling the field it's possible to click on "Add email" for adding a new email address. By this way it's possible to add 4 others emails (5 emails in total).
The system can verify if the format of the email is correct and display a message if necessary and register the data in a DB.
Here my view (manageContact.html)
<h3>{{title}}</h3>
<div class="panel panel-default" ng-show="authorRole==1">
<div class="panel-heading">
<div class="panel-title">Person Sheet</div>
</div>
<div class="panel-body">
<form name="ContactForm" class="form-horizontal" role="form" novalidate ng-submit="submitForm(contact)">
<!---------------- FOR UPDATING EMAILS FIELDS ------------ START --->
<div ng-repeat="(key, email) in emails | limitTo : 5" style="z-index:6">
<div class="form-group">
<span ng-switch="$index">
<label ng-switch-when="0" for="txtEmail" class="col-sm-2 control-label">Main email</label>
<label ng-switch-default for="txtEmail" class="col-sm-2 control-label">Email {{$index+1}}</label>
</span>
<div class="col-sm-9" ng-switch="$index">
<input ng-switch-when="0" type="email" class="form-control"
name="txtEmail_{{$index}}" maxlength="100" placeholder="Enter main email"
ng-model="contact.EMAIL">
<input ng-switch-default type="email" class="form-control"
name="txtEmail_{{$index}}" maxlength="100" placeholder="Enter Email {{$index+1}}"
ng-model="contact['EMAIL_'+$index]">
<div class="error-container"
ng-show="ContactForm['txtEmail_' + $index].$dirty && ContactForm['txtEmail_' + $index].$invalid">
<div ng-show="ContactForm['txtEmail_' + $index].$error.email" class="alert alert-info" role="alert" style="margin-top:10px;">
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
<span class="sr-only">Error:</span>
That is not a valid email. Please input a valid email.
</div>
<div ng-show="ContactForm['txtEmail_' + $index].$error.required" class="alert alert-info" role="alert" style="margin-top:10px;">
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
<span class="sr-only">Error:</span>
Your email is required.
</div>
<div ng-show="ContactForm['txtEmail_' + $index].$error.minlength" class="alert alert-info" role="alert" style="margin-top:10px;">
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
<span class="sr-only">Error:</span>
Your email is required to be at least 3 characters
</div>
<div ng-show="ContactForm['txtEmail_' + $index].$error.maxlength" class="alert alert-info" role="alert" style="margin-top:10px;">
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
<span class="sr-only">Error:</span>
Your email cannot be longer than 20 characters
</div>
</div>
</div>
<div class="col-sm-1" ng-show="$index == 0">
<a href="" ng-click="add()" ng-show="emails.length<5" class="inline btn btn-primary icon_email">
<span class="glyphicon glyphicon-plus icon2"></span><span class="addButton">Add email</span>
</a>
</div>
</div>
</div>
<!---------------- FOR UPDATING EMAILS FIELDS ------------ END --->
</form>
</div>
</div>
For adding a contact all is working and the emails are correctly registered.
For updating a contact I have a problem with the contact's emails. In order to see all emails registered of the contact, it's necessary with my current script to click on the button "Add email" each time that an email is registered for seeing data.
I would like to display the emails if they exist in the DB - so display each time the row (field + data). If it doesn't exist it's necessary to click on the button for adding an new email.
Could you please help me to update this code for doing that because I cannot do that directly in ng-switch?
Here my controlers "ctrlEditContacts" and module (app.js):
var app=angular.module('ContactsApp', ['ngRoute', 'ui.bootstrap', 'ngDialog']);
app.factory('HttpInterceptor', ['$q', '$rootScope', function($q, $rootScope) {
return {
......
}
};
app.config(function($routeProvider, $httpProvider, ngDialogProvider){
$httpProvider.defaults.cache = false;
if (!$httpProvider.defaults.headers.get) {
$httpProvider.defaults.headers.get = {};
}
$httpProvider.defaults.headers.get['If-Modified-Since'] = '0';
$routeProvider.when('/add-contacts',
{
templateUrl: 'template/manageContact.html',
controller: 'ctrlAddContacts'
})
.when('/edit-contacts/:contactId',
{
templateUrl: 'template/manageContact.html',
controller: 'ctrlEditContacts'
})
.otherwise({redirectTo:'/all-requests'});
});
app.controller('ctrlAddContacts', function ($scope, ContactService){
$scope.title="Add a contact";
// Allow to create several fields EMAIL
$scope.emails = [
{
}];
$scope.log = function() {
console.log($scope.emails);
};
$scope.add = function() {
var dataObj = {email:''};
$scope.emails.push(dataObj);
}
$scope.submitForm = function(contact){
if($scope.ContactForm.$valid){
// Send the object to the backend for saving data
ContactService.addNewPerson(contact).success(function(Person){
$scope.ContactForm.$setPristine();
$scope.contact= Person;
});
}
}
});
app.controller('ctrlEditContacts', function ($scope, $routeParams, MyTextSearch, ContactService, ngDialog, $timeout){
//FOR ALLOWING SEVERAL EMAILS
$scope.emails = [
{
}];
$scope.log = function() {
console.log($scope.emails);
};
$scope.add = function() {
var dataObj = {email:''};
$scope.emails.push(dataObj);
}
$scope.contact={};
if($routeParams.contactId){
$scope.title="Edit the contact";
}
ContactService.loadPersonById($routeParams.contactId).success(function(contact){
$scope.contact.ID = contact[0].ID;
$scope.contact.EMAIL = contact[0].EMAIL;
$scope.contact.EMAIL_1 = contact[0].EMAIL_1;
$scope.contact.EMAIL_2 = contact[0].EMAIL_2;
$scope.contact.EMAIL_3 = contact[0].EMAIL_3;
$scope.contact.EMAIL_4 = contact[0].EMAIL_4;
})
.error(function (data, status, header, config) {
console.log("Query loadPersonById ERROR");
console.log("status:" + status);
if (status==302) {
alert("Session expired - New Authentication requested");
}
}).finally(function() {
});
$scope.submitForm = function(contact){
if($scope.ContactForm.$valid){
ContactService.updatePerson(contact, $routeParams.contactId).success(function(){
alert('Person updated successfully');
})
.error(function (data, status, header, config) {
})
.finally(function() {
});
}
};
});
Here my factory (appService.js)
app.factory('ContactService', function($http){
var factory={};
factory.addNewPerson=function(objContact){
return $http.get('http://myapp/contacts.cfc?method=addNewPerson&jsStruct=' + JSON.stringify(objContact))
};
factory.updatePerson=function(objContact,id){
var params = {
method: "updatePerson",
contactid: id,
jsStruct: objContact
};
var config = { params: params };
return $http.get('http://myapp/contacts.cfc', config)
};
return factory;
})
If you have a best solution than ng-switch for doing that, please tell me.
Thank you in advance for your help.
Populate $scope.emails inside ContactService.loadPersonById()
I updated the controller:
app.controller('ctrlEditContacts', function ($scope, $routeParams, ContactService, ngDialog, $timeout){
//FOR ALLOWING SEVERAL EMAILS
$scope.emails = [];
$scope.log = function() {
console.log($scope.emails);
};
$scope.add = function() {
var dataObj = {email:''};
$scope.emails.push({});
};
$scope.contact={};
if($routeParams.contactId){
$scope.title="Edit the contact";
$scope.edit_oldContact = "true";
}
ContactService.loadPersonById($routeParams.contactId).success(function(contact){
console.log("Query loadPersonById OK");
$scope.contact.ID = contact[0].ID;
$scope.contact.EMAIL = contact[0].EMAIL;
$scope.contact.EMAIL_1 = contact[0].EMAIL_1;
$scope.contact.EMAIL_2 = contact[0].EMAIL_2;
$scope.contact.EMAIL_3 = contact[0].EMAIL_3;
$scope.contact.EMAIL_4 = contact[0].EMAIL_4;
// GET the emails already registered for displaying in the contact edit form
if($scope.contact.EMAIL.length > 0) {
$scope.emails.push($scope.contact.EMAIL);
}
if($scope.contact.EMAIL_1.length > 0) {
$scope.emails.push($scope.contact.EMAIL_1);
}
if($scope.contact.EMAIL_2.length > 0) {
$scope.emails.push($scope.contact.EMAIL_2);
}
if($scope.contact.EMAIL_3.length > 0) {
$scope.emails.push($scope.contact.EMAIL_3);
}
if($scope.contact.EMAIL_4.length > 0) {
$scope.emails.push($scope.contact.EMAIL_4);
}
})
.error(function (data, status, header, config) {
console.log("Query loadPersonById ERROR");
console.log("status:" + status);
}).finally(function() {
console.log("Query loadPersonById Finalized");
});
$scope.submitForm = function(contact){
//console.log(contact);
};
});
And The template:
<!---------------- FOR UPDATING EMAILS FIELDS ------------ START --->
<div ng-repeat="(key, email) in emails | limitTo : 5" style="z-index:6">
<div class="form-group">
<span ng-switch="$index">
<label ng-switch-when="0" for="txtEmail" class="col-sm-2 control-label">Main email</label>
<label ng-switch-default for="txtEmail" class="col-sm-2 control-label">Email {{$index+1}}</label>
</span>
<div class="col-sm-9" ng-switch="$index">
<input ng-switch-when="0" type="email" class="form-control"
name="txtEmail_{{$index}}" maxlength="100" placeholder="Enter main email"
ng-model="contact.EMAIL">
<input ng-switch-default type="email" class="form-control"
name="txtEmail_{{$index}}" maxlength="100" placeholder="Enter Email {{$index+1}}"
ng-model="contact['EMAIL_'+$index]">
<div ng-show="ContactForm['txtEmail_' + $index].$dirty && ContactForm['txtEmail_' + $index].$error.emailExists" class="alert alert-info" role="alert" style="margin-top:10px;">
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
<span class="sr-only">Error:</span>
This email is already used
<ul id="contacts_list">
<li ng-repeat=" cont in ContactForm['txtEmail_' + $index].persons" style="position:relative; z-index:1">
<div angular-popover direction="right" template-url="template/popover.html" mode="mouseover">
{{ cont.lastname }} {{ cont.firsttname }}
</div>
</li>
</ul>
</div>
<div ng-if="ContactForm['txtEmail_' + $index].$pending.emailExists">checking....</div>
<div class="error-container"
ng-show="ContactForm['txtEmail_' + $index].$dirty && ContactForm['txtEmail_' + $index].$invalid">
<div ng-show="ContactForm['txtEmail_' + $index].$error.email" class="alert alert-info" role="alert" style="margin-top:10px;">
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
<span class="sr-only">Error:</span>
That is not a valid email. Please input a valid email.
</div>
<div ng-show="ContactForm['txtEmail_' + $index].$error.required" class="alert alert-info" role="alert" style="margin-top:10px;">
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
<span class="sr-only">Error:</span>
Your email is required.
</div>
</div>
</div>
<div class="col-sm-1" ng-show="$index == emails.length - 1">
<a href="" ng-click="add()" ng-show="emails.length<5" class="inline btn btn-primary icon_email">
<span class="glyphicon glyphicon-plus icon2"></span><span class="addButton">Add</span>
</a>
</div>
</div>
</div>
<!---------------- FOR UPDATING EMAILS FIELDS ------------ END --->

Angular object not binding

I have the following issue. I have 2 controllers defined for 2 separate functions.
The 1st controller handle my login and the second 1 handles forgot password.
Login controller binds well but forgot password controller does bind but not the object.
Controllers
var singlePageApp = angular.module('SinglePageApp',[]);
singlePageApp.controller('LoginController', function ($scope, $location, $window) {
$scope.isFormValid = false;
$scope.message = null;
$scope.login = null;
// Login object
$scope.Login = {
Email: '',
Password: '',
};
//check form validation
$scope.$watch('LoginForm.$valid', function (newValue) {
$scope.isFormValid = newValue;
});
$scope.submitForm = function () {
console.log('Form is submitted with:', $scope.login);
...
};
});
singlePageApp.controller('ForgotPasswordController', function ($scope, $location, $window) {
$scope.message = null;
$scope.password = null;
// Password object
$scope.Password = {
Email: '',
};
$scope.$watchGroup(['password', 'Password'], function (newValues, oldValues, scope) {
console.log(newValues);
});
$scope.forgotPassword = function () {
};
});
Login HTML
<div ng-controller="LoginController">
<form class="form-signin mt10" name="LoginForm">
<h2 class="form-signin-heading pwc">Please login</h2>
<div class="login-wrap">
<input ng-model="login.Email" id="tbEmail" name="Email" type="email" class="form-control" placeholder="Email" autofocus required>
<span class="error" ng-show="LoginForm.Email.$touched && LoginForm.Email.$error.required">Email is required</span>
<input ng-model="login.Password" id="tbPassword" name="Password" type="password" class="form-control" placeholder="Password" required>
<span class="error" ng-show="LoginForm.Password.$touched && LoginForm.Password.$error.required">Password is required</span>
<label class="checkbox">
<span class="pull-right">
#* Forgot Password?*#
Forgot Password?
</span>
</label>
<div class="clearfix"></div>
<button id="btnloginAdmin" type="button" ng-click="submitForm()" ng-disabled="LoginForm.$invalid && !!LoginForm.$error.email" class="btn btn-success btn-block">Login</button>
<div class="text-center">
<label style="color: red;" id="lblError" class="hasError-label clearfix">{{message}}</label>
<div class="error error-red"></div>
</div>
</div>
</form>
</div>
HTML Modal
<div ng-controller="ForgotPasswordController">
<div aria-hidden="false" aria-labelledby="myModalLabel" role="dialog" tabindex="-1" id="modalForgotPassword" class="modal fade">
<div class="modal-dialog">
<div class="modal-content" ng-form="fgForm">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Forgot Password ?</h4>
</div>
<div class="modal-body">
<p>Enter your e-mail address below to reset your password.</p>
<input type="email" name="Email" ng-model="password.Email"
placeholder="Email" autocomplete="off"
class="form-control placeholder-no-fix" required>
<span class="error" ng-show="fgForm.Email.$touched && fgForm.Email.$error.required">Email is required</span>
<div class="text-center">
<label style="color: red;" id="fError" class="hasError-label clearfix">{{message}}</label>
<div class="error error-red"></div>
</div>
</div>
<div class="modal-footer">
<a href="javascript:;" class="btn btn-success" ng-disabled="fgForm.$invalid && !fgForm.$error.email" ng-click="forgotPassword();">
<i class="fa fa-check"></i> | Submit
</a>
<a href="javascript:;" class="btn btn-danger" data-dismiss="modal">
<i class="fa fa-times"></i> | Cancel
</a>
</div>
</div>
</div>
</div>
I have tried changing to bind to a single object 'password' but it states its undefined. Then I changed it to 'Password.Email' but then it stays empty.
The 2 controllers are bind on the same page so not sure if that is the issue.
Thank you in advance.

Input field is not validating while using angularjs

Input box requires following validations:
1) Length input box should take upto 3 integer length values (decimals not allowed)
2) Height input box should take 3 integer number and decimals upto 2 places
Its working fine for the first time, but after clicking + button same input fields are opening but now: In the new boxes validations are not working even if I use the same classes for input boxes, i.e, newly added input boxes are taking any number of digits and characters.
Following is my code:
var app = angular.module('Calc', []);
var inputQuantity = [];
$(function () {
$(".form-control").each(function (i) {
inputQuantity[i] = this.defaultValue;
$(this).data("idx", i); // save this field's index to access later
});
$(".form-control").on("keyup", function (e) {
var $field = $(this),
val = this.value,
$thisIndex = parseInt($field.data("idx"), 10); // retrieve the index
// window.console && console.log($field.is(":invalid"));
// $field.is(":invalid") is for Safari, it must be the last to not error in IE8
if (this.validity && this.validity.badInput || isNaN(val) || $field.is(":invalid")) {
this.value = inputQuantity[$thisIndex];
return;
}
if (val.length > Number($field.attr("maxlength"))) {
val = val.slice(0, 5);
$field.val(val);
}
inputQuantity[$thisIndex] = val;
});
});
app.controller('Calc_Ctrl', function ($scope, $http) {
$scope.choices = [{id : 'choice1', l2 : 0, b2 : 0}];
$scope.areas = [{id : 'choice2', total : 0}];
$scope.addNewChoice = function () {
var newItemNo = $scope.choices.length + 1;
$scope.choices.push({
'id' : 'choice' + newItemNo, l2 : 0, b2 : 0
});
};
$scope.removeChoice = function () {
var lastItem = $scope.choices.length - 1;
if (lastItem !== 0) {
$scope.choices.splice(lastItem);
}
};
});
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="newscript.js"></script>
<body>
<div ng-app="Calc" ng-controller="Calc_Ctrl">
<div data-ng-repeat="choice in choices" class="col-md-12 col-sm-12 col-xs-12 bottom-line no-gap">
<h6>Flooring Area {{$index + 1}}
<button type="button" class="btn btn-default pull-right btn-right-gap btn-red" aria-label="Left Align" ng-click="addNewChoice()" style="margin-top: -5px;" id="plus_icon">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
</h6>
<div class="row walls top-gap">
<div class="form-group col-md-3 col-sm-3 col-xs-12">
<label for="length">Length :</label>
<input type="number" class="form-control text-red bold" id="length" ng-model="choice.l2" min="0" max="999" maxlength="6" step="0.00" >
</div>
<div class="form-group col-md-3 col-sm-3 col-xs-12">
<label for="height">Height :</label>
<input type="number" class="form-control text-red bold" id="height" ng-model="choice.b2" min="0" max="999" maxlength="6" step="0.01">
</div>
<div class="form-group col-md-3 col-sm-3 col-xs-12">
<label for="area">Area sq :</label>
<input type="number" class="form-control text-red bold" id="area" value="{{choice.l2 * choice.b2}}" readonly>
</div>
<button type="button" class="btn btn-default pull-right btn-red" aria-label="Left Align" ng-click="removeChoice()" id="minus_icon">
<span class="glyphicon glyphicon-minus minus-btn" aria-hidden="true" ></span>
</button>
</div>
</div>
</div>
</body>
</html>

bootstrap "control-label" behaves strange when following dynamically created list

<!-- code snippet of html -->
<div class="form-group">
<label for="items" class="col-sm-2 control-label">Items</label>
<div class="pull-left input-group">
<input type="text" class="form-control" ng-model="name">
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="addNewItem()">Add</button>
</span>
</div>
<div>
<ul class="pull-left">
<li ng-repeat="item in items">
<p style="display: inline-block">{{item}}</p>
<button type="button" class="btn btn-default" ng-click="deleteItem(item)">Delete</button>
</li>
</ul>
</div>
</div>
<div class="form-group">
<label for="anotherField" class="col-sm-2 control-label">Another Field</label>
<input type="text" class="form-control" ng-model="anotherField" id="anotherField">
</div>
/* code snippet in Augular controller */
$scope.addNewItem = function() {
if ($scope.name && $scope.name.trim()) {
if ($scope.items.indexOf($scope.name.trim()) >= 0) {
console.log('item name should not be duplicated');
} else {
$scope.items.push($scope.name.trim());
$scope.name = '';
}
}
};
$scope.deleteItem = function(item) {
var idx = $scope.items.indexOf(item);
if (idx >= 0) $scope.items.splice(idx, 1);
};
Above codes function properly, but the only problem is that when I create even on one new item, the label supposedly for "anotherField" just shows up immediately after this this very item (even misaligned with the label for "items"); when more items were created, it's simply placed at the end of the 1st item but not like a label for "anotherField" any more. Anybody can help to address this "strange" style issue?
Thanks,
Xihua

AngularJS - Scope Not Updating

For some reason, I can't remove the description and packing elements/fields (see picture) from the scope variable, even after deleting their respective code and restarting the application. Any help is much appreciated.
My directive:
app.directive('formElement', function() {
return {
restrict: 'E',
transclude: true,
scope: {
label : "#",
model : "="
},
link: function(scope, element, attrs) {
scope.disabled = attrs.hasOwnProperty('disabled');
scope.required = attrs.hasOwnProperty('required');
scope.pattern = attrs.pattern || '.*';
console.log(element);
},
template:
'<div class="form-group">' +
'<label class="col-sm-3 control-label no-padding-right"> {{label}}</label>' +
'<div class="col-sm-7">' +
'<span class="block input-icon input-icon-right" ng-transclude></span>' +
'</div></div>'
};
});
My controllers:
app.controller('ProductsCtrl', function ($scope, $modal, $filter, Data) {
$scope.product = {};
Data.get('products').then(function(data){
$scope.products = data.data;
});
$scope.changeProductStatus = function(product){
product.status = (product.status=="Active" ? "Inactive" : "Active");
Data.put("products/"+product.id,{status:product.status});
};
$scope.deleteProduct = function(product){
if(confirm("Are you sure to remove the product?")){
Data.delete("products/"+product.id).then(function(result){
$scope.products = _.without($scope.products, _.findWhere($scope.products, {id:product.id}));
});
}
};
$scope.open = function (p,size) {
var modalInstance = $modal.open({
templateUrl: 'partials/product-edit.html',
controller: 'ProductEditCtrl',
size: size,
resolve: {
item: function () {
return p;
}
}
});
modalInstance.result.then(function(selectedObject) {
if(selectedObject.save == "insert"){
$scope.products.push(selectedObject);
$scope.products = $filter('orderBy')($scope.products, 'id', 'reverse');
}else if(selectedObject.save == "update"){
p.price = selectedObject.price;
p.stock = selectedObject.stock;
}
});
};
$scope.columns = [
{text:"ID",predicate:"id",sortable:true,dataType:"number"},
{text:"Name",predicate:"name",sortable:true},
{text:"Price",predicate:"price",sortable:true},
{text:"Stock",predicate:"stock",sortable:true},
{text:"Status",predicate:"status",sortable:true},
{text:"Action",predicate:"",sortable:false}
];
});
app.controller('ProductEditCtrl', function ($scope, $modalInstance, item, Data) {
$scope.product = angular.copy(item);
$scope.cancel = function () {
$modalInstance.dismiss('Close');
};
$scope.title = (item.id > 0) ? 'Edit Product' : 'Add Product';
$scope.buttonText = (item.id > 0) ? 'Update Product' : 'Add New Product';
var original = item;
$scope.isClean = function() {
return angular.equals(original, $scope.product);
};
$scope.saveProduct = function (product) {
product.uid = $scope.uid;
if(product.id > 0){
Data.put('products/'+product.id, product).then(function (result) {
if(result.status != 'error'){
var x = angular.copy(product);
x.save = 'update';
$modalInstance.close(x);
}else{
console.log(result);
}
});
}else{
product.status = 'Active';
Data.post('products', product).then(function (result) {
if(result.status != 'error'){
var x = angular.copy(product);
x.save = 'insert';
x.id = result.data;
$modalInstance.close(x);
}else{
console.log(result);
}
});
}
};
});
HTML:
product-edit.html (partial):
<div class="modal-header">
<h3 class="modal-title">Edit product [ID: {{product.id}}]</h3>
</div>
<div class="modal-body">
<form name="product_form" class="form-horizontal" role="form" novalidate>
<form-element label="NAME" mod="product">
<input type="text" class="form-control" name="name" placeholder="Name" ng-model="product.name" ng-disabled="product.id" focus/>
</form-element>
<form-element label="PRICE" mod="product">
<input type="text" name="price" class="form-control" placeholder="PRICE" ng-model="product.price" only-numbers/>
<small class="errorMessage" ng-show="product_form.price.$dirty && product_form.price.$invalid"> Enter the price.</small>
</form-element>
<form-element label="STOCK" mod="product">
<input type="text" name="stock" class="form-control" placeholder="STOCK" ng-model="product.stock" only-numbers/>
<small class="errorMessage" ng-show="product_form.stock.$dirty && product_form.stock.$invalid"> Enter the available stock.</small>
</form-element>
<div class="modal-footer">
<form-element label="">
<div class="text-right">
<a class="btn btn-sm" ng-click="cancel()">Cancel</a>
<button ng-click="saveProduct(product);"
ng-disabled="product_form.$invalid || enableUpdate"
class="btn btn-sm btn-primary"
type="submit">
<i class="ace-icon fa fa-check"></i>{{buttonText}}
</button>
</div>
</form-element>
</div>
</form>
</div>
products.html (partial):
<div class="panel panel-default">
<div class="panel-heading" style="height: 60px;">
<div class="pull-left">
<input placeholder="Filter inventory list ..." class="form-control" aria-describedby="basei" ng-model="filterProduct" ng-change="resetLimit();" autocomplete="off" type="text" focus>
</div>
<div class="pull-right">
<button type="button" class="btn btn-default fa fa-plus" ng-click="open(product);">Add New Product</button>
</div>
</div>
<div class="panel-body">
<div class="input-group pull-right">
</div>
<table class="table table-striped">
<tr ng-show="products.length==0"><td style="vertical-align:middle;"><i class="fa fa-ban fa-3x"></i> No data found</td></tr>
<tr ng-hide="products.length>-1"><td style="vertical-align:middle;"><i class="fa fa-spinner fa-spin"></i> Loading</td></tr>
<tr><th ng-repeat="c in columns">{{c.text}}</th></tr>
<tr ng-repeat="c in products | filter:filterProduct | orderBy:'-id'" id="{{c.id}}" animate-on-change='c.stock + c.price' ng-animate=" 'animate'">
<td>{{c.id}}</td><td>{{c.name}}</td><td>{{c.price}}</td><td>{{c.stock}}</td>
<td>
<button class="btn" ng-class="{Active:'btn-success', Inactive:''}[c.status]" ng-click="changeProductStatus(c);">{{c.status}}</button>
</td>
<td>
<div class="btn-group">
<button type="button" class="btn btn-default fa fa-edit" ng-click="open(c);"></button>
<button type="button" class="btn btn-danger fa fa-trash-o" ng-click="deleteProduct(c);"></button>
</div>
</td>
</tr>
</table>
</div>
</div>
I often have a problem with my templates being cached while using Angular. In chrome if you have the developer console open you can go to settings and prevent it from using cached results while the console is open. Or clear your browser cache manually

Resources