AngularJS: Submit button requires two clicks to work - javascript

I have a submit button on my form but for some weird reason it requires me to click on the button twice before it calls the save function underneth, I am using Pug for my HTML
Here is my HTML template:
<form ng-submit="save()">
<div class="form-group">
<div class="row">
<div class="col col-md-6">
<ol ng-model="service.category" title="Select a category" class="nya-bs-select">
<li nya-bs-option="category in categories.rows" class="nya-bs-option"><a> <span>{{category.name}} </span><span class="glyphicon glyphicon-ok check-mark"></span></a></li>
</ol>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col col-md-6">
<div class="input-group"><span class="input-group-addon">Service Name</span>
<input type="text" ng-model="service.name" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col col-md-6">
<textarea ng-model="service.description" placeholder="Service Description" rows="10" class="form-control"></textarea>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col col-md-6">
<button type="submit" value="Save" class="btn btn-default"> Save</button>
</div>
</div>
</div>
</form>
The save function called is as
angular.module('App.controllers')
.controller('UpdateServiceCtrl', [
'$scope', '$state', 'ServicesService', 'Notification',
function ($scope, $state, ServicesService, Notification) {
$scope.service = $scope.$parent.service;
$scope.categories = $scope.$parent.categories;
/**
* Edits a service
* #param {integer} serviceID Id of the service to be edited
* #return {undefined} Does not return any values
*/
$scope.save = function () {
$scope.service.category_id = $scope.service.category.id;
ServicesService.save($scope.service, $scope.service.id)
.then(function (result) {
$state.reload();
})
}
}]);

You can disable the submit button after it clicked first time using
ng-disabled='isButtonEnabled' your html.
Modify your save like this
$scope.save = function () {
$scope.isButtonEnabled = false;
$scope.service.category_id = $scope.service.category.id;
ServicesService.save($scope.service, $scope.service.id)
.then(function (result) {
$state.reload();
})
}
Let me know if it doesn't works.

Related

AngularJS - Ng-Submit not executing function call

I'm building a simple to do app in order to better understand some AngularJS fundamentals.
I have two views, home and new item.
In the new item view, I have a form, which uses a function on ng-submit call addNewToDoTask.
When the form is submitted it should execute this function, which will in turn update an object with the input values.
I will then use these values by means of a service, to show the new object on the home page.
But it appears nothing is being pushed into the taskArr array.
I've stepped through and debugged and the issue seems to be that the function in ng-submit is not being called at all when I click my submit button.
The button is of type submit it is also inside of the form, so I'm not sure what I'm doing wrong here.
New item html
<div ng-controller="newItemCtrl">
<div class="row header">
<div class="col-12">
<h1>DOINGO</h1>
</div>
</div>
<div class="row addNewItem">
<form class="form" ng-submit="addNewToDoTask()">
<div class="row projectInput text-center">
<div class="col-12">
<input type="text" ng-model="projectInput" placeholder="Enter a project title">
</div>
</div>
<div class="row taskInput text-center">
<div class="col-12">
<input type="text" ng-model="taskInput" placeholder="Enter your task details">
</div>
</div>
</div>
<div class="buttonRow row">
<div class="col-12 text-center">
<button type="submit" class="btn-lg btn-success addItemButton">Add</button>
</form>
<button class="btn-lg btn-danger cancelButton">Cancel</button>
<button class="btn-lg btn-info addItemButton">Open Tasks</button>
</div>
</div>
</div>
app.module.js
var app = angular.module('ToDoListApp', ['ngRoute']);
app.config(function ($routeProvider, $locationProvider) {
$locationProvider.hashPrefix('');
$routeProvider
.when("/", {
templateUrl: "app/home/homePage.html",
})
.when("/newItem", {
templateUrl: "app/newItem/newitem.html",
})
.otherwise({
redirectTo: '/'
});
});
//controller for home page
app.controller('homePageCtrl', function ($scope, newToDoTaskService) {
$scope.toDoList = newToDoTaskService.getTasks();
});
//controller for new item page
app.controller('newItemCtrl', function ($scope, newToDoTaskService) {
$scope.addNewToDoTask = function () {
newToDoTaskService.addTask({
project: $scope.projectInput,
task: $scope.taskInput,
done: false
});
$scope.projectInput = "";
$scope.taskInput = "";
};
});
//service to persist data across views
app.service('newToDoTaskService', function () {
var taskArr = [];
this.getTasks = function () {
return taskArr;
};
this.addTask = function (task) {
taskArr.push(task);
};
});
The ng-submit function is not executing because the submit button is not part of the form:
ERRONEOUS
<div ng-controller="newItemCtrl">
<div class="row header">
<div class="col-12">
<h1>DOINGO</h1>
</div>
</div>
<div class="row addNewItem">
<form class="form" ng-submit="addNewToDoTask()">
<div class="row projectInput text-center">
<div class="col-12">
<input type="text" ng-model="projectInput" placeholder="Enter a project title">
</div>
</div>
<div class="row taskInput text-center">
<div class="col-12">
<input type="text" ng-model="taskInput" placeholder="Enter your task details">
</div>
</div>
<!-- FORM tag closes early here -->
</div>
<div class="buttonRow row">
<div class="col-12 text-center">
<button type="submit" class="btn-lg btn-success addItemButton">Add</button>
<!-- FORM CLOSING tag ignored -->
</form>
<button class="btn-lg btn-danger cancelButton">Cancel</button>
<button class="btn-lg btn-info addItemButton">Open Tasks</button>
</div>
</div>
</div>
The </div> closing tag closes the <form> element early. The HTML5 parser ignores the subsequent </form> closing tag.
The submit event event listener on the <form> element does not get the event because the submit button dispatches its submit event from outside the form.

