ng-style not working in angularjs ionicapp - angularjs

I'm having an issue with what looks like ng-style but I suspect it may be a scoping issue also.
The HTML code;
<ion-view view-title="Demographics" name="demographics-view" can-swipe-back="false">
<ion-content class="has-header">
<div class="list card">
<div class="item item-divider">
<div class="button-bar">
**<a ng-style="{'color':'{{ data.demographics.showRed }}' }"** class="button button-small button-icon icon ion-alert-circled" ng-click="goPMIAlerts($event)"></a>
.....
The js code:
$scope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
$('ion-nav-bar .title').each(function () {
$(this).text("Demographics");
});
...
tblDemographics.demographicsUID(sysGlobals.pmi_id)
.then(function (res) {
if (res) {
$scope.data.demographics = res;
}
return tblSettings.getType("LANG");
})
.then(function (res) {
if (res) {
$scope.data.demographics.langcodes = res;
}
tblPMIAlerts.pmiID(sysGlobals.pmi_id)
.then(function (res) {
if (res) {
$scope.data.demographics.pmialerts = res;
** if($scope.data.demographics.pmialerts.length > 0) {
$scope.data.demographics.showRed = 'red';
} else {
$scope.data.demographics.showRed = 'grey';
}**
}
});
})
What I'm trying to achieve is to have the icon color of red if there is data and grey if not.
I've looked around here on SO and Googled of course but I've as yet not been able to solve the issue!

I think the braces and quotes are not required, as you already using a Angular directive.
Try:
<a ng-style="{'color': data.demographics.showRed}" class="button button-small button-icon icon ion-alert-circled" ng-click="goPMIAlerts($event)"></a>

Related

How to correctly reinitiate view with $state.go from another view

