$scope on $ionicPopup not recognized - angularjs

I need a dynamic popup where images change its opacity when clicked. It works perfectly, but only when the popup is out of a function. I need it inside a function.
This is my controller:
$scope.imgIds = ['0', '1', '2', '3', '4', '5'];
$scope.selectedImg = '-1';
$scope.itemClicked = function(index){
console.log(index);
$scope.selectedImg = index;
}
/*$ionicPopup.prompt({
title: 'Como foi seu treino?',
scope: $scope,
templateUrl: 'templates/icons.html'
});*/
//Envia Mensagem do Treino
$scope.sendMessage = function(tempo,id_serie) {
$ionicPopup.prompt({
title: 'Como foi seu treino?',
scope: $scope,
templateUrl: 'templates/icons.html'
}).then(function(res) {
$http({
url: $localStorage.url+'/serie/mensagem',
method: 'POST',
data: {id_serie : id_serie, mensagem :res, tempo: tempo, datahora: $scope.getData()},
headers : {'Content-Type':'application/json; charset=UTF-8'}
});
});
}
//Finaliza Treino
$scope.finalizar = function() {
document.getElementById('timer').getElementsByTagName('timer')[0].stop();
document.getElementById('play').className = 'button icon button-balanced button-block ion-play col';
var tempo = document.getElementById('timer').getElementsByTagName('timer')[0].innerText;
var confirmPopup = $ionicPopup.confirm({
title: 'Atenção',
template: 'Tempo: '+tempo+'<br>Finalizar Treino?',
buttons: [
{ text: 'Cancelar', onTap: function(e) { return false; }},
{ text: '<b>Ok</b>',
type: 'button-positive',
onTap: function(e) {
document.getElementById('timer').getElementsByTagName('timer')[0].start();
document.getElementById('timer').getElementsByTagName('timer')[0].stop();
$state.go('tab.series', {});
$scope.sendMessage(tempo,$scope.id_serie);
}
},
]
});
}
This is icons.html:
<style>
.selected {opacity:1;margin:auto;}
.unselected {opacity:0.5;margin:auto;}
</style>
<div class='row'>
<img ng-repeat="imgId in imgIds" src="img/{{imgId}}.png" width="30" height="30"
ng-class="{'selected':{{imgId}}==selectedImg,'unselected':{{imgId}}!=selectedImg}" ng-click="itemClicked(imgId)"/>
</div>
Algum Comentário?<br>
<input type="text"/>
There is no error on console. But the images don't change css, the popup gets locked and the buttons doesn't do nothing.

I got it.
The problem is I put $state.go('tab.series'); before call the popup, so the scope were different.

Related

how to add localization in ionic popup

i had completed ionic project. i would like to change lanaguages in this code. project title, place holder , button it had changed but popup was doesn't changed. i used this code in controller and language change file.
farmer-ctrl.js :
function showPopup () {
$scope.data = {};
var myPopup = $ionicPopup.show({
template: '<input type="text" ng-model="data.category">',
title: '{{"farmers_message" | translate}}', //'Enter CoconutType',
scope: $scope,
buttons: [
{ text: 'Cancel' },
{
text: '<b>{{"save_message" | translate}}</b>',
type: 'button-positive',
onTap: function (e) {
if (!$scope.data.category) {
//don't allow the user to close unless he enters producttype
e.preventDefault();
} else {
$log.log('yes clicked: ', $scope.data.category);
addProductType();
return $scope.data.category;
}
}
},
]
});
myPopup.then(function (res) {
$log.log('Tapped!', res);
});
}
i had founded by adding translate.instant
function showPopup () {
$scope.data = {};
var myPopup = $ionicPopup.show({
template: '<input type="text" ng-model="data.category">',
// title: 'Enter CoconutType',
title: $translate.instant('{{"farmers_message" | translate}}'),
scope: $scope,
buttons: [
{ text: 'Cancel' },
{
text: $translate.instant('{{"save_message" | translate}}'),
type: 'button-positive',
onTap: function (e) {
if (!$scope.data.category) {
//don't allow the user to close unless he enters producttype
e.preventDefault();
} else {
$log.log('yes clicked: ', $scope.data.category);
addProductType();
return $scope.data.category;
}
}
},
]
});
myPopup.then(function (res) {
$log.log('Tapped!', res);
});
}
To add localization in popup you need something like this:
var alertPopup = $ionicPopup.alert({
title: $translate.instant('networkerror'),
template: '<div><p translate="onlinemessagepois"></p></div>'
});
where networkerror and onlinemessagepois exist in your local js files. (Example: "networkerror":"sometext","onlinemessagepois":"someothertext" )
Note: you have to inject $translate in your controller.

