I have a html page there is one button. on click this button a angular modal pop is open. we have sent some data from parent window to pop window. There are three kendo dropdown on pop window. data is sent from parent window to popup will be selected value in drop down. but data sent, becomes blank on load of pop window, even data successfully sent to pop window..
My parent page code is below :
$scope.openPOPWindow = function (condition) {
var objRegelDetails = {
//param1: $scope.modelObject[condition.ParameterFejl1Model],
//param2: $scope.modelObject[condition.ParameterFejl2Model],
//param3: $scope.modelObject[condition.ParameterFejl3Model],
param1: '13',
param2: '14',
param3: '15',
conditionKode: condition.ConditionKode
};
var modalInstance = $modal.open({
backdrop: 'static',
templateUrl: './RuleEngine/UI/RegelConditionPopUp',
controller: RegelContrl.RegelConditionController,
keyboard: false,
resolve: {
items: function () {
return objRegelDetails;
}
}
});
modalInstance.result.then(function (selectedItem) {
if (!IsNullorEmpty(selectedItem)) {
alert(selectedItem.Param1);
}
}, function () {
});
};
and POP window controller is below :
var adm = angular.module('AdminModule');
adm.controller('RegelConditionPopUpCtrl', ['$scope', 'RegelService', '$q', '$rootScope', '$modalInstance', 'items', 'DirtyFlagPopup', 'SagService', 'localize', 'toaster', 'ValidationService',
function ($scope, RegelService, q, $rootScope, $modalInstance, items, DirtyFlagPopup, SagService, localize, toaster, ValidationService) {
function loadhandlingType() {
var paramTypes = RegelService.GetParamTypes();
//angular.element('#dvLoadingUA').show();
q.all([paramTypes]).then(function (responses) {
if (responses[0].length > 0) {
$scope.drpParamType.data(responses[0]);
}
else {
$scope.drpParamType.data([]);
}
//angular.element('#dvLoadingUA').hide();
});
};
$scope.cancel = function () {
$modalInstance.close();
};
$scope.PushRegelConditionParamData = function () {
var selectedData = {
Param1: '',
Param2: '',
Param3: ''
};
selectedData.Param1 = angular.element('#ddlparameterOption1' + $scope.RegelConditionUID).val();
selectedData.Param2 = angular.element('#ddlparameterOption2' + $scope.RegelConditionUID).val();
selectedData.Param3 = angular.element('#ddlparameterOption3' + $scope.RegelConditionUID).val();
$modalInstance.close(selectedData);
};
$scope.initializedDropDown = function () {
$scope.drpHandlingType = new kendo.data.DataSource({
data: [],
type: "json",
});
$scope.drpHandlingTypeOption = {
dataSource: $scope.drpHandlingType,
dataTextField: FindRegelEnum.TextField,
dataValueField: FindRegelEnum.ValueField
};
$scope.drpParamType = new kendo.data.DataSource({
data: [],
type: "json",
});
$scope.drpParamTypeOption = {
dataSource: $scope.drpParamType,
optionLabel: localize.getLocalizedString("_RE_Home_DefaultSelect_"),
dataTextField: FindRegelEnum.TextField,
dataValueField: FindRegelEnum.ValueField
};
loadhandlingType();
};
$scope.InitializeRC = function () {
$scope.RegelConditionUID = GetUID();
$scope.ModelData = {
Parameter1: '',
Parameter2: '',
Parameter3: ''
};
$scope.initializedDropDown();
$scope.ModelData.Parameter1 = items.param1,
$scope.ModelData.Parameter2 = items.param2,
$scope.ModelData.Parameter3 = items.param3
};
}]);
but problem is that on html we can see value for ModelData.Parameter2 for a second and than it disappear...
please tell me why scope variable not retain their values
Related
I'm trying to cleanup code of one of my controllers which became too big. First I have decided to move attendee registration, which uses AngularJS Material mdDialog, to the service.
Original (and working) controller code looks like:
myApp.controller('RegistrationController', ['$scope','$routeParams','$rootScope','$location','$filter','$mdDialog', function($scope, $routeParams, $rootScope, $location, $filter, $mdDialog){
var attendee = this;
attendees = [];
...
$scope.addAttendee = function(ev) {
$mdDialog.show({
controller: DialogController,
templateUrl: 'views/regForm.tmpl.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true,
controllerAs: 'attendee',
fullscreen: $scope.customFullscreen, // Only for -xs, -sm breakpoints.
locals: {parent: $scope}
})
.then(function(response){
attendees.push(response);
console.log(attendees);
console.log(attendees.length);
})
};
function DialogController($scope, $mdDialog) {
var attendee = this;
$scope.hide = function() {
$mdDialog.hide();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.save = function(response) {
$mdDialog.hide(response);
};
}
}]);
and the code for the controller after separation:
myApp.controller('RegistrationController', ['$scope','$routeParams','$rootScope','$location','$filter','$mdDialog','Attendees', function($scope, $routeParams, $rootScope, $location, $filter, $mdDialog, Attendees){
...
$scope.attendees= Attendees.list();
$scope.addAttendee = function (ev) {
Attendees.add(ev);
}
$scope.deleteAttendee = function (id) {
Attendees.delete(id);
}
}]);
New service code looks like:
myApp.service('Attendees', ['$mdDialog', function ($mdDialog) {
//to create unique attendee id
var uid = 1;
//attendees array to hold list of all attendees
var attendees = [{
id: 0,
firstName: "",
lastName: "",
email: "",
phone: ""
}];
//add method create a new attendee
this.add = function(ev) {
$mdDialog.show({
controller: DialogController,
templateUrl: 'views/regForm.tmpl.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true,
controllerAs: 'attendee',
fullscreen: this.customFullscreen, // Only for -xs, -sm breakpoints.
//locals: {parent: $scope}
})
.then(function(response){
attendees.push(response);
console.log(attendees);
console.log(attendees.length);
})
};
//simply search attendees list for given id
//and returns the attendee object if found
this.get = function (id) {
for (i in attendees) {
if (attendees[i].id == id) {
return attendees[i];
}
}
}
//iterate through attendees list and delete
//attendee if found
this.delete = function (id) {
for (i in attendees) {
if (attendees[i].id == id) {
attendees.splice(i, 1);
}
}
}
//simply returns the attendees list
this.list = function () {
return attendees;
}
function DialogController($mdDialog) {
this.hide = function() {
$mdDialog.hide();
};
this.cancel = function() {
$mdDialog.cancel();
};
this.save = function(response) {
$mdDialog.hide(response);
};
}
}]);
but I'm not able to "save" from the spawned mdDialog box which uses ng-click=save(attendee) neither close the dialog box.
What I'm doing wrong?
I'm not able to "save" from the spawned mdDialog box which uses ng-click=save(attendee) neither close the dialog box.
When instantiating a controller with "controllerAs" syntax, use the name with which it is instantiated:
<button ng-click="ctrl.save(ctrl.attendee)">Save</button>
this.add = function(ev) {
$mdDialog.show({
controller: DialogController,
templateUrl: 'views/regForm.tmpl.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true,
controllerAs: ̶'̶a̶t̶t̶e̶n̶d̶e̶e̶'̶ 'ctrl',
fullscreen: this.customFullscreen, // Only for -xs, -sm breakpoints.
//locals: {parent: $scope}
})
.then(function(response){
attendees.push(response);
console.log(attendees);
console.log(attendees.length);
return response;
});
To avoid confusion, choose a controller instance name that is different from the data names.
$scope is not available to be injected into a service when it's created. You need to refactor the service and its methods so that you don't inject $scope into it and instead pass the current scope to the service methods when you call them.
I actually have a notification module that I inject which uses $mdDialog. Below is the code for it. Perhaps it will help.
(() => {
"use strict";
class notification {
constructor($mdToast, $mdDialog, $state) {
/* #ngInject */
this.toast = $mdToast
this.dialog = $mdDialog
this.state = $state
/* properties */
this.transitioning = false
this.working = false
}
openHelp() {
this.showAlert({
"title": "Help",
"textContent": `Help is on the way for ${this.state.current.name}!`,
"ok": "OK"
})
}
showAlert(options) {
if (angular.isString(options)) {
var text = angular.copy(options)
options = {}
options.textContent = text
options.title = " "
}
if (!options.ok) {
options.ok = "OK"
}
if (!options.clickOutsideToClose) {
options.clickOutsideToClose = true
}
if (!options.ariaLabel) {
options.ariaLabel = 'Alert'
}
if (!options.title) {
options.title = "Alert"
}
return this.dialog.show(this.dialog.alert(options))
}
showConfirm(options) {
if (angular.isString(options)) {
var text = angular.copy(options)
options = {}
options.textContent = text
options.title = " "
}
if (!options.ok) {
options.ok = "OK"
}
if (!options.cancel) {
options.cancel = "Cancel"
}
if (!options.clickOutsideToClose) {
options.clickOutsideToClose = false
}
if (!options.ariaLabel) {
options.ariaLabel = 'Confirm'
}
if (!options.title) {
options.title = "Confirm"
}
return this.dialog.show(this.dialog.confirm(options))
}
showToast(toastMessage, position) {
if (!position) { position = 'top' }
return this.toast.show(this.toast.simple()
.content(toastMessage)
.position(position)
.action('OK'))
}
showYesNo(options) {
options.ok = "Yes"
options.cancel = "No"
return this.showConfirm(options)
}
uc() {
return this.showAlert({
htmlContent: "<img src='img\\underconstruction.jpg'>",
ok: "OK",
title: "Under Construction"
})
}
}
notification.$inject = ['$mdToast', '$mdDialog', '$state']
angular.module('NOTIFICATION', []).factory("notification", notification)
})()
Then inject notification (lower case) into my controllers in order to utilize it. I store notification in a property of the controller and then call it with something like this:
this.notification.showYesNo({
clickOutsideToClose: true,
title: 'Delete Customer Setup?',
htmlContent: `Are you sure you want to Permanently Delete the Customer Setup for ${custLabel}?`,
ariaLabel: 'Delete Dialog'
}).then(() => { ...
this.notification.working = true
this.ezo.EDI_CUSTOMER.remove(this.currentId).then(() => {
this.primaryTab = 0
this.removeCustomerFromList(this.currentId)
this.currentId = 0
this.notification.working = false
}, error => {
this.notification.working = false
this.notification.showAlert({
title: "Error",
htmlContent: error
})
})
I'm trying to store captured data from the form in an object using angular-material for dialog box with the form to capture.
Related part of the controller looks like
$scope.attendees = [{
firstName: "",
lastName: "",
email: "",
phone: ""
}];
$scope.addAttendee = function(ev) {
$mdDialog.show({
controller: DialogController,
templateUrl: 'views/regForm.tmpl.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true,
fullscreen: $scope.customFullscreen // Only for -xs, -sm breakpoints.
})
};
function DialogController($scope, $mdDialog) {
$scope.hide = function() {
$mdDialog.hide();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.saveAttendee = function(attendee) {
str = JSON.stringify(attendee, null, 4);
$mdDialog.hide(attendee);
console.log('Attendee ' + str);
$scope.attendees.push(attendee);
console.log('Attendees ' + $scope.attendees);
};
}
Output for Attendee is correct but later it crashed on push(attendee) as Cannot read property 'push' of undefined or push will overwrite added previously data (based on given answer)
Any tips on that?
Just move the $scope.attendees inside the controller.
function DialogController($scope, $mdDialog) {
$scope.attendees = [{
firstName: "",
lastName: "",
email: "",
phone: ""
}];
$scope.hide = function() {
$mdDialog.hide();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.saveAttendee = function(attendee) {
str = JSON.stringify(attendee, null, 4);
$mdDialog.hide(attendee);
console.log('Attendee ' + str);
$scope.attendees.push(attendee);
console.log('Attendees ' + $scope.attendees);
};
}
What you saying about to send data from controller who calls the mdDialog, a alld a plnkr with a basic example.
example plnkr
cour code modificated should be.
function DialogController($scope, $mdDialog, attendees) {
$scope.attendees = attendees;
$scope.hide = function() {
$mdDialog.hide();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.saveAttendee = function(attendee) {
str = JSON.stringify(attendee, null, 4);
$mdDialog.hide(attendee);
console.log('Attendee ' + str);
$scope.attendees.push(attendee);
console.log('Attendees ' + $scope.attendees);
};
}
and in the controller who calls for example
$modal.show({
// configuration like you have.
}).then(function(response){
//when hide the modal
$scope.attendees = response;
});
Check if out if this help.
If someone will need "fixed" code for the dialog box controller is below
var attendee = this;
attendees = [];
$scope.addAttendee = function(ev) {
$mdDialog.show({
controller: DialogController,
templateUrl: 'views/regForm.tmpl.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true,
controllerAs: 'attendee',
fullscreen: $scope.customFullscreen, // Only for -xs, -sm breakpoints.
locals: {parent: $scope}
})
.then(function(response){
attendees.push(response);
console.log(attendees);
console.log(attendees.length);
})
};
function DialogController($scope, $mdDialog) {
var attendee = this;
$scope.hide = function() {
$mdDialog.hide();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.save = function(response) {
$mdDialog.hide(response);
};
}
I am using the following code to add markers in leaflet:
.controller('MapController',
[ '$scope',
'$cordovaGeolocation',
'$stateParams',
'$ionicModal',
'$ionicPopup',
'$http',
function(
$scope,
$cordovaGeolocation,
$stateParams,
$ionicModal,
$ionicPopup,
$http
) {
$scope.$on("$stateChangeSuccess", function() {
$scope.map = {
defaults: {
tileLayer: 'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
maxZoom: 18,
zoomControlPosition: 'bottomleft'
},
markers : {},
events: {
map: {
enable: ['context'],
logic: 'emit'
}
}
};
$scope.locate();
});
$scope.locate = function(){
$scope.map.center = {
lat : location.lat,
lng : location.lng,
zoom : 12,
};
var Location = function() {
if ( !(this instanceof Location) ) return new Location();
this.lat = "";
this.lng = "";
this.name = "";
};
$ionicModal.fromTemplateUrl('templates/addLocation.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.map.markers.push=({
lat:35.654,
lng:73.244,
message:'demo 1'
})
$scope.map.markers.push=({
lat:38.654,
lng:73.244,
message:'demo 2'
})
$scope.$on('leafletDirectiveMap.click', function(event, locationEvent){
$scope.newLocation = new Location();
$scope.newLocation.lat = locationEvent.leafletEvent.latlng.lat;
$scope.newLocation.lng = locationEvent.leafletEvent.latlng.lng;
$scope.modal.show();
});
$scope.saveLocation = function(lat, lang) {
//LocationsService.savedLocations.push($scope.newLocation);
//alert(lat + " - " + lang);
var link = 'http://192.168.5.110/server/addLocation.php';
var json1 = {l1 : lat, l2 : lang , l3: sessionStorage.getItem('loggedin_phone')};
$http.post(link, { data: json1 })
.then(function (res){
$scope.response = res.data.result;
if($scope.response.created=="1"){
$scope.title="Thank You";
$scope.template="Mobile Toilet Added!";
//no back option
/*
$ionicHistory.nextViewOptions({
disableAnimate: true,
disableBack: true
});
$state.go('login', {}, {location: "replace", reload: true});
*/
}else if($scope.response.exists=="1"){
$scope.title="Duplication";
$scope.template="This Location is already added!";
}else{
$scope.title="Failed";
$scope.template="Contact Our Technical Team";
}
var alertPopup = $ionicPopup.alert({
title: $scope.title,
template: $scope.template
});
});
$scope.modal.hide();
};
$cordovaGeolocation
.getCurrentPosition()
.then(function (position) {
$scope.map.center.lat = position.coords.latitude;
$scope.map.center.lng = position.coords.longitude;
$scope.map.center.zoom = 18;
$scope.map.markers.now = {
lat:position.coords.latitude,
lng:position.coords.longitude,
focus: true,
draggable: false,
//message: ''
};
}, function(err) {
// error
console.log("Location error!");
console.log(err);
});
};
}]);
But only the demo2 marker is displaying.
Is there a way to show multiple markers on the leaflet map by using JSON data of latitudes and longitudes loaded from API?
<leaflet defaults="defaults" event-broadcast="events" lf-center="center" markers="markers" layers="layers" id="global-map" width="100%" height="240px"></leaflet>
<leaflet defaults="defaults2" event-broadcast="events2" lf-center="center2" markers="markers2" layers="layers2" id="global-map2" width="100%" height="240px"></leaflet>
I am new to ionic.
I have a function in my controller. I want to call that function from another function which has ionic popup. but, the function call does not happen.
Here is the code
Function with ionic popup
$scope.show = function() {
var myPopup = $ionicPopup.show({
templateUrl: 'views/d.html',
cssClass: 'custom-ipopup',
title: 'Welcome to myapp',
subTitle: 'enter username.',
scope: $scope,
buttons: [
{ text: '<b>Cancel</b>' },
{
text: 'Test',
type: 'button-positive',
onTap: function(e) {
e.preventDefault();
scope.usernameCheck = usernameLookup();
console.log(scope.usernameCheck); //prints undefined
}
}
]
});
};
usernameLookup() function i am calling from $ioninPopup.show()'s onTap()
$scope.usernameLookup = function() {
console.log('inside usernameLookup()');
$scope.lookingDB = true;
$scope.unamePresent = 3;
$http({
method: 'GET',
url: $rootScope.cred.url + '/api',
params: {
}
}).success(function(d) {
$scope.lookingDB = false;
$scope.unamePresent = 1;
return $scope.unamePresent
}).error(function(d) {
$scope.lookingDB = false;
$scope.unamePresent = 2;
return $scope.unamePresent
});
};
Can someone tell me why is it not calling usernameLookup() function? Both these methods are in same controller.
I have a main controller in which I load data into a "angular-ui-grid" and where I use a bootstrap modal form to modify detail data, calling ng-dlbclick in a modified row template :
app.controller('MainController', function ($scope, $modal, $log, SubjectService) {
var vm = this;
gridDataBindings();
//Function to load all records
function gridDataBindings() {
var subjectListGet = SubjectService.getSubjects(); //Call WebApi by a service
subjectListGet.then(function (result) {
$scope.resultData = result.data;
}, function (ex) {
$log.error('Subject GET error', ex);
});
$scope.gridOptions = { //grid definition
columnDefs: [
{ name: 'Id', field: 'Id' }
],
data: 'resultData',
rowTemplate: "<div ng-dblclick=\"grid.appScope.editRow(grid,row)\" ng-repeat=\"(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name\" class=\"ui-grid-cell\" ng-class=\"{ 'ui-grid-row-header-cell': col.isRowHeader }\" ui-grid-cell></div>"
};
$scope.editRow = function (grid, row) { //edit row
$modal.open({
templateUrl: 'ngTemplate/SubjectDetail.aspx',
controller: 'RowEditCtrl',
controllerAs: 'vm',
windowClass: 'app-modal-window',
resolve: {
grid: function () { return grid; },
row: function () { return row; }
}
});
}
});
In the controller 'RowEditCtrl' I perform the insert/update operation and on the save function I want to rebind the grid after insert/update operation. This is the code :
app.controller('RowEditCtrl', function ($modalInstance, $log, grid, row, SubjectService) {
var vm = this;
vm.entity = angular.copy(row.entity);
vm.save = save;
function save() {
if (vm.entity.Id === '-1') {
var promisePost = SubjectService.post(vm.entity);
promisePost.then(function (result) {
//GRID REBIND ?????
}, function (ex) {
$log.error("Subject POST error",ex);
});
}
else {
var promisePut = SubjectService.put(vm.entity.Id, vm.entity);
promisePut.then(function (result) {
//row.entity = angular.extend(row.entity, vm.entity);
//CORRECT WAY?
}, function (ex) {
$log.error("Subject PUT error",ex);
});
}
$modalInstance.close(row.entity);
}
});
I tried grid.refresh() or grid.data.push() but seems that all operation on the 'grid' parameter is undefinied.
Which is the best method for rebind/refresh an ui-grid from a bootstrap modal ?
I finally solved in this way:
In RowEditCtrl
var promisePost = SubjectService.post(vm.entity);
promisePost.then(function (result) {
vm.entity.Id = result.data;
row.entity = angular.extend(row.entity, vm.entity);
$modalInstance.close({ type: "insert", result: row.entity });
}, function (ex) {
$log.error("Subject POST error",ex);
});
In MainController
modalInstance.result.then(function (opts) {
if (opts.type === "insert") {
$log.info("data push");
$scope.resultData.push(opts.result);
}
else {
$log.info("not insert");
}
});
The grid that received inside RowEditCtrl is not by reference, so it wont help to refresh inside the RowEditCtrl.
Instead do it right after the modal promise resolve in your MainController.
like this:
var modalInstance = $modal.open({ ...});
modalInstance.result.then(function (result) {
grid.refresh() or grid.data.push()
});