Error: [ng:areq] Argument 'UsersSettingsController' is not a function, got undefined

I'm trying to create a edit profile section in angularjs. For that i create in my users controller a section to make a rest api call to get info to inject on the page and later i will do the parte of changePassword also.
At the moment i'm getting the error "Error: [ng:areq] Argument 'UsersSettingsController' is not a function, got undefined" and I cant undestand why.
editAccount view:
<div class="row" ng-controller="UsersSettingsController as usersSettingsCtrl" >
{{userInfo}}
<!-- edit form column -->
<div class="col-md-9 personal-info">
<h3>Personal info</h3>
<form class="form-horizontal" role="form">
<div class="form-group">
<label class="col-md-3 control-label">Username:</label>
<div class="col-md-8">
<input class="form-control" type="text" style="background-color: #fff" value="{{userInfo.username}}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Organization:</label>
<div class="col-lg-8">
<input class="form-control" type="text" style="background-color: #fff" value="{{userInfo.organization_name}}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Permission Group:</label>
<div class="col-lg-8">
<input class="form-control" type="text" style="background-color: #fff" value="{{userInfo.permission_group_name}}" readonly>
</div>
</div>
<div class="form-group" nf-ig="user.organization_permission_group_id=='df0417e3-ce36-41ca-9f13-f58c1a3a96f5'">
<label class="col-lg-3 control-label">Root:</label>
<div class="col-lg-8">
<input class="form-control" type="text" style="background-color: #fff" value="{{userInfo.data.root}}" readonly>
</div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Email:</label>
<div class="col-lg-8">
<input class="form-control" type="text" style="background-color: #fff" value="{{userInfo.username}}" readonly>
</div>
</div>
<hr>
<h4>Change Password</h4>
<br>
<form name="newPasswordForm" role="form" ng-submit="newPasswordForm.$valid && ok()" novalidate>
<div class="form-group">
<label class="col-md-3 control-label">Change Password:</label>
<div class="col-md-8">
<input type="password" name="newPassword" ng-model="password.new"
ng-minlength="6" required />
<span class="help-block"
ng-show="newPasswordForm.newPassword.$dirty && newPasswordForm.newPassword.$invalid">
Please enter a new password, it must be at least 6 characters long.
</span>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">Confirm password:</label>
<div class="col-md-8">
<input type="password" name="newPasswordConfirm"
ng-model="password.confirm" ng-minlength="6"
value-matches="password.new" required />
<span class="help-block"
ng-show="newPasswordForm.newPasswordConfirm.$dirty && newPasswordForm.newPasswordConfirm.$invalid">
Please enter the same password again to confirm.
</span>
</div>
</div>
</form>
<div class="form-group">
<label class="col-md-3 control-label"></label>
<div class="col-md-8">
<input type="button" class="btn btn-primary" style="float:right" value="Save Changes">
<div ng-messages="registrationForm.confirmPassword.$error" ng-messages-include="messages.html"></div>
</div>
</div>
</form>
</div>
</div>
usersController:
app.controller('UsersSettingsController',['$scope', 'user', function ($scope, user) {
$http.get('/api/users/userInfo/'+user.id).success(function (data) {
console.log("user info ",data);
$scope.userInfo = data;
});
//changePassword call to rest api
}]);
usersDirective:
(function() {
var app = angular.module('userSettings', []);
app.directive('valueMatches', ['$parse', function ($parse) {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ngModel) {
var originalModel = $parse(attrs.valueMatches),
secondModel = $parse(attrs.ngModel);
// Watch for changes to this input
scope.$watch(attrs.ngModel, function (newValue) {
ngModel.$setValidity(attrs.name, newValue === originalModel(scope));
});
// Watch for changes to the value-matches model's value
scope.$watch(attrs.valueMatches, function (newValue) {
ngModel.$setValidity(attrs.name, newValue === secondModel(scope));
});
}
};
}]);
})();