How to split angularjs controller into chunks?

I am very new to AngularJs and hope I can get some help here. Below I have two controllers that are very similar. One is for editing an item and one for adding a new item. I would like to know how I can refactor this code in order to reuse most of this code for both controllers or simply use one controller for both. I originally tried to use one controller for both but the new item page wouldn't let me type anything into the fields. I supposed because there was no current model data like there is when editing.
Any help would be appreciated.
tplApp.controller('editController', function ($scope, $http, $routeParams){
$scope.template = {};
$scope.id = $routeParams.template_id;
$http.get(baseUrl+'templates/get_template/'+$scope.id).success(function(data) {
$scope.template = data;
});
$scope.bodyOptions = {
plugins: 'link image code',
toolbar: 'bold, italic, underline, alignleft, aligncenter, alignright, alignjustify, styleselect, bullist, numlist, outdent, indent, removeformat, mybutton, code',
height: 300,
menubar: false,
statusbar: false,
setup: function(editor) {
editor.addButton('mybutton', {
type: 'menubutton',
text: 'Variables',
icon: false,
menu: [
{text: 'Candidate Name', onclick: function() {editor.insertContent('%name%');}},
{text: 'Company Name', onclick: function() {editor.insertContent('%company-name%');}},
{text: 'Today\'s Date', onclick: function() {editor.insertContent('%date%');}},
{text: 'Your Name', onclick: function() {editor.insertContent('%your-name%');}},
]
});
}
};
$scope.saveTemplate = function() {
$http({
method : 'POST',
url : baseUrl+'templates/save',
data : $.param($scope.template),
headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
})
.success(function(data) {
$scope.message = data.message;
if (data.success) {
console.log(data);
$scope.templates = data.templates;
}
});
};
});
tplApp.controller('addController', function ($scope, $http){
$scope.template = {};
$scope.bodyOptions = {
plugins: 'link image code',
toolbar: 'bold, italic, underline, alignleft, aligncenter, alignright, alignjustify, styleselect, bullist, numlist, outdent, indent, removeformat, mybutton, code',
height: 300,
menubar: false,
statusbar: false,
setup: function(editor) {
editor.addButton('mybutton', {
type: 'menubutton',
text: 'Variables',
icon: false,
menu: [
{text: 'Candidate Name', onclick: function() {editor.insertContent('%name%');}},
{text: 'Company Name', onclick: function() {editor.insertContent('%company-name%');}},
{text: 'Today\'s Date', onclick: function() {editor.insertContent('%date%');}},
{text: 'Your Name', onclick: function() {editor.insertContent('%your-name%');}},
]
});
}
};
$scope.saveTemplate = function() {
$http({
method : 'POST',
url : baseUrl+'templates/save',
data : $.param($scope.template),
headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
})
.success(function(data) {
$scope.message = data.message;
if (data.success) {
console.log(data);
$scope.templates = data.templates;
}
});
};
});
What you want is a service: https://docs.angularjs.org/guide/services
"You can use services to organize and share code across your app"
Google it and/or look here in SO for more info.
Try these changes. You will need 2 services + 2 controllers (for saveTemplateService.js and buildBodyOptionsService.js ). The services will be injected to the controllers.
At the end,don't forget to add the src of each service in the template/html file.
I think it could be even more reduced (without the $http's success in the controllers) but since we are working with callbacks here, I'm not sure. Try it out ;).
It might not be fully functional because I don't have all your code. But debugging should solve it.
saveTemplateService.js:
app.factory('saveTemplateService', function ( baseUrl, $http ) {
return $http({
method : 'POST',
url : baseUrl+'templates/save',
data : $.param($scope.template), //fix these (injecting them like baseUrl)
headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
});
});
buildBodyOptionsService.js:
app.factory('buildBodyOptionsService', function() {
return {
build: function ( editor ) { //maybe editor needs to be injected
var output = {
plugins: 'link image code',
toolbar: 'bold, italic, underline, alignleft, aligncenter, alignright, alignjustify, styleselect, bullist, numlist, outdent, indent, removeformat, mybutton, code',
height: 300,
menubar: false,
statusbar: false,
setup: function(editor) {
editor.addButton('mybutton', {
type: 'menubutton',
text: 'Variables',
icon: false,
menu: [
{text: 'Candidate Name', onclick: function() {editor.insertContent('%name%');}}, // I dont like this functions here. There must be a better way to do this (ex: in a partial html with ng-click)
{text: 'Company Name', onclick: function() {editor.insertContent('%company-name%');}},
{text: 'Today\'s Date', onclick: function() {editor.insertContent('%date%');}},
{text: 'Your Name', onclick: function() {editor.insertContent('%your-name%');}},
]
});
}
};
return output;
}
};
});
editController.js
tplApp.controller('editController', function ($scope, saveTemplateService, buildBodyOptionsService) {
$scope.template = {};
$scope.id = $routeParams.template_id;
$http.get(baseUrl+'templates/get_template/'+$scope.id)
.success(function(data) {
$scope.template = data;
});
// call 1st service
$scope.bodyOptions = buildBodyOptionsService.build( editor );
// call 2nd service
$scope.saveTemplate = saveTemplateService.success( function(data) {
$scope.message = data.message;
if (data.success) {
console.log(data); //use $log.info() instead
$scope.templates = data.templates;
}
});
});
addController.js
tplApp.controller('addController', function ($scope, saveTemplateService, buildBodyOptionsService) {
$scope.template = {};
// call 1st service
$scope.bodyOptions = buildBodyOptionsService.build( editor );
// call 2nd service
$scope.saveTemplate = saveTemplateService.success( function(data) {
$scope.message = data.message;
if (data.success) {
console.log(data); //use $log.info() instead
$scope.templates = data.templates;
}
});
});
Check these links for more info:
custom services in Angular (really well explained): https://youtu.be/rlx1cf7qM0E?list=PL6n9fhu94yhWKHkcL7RJmmXyxkuFB3KSl
promises in services: AngularJS: Performing $http request inside custom service and returning data
(relevant) Angular $http difference between .success() and .then()
I would probably put everything in a single service (templateService). I'm not sure if the bodyOption belongs there but for now I would just put it there. Then I would move the load/save template function to the service.
You could probably do more, for instance, your might set the $scope.templateService = templateService and in your html use templateService.bodyOptions/templates directly.
Also, you could probably move the save.success from the controller to the service aswell.
tplApp.service('templateService', function($http, $routeParams) {
var self = this;
this.template = {};
this.loadTemplate = function() {
$http.get(baseUrl+'templates/get_template/' + $routeParams.template_id)
.success(function(data) {
self.template = data;
});
};
this.saveTemplate = function() {
return $http({
method: 'POST',
url: baseUrl + 'templates/save',
data: $.param(self.template),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});
};
this.bodyOptions = {
plugins: 'link image code',
toolbar: 'bold, italic, underline, alignleft, aligncenter, alignright, alignjustify, styleselect, bullist, numlist, outdent, indent, removeformat, mybutton, code',
height: 300,
menubar: false,
statusbar: false,
setup: function(editor) {
editor.addButton('mybutton', {
type: 'menubutton',
text: 'Variables',
icon: false,
menu: [
{text: 'Candidate Name', onclick: function() {editor.insertContent('%name%');}},
{text: 'Company Name', onclick: function() {editor.insertContent('%company-name%');}},
{text: 'Today\'s Date', onclick: function() {editor.insertContent('%date%');}},
{text: 'Your Name', onclick: function() {editor.insertContent('%your-name%');}},
]
});
}
};
});
tplApp.controller('editAndAddController', function ($scope, templateService){
$scope.template = templateService.template;
$scope.bodyOptions = templateService.bodyOptions;
if(edit) {
templateService.loadTemplate();
}
$scope.saveTemplate = function() {
templateService.saveTemplate()
.success(function(data) {
$scope.message = data.message;
if (data.success) {
console.log(data);
$scope.templates = data.templates;
}
});
};
});
Ideally your controller would probably look like this:
tplApp.controller('editAndAddController', function ($scope, templateService){
$scope.templateService = templateService;
if(edit) {
templateService.loadTemplate();
}
});
Heads up! This is just example, code is not tested!

