I'm trying to load a modal with Angular and then fill it with a template.
The problem is that the inputs are overshooting the modal - here is a screenshot of the problem:
Here is the code for the modal instantiation:
$scope.logInOpen = function () {
console.log($modal);
var modalInstance = $modal.open({
templateUrl: '../views/login.html',
controller: 'AuthController',
size: 'sm'
});
modalInstance.result.then(function () {
console.log($scope.modalInstance);
}, function () {
$log.info('Modal dismissed at: ' + new Date());
$scope.modalInstance = null;
});
}
and here is the /view/login.html
<div class="container">
<div class="row">
<div class="col-md-6 col-lg-2">
<form ng-submit="logIn()" style="margin-top:30px;">
<h3>Log In</h3>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Email"
ng-model="user.username"></input>
</div>
<div class="form-group">
<input type="password"
class="form-control"
placeholder="Password"
ng-model="user.password"></input>
</div>
<button type="submit" class="btn btn-success">Log In</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
<span ><small> Forgot Password</small></span>
</form>
<div class="row">
<div ng-show="error" class="alert alert-danger">
<span>{{ error.message }}</span>
</div>
</div>
</br><br>
</div><!-- closes .col-md-6 -->
</div><!-- closes .row -->
</div><!-- closes .container -->
It's because you have them in a modal - in a .container. Try removing the .container class from the modal.
.container has static widths and not percentages. This is why it's overflowing.
Related
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.
I made a global modal with this
<div id="GlobalModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<style>
#GlobalModal .modal-body .body-content {
margin:0;
width: 100%;
}
</style>
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header" style="background:#337ab7;">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title" style="color:white">Not set...</h4>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary">Save</button>
<button type="button" class="btn btn-warning" data-dismiss="modal">Close</button>
</div>
</div>
</div>
and this is my button for calling the modal
<button id="new-communication" type="button" class="btn btn-info btn-sm">NEW <i class="glyphicon glyphicon-plus"></i></button>
and this is the content
<div class="hidden">
<div id="mc-communication">
<form id="loginForm" class="form-horizontal" role="form" method="POST" action="" >
<div class="form-group">
<label class="col-sm-2 control-label">Type</label>
<div class="col-sm-10">
<select class="form-control selectpicker show-tick" name="SingleSelectFieldType">
<option></option>
<option>Mobile - Private</option>
<option>Mobile - Office</option>
<option>Others</option>
</select>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Value</label>
<div class="col-sm-10 col-md-10">
<input class="form-control" type="tel" id="input-mobile-number" placeholder="" name="MobileNumberFieldType">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<div class="[ form-group ]">
<input type="checkbox" checked />
<span></span><span> </span></label>
<label>Primary</label>
</div>
</div>
</div>
</form>
</div>
</div>
and this is my jQuery of calling the content to get into the modal
class.modal.js
var Modal = {
Me: $('#GlobalModal'),
Title: 'Undefined Title',
Width: { xs: '25%', sm: '40%', md: '55%', lg: '70%', xl: '85%', full: '95%' },
Show: function (params) {
this.Me.find('.modal-body').empty();
this.Me.find('.modal-title').text((this.Title == null) ? this.Title : params.Title);
if(params.Content.substr(0, 1) == '#') { //To Check if content may come from a view or a div
this.Me.find('.modal-body').append($(params.Content).clone());
} else {
this.Me.find('.modal-body').load(params.URI);
}
this.Me.find('.modal-dialog').css('width', this.Width[params.Width]);
this.Me.modal('show');
}
}
and the script to call in my view
$(document).ready(function(){
$('#new-communication').on('click', function(){
Modal.Show({
Title: 'Communication',
Content: '#mc-communication',
Width: 'sm'
});
});
});
The thing is I can see the contents inside my select, but I can't select it and I also got a checkbox there and I can't check it. I tried making a new modal that is not global, but just for the communication, and it worked, I don't know what's wrong with my code.
You will have to reinitialize the selectpicker after appending the html
if(params.Content.substr(0, 1) == '#') { //To Check if content may come from a view or a div
this.Me.find('.modal-body').append($(params.Content).clone());
// This will reinitialize selectpicker. You may need to revalidate this logic since you are appending data and not replacing.
$('.selectpicker').selectpicker();
} else {
this.Me.find('.modal-body').load(params.URI, function() {
// Initialize the selectpicker after loading the data
$('.selectpicker').selectpicker();
});
}
The reason y this is happening is, the html data is dynamic and selectpicker is not initialized in newly added html elements
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.
I am trying to get an animation to work, when you click the search button it should be pulled to the right in order to allow the user to type whatever they want to search for. However, the ng-click doesn't even seem to trigger. I have tried "alert('its working');" several times but nothing pops up. The code is below, any ideas of what the problem could be?
HTML:
<li class="pull-right">
<div>
<!-- ngIf: showNavbarSearch --><div ng-if="showNavbarSearch" class="mat-slide-right pull-right ng-scope">
<form class="search-form form-inline ng-valid pull-left ng-pristine" ng-show="showNavbarSearch" ng-submit="submitNavbarSearch()">
<div class="form-group">
<label class="sr-only" for="search-input">Search</label>
<input type="text" class="form-control" id="search-input" placeholder="Search" autofocus="">
</div>
</form>
</div><!-- end ngIf: showNavbarSearch -->
<div class="pull-right">
<button ng-click="toggleSearch()" class="btn btn-sm btn-link pull-left withoutripple">
<i class="md md-search f20"></i>
</button>
</div>
</li>
JS:
app.directive('navbarSearch', ['$timeout', function ($timeout) {
return {
restrict: 'A',
templateUrl: '/dist/assets/tpl/directives/navbar-search.html',
link: function($scope, element, attrs) {
$scope.showNavbarSearch = false;
$scope.toggleSearch = function () {
$scope.showNavbarSearch = !$scope.showNavbarSearch;
};
$scope.submitNavbarSearch = function(){
$scope.showNavbarSearch = false;
};
}
};
}]);
Does this help:
app.directive('navbarSearch', [ function () {
return {
restrict: 'A',
templateUrl: 'navbar-search.html',
controller: function($scope){
$scope.showNavbarSearch = false;
$scope.mySearch = "";
$scope.submitNavbarSearch = function(myVal){
$scope.mySearch = myVal;
console.log("submitting: " + $scope.mySearch);
$scope.showNavbarSearch = false;
}
$scope.toggleSearch = function(){
$scope.showNavbarSearch = !$scope.showNavbarSearch;
}
},
};
}]);
Template:
<li class="pull-right">
<div ng-if="showNavbarSearch" class="mat-slide-right pull-right ng-scope">
<form class="search-form form-inline ng-valid pull-left ng-pristine" ng-show="showNavbarSearch" ng-submit="submitNavbarSearch(mySearch)">
<div class="form-group">
<label class="sr-only" for="search-input">Search</label>
<input type="text" ng-model="mySearch" placeholder="Search" autofocus="">
</div>
</form>
</div><!-- end ngIf: showNavbarSearch -->
<br />
<div class="pull-right">
<button ng-click="toggleSearch()">
<i class="md md-search f20">Toggle search</i>
</button>
</div>
</li>
Usage:
<div navbar-search>
</div>
I have a simple modal, which contains a form in it. The 'Ok' button should handle success and close the modal whereas the cancel button should just dismiss the modal. If I put the 'Ok' button inside the form tag, the modal instance is shown as undefined in the handler. I need to put the button inside the form for 2 reasons: Design perspective and for ng-submit to work. What could be the issue? Here is the very basic code:
//Modal:
<div class="modal-header">
<h3 class="modal-title">My modal</h3>
</div>
<div class="modal-body">
<form name="modalForm" id="modal-form" class="form-horizontal" role="form" ng-submit="modalOk()" novalidate>
<div class="form-group">
<label class="col-xs-2 control-label">Sample</label>
<div class="col-xs-8" ng-class="{'has-error': modalForm.command.$error.required}">
<input name="command" class="form-control" ng-model="formData.command" maxlength="65" ng-trim="false" required>
</div>
<div class="col-xs-2">
<!-- Modal undefined -- >
<button id="modal-ok" class="btn btn-primary" ng-click="modalOk()" ng-disabled="modalForm.$invalid">Run</button>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<!-- Works here-->
<button id="modal-ok" class="btn btn-primary" ng-click="modalOk()" ng-disabled="modalForm.$invalid">Run</button>
<button class="btn btn-primary site-btn-form" ng-click="modalCancel()">Close</button>
</div>
//Controller code
//.....
$scope.myModal = {};
$scope.launchModal = function() {
//Create a modal for saving the filter
$scope.myModal = $modal.open({
templateUrl : 'views/dialogs/myModal.html',
scope : $scope,
backdrop : 'static'
});
//Save
$scope.modalOk = function() {
//myModal undefined if called from inside the form
$scope.myModal.close();
};
//Cancel the operation
$scope.modalCancel = function() {
$scope.myModal.dismiss();
};
//Handle the modal promise
$scope.myModal.result.then(function() {
console.log('Ok');
}, function() {
console.log('Cancel');
})['finally'](function(){
$scope.myModal = undefined; // Something I tried!
});
};
Any help is appreciated!
You are getting undefined because the modelOk() function is running twice because its also called on ng-submit:
<form name="modalForm" id="modal-form" class="form-horizontal" role="form" ng-submit="modalOk()" novalidate>
You can test this by putting a console.log inside your modalOk() function before the close call.
var app = angular.module('app', ['ui.bootstrap']);
app.controller('myController', function($scope, $modal) {
$scope.myModal = {};
$scope.launchModal = function(num) {
//Create a modal for saving the filter
$scope.myModal = $modal.open({
templateUrl: 'm' + num + '.html',
scope: $scope,
backdrop: 'static'
});
//Save
$scope.modalOk = function() {
console.log("modalOk called");
//myModal undefined if called from inside the form
$scope.myModal.close();
};
//Cancel the operation
$scope.modalCancel = function() {
$scope.myModal.dismiss();
};
//Handle the modal promise
$scope.myModal.result.then(function() {
console.log('Ok');
}, function() {
console.log('Cancel');
})['finally'](function() {
$scope.myModal = undefined; // Something I tried!
});
};
});
<html ng-app='app'>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.0/ui-bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.0/ui-bootstrap-tpls.min.js"></script>
</head>
<body>
<div ng-controller='myController'>
<button ng-click="launchModal(1)">modal1</button>
<button ng-click="launchModal(2)">modal2</button>
</div>
</body>
<script type="text/ng-template" id="m1.html">
<div class="modal-header">
<h3 class="modal-title">My modal</h3>
</div>
<div class="modal-body">
<form name="modalForm" id="modal-form" class="form-horizontal" ng-submit="modalOk()" role="form" novalidate>
<div class="form-group">
<label class="col-xs-2 control-label">Sample</label>
<div class="col-xs-8" ng-class="{'has-error': modalForm.command.$error.required}">
<input name="command" class="form-control" ng-model="formData.command" maxlength="65" ng-trim="false" required>
</div>
<div class="col-xs-2">
<button id="modal-ok" class="btn btn-primary" ng-click="modalOk()" ng-disabled="modalForm.$invalid">Run</button>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary site-btn-form" ng-click="modalCancel()">Close</button>
</div>
</script>
<script type="text/ng-template" id="m2.html">
<div class="modal-header">
<h3 class="modal-title">My modal</h3>
</div>
<div class="modal-body">
<form name="modalForm" id="modal-form" class="form-horizontal" role="form" novalidate>
<div class="form-group">
<label class="col-xs-2 control-label">Sample</label>
<div class="col-xs-8" ng-class="{'has-error': modalForm.command.$error.required}">
<input name="command" class="form-control" ng-model="formData.command" maxlength="65" ng-trim="false" required>
</div>
<div class="col-xs-2">
<button id="modal-ok" class="btn btn-primary" ng-click="modalOk()" ng-disabled="modalForm.$invalid">Run</button>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary site-btn-form" ng-click="modalCancel()">Close</button>
</div>
</script>
</html>