How do i toggle between classes within 2 divs in ionic/angular? - angularjs

example.. i have a match between team-A and team-B. when i click on team-A, i want to add a class call 'selected' to team-A, and then if i click on team-B i want to remove the 'selected' class from team-A and add it to team-B, if i click on team-B again then i want to remove the class all together. Here is what i have so far in play.ionic.
http://play.ionic.io/app/914bb06d2570
similarly i want it to work for match 2 and 3 as well. very appreciate the help.
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<link href="https://code.ionicframework.com/1.0.0/css/ionic.min.css" rel="stylesheet">
<script src="https://code.ionicframework.com/1.0.0/js/ionic.bundle.js"></script>
</head>
<body ng-app="app" ng-controller="matchCtrl">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Matches</h1>
</ion-header-bar>
<ion-content class="padding">
<div ng-repeat="match in schedule" ng-init="{'awayActive': false, 'homeActive': false}">
<div>Match {{match.matchNum}}</div>
<div class="match">
<div class="inline" ng-class="{'selected': awayActive}" ng-click="awayActive = !awayActive">{{match.away}}</div>
vs
<div class="inline" ng-class="{'selected': homeActive}" ng-click="homeActive = !homeActive">{{match.home}}</div>
</div>
</div>
</ion-content>
</ion-pane>
</body>
</html>
js
angular.module('app', ['ionic'])
.controller('matchCtrl', function($scope){
$scope.schedule = [{
matchNum: 1,
away: 'Team A',
home: 'Team B'
},{
matchNum: 2,
away: 'Team C',
home: 'Team D'
},{
matchNum: 3,
away: 'Team E',
home: 'Team F'
}];
});
css
.selected {
border: 2px solid blue;
}

If you use a common variable assigned to each schedule array object you can set defaults if desired, but even if you just default to nothing it will allow an easy switch between home and away selections, like so:
<div ng-repeat="match in schedule" ng-init="{'awayActive': false, 'homeActive': false}" ng-init="match.selection = ''">
<div>Match {{match.matchNum}}</div>
<div class="match">
<div class="inline" ng-class="{'selected': match.selection == 'away'}" ng-click="match.selection = 'away';">{{match.away}}</div>
vs
<div class="inline" ng-class="{'selected': match.selection == 'home'}" ng-click="match.selection = 'home';">{{match.home}}</div>
</div>
</div>
Demo: http://play.ionic.io/app/7a63c124586b

Related

Cannot click button inside a list (ng-repeat)