Custom Ionic Framework Popup

I have an IONIC popup, See image below in the link.
I have an issue when i click on the buttons Arrange Coupon, It redirect me to the next screen. It is fine.But the popup doesn't hide. Please help me.
Thanks.
http://awesomescreenshot.com/0e55lzsl39
var myPopup;
$scope.showPopup = function() {
myPopup = $ionicPopup.show({
template: '<a class="button button-block button-energized" href="#/redeem">Arrange Coupon</a> <a class="button button-block button-balanced">Add Coupon</a> ',
title: 'Coupon Management',
buttons: [{
text: '<b>OK</b>',
type: 'button button-small button-positive',
onTap: function(e) {
}
}, ]
});
myPopup.then(function(res) {
if (res) {
console.log(res);
}
else{
alert('here');
}
});
};
Looks like you forgot to add the image. However, The Ionic Popup service allows programmatically creating, showing and closing popup.
If you have a popup defined like this,
var myPopup = $ionicPopup.show({
template: '<input type="password" ng-model="data.wifi">',
title: 'Enter Wi-Fi Password',
subTitle: 'Please use normal things',
scope: $scope,
buttons: [
{ text: 'Cancel' },
{
text: '<b>Save</b>',
type: 'button-positive',
onTap: function(e) {
if (!$scope.data.wifi) {
//don't allow the user to close unless he enters wifi password
e.preventDefault();
} else {
return $scope.data.wifi;
}
}
}
]
});
You can close it like this
myPopup.close();