Modal state angularjs

I want set modal state using ui-router.I make state:
.state('adminUsers.new', {
url: '/new',
controller: 'adminUsersCtrl',
onEnter: ['$uibModal', '$state', function($uibModal, $state){
$uibModal.open({templateUrl: "administration/users/new.html"})
.result.then(
function(){
$state.go('^');
},
function(){
$state.go('adminUsers');
},
function(){
$state.go('adminUsers');
}
).finally(function(){$state.go('^')});
}]
})
when I go to adminUsers.new state, template normal loaded and showing. In template I have two buttons:
<span class="btn btn-success" ng-click="addUser()">Add user</span>
<a class="btn btn-danger" ui-sref="adminUsers" href="#/admin/users">Cancel</a>
adminUsersController
var adminUsersController = function($scope, Restangular, $stateParams, $state) {
$scope.store = Restangular.all('users');
console.log("adminUsersController");
$scope.store
.getList()
.then(
function(users){
$scope.users = users;
},
function()
{
alertify.log("Не удалось получить список пользователей");
}
)
$scope.addUser = function() {
alert('hello');
}
};
angular
.module('mofs')
.controller('adminUsersCtrl', [
'$scope',
'Restangular',
'$stateParams',
'$state',
adminUsersController
]);
when I clicked to "addUser" button I don't get alert, but when I clicked to "cancel" button modal window not closed, but in browser url changed to #/admin/users. What am i doing wrong? Thank you.
full template code
<div class="modal-content" uib-modal-transclude=""><div class="row no-margin ng-scope">
<h3>
Новый пользователь
</h3>
<form class="form-horizontal ng-pristine ng-valid" id="userForm">
<div class="form-group">
<label class="col-sm-3 control-label" for="user[surname]">
Фамилия
</label>
<div class="col-sm-9">
<input class="form-control" id="user[surname]" name="user[surname]" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="user[name]">
Имя
</label>
<div class="col-sm-9">
<input class="form-control" id="user[name]" name="user[name]" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="user[patronimyc]">
Отчество
</label>
<div class="col-sm-9">
<input class="form-control" id="user[patronimyc]" name="user[patronimyc]" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="user[login]">
Логин
</label>
<div class="col-sm-9">
<input class="form-control" id="user[login]" name="user[login]" type="password">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="user[password]">
Пароль
</label>
<div class="col-sm-9">
<input class="form-control" id="user[password]" name="user[password]" type="password">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="user[password_confirmation]">
Подтверждение пароля
</label>
<div class="col-sm-9">
<input class="form-control" id="user[password_confirmation]" name="user[password_confirmation]" type="password">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="user[role]">
Роль
</label>
<div class="col-sm-9">
<select class="form-control" id="user[role]" name="user[role]">
<option value="1">Администратор</option>
<option value="2">Главный врач</option>
<option value="3">Врач</option>
<option value="4">Сотрудник регистратуры</option>
</select>
</div>
</div>
</form>
</div>
<div class="row no-margin ng-scope">
<div class="pull-right">
<span class="btn btn-success" ng-click="addUser()">Добавить</span>
<a class="btn btn-danger" ui-sref="adminUsers" href="#/admin/users">Отменить</a>
</div>
</div></div>
Along with teplateUrl, you provide controller as property.Like as fallows
$uibModal.open({
animation: true,
templateUrl: 'Your template URL',
controller: 'Your controller',
size: undefined,
resolve : {
// If you have anything to resolve
embedLink : function (){
return embedLink;
}
}
});
Inside your controller add a method which will call on click of cancel button as fallows.
$scope.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
Don't forget to have a dependency of uibModalInstance in you controller.
The same you can do inside the same controller on click of addUser button.
Please refer Plunker

