$uibModal tries force execute submit in my form - angularjs

I have a modal dialog, created with ui.bootstrap. When I'm performing some code with $uibModal or $uibModalInstance, inside of controller of this modal, AngularJS try to call submit method of my <form> from dialog. Also, my <form> hasn't a submit attribute, but it has a ng-submit attribute.
Here is a part of my modal dialog:
<div class="modal-content">
<form name="newActionForm" class="form-horizontal" role="form" ng-submit="">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title">{{ 'action.labelNewAction' | translate }}</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label class="col-sm-3 control-label site-form-label">{{ 'common.labelName' | translate }}:</label>
<div class="col-sm-9 input-group padding_right_left_15" ng-class=" newActionForm.name.$valid ? 'has-success' : 'has-error' ">
<input required ng-maxlength="160" ng-change="vm.test()" name="name" class="form-control" ng-model="vm.newAction.name"/>
<span class="input-group-addon">
<i class="glyphicon glyphicon-remove" ng-show="newActionForm.name.$error.required" tooltip="{{'formValidationRequired' | translate}}"></i>
<i class="glyphicon glyphicon-remove" ng-show="newActionForm.name.$error.maxlength" tooltip="{{'formValidationNameTooLong' | translate}}"></i>
<i class="glyphicon glyphicon-ok" ng-show="newActionForm.name.$valid"></i>
</span>
</div>
</div>
</div>
<div class="modal-footer">
<button ng-disabled="newActionForm.$invalid" class="btn btn_kassir" ng-click="vm.addAction()">{{ 'common.labelButtonAdd' | translate }}</button>
<button class="btn btn-default" ng-click="close()">{{ 'common.labelButtonClose' | translate }}</button>
</div>
</form>
</div>
and modal contoller with two functions, that tries to perform sumbit on my form:
angular
.module('newActionDialog')
.controller('NewActionDialogController',
[ '$scope', '$stateParams', '$uibModalInstance', 'Requester', '$uibModal', '$filter', '$translate', 'alertService', NewActionDialogController]);
function NewActionDialogController($scope, $stateParams, $uibModalInstance, Requester, $uibModal, $filter, $translate, alertService) {
var vm = this;
vm.showSelectHall=function(){
$uibModal.open({
templateUrl: 'app/repertoire/listHalls.html',
controller: function ($scope, $uibModalInstance) {
this.select = function (hallConfig) {
$uibModalInstance.close(hallConfig);
};
},
controllerAs: 'ctrl',
}).result.then(function (hallConfig) {
vm.newAction.defaultHallConfiguration=hallConfig;
});
};
......
vm.close=function(){
$uibModalInstance.close();
}
}

The issue has been solved and it was occuring because of the $uibModal.open() method creates a modal with a <buttons type="submit"> by default. So, after $uibModal.open() <button> transformed to <button type="submit>. Solution is add to all buttons type="button", except real submit button, of course.

Related

$modal is not open for the second time in Angularjs

$modal is called in the $ngonint hook. First time when controller loads, it works perfectly. But for the second time, it is not showing up when the controller loads.
Expectation:
Consider two controllers first and second.
Navigate to second controller from first controller by clicking link.
We need to show below modal when page loads whenever navigate to second controller page.
Actual Result:
For the first time, when it navigate to second controller, it showed the modal as expected. once go back to first page and come again to second controller, modal is not showed up.
Can anyone help me to solve this issue ? Thanks.
Below are the code sample:
Controller
$onInit() {this.showModal();} // Need to show modal when page loads
public showModal= function () {
var modalInstance = $modal.open({
template: ModalTemplate,
controller: [
'$scope',
'$modalInstance',
function ($scope, $modalInstance) {
$scope.answer = '';
$scope.close = function () {
$modalInstance.dismiss();
};
$scope.next = function () {
$modalInstance.close($scope.answer);
};
},
],
windowClass: 'open-account'
});
modalInstance.result.then((response) => {
console.log(response);
})
}
ModalTemplate.html
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-hidden="true">
<fa-icon icon="times" prefix="fal" class="close-fa fa-lg"></fa-icon>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-sm-4">
<div class="form-group radio-group-label">
<label class="control-label">
Click
</label>
</div>
</div>
<div class="col-xs-2">
<div class="form-group">
<label class="control-label" for="answer-yes">
<input type="radio" name="answer" ng-model="answer" value="yes"
id="answer-yes" />
Yes
</label>
</div>
</div>
<div class="col-xs-2">
<div class="form-group">
<label class="control-label" for="answer-no">
<input type="radio" name="answer" ng-model="answer" value="no"
id="answer-no" />
No </label>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-success" ng-disabled="!answer" ng-click="next()">Next</button>
</div>