bind data in $ionicPopup

when i click on qty than it will be set on ionicPopup
$ionicPopup.show({
template: '<input type="tel" placeholder="Quantity" ng-model="data.wifi" >',
title: 'Enter quantity to change',
scope: $scope,
buttons: [{
text: '<i class="icon ion-close"></i>', type: 'popup-close'},
{
text: '<b>Ok</b>',
type: 'common-btn',
onTap: function (e) {
qty = $scope.data.wifi;
var date = new Date();
var cartData = {
'companyId': compid,
'userId': userid,
'cartDate': date,
'cartStatus': 1,
'productId': val.ProductID,
'quantity': qty,
'cartDetailStatus': 1
};
//alert(JSON.stringify(cartData));
$http.post($rootScope.url + 'UpdateCartQty?margin=' + marginVal + '&roleid=' + roleid, cartData).success(function (data) {
console.log(JSON.stringify(data));
$ionicPopup.alert({
title: 'Message',
template: 'Quantity updated successfully !'
}).then(function () {
$scope.items = data;
//cartid = data.CartID;
});
});
return qty;
}]
}).then(function (qty) {
if (qty) {
console.log('Got quantity ' + qty);
} else {
//alert('please enter value');
}
}
});
I want to bind quantity from my database value so how can not bind the value in ionic popup it's possible in ionicPopup? any help thanks in advance
You can do it. This is the content of your controller:
var compid = 1;
var userid = 1;
var val = {
ProductID: 1
};
$scope.data = {
wifi: "my wifi data"
};
$scope.openModal = function(){
$ionicPopup.show({
template: '<input type="tel" placeholder="Quantity" ng-model="data.wifi" >',
title: 'Enter quantity to change',
scope: $scope,
buttons: [
{
text: '<i class="icon ion-close"></i>',
type: 'popup-close'
},
{
text: '<b>Ok</b>',
type: 'common-btn',
onTap: function (e) {
qty = $scope.data.wifi;
var date = new Date();
var cartData = {
'companyId': compid,
'userId': userid,
'cartDate': date,
'cartStatus': 1,
'productId': val.ProductID,
'quantity': qty,
'cartDetailStatus': 1
};
//alert(JSON.stringify(cartData));
$http.post($rootScope.url + 'UpdateCartQty?margin=' + marginVal + '&roleid=' + roleid, cartData).success(function (data) {
console.log(JSON.stringify(data));
$ionicPopup.alert({
title: 'Message',
template: 'Quantity updated successfully !'
}).then(function () {
$scope.items = data;
//cartid = data.CartID;
});
});
return qty;
}
}
]
}).then(function (qty) {
if (qty) {
console.log('Got quantity ' + qty);
} else {
//alert('please enter value');
}
});
};
This is the template:
<ion-view view-title="My View">
<ion-content class="padding">
<input type="text" ng-model="data.wifi">
<button class="button" ng-click="openModal()">Open</button>
</ion-content>
</ion-view>

Angular UI Bootstrap modal result is undefined