I'm having a problem with a button inside a list. The list is being built with ng-repeat. I'm trying to create a simple web app for creating tasks. Given the following code,
I can't click the button which is supposed to show the task description (the one with the gear). Thank you in advance.
HTML:
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Tasks List</title>
<link rel="manifest" href="manifest.json">
<!-- un-comment this code to enable service worker
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js')
.then(() => console.log('service worker installed'))
.catch(err => console.log('Error', err));
}
</script>-->
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
</head>
<body ng-app="todo" ng-controller='mainCtrl'>
<ion-pane>
<ion-header-bar class="bar-dark">
<h1 class="title">Tasks</h1>
</ion-header-bar>
<ion-content>
<div class="list list-inset">
<label class="item item-input">
<input type="text" name="list" placeholder="Task Name" ng-model="task">
</label>
<label class="item item-input">
<input type="text" placeholder="Description" ng-model="description">
</label>
</div>
<button class ="button button-dark right" ng-click="add(task,description)">Add</button>
<div class="row">
<div class="col"></div>
<div class="col"></div>
<div class="col col-50">
<ion-list show-delete="1==1" ng-repeat="task in tasks">
<ion-item>
{{task.taskname}}
<ion-delete-button class="ion-minus-circled" ng-click="delete(task)"></ion-delete-button>
<button ng-click="task.selected=!task.selected" class="btn button icon ion-gear-a"></button>
</ion-item>
<div class="item item-divider" ng-show="task.selected">
{{task.description}}
</div>
</ion-list>
</div>
</div>
</ion-content>
</ion-pane>
</body>
</html>
app.js:
angular.module('todo', ['ionic'])
.controller('mainCtrl',function($scope, $ionicModal){
$scope.tasks=[
{
taskname: 'Hi',
description:'I am a description',
selected: false
},
{
taskname:'Hello',
description:'I am another description',
selected: false
},
{
taskname: '123',
description:'I am another description',
selected: false
},
{
taskname: '456',
description:'I am another description',
selected: false
},
{
taskname: '789',
description:'I am another description',
selected: false
},
]
$scope.select=-1;
$scope.add=function(task,description){
if ($scope.tasks.indexOf(task)!== -1){
this.list="Already exists!"
}
else{
newtask={
taskname: task,
description: description,
selected: false
};
$scope.tasks.push(newtask);
}
};
$scope.delete=function(task){
var index = $scope.tasks.indexOf(task);
$scope.tasks.splice(index, 1);
}
});
Your controller line should be:
.controller('mainCtrl', ['$scope', '$ionicModal', function($scope, $ionicModal) {
And obviously the extra ] at the end.
I removed the ios-list and ion-item tags and replace them with the ul and li ones and it worked perfectly, is there something wrong with those tags?

Filter images by category Checkbox AngularJS

I need to filter MAN and WOMAN. In the Filter list, appear 4 items, and should appear only two (man and woman), or by category.
Another problem is that the filter is for ng-show = "picture.checked" and this brings me only 1 image by check, must come BY CATEGORY, that is, when I click on woman show two images, as there are two pictures woman with the same category and the same goes for the man.
What already have:
angular.module('ionicApp', ['ionic'])
.controller('MainCtrl', function($scope) {
$scope.devList = [
{ categoria: "woman", img: "http://extra.globo.com/incoming/14942281-f88-b8b/w448/Elisabeth-Reyes-mulher-Sergio-Sanchez.jpg" },
{ categoria: "woman", img: "http://extra.globo.com/incoming/14942281-f88-b8b/w448/Elisabeth-Reyes-mulher-Sergio-Sanchez.jpg" },
{ categoria: "man", img: "http://dicasmodafeminina.com/wp-content/uploads/2012/08/qualidades-de-homem-ideal-autoconfianca.jpg" },
{ categoria: "man", img: "http://dicasmodafeminina.com/wp-content/uploads/2012/08/qualidades-de-homem-ideal-autoconfianca.jpg" }
];
$scope.pushNotificationChange = function() {
console.log('Push Notification Change', $scope.pushNotification.checked);
};
$scope.pushNotification = { checked: true };
$scope.emailNotification = 'Subscribed';
});
body {
cursor: url('http://ionicframework.com/img/finger.png'), auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Checkboxes</title>
<link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
</head>
<body ng-controller="MainCtrl">
<ion-header-bar class="bar-positive">
<h1 class="title">Checkboxes</h1>
</ion-header-bar>
<ion-content>
<div class="list">
<ion-checkbox ng-repeat="item in devList"
ng-model="item.checked"
ng-checked="item.checked">
{{ item.categoria }}
</ion-checkbox>
</div>
<div class="imgs" ng-repeat="picture in devList" ng-show="picture.checked">
<img width="200" ng-src="{{picture.img}}" width="100%" ng-click="showImage($index)"/>
</div>
</ion-content>
</body>
</html>
You could use a separate $scope.options object with just 2 entries (man, woman) to filter the list with, and show/hide based on the state of the checked property of each item.
I've built the $scope.options object by looping over the values in $scope.devList, so that it is dynamic.
angular.module('ionicApp', ['ionic'])
.controller('MainCtrl', function($scope) {
$scope.devList = [
{ categoria: "woman", img: "http://extra.globo.com/incoming/14942281-f88-b8b/w448/Elisabeth-Reyes-mulher-Sergio-Sanchez.jpg" },
{ categoria: "woman", img: "http://extra.globo.com/incoming/14942281-f88-b8b/w448/Elisabeth-Reyes-mulher-Sergio-Sanchez.jpg" },
{ categoria: "man", img: "http://dicasmodafeminina.com/wp-content/uploads/2012/08/qualidades-de-homem-ideal-autoconfianca.jpg" },
{ categoria: "man", img: "http://dicasmodafeminina.com/wp-content/uploads/2012/08/qualidades-de-homem-ideal-autoconfianca.jpg" }
];
$scope.options = buildOptions();
function buildOptions() {
var ret = {};
angular.forEach($scope.devList, function(item){
ret[item.categoria] = { checked : false };
});
return ret;
}
$scope.pushNotificationChange = function() {
console.log('Push Notification Change', $scope.pushNotification.checked);
};
$scope.pushNotification = { checked: true };
$scope.emailNotification = 'Subscribed';
});
body {
cursor: url('http://ionicframework.com/img/finger.png'), auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Checkboxes</title>
<link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
</head>
<body ng-controller="MainCtrl">
<ion-header-bar class="bar-positive">
<h1 class="title">Checkboxes</h1>
</ion-header-bar>
<ion-content>
<div class="list">
<ion-checkbox ng-repeat="(key,item) in options"
ng-model="item.checked"
ng-checked="item.checked">
{{ key}}
</ion-checkbox>
</div>
<div class="imgs" ng-repeat="picture in devList" ng-show="options[picture.categoria].checked">
<img width="200" ng-src="{{picture.img}}" width="100%" ng-click="showImage($index)"/>
</div>
</ion-content>
</body>
</html>

How to update $scope in Ionic slide box?

I've changing a $scope variable dynamically but Ionic doens't detect the change:
In my controller:
$scope.something = "something" ;
And in my ion-box I see $scope.something, but when try to set a new value to $scope.something ionic slide box doesn't detect the change. If I do the new value has been set..
console.log($scope.something) // The new value
A lot of people says that with $ionicBoxDelegate.update() is enough but doesn't work me. I also tyied all options that I've seen on Internet, but there is no way.
My code works because if I move it to a normal view, out of a slide, runs fine. Using the same code with the same controller.
Is a mystery. Any idea?
If the scope isn't updating correctly you can use $scope.$apply() to force angular to re-evaluate the scope.
I just made a codepen. Will this help?
http://codepen.io/nabinkumarn/pen/obVbmN
HTML
<div ng-controller="SlideBoxController as vm">
<div style="height:30px">{{vm.something}}</div>
<ion-slide-box show-pager="true" on-slide-changed="vm.onSlideChanged($index)">
<ion-slide ng-repeat="item in vm.items">
<div class="box">
<h2>{{item.title}}</h2>
<p>{{item.desc}}</p>
</div>
</ion-slide>
</ion-slide-box>
</div>
JS
vm.something=1
vm.onSlideChanged = function(slideIndex) {
vm.something ++;
};
It would be useful to see your code, in particular, how you are updating $scope.something.
I created the snippet below (loosely based on Scott Whittaker's codepen). Is this what you're trying to accomplish:
angular.module('app', ['ionic'])
.controller('SlideBoxController', function($scope) {
$scope.something = "old value";
$scope.items =
[{title: "item 1", desc: "item 1 description"},
{title: "item 2", desc: "item 2 description"}
];
$scope.onSlideChanged = function(slideIndex) {
if (slideIndex === 1) {
$scope.something = "new value";
}
else
{
$scope.something = "old value"
}
};
})
.slider {
height: 300px;
background-color: #eee;
}
.box {
padding: 1em;
}
<html ng-app="app">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Ionic Slide Box</title>
<link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
</head>
<body>
<ion-header-bar class="bar bar-header bar-calm">
<h2 class="title">Slide Box</h2>
</ion-header-bar>
<ion-content scroll="false">
<div ng-controller="SlideBoxController">
<ion-slide-box show-pager="true" on-slide-changed="onSlideChanged($index)">
<ion-slide ng-repeat="item in items">
<div class="box">
<h3>$scope.something = {{something}}</h3>
<h2>{{item.title}}</h2>
<p>{{item.desc}}</p>
</div>
</ion-slide>
</ion-slide-box>
</div>
</ion-content>
</body>
</html>
The problem was that the model needs a dot. Because I was using it in a filter and and input.

Weird Angular Binding Issue

I'm having a weird angularjs binding problem
<a class="navbar-brand" href="#">Application (Environment: {{ globalConfig.environment + ""}})</a>
That will work, and render the value "dev"
<a class="navbar-brand" href="#">Application (Environment: {{ globalConfig.environment }})</a>
This doesn't render anything.
<a class="navbar-brand" href="#">Application (Environment: <span ng-bind="globalConfig.environment"></span>)</a>
This last example works.
Any ideas why the second example won't render out the value "dev"?
The controller is as follows:
angular.module('uppApp').controller('globalController', function ($scope) {
$scope.globalConfig = {
environment: 'dev'
};
});
the html looks as follows:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" ng-app="uppApp">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../favicon.ico">
<title>Pixel Pimp Web UI</title>
<link href="assets/css/style.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="assets/thirdparty/ie8mediasupport.js"></script>
<![endif]-->
</head>
<body ng-controller="globalController">
<div class="navbar navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Pixel Pimp (Environment: <span ng-bind="globalConfig.environment"></span>)</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active">Dashboard</li>
<li>Pixel Groups</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
<div class="container">
<h1>Dashboard</h1>
<div id="myfirstchart" style="height: 250px;"></div>
</div><!-- /.container -->
<script src="assets/thirdparty/built.js"></script>
<script src="assets/js/uppangular.js"></script>
<script>
$(function () { genGraph(); });
function genGraph() {
new Morris.Line({
// ID of the element in which to draw the chart.
element: 'myfirstchart',
// Chart data records -- each entry in this array corresponds to a point on
// the chart.
data: [
{ year: '2008', value: 20 },
{ year: '2009', value: 10 },
{ year: '2010', value: 5 },
{ year: '2011', value: 5 },
{ year: '2012', value: 20 }
],
// The name of the data record attribute that contains x-values.
xkey: 'year',
// A list of names of data record attributes that contain y-values.
ykeys: ['value'],
// Labels for the ykeys -- will be displayed when you hover over the
// chart.
labels: ['Value']
});
}
</script>
</body>
</html>
UPDATE
When i wrap the decorate the interpolate service for debugging like this:
app.config(function($provide){
$provide.decorator("$interpolate", function($delegate){
var interpolateWrap = function(){
var interpolationFn = $delegate.apply(this, arguments);
if(interpolationFn) {
return interpolationFnWrap(interpolationFn, arguments);
}
};
var interpolationFnWrap = function(interpolationFn, interpolationArgs){
return function(){
var result = interpolationFn.apply(this, arguments);
var log = result ? console.log : console.warn;
log.call(console, "interpolation of " + interpolationArgs[0].trim(),
":", result.trim());
return result;
};
};
angular.extend(interpolateWrap, $delegate);
return interpolateWrap;
});
});
The console log will show:
interpolation of {{globalConfig.environment+""}} : dev
However for the binding of {{globalConfig.environment}} nothing shows up in the console window.
Ok I figured it out. I'm using grunt bake for the first time, and I think grunt bake, is stripping out the {{globalConfig.environment}} code from the rendered file.
Sorry. Stupid mistake.
UPDATE
Ultimately I fixed it by modifying the BAKE parse pattern to use [{ }] instead of {{ }}
bake: {
build: {
options: {
parsePattern: '/\[\{\s?([\.\-\w]*)\s?\}\]/g'
},
files: {
"app/index.html": "app/base.html"
}
}
},

How I can save the value of ng-include and use later

I am blocked and can not be as follow, to see if someone could help me ... (sorry for my bad English and my explanation).
I have this pen where I have an input to insert a value or load default. NgStorage I use to store the value in memory if the app is reloaded and always load the user types in the input (localStorage).
After I have a dropdown where I choose one of the two numbers that charged me one of two templates that I have created (or template1 template2) in the following div.
Far right, but now I would like to save that result in any way for the next div (red border) perform a simple arithmetic operation as chosen above using a scope variable declared in the driver from the start.
Any help please?
Here my pen (I use ionic): http://codepen.io/maestromutenrroy/pen/ukwIC
<html ng-app="ionicApp"><head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Ionic....</title>
<link href="//code.ionicframework.com/1.0.0-beta.12/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/1.0.0-beta.12/js/ionic.bundle.js"></script>
<script src="https://rawgithub.com/gsklee/ngStorage/master/ngStorage.js"></script>
</head>
<body ng-controller="MainCtrl">
<ion-header-bar class="bar-positive">
<h1 class="title">Hello!</h1>
</ion-header-bar>
<br /><br /><br />
<!-- load 11, but I change the valor -->
Write a number: <input type="number" ng-model="$storage.c6" style="border: 1px solid #ddd; padding-left: 10px">
<br>
<!-- select of two templates -->
Select one option:
<select ng-model="template" ng-options="t.name for t in templates">
<option value="">(blank)</option>
</select>
<!-- print a template select -->
<div ng-include src="template.url" onload='myFunction()'></div>
<!-- template1.html -->
<script type="text/ng-template" id="template1.html">
{{1000 - $storage.c6}}
</script>
<!-- template2.html -->
<script type="text/ng-template" id="template2.html">
{{10 - $storage.c6}}
</script>
<br>
<hr />
<div style="border: 2px solid red; padding: 20px">
Now, I would like a same operation (result of template1 or template2 - $storage.c12): .....
</div>
</body>
</html>
angular.module('ionicApp', ['ionic','ngStorage'])
.controller('MainCtrl', function($scope, $localStorage) {
$scope.$storage = $localStorage.$default({
c6: 1,
c12: 2
});
$scope.templates = [{
name: '5',
url: 'template1.html'}
,
{
name: '10',
url: 'template2.html'}];
$scope.template = $scope.templates[0];
})
Thank you!
You can save the results in a scope object and update it inside each template:
<!-- template1.html -->
<script type="text/ng-template" id="template1.html">
{{results.x = 1000 - $storage.c6}}
</script>
<!-- template2.html -->
<script type="text/ng-template" id="template2.html">
{{results.x = 10 - $storage.c6}}
</script>
<div style="border: 2px solid red; padding: 20px">
Now, I would like a same operation (result of template1 or template2 - $storage.c12): ..... {{results.x - $storage.c12}}
</div>
And on the controller:
$scope.results = {};
Demo

Resources