Keydown event not updating the $scope variable for dropdown in angularjs

I have a simple page with 2 fields. I enter the goal name and the use tab to navigate to the next field and then hit the down arrow key to select the Public Group value and when I click the save button, the value of the picklist is setting to Individual which is incorrect. I am not exactly sure how to make the $scope variable pick the updated value from the dropdown
Here's the fiddle
<div ng-app>
<div class="container" ng-controller="goalCtrl">
<div class="row">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">New Record</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-lg-4">
<div class="form-group">
<label for="goalName" class="control-label">Name</label>
<input type="text" class="form-control" id="goalName" placeholder="Goal Name" ng-model="goalie__goal__c.Name">
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label for="fulfilment" class="control-label">Fulfilment</label>
<select class="form-control" id="fulfilment" ng-model="goalie__goal__c.goalie__Fulfilment__c">
<option selected>Individual</option>
<option>Public Group</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<center>
<button class="btn btn-success" ng-click="save()"> Save and add critera</button>
<button class="btn btn-danger" ng-click="cancel()">Cancel</button>
</center>
</div>
</div>
</div>
</div>
</div>
</div></div>
Controller
function goalCtrl($scope) {
$scope.save = function() {
alert(JSON.stringify($scope.goalie__goal__c));
}
}
Update
I updated the controller where I am setting the value to Individual explicitly and then when I hit the save button all the values are updated correctly in the $scope. Not sure why its not working it the initial case.
function goalCtrl($scope) {
$scope.goalie__goal__c = {};
$scope.goalie__goal__c.goalie__Fulfilment__c = 'Individual';
$scope.save = function() {
alert(JSON.stringify($scope.goalie__goal__c));
}
}

Clear the form after submit angularjs