Data edit - modal Bootstrap

I have a problem with editing data in the bootstrap modal.
The problem is that in the modal, only first record from the database is displayed.
Modal only displays the problem because it retrieves data from 1 record.
Could it show me something wrong with the code, that it only gets 1 record for me?
My code AngularJS:
controllersAdmin.controller('linkEdit', function( $scope, $http, $routeParams, $timeout){
var linkID = $routeParams.id;
$scope.id = linkID;
$scope.link = function( link ){
$http({
method: 'GET',
url: 'api/admin/links/get/' + linkID,
}).then(function (response){
$scope.link = response.data.records;
},function (error){
console.log('Blad we wczytywaniu danych');
});
}
$scope.saveChanges = function( link ){
$http({
method: 'POST', url: 'api/admin/links/update/', data: {'link' : link}},
).then(function (){
$scope.success = true;
},function (error){
console.log('Blad we wczytywaniu danych');
});
}
});
<tr ng-repeat="link in link">
<td>{{$index+1}}</td>
<td>{{link.links | limitTo:50}}...</td>
<td>{{ link.login }}</td>
<td>{{link.password}}</td>
<td>{{link.date}}</td>
<td>
<button ng-click="deleteLink(link, $index)" class="btn btn-danger">×</button>
<button data-toggle="modal" ng-click="edtlnk(link)" data-target="#edit-data" class="btn btn-primary">Edit</button>
<div class="modal fade" id="edit-data" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form method="POST" name="editlinke" role="form" ng-submit="saveChanges( link )">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Edit Item</h4>
</div>
<div class="modal-body">
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-6">
<div class="form-group">
<input type="text" class="form-control" ng-model="link.login">
<input type="text" class="form-control" ng-model="link.password">
<input type="text" class="form-control" ng-model="link.links">
</div>
</div>
</div>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
</div>
</div>
</div>
</td>
</tr>

AngularJS: Passing data to modal from list

I am currently learning how to build a MEAN webapp from scratch. Stuff goes quite well until this point but now i am stuck at trying to pass data from my list (ng-repeat) to my modal via ng-click=updatePerson(person). I have absolutely no clue why I can't access the data from the list. I tried like 20 variants to link the data between both scopes without any success.
This is my Controller:
angular.module('userCtrl', ['userService','ui.bootstrap'])
.controller( 'userController', function(User, $uibModal, $log, $scope) {
var vm = this;
User.all().success( function(data) {
vm.users = data;
})
vm.deleteUser = function(id) {
User.delete(id).success(function(data) {
User.all().success(function(data) {
vm.users = data;
});
});
};
vm.createUser = function() {
User.create(vm.userData).success(function(data) {
vm.userData = {};
User.all().success(function(data) {
vm.users = data;
});
});
};
vm.updateUser = function(selectedUser) {
$scope.selectedUser = selectedUser;
var modalInstance = $uibModal.open({
animation: true,
templateUrl: 'app/views/pages/modal.html',
resolve: {
user: function () {
return $scope.selectedUser;
}
}
});
modalInstance.result.then(function(selectedUser) {
$scope.selected = selectedUser;
});
};
});
My angular-router:
angular.module('appRoutes', ['ngRoute'])
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl : 'app/views/pages/home.html',
controller : 'userController',
controllerAs : 'user'
})
.when('/users', {
templateUrl : 'app/views/pages/user.html',
controller : 'userController',
controllerAs : 'user'
});
$locationProvider.html5Mode(true);
});
My list:
<div class="btn-group">
<button type="button" class="btn-lg btn-default glyphicon glyphicon-plus" data-toggle="modal" data-target="#createModal"></button>
<table class="table table-nonfluid table-bordered table-striped" ng-show="user.users">
<thead>
<tr>
<th></th>
<th>Vorname</th>
<th>Nachname</th>
<th>E-Mail</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="person in user.users">
<td><button ng-click="user.deleteUser(person._id)" class="btn btn-default btn-lg glyphicon glyphicon-trash"></button></td>
<td>{{person.firstname}}</td>
<td>{{person.lastname}}</td>
<td>{{person.mail}}</td>
<td><button ng-click="user.updateUser(person)" class="btn btn-default btn-lg glyphicon glyphicon-trash"></button></td>
<!--<td><button class="btn-lg btn-default glyphicon glyphicon-option-horizontal" data-toggle="modal" data-target="#updateModal"></button> </td>-->
</tr>
</tbody>
</table>
<!--Create Modal-->
<div class="modal fade bs-example-modal-lg" id="createModal" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
<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">×</span></button>
<h4 class="modal-title" id="exampleModalLabel">Neue Person</h4>
</div>
<form id="form1" ng-submit="user.createUser()">
<div class="modal-body">
<div class="form-group">
<label for="recipient-name" class="control-label">Vorname</label>
<input type="text" class="form-control" ng-model="user.userData.firstname">
</div>
<div class="form-group">
<label for="recipient-name" class="control-label">Nachname</label>
<input type="text" class="form-control" ng-model="user.userData.lastname">
</div>
<div class="form-group">
<label for="recipient-name" class="control-label">E-Mail</label>
<input type="text" class="form-control" ng-model="user.userData.mail">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Schließen</button>
<button id="button1" type="submit" class="btn btn-primary">Person erstellen</button>
</div>
</form>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$('#button1').click(function() {
$('#createModal').modal('hide');
});
</script>
And here is my modal:
<div class="modal-content bs-example-modal-lg" role="dialog document">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="exampleModalLabel">Ändere Person</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="recipient-name" class="control-label">Vorname</label>
<input type="text" class="form-control" ng-model="person.firstname" placeholder={{person.firstname}}>
</div>
<div class="form-group">
<label for="recipient-name" class="control-label">Nachname</label>
<input type="text" class="form-control" ng-model="person.firstname" placeholder={{person.lastname}}>
</div>
<div class="form-group">
<label for="recipient-name" class="control-label">E-Mail</label>
<input type="text" class="form-control" ng-model="person.firstname" placeholder={{person.mail}}>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Schließen</button>
<button id="button1" type="submit" class="btn btn-primary">Person ändern</button>
</div>
</div>
The user you're resolving won't be bound to the view automatically. You need a controller to do that. You can use the code below, or you can use controllerAs, but you'd have to update the modal's HTML accordingly.
vm.updateUser = function(selectedUser) {
$scope.selectedUser = selectedUser;
var modalInstance = $uibModal.open({
animation: true,
templateUrl: 'app/views/pages/modal.html',
resolve: {
user: function () {
return $scope.selectedUser;
}
},
controller: function($scope, user) {
$scope.user = user;
}
});
modalInstance.result.then(function(selectedUser) {
$scope.selected = selectedUser;
});
};

