I've been aggressively working on an app that uses AngularJS and Bootstrap. To help, I've included the Bootstrap UI framework. I am successfully opening a dialog and closing the dialog. However, I'm not sure how to actually "get" the data when a user clicks "Save Item".
My Plunker is Here
As shown in the Plunker above, I have my controller defined like this:
var modalInstance = $modal.open({
templateUrl: 'item-dialog.html',
size: 'sm',
controller: function($scope, $modalInstance) {
$scope.saveItem = function () {
alert('Saving...');
alert('ID: ' + $scope.newItem.typeId);
alert('Data: ' + $scope.newItem.data);
};
$scope.cancelItem = function() {
$modalInstance.close(false);
};
}
});
When I go to show the id of the item the user selected, and the text the user entered, it doesn't work. newItem is undefined. However, in the markup, you can see ng-model="newItem.data"
How do I get the information that the user entered in my controller?
Thank you!
You are not passing the result back to the controller opening the modal when you close it, you just need to add this in the modal's controller:
$modalInstance.close($scope.newItem);
See plunk.
Another thing: I've found that if you do not manually initialize objects on the $scope of the modal controllers of angular ui, they do not get bound properly, hence the $scope.newItem={} in the controller of the modal.
Related
In an Angular 1.5 component I'm showing a Material mdDialog, which itself has an embedded component:
$mdDialog.show({
controller: function($scope, $log) {
$scope.notify=function() {
$log.debug("need to cancel");
$mdDialog.hide();
}
},
template: "<md-dialog aria-label='Add Foobar'><new-foobar-panel on-cancel='notify()'></new-foobar-panel></md-dialog>",
targetEvent: ev,
clickOutsideToClose: true,
fullscreen: true
});
When the embedded component invokes the onCancel() callback, the dialog's controller closes the dialog by using $mdDialog.hide().
But that seems sort of messy. The documentation for $mdDialog says that it will close the last opened dialog, but that seems sort of lazy and wishy-washy. I'm sure there is some case with many components and dialogs that would cause this to fail. I'm inside the controller of the dialog after all --- shouldn't there be a reference to the dialog instance I can use to close it directly?
I tried this:
var dialog = $mdDialog.show({
controller: function($scope, $log) {
$scope.notify=function() {
$log.debug("need to cancel");
dialog.hide();
}
But that doesn't work; perhaps a promise is returned instead of a dialog.
So am I stuck with calling $mdDialog.hide() (the global service!!) and hoping that refers to the dialog I'm working with? (That's not very good modularization.)
Actually the documentation says
// Close the specified dialog instance and resolve with 'finished' flag
// Normally this is not needed, just use '$mdDialog.hide()' to close
// the most recent dialog popup.
function closeAlert() {
$mdDialog.hide( alert, "finished" );
alert = undefined;
}
where alert is the dialog instance previously build. So if you actually need to refer to a specific instance of dialog and not the last one, you can use the above method to close it.
I've opened a modal using $modal.open and taking the return value which is a modal instance to a variable. When I try to close the $modal using that modal instance's either dismiss() or close() methods it is not closing. When I tried to check the $$state.value for the modal instance that I've taken in to variable I don't see it present and $$state.state is also coming as 0. I couldn't understand why is it happening so, could this be reason why I'm not able to close the modal. I could clearly see the modal is opened. Does anyone know why is it so? Has anyone faced the similar issue?
var modalOpened = $modal.open({
templateUrl: modalOptions.template,
controller: modalOptions.cntrlr,
windowClass: modalOptions.winClass,
backdrop: modalOptions.backdrop,
resolve: {
modalParams: function () {
return params;
}
}
});
modalOpened.dismiss('cancel');
I have a text box with a search Button as below
On clicking the search button, I am calling SearchController.search method and
my expectation is it will display a new page with the result.
$scope.search = function () {
$http.get('data/results.json').success(function (data) {
$scope.activities = data;
$state.go('results',data);
});
and my app.js looks as below
var myApp = angular.module('MyApp', ['ui.router']);
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('results', {
url: '/results',
templateUrl: 'result.html',
controller: 'SearchController'
});
$urlRouterProvider.otherwise('/');
});
But when I click on search button, nothing happens and url only changes to l/#/results .
I am not having any ui-view in search page and I want to go results page to display the result. How to get this fixed? what is the mistake I am doing?
You can't send a not mapped object into $state.go.
Looking the API: http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state
Another similar problem: AngularJS: Pass an object into a state using ui-router
If you want to display it on a different page, use the "ui-sref" on the html to navigate to the new page and call ng-init on the page e.g
<button type="button" ui-sref="results">
and on result.html, you can call the init on the parent node such as
<section ng-init="search()">
.....
....
</section>
and your controller will look like this now
$scope.search = function () {
$http.get('data/results.json').success(function (data) {
$scope.activities = data;
});
With ui-router, state changes happens and different view is displayed based on state. So , when ui-router is used , moving from one page to another page is a wrong perception . We move from one state to another state and hence parameter passing can be done using "services".
I've got a modal with a registration form. The same form should be displayed at the bottom of the landing page not in a modal.
Currently my controller that handles registration modal takes $modalInstance as one of its parameters along $scope etc. If I add ng-controller="SignUpCtrl" to an element in the landing page, it doesn't work, because the controller wasn't created via $modal.open method and so Angular complains about Unknown provider: $modalInstanceProvider <- $modalInstance.
I've got a service for registering users (authService.signUp(data).then/catch...), but the controller itself does a bit more - handles input, emits events (e.g. with translated error messages), sets cookies etc.
What's the best way to handle such case without duplicating almost whole controller code? Should I move the code from controller into yet another, higher-level service?
After struggling for a long while I found a easier trick to reuse our Controller for both modal and normal case.
I found that we can pass caller's scope to modal controller, so I pushed modalInstance into $scope and passed it to the modal controller.
Now you don't have unknown provider problem because $scope is a well known one.
Below is an example:
CallerController = function($rootScope, ...) {
var modalScope = $rootScope.$new();
modalScope.modalInstance = $modal.open({
templateUrl: tempUrl,
controller: ReusableModalController,
scope: modalScope // <- This is it!
});
modalScope.modalInstance.result.then(function (result) {
// Closed
}, function () {
// Dismissed
});
};
ReusableModalController = function($scope, ...){
var dataToSendBack = 'Hello World';
$scope.modalInstance.close(dataToSendBack);
};
Cheers!
If you are using ui-router you can easily use the resolve from ui-router to provide a $uibModalInstance (was $modalInstance before):
$stateProvider
.state('conductReview', {
url: '/review',
templateUrl: '/js/templates/review.html',
controller: 'yourController',
resolve: {
$uibModalInstance: function () { return null; } // <- workaround if you want to use $uibModalInstance in your controller.
}
})
That way you can use your modal controller like a normal controller. If you inject $uibModalInstance in your controller it will be null.
If you want to use same controller for both modal form as well as landing page form, make use of
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
You can get all the data from modal form in selectedItem and use this in landing page form.
Also, how do you open the modal. If it is through a button, bind that ng-model to open modal using $modal.open.Don't create separate controller for your modal.Use the same one as your landing page. This way you can use 1 controller to open modal as well as other function after the modal is closed.
PS: Code snippet given here is from angular ui's page. Check that page's documentation for selectedItem
I am working with AngularJS and UI Bootstrap
I open a modal for the user login.
It works fine, but the problem is when I try to return to the first page.
Seems like when the modal is closed, but the controller ('LoginInstanceCtrl') is still there and is listening for the event '$routeChangeSuccess'. So the modal doesn't exist now and I get an error.
.controller('LoginInstanceCtrl', ['$modalInstance', '$scope', function($modalInstance, $scope) {
//do stuff
$scope.$on('$routeChangeSuccess', function ($event, current) {
$modalInstance.close();
});
}])
Thanks
Edit
Here I put a link to the full code, the only difference with the real code is that in the modal I have an iFrame and the routing to the "second page" is made there.
https://github.com/agusgambina/angularModalError
Thank you in advance