hi i want to clear the form values after successfull completion. Houw should i implemnt
<div ng-controller="employeelistController as listControl">
<div class="container form-group" ng-controller="addEmployee as addemp">
<form name="frmEmployee" ng-submit="Add(addemp.employee) && frmEmpbloyee.$valid">
<div class="col-lg-4 ctrmain">
<div class="row">
<div class="col-lg-6">
<strong>Employee No</strong>
</div>
<div class="col-lg-6">
<input type="number" id="txtEmpId" ng-model="addemp.employee.employeeid" required class="form-control" />
</div>
</div>
<div class="row">
<div class="col-lg-6">
<strong>FirstName</strong>
</div>
<div class="col-lg-6">
<input type="text" id="txtfirstName" ng-model="addemp.employee.firstname" required class="form-control" />
</div>
</div>
<div class="row">
<div class="col-lg-6">
<strong>LastName</strong>
</div>
<div class="col-lg-6">
<input type="text" id="txtlastName" ng-model="addemp.employee.lastname" required class="form-control" />
</div>
</div>
<div class="row">
<div class="col-lg-6">
<strong>Department</strong>
</div>
<div class="col-lg-6">
<input type="text" id="txtDept" ng-model="addemp.employee.department" required class="form-control" />
</div>
</div>
<div class="row">
<div class="col-lg-6">
<strong>DOB</strong>
</div>
<div class="col-lg-6">
<input type="date" id="DTdob" ng-model="addemp.employee.dateofbirth" required class="form-control" />
</div>
</div>
<div class="row">
<input type="submit" id="btnSubmit" class="btn btn-primary value=" save" />
</div>
</div>
which is the best way to implement this. I have tried many ways. please help.
$scope.Add = function (emp,$scope) {
this.EmployeeObject = angular.copy(emp);
employee.push(this.EmployeeObject);
$scope.emp = null;
}
which is the best way to implement this. I have tried many ways. please help.
First of all you don't need $scope in the argument of the Add function.
$scope.Add = function (emp) {
this.EmployeeObject = angular.copy(emp);
employees.push(this.EmployeeObject);
this.employee=null;
$scope.$setPristine(true);
}
update it with the demo
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope, $compile) {
'use strict';
$scope.empList = [];
$scope.addemp = {};
$scope.saveEmp = function(){
$scope.empList.push($scope.addemp);
$scope.reset();
};
$scope.reset = function() {
$scope.addemp = {};
$scope.form.$setPristine();
}
});
input.ng-invalid.ng-dirty {
background-color: #FA787E;
}
input.ng-valid.ng-dirty {
background-color: #78FA89;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="MainCtrl">
<form name="form" id="form" novalidate ng-submit="saveEmp()">
<div class="row">
<div class="col-lg-6">
<strong>Employee No</strong>
</div>
<div class="col-lg-6">
<input type="number" id="txtEmpId" ng-model="addemp.employeeid" required class="form-control" />
</div>
</div>
<div class="row">
<div class="col-lg-6">
<strong>FirstName</strong>
</div>
<div class="col-lg-6">
<input type="text" id="txtfirstName" ng-model="addemp.firstname" required class="form-control" />
</div>
</div>
<div class="row">
<div class="col-lg-6">
<strong>LastName</strong>
</div>
<div class="col-lg-6">
<input type="text" id="txtlastName" ng-model="addemp.lastname" required class="form-control" />
</div>
</div>
<div class="row">
<div class="col-lg-6">
<strong>Department</strong>
</div>
<div class="col-lg-6">
<input type="text" id="txtDept" ng-model="addemp.department" required class="form-control" />
</div>
</div>
<div class="row">
<div class="col-lg-6">
<strong>DOB</strong>
</div>
<div class="col-lg-6">
<input type="date" id="DTdob" ng-model="addemp.dateofbirth" required class="form-control" />
</div>
</div>
<div class="row">
<button type="submit" ng-disabled="form.$invalid ">submit</button>
<button type="reset" ng-disabled="form.$pristine" ng-click="reset()">reset</button>
</div>
</form>
<p>form: {{addemp | json}}</p>
<p>empList: {{empList | json}}</p>
<p>Pristine: {{form.$pristine}}</p>
<p> <pre>Errors: {{form.$error | json}}</pre>
</p>
</div></div>
$scope.Add = function (emp) {
this.EmployeeObject = angular.copy(emp);
employee.push(this.EmployeeObject);
$scope.emp = {}; // initialize the form to empty object
$scope.frmEmployee.$setPristine(); // set it to as user has not interacted with the form.
}
I have cleared textbox with below code. e.g I have cleared FirstName textbox.
HTML SECTION
<td ng-show="a">
<input type="text" ng-model="e.FirstName" />
</td>
Controller SECTION
e.FirstName= "";
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope, $compile) {
'use strict';
function resetform() {
document.getElementById("frmEmployee").reset();
}
$scope.Add = function (emp,$scope) {
this.EmployeeObject = angular.copy(emp);
employee.push(this.EmployeeObject);
resetform();
}
});
Its pure JavaScript with simple one line code.
document.getElementById('yourFormId').reset()
Add this syntax at the end of the function in controller after submitting the form.

Categories

Resources