Bootstrap modal form elements unfocussable (on mobile/mobile emulation)

From the repo: https://github.com/jmsherry/kitchenapp
Live at: https://kitchenapp2.herokuapp.com
If you click the 'contact us' link in the bottom right corner of the screen a modal appears. The modal is coded like:
<div class="modal-container">
<button type="button" class="close" aria-label="Close" ng-click="$close(null)">
<span aria-hidden="true">×</span>
</button>
<div class="content">
<h1>Contact Us</h1>
<div class="contact-form">
<form ng-submit="vm.sendMessage(this)" novalidate name="contactForm">
<div class="form-group" ng-if="vm.user && vm.user.email">
<p class="faux-label">From: <span class="faux-value">{{vm.user.email}}</span></p>
</div>
<div class="form-group" ng-class="{ 'has-error' : contactForm.from.$invalid && !contactForm.from.$pristine }" ng-if="!vm.user || !vm.user.email">
<label for="subject">From</label>
<input type="email" name="from" id="from" class="form-control" placeholder="From" ng-model="vm.user.email" ng-maxlength="30" ng-required="true" autofocus>
<ul ng-if="contactForm.from.$invalid && !contactForm.from.$pristine" ng-messages="contactForm.from.$error" class="help-block list-unstyled">
<li ng-message="maxlength">The subject must be less than 30 characters.</li>
<li ng-message="email">Not a valid email. Please check carefully and try again...</li>
</ul>
</div>
<div class="form-group" ng-class="{ 'has-error' : contactForm.subject.$invalid && !contactForm.subject.$pristine }">
<label for="subject">Subject</label>
<input type="text" name="subject" id="subject" class="form-control" placeholder="Subject" ng-model="vm.email.subject" ng-maxlength="30">
<ul ng-if="contactForm.subject.$invalid && !contactForm.subject.$pristine" ng-messages="contactForm.subject.$error" class="help-block list-unstyled">
<li ng-message="maxlength">The subject must be less than 30 characters.</li>
</ul>
</div>
<div class="form-group" ng-class="{ 'has-error' : contactForm.message.$invalid && !contactForm.message.$pristine }">
<label for="message">Message</label>
<textarea name="message" id="message" class="form-control" placeholder="Message..." ng-model="vm.email.body" ng-required="true" ng-minlength="10" ng-maxlength="500"></textarea>
<ul ng-if="contactForm.message.$invalid && !contactForm.message.$pristine" ng-messages="contactForm.message.$error" class="help-block list-unstyled">
<li ng-message="required">A description is required.</li>
<li ng-message="minlength">The name must be longer than 10 characters.</li>
<li ng-message="maxlength">The name must be less than 500 characters.</li>
</ul>
</div>
<!-- <div class="form-group"> -->
<div class="checkbox">
<label for="cc_self">
<input type="checkbox" id="cc_self" name="cc_self" ng-model="vm.email.cc_self">Send a copy to my email.
</label>
</div>
<!-- </div> -->
<div class="form-group">
<div class="pull-right">
<button type="button" class="btn btn-default" ng-click="$close(null)">Cancel</button>
<button type="submit" class="btn btn-primary" ng-disabled="contactForm.$invalid">Send</button>
</div>
</div>
</form>
</div>
</div>
</div>
Controller looks like:
angular.module('kitchenapp.directives')
.controller('KaFooterCtrl', ['$scope', '$q', '$log', '$modal', 'Email', 'Auth', 'toastr', function ($scope, $q, $log, $modal, Email, Auth, toastr) {
var vm = this,
$user;
function contact(day) {
$log.log('contact fn', arguments);
$modal.open({
templateUrl: '/views/modals/contact-modal.html',
controller: function modalController($modalInstance, $scope) {
$scope.vm = this;
$scope.vm.email = vm.email;
$scope.vm.user = vm.user;
$scope.vm.sendMessage = function () {
$modalInstance.close();
$q.when(vm.user, function (user) {
var $emailSent = Email.sendEmail(vm.email, vm.user);
$q.when($emailSent, function (res) {
toastr.success('Email sent! Thank you for your interest...');
}, function () {
toastr.error('We\'re sorry your email hasn\'t been sent, please try again later...');
});
});
event.preventDefault();
event.stopPropagation();
};
},
contollerAs: 'vm'
});
}
vm.year = new Date().getFullYear();
vm.email = {};
$user = Auth.getUser();
$q.when($user, function (user) {
vm.user = user;
});
vm.contact = contact;
vm.name = 'KaFooterCtrl';
}])
.directive('kaFooter', function () {
return {
restrict: 'E',
replace: true,
templateUrl: 'directives/footer/footer.html',
scope: {
companyName: '#',
companyEmail: '#'
},
controller: 'KaFooterCtrl as vm',
bindToController: true
};
});
}());
For some reason the first element focusses once, but any further interaction and the elements are not focussable by touch or mouse. Any clues why?
Thanks
So, it transpires that this is a problem when ng-touch is used. ng-touch auto-blurs the fields (https://github.com/angular/angular.js/pull/11212). A fix is on the way, but for now the user #jdhiro suggests using a directive to stop propagation of the touchend event outside of your modal. See https://github.com/angular-ui/bootstrap/issues/2017#issuecomment-39515923 for more

Why an undefined is not a function with Angular directive to close Bootstrap modal

As a newbie to Angularjs I copied a directive from here: Closing Twitter Bootstrap Modal From Angular Controller, to be able to close a bootstrap modal from a controller, and in my implementation I'm getting an undefined is not a function error. (http://jsfiddle.net/jlamont/7f6dH/6/)
Here's the html
<div ng:app="app">
<div>
<ul><li>Login</li></ul>
<div id='loginModal' class='modal fade' myModal ng-controller="LoginDialogController" tabindex="-2" role="dialog" aria-labelledby="loginModal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" ng-click="cancel()">x</button>
<h3>Login MyApp</h3>
</div>
<div class="modal-body">
<form name="login_form">
<alert ng-repeat="alert in alerts" type="danger" close="closeAlert($index)">{{alert.msg}}</alert>
<p><input type="text" class="span3" ng-model="login.user_email" placeholder="Email" required></p>
<p><input type="password" class="span3" ng-model='login.password' placeholder="Password" required></p>
<p><button type="submit" class="btn btn-primary" ng-click="ok()">Sign in</button>
Forgot Password?
</p>
</form>
</div>
<div class="modal-footer">
My.com?
Register
</div>
</div>
</div>
</div>
</div>
</div>
Here's the js
angular.module("app", []).directive('myModal', function() {
return {
restrict: 'A',
scope:{},
link: function(scope, element, attr) {
scope.dismiss = function() {
element.modal('hide');
};
}
}
});
function LoginDialogController($scope){
$scope.ok = function(){
$scope.dismiss();
};
}

Resources