I have a little Angularjs application making use of $mdDialog to pop up a html page that has one text input on it
I want to be able to return the value the user types into the input back to the parent scope. I'm unsure how to do this.
This is what I have so far
$scope.showNewTeamDialog = function () {
$mdDialog.show({
controller: NewTeamDialogController,
templateUrl: 'NewTeam.html',
locals: { newTeamName: $scope.newTeamName },
parent: angular.element(document.body)
})
};
function NewTeamDialogController($scope, $mdDialog, newTeamName) {
$scope.closeDialog = function(newTeamName) {
// before closing I want to set $scope.newTeamName to whatever the user typed in the text on the dialog pop up
$mdDialog.hide();
}
}
The cleanest solution that I use is sending the data back when $destroy is fired. This is clean because it handles all cases for why the dialog is closing, ie when there's a click outside or the escape key is pressed or $mdDialog.hide() is called.
app.controller('CallerController', ['$scope', '$mdDialog',
function($scope, $mdDialog) {
$scope.some_event_listener = function(e) {
$mdDialog.show({
parent: angular.element(document.body),
controller: SomeDialogController,
templateUrl: 'some_dialog.html',
locals: {
on_complete: function(data_from_dialog_controller) {
console.log(data_from_dialog_controller);
}
}
});
};
}]);
app.controller('SomeDialogController', ['$scope', '$mdDialog', 'on_complete',
function($scope, $mdDialog, on_complete) {
$scope.$on('$destroy', function() {
on_complete($scope.some_input_model);
});
}]);
While this wouldn't be right before the dialog closed, I would probably do this using the .then part of the dialog.show promise. Here is a codepen with using one of the ngMaterial examples to modify a variable on close: https://codepen.io/mckenzielong/pen/veBrgE. Basically, something like this:
$scope.showNewTeamDialog = function () {
$mdDialog.show({
controller: NewTeamDialogController,
templateUrl: 'NewTeam.html',
locals: { newTeamName: $scope.newTeamName },
parent: angular.element(document.body)
})
.then((newTeamName) => {
$scope.newTeamName = newTeamName;
})
};
function NewTeamDialogController($scope, $mdDialog, newTeamName) {
$scope.closeDialog = function(newTeamName) {
$mdDialog.hide(newTeamName);
}
}
Alternatively you could do something a little more ugly, and share the scope like this: https://codepen.io/mckenzielong/pen/zEOaRe. One downside to this is your code will become confusing very quickly. Something like this:
$scope.showNewTeamDialog = function () {
$mdDialog.show({
controller: NewTeamDialogController,
templateUrl: 'NewTeam.html',
scope: $scope.newTeamName,
parent: angular.element(document.body)
})
.then(() => {
})
};
function NewTeamDialogController($scope, $mdDialog) {
$scope.closeDialog = function(newTeamName) {
$scope.newTeamName = newTeamName
$mdDialog.hide();
}
}
Related
I want to show a loading animation during state transitions in a Angular ui-router application.
Check out the following code
$stateProvider
.state("app",
{
abstract: true,
url: "",
template: "<ui-view/>",
controller: "appController",
controllerAs: "vm",
resolve: {
result_data_abstract: function ($q, $timeout))
{
var deferred = $q.defer();
$timeout(function () {
deferred.resolve("from abstract");
}, 500);
return deferred.promise;
}
}
})
.state("app.real",
{
url: "/real/{id}",
templateUrl: "somepath/template.html",
controller: "realController",
controllerAs: "vm",
resolve: {
result_data_real: function ($q, $timeout))
{
var deferred = $q.defer();
$timeout(function () {
deferred.resolve("from real");
}, 500);
return deferred.promise;
}
}
}
.state("app.real2",
{
url: "/real2/{id}",
templateUrl: "somepath2/template.html",
controller: "real2Controller",
controllerAs: "vm",
// Note no resolve
})
So both concrete states inherit from the abstract one - the abstract class has a resolve.
However, only one of the real (concrete) states has a resolve of its own.
My goal is to show a loading animation during transitions using the following code:
$scope.$on("$stateChangeStart", function (event, toState) {
console.log("stateChangeStart", toState);
if (toState.resolve) {
showSpinner();
}
});
$scope.$on("$stateChangeSuccess", function (event, toState) {
console.log("stateChangeSuccess", toState);
if (toState.resolve) {
hideSpinner();
}
});
Since the abstract state the concrete states inherit from has a resolve, I expected 'toState.resolve' to be true every time, getting the resolves from the abstract parent state it inherits from.
That however is not the case - when I load app.real2, 'toState.resolve' is null.
Is there any way to make this work?
Are you loading an entire "page"? If so I do this by calling it in run.
app.run(function($rootScope) {
$rootScope.$on("$stateChangeStart", function () {
console.log("stateChangeStart");
showSpinner();
});
$rootScope.$on("$viewContentLoaded", function () {
console.log("stateChangeSuccess");
hideSpinner();
});
});
I don't use $stateChangeSuccess and toState but it looks like it might work as well.
I'm new to angular, trying to use angular material to create a popup dialog. I'm confused with the promise and $scope here. If I click the dialog button, console will show 'created' and then no window will popup.
But if I change it to .then(createFolder, ..), function createFolder(){...}, everything is ok.
$scope.createFolder = function(ev) {
$mdDialog.show({
controller: dialogController,
templateUrl: 'dialog_new_folder.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true,
})
.then($scope.createFolder, $scope.cancelDialog);
};
$scope.createFolder = function() {
console.log('created')
}
$scope.cancelDialog = function() {
console.log('cancelled')
}
function dialogController($scope, $mdDialog) {
$scope.folderName = '';
$scope.hide = function() {
$mdDialog.hide();
}
$scope.cancel = function() {
$mdDialog.cancel();
}
}
You're using $scope.createFolder for both the function to call when the dialog is closed successfully, and for the function to show the dialog. Your second declaration is overwriting your first. Rename one of them.
I have one controller named controller1 which has bellow code to open modal dialog
var openDilaogBox = function () {
$scope.modalInstance = $modal.open({
templateUrl : 'templatepth here',
controller : controller2,
keyboard : false,
backdrop : false
});
}
I want to use controller2 for this modal dialog. Please help.
Just use the name of controller2. For example, if controller2's name is ModalCtrl, you can do it like this:
var openDialogBoxWithParams = function (param) {
var modalInstance = $modal.open({
templateUrl: '../path/to/modal.html',
controller: 'ModalCtrl',
scope: $scope,
resolve: { Param: function () { return param } }
});
modalInstance.result.then(function (returnValue) {
$scope.someData = returnValue;
}, function () { });
};
Just make sure that ModalCtrl is injected to the app properly, i.e.
app.controller('ModalCtrl', ['$scope', ...
I'm using $mdDialog in my application, but would like to use it as a "confirm" dialog instead of normal one. This means, the code flow should not proceed until user clicks on one of the two buttons in confirm dialog. I noticed that $mdDialog.confirm() can be used, but I'm not sure how to use it with custom templateUrl and a corresponding controller as the dialog's content.
Following is what I have written which works fine as far as dialog is concerned, but the code flow doesn't stop after the dialog is opened. It should stop until Ok or Cancel is clicked by the user.
$mdDialog.show({
controller: 'incomingCallDialogController',
templateUrl: 'app/components/others/incomingCallDialog/incomingCallDialog.tpl.html',
locals: {message: message},
parent: angular.element(document.body)
}).then(function (answer) {
console.log("here");
}
Basically it would be something like:
var confirm = $mdDialog.confirm({
controller: 'incomingCallDialogController',
templateUrl: 'app/components/others/incomingCallDialog/incomingCallDialog.tpl.html',
locals: {message: message},
parent: angular.element(document.body)
})
$mdDialog.show(confirm).then(function() {
console.log("here");
}
Here's a codepen.
Angular Js confirm dialog design using Matrial Ui and with icon/images
Screenshot : https://i.stack.imgur.com/rghwX.png
Online demo : https://codepen.io/MuhammadRizwan/pen/aYBKqW?editors=1010
try this
$scope.showTimContent = function (tim) {
$mdDialog.show({
controller: ['$scope', '$mdDialog', 'tim', $scope.ViewTimContentCtrl],
templateUrl: 'wgt/tim/TimContentDialog.html',
locals: {'tim': tim},
clickOutsideToClose: true,
});
};
$scope.ViewTimContentCtrl = function ($scope, $mdDialog, tim) {
$scope.tim = tim;
$scope.hide = function () {
$mdDialog.hide();
};
$scope.cancel = function () {
$mdDialog.cancel();
};
};
i had to replace my md-dialog with an angular model UI bootstrap. in the md-dialog, i used the locals attribute to send anguler.copy, from the main controller into the dialog controller.
my question is, how do i get the same result with modal UI bootstrap?
md-dialog code (the old version)
$scope.notefullScreen=function(event){
$mdDialog.show({
controller: DialogNoteFullscreenController,
templateUrl: 'views/schedule/note-fullscreen.html',
targetEvent:event,
locals: {
editNote: angular.copy($scope.noteEdit),
editPtivacy:angular.copy($scope.privacyOptions),
detailsFull:$scope.details
}
}).then(function () {
}, function () {
});
modal ui code: ( in progress new version, what i have so far)
$scope.notefullScreenNew = function (event) {
var modalInstance = $modal.open({
templateUrl: 'views/schedule/schedule-extended-note-popup.html',
controller: ScheduleService.NotePopupCtrl,
targetEvent: event,
resolve: {
editNote: function () { return angular.copy($scope.noteEdit); },
editPtivacy: function() { return angular.copy($scope.privacyOptions); },
detailsFull: function(){return $scope.details;}
// locals: {
// editNote: angular.copy($scope.noteEdit),
// editPtivacy: angular.copy($scope.privacyOptions),
// detailsFull: $scope.details
// attachmentFull:angular.copy($scope.attachment)
}
});
modalInstance.result.then(function () {
}, function () {
});
};
angular-ui-bootstrap can resolve locals for the modal controller through the resolve attribute. These will then be available to your modal controller function as function parameters.
To adapt this to your scenario, it would become:
var modalInstance = $modal.open({
templateUrl: 'views/schedule/schedule-extended-note-popup.html',
controller: ScheduleService.NotePopupCtrl,
targetEvent: event,
resolve: {
editNote: function()( {
return angular.copy($scope.noteEdit);
},
editPtivacy: function() {
return angular.copy($scope.privacyOptions)
},
detailsFull: function() {
return $scope.details;
}
}
});
These will then be passed into your NotePopupCtrl as function parameters with the same name (just like the injections);
Sidenotes: I assume your attribute editPtivacy was supposed to be editPrivacy, also I don't think angular-ui-bootstrap supports the targetEvent attribute.