I'm building an app that loads a modal on a click on a button in an ng-grid row. Displaying the modal and the correct data works great. Problem is with getting the data back form the form in the modal. This bit of code
modalInstance.result.then(function(selectedItem){
$scope.selected = selectedItem;
});
Returns 'undefined' for 'selectedItem'
Here's the modal.
<div ng-app="myApp">
<div ng-controller="UsersCtrl">
<script type="text/ng-template" id="editUserModal.html">
<div class="modal-header">
<h3 class="modal-title">Edit User <em>{{user.user_full_nm}} {{user.user_id}}</em></h3>
</div>
<div class="modal-body">
<p>User Name: <input type="text" name="user_full_nm" value="{{user.user_full_nm}}"></p>
<p>Email: <input type="text" name="user_nm" value="{{user.user_nm}}"></p>
<p>Active:
<select ng-model="user.deleted" ng-selected="user.deleted">
<option value="0" ng-selecte>Active</option>
<option value="1">Inactive</option>
</select>
</p>
<p>Termination Date: {{user.termination_date | date:'longDate'}}</p>
<p>Last Entry Date: {{user.last_entry | date:'longDate'}}</p>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
<div class="gridStyle" ng-grid="gridOptions"></div>
</div>
</div>
Here's the Angular app.
var app = angular.module('myApp', ['ngGrid','ui.bootstrap']);
app.controller('UsersCtrl', function($scope, $http, $modal) {
$scope.filterOptions = {
filterText: "",
useExternalFilter: false
};
$scope.totalServerItems = 0;
$scope.pagingOptions = {
pageSizes: [20, 40, 60],
pageSize: 20,
currentPage: 1
};
$scope.setPagingData = function(data, page, pageSize){
var pagedData = data.slice((page - 1) * pageSize, page * pageSize);
$scope.userData = pagedData;
$scope.totalServerItems = data.length;
if (!$scope.$$phase) {
$scope.$apply();
}
};
$scope.getPagedDataAsync = function (pageSize, page, searchText) {
setTimeout(function () {
var data;
if (searchText) {
var ft = searchText.toLowerCase();
$http.get('getUsers').success(function (largeLoad) {
data = largeLoad.filter(function(item) {
return JSON.stringify(item).toLowerCase().indexOf(ft) != -1;
});
$scope.setPagingData(data,page,pageSize);
});
} else {
$http.get('getUsers').success(function (largeLoad) {
$scope.setPagingData(largeLoad,page,pageSize);
});
}
}, 100);
};
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
$scope.$watch('pagingOptions', function (newVal, oldVal) {
if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize,$scope.pagingOptions.currentPage,$scope.filterOptions.filterText);
}
}, true);
$scope.$watch('filterOptions', function (newVal, oldVal) {
if (newVal !== oldVal) {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage,
$scope.filterOptions.filterText);
}
}, true);
var editUserButtonTemplate = '<i class="fa fa-pencil" style="cursor:pointer;" ng-click="editUser(row.entity)"></i>';
$scope.gridOptions = {
data: 'userData',
columnDefs: [
{field: 'user_id', displayName: 'User ID', visible: false},
{field: 'user_nm', displayName: 'Email'},
{field: 'user_full_nm', displayName: 'Name'},
{field: 'deleted', displayName: 'Active', width: 60, cellFilter: 'activeFilter'},
{field: 'termination_date', displayName: 'Termination Date',cellFilter: 'date:\'longDate\''},
{field: 'last_entry', displayName: 'Last Entry Date',cellFilter: 'date:\'longDate\''},
{field: '', DisplayName: '', cellTemplate: editUserButtonTemplate, colFilterText: '', width:20}
],
enablePaging: true,
showFooter: true,
showFilter: true,
enableRowSelection: false,
filterOptions: $scope.filterOptions,
totalServerItems:'totalServerItems',
pagingOptions: $scope.pagingOptions,
filterOptions: $scope.filterOptions
};
/************ open the edit user modal *********************/
$scope.editUser = function(value) {
var modalInstance = $modal.open({
templateUrl: 'editUserModal.html',
// scope: $scope,
controller: 'editUserCtrl',
resolve: {
user: function () {
return value;
}
}
});
modalInstance.result.then(function(selectedItem){
$scope.selected = selectedItem;
});
};
});
app.controller('editUserCtrl', function($scope, $http, $modalInstance, user) {
$scope.user = user;
$scope.ok = function () {
$modalInstance.close($scope.selected);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
// for the 'deleted' column, display 'Active' or 'Inactive' instead of 1 or 0
app.filter('activeFilter', function(){
var types = ['Active', 'Inactive'];
return function(type){
return types[type];
};
});
So as happens so often, as soon as I posted my question I found this one.
angular-ui-bootstrap modal not passing back result
Which led me to the problem.
$scope.ok = function () {
$modalInstance.close($scope.selected);
};
Changed $scope.selected to $scope.user and it's working as expected now.

Resources