I am attempt to send users from one state to another with this method:
$state.go('splash');
This works correctly, however, when users are sent to my splash view the code does not reinitiate.
This is the html of the splash state:
<ion-view hide-nav-bar="true">
<ion-content class="splash-screen" scroll="false">
<div class="loading">
<i class="fa fa-circle-o-notch fa-spin fa-5x fa-fw"></i>
</div>
</ion-content>
</ion-view>
<script id="login.html" type="text/ng-template">
<ion-modal-view>
<ion-header-bar class="bar bar-header bar-stable">
<h1 class="title">Login</h1>
</ion-header-bar>
<ion-content>
<div class="list padding">
<div class="error" ng-if="errors">
<p ng-bind-html="error_message"></p>
</div>
<label class="item item-input">
<input ng-model="data.password" type="password" placeholder="Password">
</label>
<button class="button button-full button-positive" ng-click="login(data)">Login</button>
</div>
</ion-content>
</ion-modal-view>
</script>
This is the controller for the view:
angular.module('app.controllers', [])
.controller('SplashCtrl', function($scope, $http, $state, $ionicModal, $ionicLoading, $ionicPlatform, $timeout, $localstorage, appAPI) {
$scope.data = {};
$scope.data.password = '';
$ionicModal.fromTemplateUrl("login.html", {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.openModal = function() {
$scope.modal.show();
};
$scope.login = function(data) {
alert(data.password);
};
$ionicPlatform.ready(function() {
$scope.openModal();
});
});
When users visit the splash view the first time, the modal loads as intended, however, when they are directed there from the $state.go - the modal does not load.
Any thoughts how I can get this to work correctly?
Multiple Calls to $ionicPlatform.ready()
Unfortunately, other callbacks passed to the function are silently ignored. (ARGH!)1
In addition to taking a callback function as a parameter, it returns a promise for the platform being ready.
Use the promise:
$ionicPlatform.ready().then(function() {
$scope.openModal();
});
I hope you are looking to reload your 'SplashCtrl' controller when the user is routed to the 'splash' state.
If so, try this $state.go('splash', {}, {reload: true});
You haven't shared your entire project so I can't tell really. It seems your structure is a bit off. You should only have one ionicPlatform.ready() and it should be to setup the environment. Once done it should forward the user to your first view, no open a modal.
This is how I check that in my app. The platform ready function has $state.go('app.calendar'); which is my first view (assuming they are logged in) - if they are not logged in the init function returns an error from the promise and the statechange error code forwards them to the login signup page.
State controller
.state('app', {
url: '/app',
cache: false,
abstract: true,
templateUrl: 'templates/tabs.html',
controller: 'TabCtrl',
resolve: {
user: function (UserService) {
var value = UserService.init();
return value;
}
}
})
// Calendar
.state('app.calendar', {
url: "/calendar",
cache: true,
views: {
'calendar-tab': {
templateUrl: 'templates/calendar.html',
controller: 'CalendarController'
}
}
})
Check if logged in.
function init(){
var deferred = $q.defer();
if (loggedIn()) {
deferred.resolve(currentUser);
} else {
deferred.reject({error: "noUser"});
}
return deferred.promise;
};
React to the state error - app-first is the login or signup page.
$rootScope.$on('$stateChangeError',
function (event, toState, toParams, fromState, fromParams, error) {
console.log('$stateChangeError ' + error && (error.debug || error.message || error));
// if the error is "noUser" the go to login state
if (error && error.error === "noUser") {
event.preventDefault();
$state.go('app-first', {});
}
}
);

AngularJS toggle ng source value on click

I need some help about toggling ng-src between for example: image.jpg and image-active.jpg, but I have some issues because I need to active that with AngularJS.
This is the scenario: I called an API data from swagger and use ng-repeat to display images in html.
HTML
<div class="input-group interests-list">
<div class="checkbox" ng-repeat="interest in interests">
<label>
<div class="interest-icon">
<img src="{{interest.iconUrl}}" ng-click="changeImage()">
</div>
<input style="display: none;" type="checkbox" value="{{interest.name}}">
{{interest.name}}
</label>
</div>
</div>
Service
this.getInterests = function () {
var deferred = $q.defer();
var req = {
method: 'get',
url: 'http://customdealwebapi20180125110644.azurewebsites.net/api/Interests'
}
$http(req).then(function (response) {
deferred.resolve(response.data);
}, function (err) {
console.log(err)
});
return deferred.promise;
}
Controller
TestService.getInterests().then(function (data) {
$scope.interests = data;
});
and everything works fine
Now I want to achieve when someone click on the image, ng-src should be changed to image-active.jpg, and on the next click image should be changed to default value (image.jpg)
I know how to achieve through jQuery, like this
$(".interests-list .checkbox label input[type='checkbox']").change(function () {
var selectedIcon = $(this).val();
if (this.checked) {
console.log($(this).prev())
$(this).prev().find("img").attr("src", "assets/img/home/icons/" + selectedIcon + "-active.png");
} else {
$(this).prev().find("img").attr("src", "assets/img/home/icons/" + selectedIcon + ".png");
}
});
Thank you
You can either use ng-show
<div class="checkbox" ng-repeat="interest in interests" ng-init="interest.active = false">
<label>
<div class="interest-icon">
<img ng-show="interest.active == true" src="active.png" ng-click="interest.active = !interest.active">
<img ng-show="interest.active == false" src="other.png" ng-click="interest.active = !interest.active">
</div>
</label>
</div>
or you can pass interest to your click function and set image src in your controller
<img src="{{interest.iconUrl}}" ng-click="changeImage(interest)">
$scope.changeImage = function(interest){
if(checked)
interest.iconUrl = "active.png";
else
interest.iconUrl = "other.png";
}

Ionic: $scope change not reflected on the page

On my Ionic App, I have a view that has a button. When you click on the button, a list of player would be served in a modal, when clicked on a player name, the name of the selected player should be shown on the page and the button should be hidden.
Here's the codepen for the same - http://codepen.io/mradul/pen/vNywqG
However, when I select a value(player name) on the modal, the scope variable gets updated(as it's printed on the console), but the change is not reflected on the page.
HTML -
<ion-header-bar class="bar-positive bar-header">
<h1 class="title">Selected Player</h1>
</ion-header-bar>
<ion-content>
<script id="select-player.html" type="text/ng-template">
<div class="modal">
<ion-header-bar>
<h1 class="title">Choose Player</h1>
</ion-header-bar>
<ion-content>
<ion-list>
<ion-item ng-repeat="player in getPlayerList().players" ng-click="closeModal(player)">
{{player}}
</ion-item>
</ion-list>
</ion-content>
</div>
</script>
<br/><br/>
<div id="player">
{{sc.player}}
<div class="row">
<a class="button" ng-click="openModal()" ng-show="sc.player.playerName == null">Set player</a>
<div ng-hide="sc.player.playerName == null">
<div class="col col-33 " > {{sc.player.playerName}}</div>
</div>
</ion-content>
JS -
angular.module('ionicApp',['ionic']).controller('scoringController', function ($scope, $ionicModal) {
$scope.player = {playerName:""};
$scope.getPlayerList = function () {
console.log("getting player list");
return {
"players": [
"Mradul",
"JAin",
"Phunsuk Wangdu",
"Hulk"
]
};
};
$ionicModal.fromTemplateUrl('select-player.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function (modal) {
$scope.modal = modal
})
$scope.openModal = function () {
console.log("Setting model open ");
$scope.modal.show()
}
$scope.closeModal = function (playerName) {
$scope.player.playerName = playerName;
//$scope.activePlayers[0] = playerName;
console.log("Player Set ", $scope);
console.log("model closed");
$scope.modal.hide();
};
$scope.$on('$destroy', function () {
$scope.modal.remove();
});
});
Player was initially a primitive(string), but I changed it into an object by having a property - playerName. May be I didn't do it right. Please suggest how can I have the parent scope variable updated correctly. I might have missed something very basic.
Write $scope.$apply() after your change
Try this, Am not sure about it
{{player.playerName}}

Function automatically called in some condition

I have code like this:
<div class="row"
ng-repeat="x in companies|orderBy:'id' ">
<div class="col left" >
<button ng-click="viewPublicId(x.id)">{{x.companyname}}</button>
</div>
<div class="col left">
{{x.address}}
</div>
<div class="col left">
{{x.telephone}}
</div>
</div>
What I want to do is add a check: when companies.size=1, function viewPublicId is automatically called. How can I achieve that? Thanks.
updated: viewPublicId function:
$scope.viewPublicId = function viewPublicId(companyid) {
var url = "http://7cf8d64c.tunnel.mobi/yii2-basic/web/index.php?r=restpublic/view&companyid=" + companyid;
console.log("debug", url);
$http.get(url)
.success(function (response)
{
console.log("debug PublicId",response);
if(response.length==33)
$scope.publicids = null;
else
$scope.publicids = response;
})
.error(function (response)
{
console.log("debug PublicId",response);
$scope.publicids = null;
});
$state.go('tabs.publicidlist');
}
In you controller:
if ($scope.companies.length === 1) {
$scope.viewPublicId();
}
If your companies could be changed dynamically, and you need to call the function everytime it changes, use $watch:
$scope.$watch('companies', function () {
if ($scope.companies.length === 1) {
$scope.viewPublicId();
}
}, true);

Can't display ng-repeat child scope property

I need to display a list of data records using ng-repeat. Within every data object entry (a coupon) displyed, I need to grab some properties ($scope.etabName and $scope.etabDistance) from that object, do some calculations and show the result in the same data object's view within the ng-repeat view.
I've managed to do the calculations and when I console.log them the results are correct, but they are not showing correctly: the property displyed is the one relative to the last data object iterated by ng-repeat.
I know I'm not understanding the Angular way of doing scopes, so any help is welcome.
My controller:
$scope.getCouponList = function () {
$http({
method: 'JSONP',
url: $scope.couponListUrl + "?callback=JSON_CALLBACK&cookie=" + $localStorage.user.cookie +
"&usr_latitude=" + $rootScope.lat + "&usr_longitude=" + $rootScope.lng
}).
success(function (data, status) {
if (data.status && data.status == "ok") {
$rootScope.couponList = data.list;
}
}).error(function (data, status, headers, config) {
});
$scope.fetchEtabDetails = function($stateParams) {
_.select($stateParams.etablissement, function (etab) {
if (etab.id === $stateParams.etabcloser) {
$scope.etabName = etab.name;
$scope.etabDistance = etab.distance;
}
});
};
};
My view:
<ion-content scroll="true" ng-controller="getCouponList">
<ion-list>
<ion-item class="decline" ng-repeat="coupon in couponList"
ng-click="fetchCouponDetails(coupon)"
ng-init="fetchEtabDetails(coupon)">
<div class="offer-image">
<img class="full-image" ng-src="{{coupon.image_operation}}">
<div class="offer-logo">
<img ng-src="{{coupon.enseigne_logo_url}}">
</div>
<div class="offer-ens-name">
<span>{{coupon.ens_name}}</span>
</div>
<div class="offer-name wrap-txt">
<span>{{coupon.name}}</span>
</div>
<div class="offer-deadline-details">
<i class="icon ion-android-time"></i>
<timer countdown="coupon.diff_date" max-time-unit="'year'" interval="1000">{{ddays}}:{{hhours}}:{{mminutes}}</timer>
</div>
<div class="offer-zone">
<i class="icon ion-location" class="etab"></i>
<span>{{etabName}} {{etabDistance}} km</span>
</div>
</div>
</ion-item>
</ion-list>
</ion-content>
In this function:
$scope.fetchEtabDetails = function($stateParams) {
_.select($stateParams.etablissement, function (etab) {
if (etab.id === $stateParams.etabcloser) {
$scope.etabName = etab.name;
$scope.etabDistance = etab.distance;
}
});
You only have 1 $scope.etabName. Each call is overwriting it.
I would do this...
$scope.fetchEtabDetails = function($stateParams) {
_.select($stateParams.etablissement, function (etab) {
if (etab.id === $stateParams.etabcloser) {
$stateParams.etabName = etab.name;
$stateParams.etabDistance = etab.distance;
}
});
then in your HTML...
<div class="offer-zone">
<i class="icon ion-location" class="etab"></i>
<span>{{coupon.etabName}} {{coupon.etabDistance}} km</span>
</div>

Resources