Using for loop in angular with $scopes - angularjs

Is it possible to made a for loop using scopes in angular? For example. I have:
$scope.start = 1;
$scope.end = 10;
and want to make a for (example i know it doesn't work)
for($scope.start; $scope.start < $scope.end; $scope.start++) {
print(<input type="radio" name="count" value="$scope.start">);
}

angular.module('app', []).controller('MyController', ['$scope', function($scope) {
$scope.start = '8:00';
$scope.stop = '20:00';
$scope.interval = '30';
$scope.getTimeArray = function(start, stop, interval){
var result = [];
if(interval == '0')
return result;
function toMinutes(time){
var pair = time.split(':');
return pair[0] * 60 + 1 * pair[1];
}
function toString(minutes){
var hours = Math.floor(minutes / 60);
var min = (minutes - hours * 60);
min = min > 9 ? min : '0' + min;
return hours + ':' + min;
}
for(var i = toMinutes(start); i <= toMinutes(stop); i += 1 * interval)
result.push(toString(i))
return result;
}
}])
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
<div ng-app='app' ng-controller="MyController">
start: <input type="text" ng-model='start'>
</br>
stop: <input type="text" ng-model='stop'>
</br>
interval: <input type="text" ng-model='interval'>
</br>
<label ng-repeat-start='item in getTimeArray(start, stop, interval)'>{{item}}</label>
<input type="radio" name="count" value="{{item}}" ng-repeat-end>
</div>

Related

AngularJS niether ng-keypress or custom directive are working

Trying to implement a simple keypress event on a div but somehow nothing happens. I have read at some places that I need tabindex="0", however problem still prevails. Here is my html:
<body ng-app="myModule">
<div ng-controller="myCtrl" movement tabindex="1" ng-keypress="iterate($event)">
<div ng-repeat="entity in entities" entity-position="entity"></div>
<div class="table">
<div>
<select selected='name' ng-model="selected" id="select">
<option value="name" >First</option>
<option value="id">Second</option>
<option value="id">Third</option>
</select>
</div>
<table id="table">
<tr ng-repeat="item in cars | orderBy:selected" ng-click="go(item)">
<td>{{item.plate}}</td>
<td>{{item.name}}</td>
<td>{item.price}}</td>
</tr>
</table>
</div>
"movement" is a custom directive with it's own controller, I'm guessing the problem is connected to this, but I'm not sure.
This is inside the movement directive's controller (never logs anything):
$scope.iterate = function($event){
console.log('iterate')
}
Thank you for your help.
Edit: Added directive
app.directive('movement', function() {
return {
controller: function($scope, animFrame) {
var width = window.innerWidth;
var height = window.innerHeight;
var speed = .5;
var lastTime = new Date().getTime();
$scope.entities = [];
$scope.changeCount = function(count) {
while(count>0) {
$scope.entities.push({
x: width/2 * Math.random()+100,
y: height/2 * Math.random()+100,
velX: 0.2,//speed * Math.random()/2,
velY: 0.1,//speed * Math.random()/3
});
count--;
}
while(count<0) {
$scope.entities.pop();
count++;
}
}
$scope.tick = function($event){
//console.log('tick')
var now = new Date().getTime(),
delay = now - lastTime,
entities = $scope.entities;
for(var i=0; i<entities.length; i++) {
var b = entities[i];
b.x += delay * b.velX;
b.y += delay * b.velY;
if (b.x < 0) { b.x *= -1; b.velX *= -1;}
if (b.y < 0) { b.y *= -1; b.velY *= -1; }
if (b.x > width) { b.x = 2*width - b.x; b.velX *= -1;}
if (b.y > height) { b.y = 2*height - b.y; b.velY *= -1; }
}
lastTime = now;
animFrame($scope.tick);
}
$scope.changeCount(1);
$scope.tick();
}
};
});

Angular ng-if + function not work

In this first code when I change the anoini, the gerar() function show the old value.
But, when I remove <div ng-if.... works fine.
do you knows what's wrong ?
Tks
// JavaScript Document
var app = angular.module('dadosHist', []);
app.controller('dadosHistCtrl', function($scope) {
$scope.mesini = 1; $scope.anoini = 2011;
$scope.mesfim = 7; $scope.anofim = 2015;
$scope.log = "";
$scope.escolherperiodo = true;
$scope.gerar = function() {
this.log = this.anoini;
meses = ((this.anofim - this.anoini) * 12) + (12 - this.mesini) + this.mesfim;
qtdLoop = arrEstacoes.length * meses;
tempoEstimadoMinutos = Math.round((qtdLoop * 20) / 60 );
this.log = 'Tempo Estimado: ' + tempoEstimadoMinutos + ' min.' ;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="dadosHist" ng-controller="dadosHistCtrl">
<input type="checkbox" ng-model="escolherperiodo">Escolher PerĂ­odo<br>
<div ng-if="escolherperiodo">
<input type="text" ng-model="mesini" placeholder="Mes">/<input type="text" ng-model="anoini" placeholder="Ano"><br>
<input type="text" ng-model="mesfim" placeholder="Mes">/<input type="text" ng-model="anofim" placeholder="Ano"><br>
</div>
<button ng-click="gerar()">Gerar</button> <br>
{{log}}
</div>
Always use a dot in ng-model ! . In other words use objects not primitives.
ng-if creates a child scope and since you are using primitives in ng-model you are losing 2 way binding with scope from this child scope.
var myModel ={
mesini : 1,
anoini : 2011,
mesfim : 7,
anofim : 2015
};
$scope.myModel = myModel;
HTML
<input type="text" ng-model="myModel.mesini">
Then in function:
$scope.gerar = function() {
$scope.log = myModel.anoini;
var meses = ((myModel.anofim - myModel.anoini)......
.....
}
Understanding scope nesting in angular is the most important thing to learn when using the framework
You should not assign value to this, but to $scope inside gerar function:
$scope.gerar = function() {
$scope.log = $scope.anoini;
meses = (($scope.anofim - $scope.anoini) * 12) + (12 - $scope.mesini) + $scope.mesfim;
qtdLoop = arrEstacoes.length * meses;
tempoEstimadoMinutos = Math.round((qtdLoop * 20) / 60 );
$scope.log = 'Tempo Estimado: ' + tempoEstimadoMinutos + ' min.' ;
}

Change listeners on 2 directives should produce one action on another directive

I'm struggeling with this problem for too long, need some help.
I made a snippet so the problem is easier to understand.
The purpose: make the DURATION input readOnly, when FROM AND TO are != null
The problem remains in how directives communicate together.
I think code is better than text explanation...
(function(){
angular.module('app', [])
.controller('AppController', function($scope){
$scope.from = 3600;
$scope.to = 7200;
$scope.duration = "null";
})
.directive('hourInput', function(){
return {
restrict : 'A',
require : 'ngModel',
link : function(scope, element, attrs, modelCtrl){
//Change scope copy of view
modelCtrl.$formatters.push(function(seconds){
if(seconds == "null" || seconds == null){
return "";
}
var sec_num = parseInt(seconds, 10);
var hours = Math.floor(sec_num / 3600);
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
//Only hours matters
return hours + ":" + minutes;
});
//Change scope copy of model
modelCtrl.$parsers.push(function(time) {
if(time.length != 5){
return "null";
}
var hours = parseInt(time.substring(0, 2));
var minutes = parseInt(time.substring(3));
return ((hours * 60) + minutes) * 60 + "";
});
//The problem is here
/*
Goal : set duration on readOnly when from || to == "null"
Problem :
This can't happen here, because can't watch both inputs.
Solution:
- Create 2 directives? (1 in each input : from and to)
- COntroller?
- ...
NOte : I know I can watch on changes with :
modelCtrl.$viewChanheListener... but the problem is:
if FROM == null -> duration will ne readOnly even if TO != null
*/
}
};
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<div ng-app="app" ng-controller="AppController">
<input type="text" ng-model="from" placeholder="from" hour-input/> <br />
<input type="text" ng-model="to" placeholder="to" hour-input/> <br />
<input type="text" ng-model="duration" placeholder="duration" get-duration/> <br />
{{from}}
</div>

how to add timeout to ng-show in angular js?

I am working on quiz app. I have add the time out to every question even though user attempts the question or not.
my code in view:
<p ng-repeat="opt in question.answer">
<label ng-show="opt._correct" for="">
<input type="radio" name="questionAnswer" id="opt.id" value=""
ng-click="checkAnswer(1)" />
{{opt.__text}}
</label>
<label ng-hide="opt._correct" for="">
<input type="radio" name="questionAnswer" id="opt.id" value=""
ng-click="checkAnswer(0)" />
{{opt}}
</label>
</p>
my code in controller:
$scope.randomQuestions = function(questionslist){
$scope.randomQuestion = questionslist
[Math.floor(Math.random() * questionslist.
length)];
console.log($scope.quiz);
var item = $scope.quiz.splice($scope.randomQuestion,1)[0];
$scope.questions = new Array();
$scope.questions.push($scope.randomQuestion);
$scope.counter = $scope.counter + 1;
return $scope.questions;
}
$scope.checkAnswer = function(option){
console.log('check answer');
if(option == 1){
console.log($scope.score);
$scope.score = $scope.score + parseInt($scope.level._points_per_question);
console.log($scope.score);
} else{
}
console.log($scope.counter);
if ($scope.counter < parseInt($scope.level._total_questions + 1)){
$scope.randomQuestions($scope.quiz);
} else {
console.log('5 questions');
}
}
$scope.nextLevel = function(){
$scope.total_score = $scope.total_score + $scope.score;
$scope.score = 0;
$scope.counter = 0;
if($scope.level_count == 1){
$scope.level_count = $scope.level_count + 1;
$scope.quiz = $scope.quiz2.question;
$scope.level = $scope.quiz2;
$scope.randomQuestions($scope.quiz);
} else if($scope.level_count == 2){
$scope.quiz = $scope.quiz3.question;
$scope.level = $scope.quiz3;
$scope.randomQuestions($scope.quiz);
$scope.level_count = $scope.level_count + 1;
} else {
$scope.level_count = $scope.level_count + 1;
$scope.result_text();
}
}
$scope.result_text = function(){
$scope.result = parseInt(($scope.total_score * 100) / 400);
for(var k=0; k < $scope.score_rules.length; k++){
if($scope.result >= $scope.score_rules[k]._min_percent){
$scope.score_status = $scope.score_rules[k].__text;
console.log($scope.score_rules[k].__text);
console.log($scope.score_rules[k]);
}
}
}
Can any one suggest how to call time out from view?
Please find below the code
function controller($scope)
{
$scope.showflag = true;
setTimeout(function ()
{
$scope.$apply(function()
{
$scope.showflag = false;
});
}, 1000);
}
You could use CSS transitions or animation to do the actual transition and use ngAnimate to trigger the transitions.
There are a few examples for ngAnimate on this page.
You can try this approach:
Modify your checkAnswer() code and call another function which sets
the timeout/sleep. When the call returns from the timeout function, set a
variable (eg. isVisible) to false and use this variable in ng-show.
Something like this:
So, new ng-show would look like ng-show=" isVisible && opt._correct"

How to update angular progress bar every time I click

Hi I am using angular progress bar and I want to update every time I click a button.
<div ng-controller="ProgressDemoCtrl">
<br/>
<h3>
Dynamic
<button class="btn btn-sm btn-primary" ng-click="random()" type="button">Randomize</button>
</h3>
<small>
<em>No animation</em>
</small>
<progressbar animate="false" type="success" value="dynamic">
<b>{{dynamic}}%</b>
</progressbar>
</div>
ANGULAR
var ProgressDemoCtrl = function ($scope) {
$scope.max = 00;
$scope.random = function() {
var value = Math.floor((Math.random() * 100) + 1);
var type;
if (value < 25) {
type = 'success';
} else if (value < 50) {
type = 'info';
} else if (value < 75) {
type = 'warning';
} else {
type = 'danger';
}
$scope.showWarning = (type === 'danger' || type === 'warning');
$scope.dynamic = value;
$scope.type = type;
};
$scope.random();
$scope.randomStacked = function() {
$scope.stacked = [];
var types = ['success', 'info', 'warning', 'danger'];
for (var i = 0, n = Math.floor((Math.random() * 4) + 1); i < n; i++) {
var index = Math.floor((Math.random() * 4));
$scope.stacked.push({
value: Math.floor((Math.random() * 30) + 1),
type: types[index]
});
}
};
$scope.randomStacked();
};
as you can see in here what it does when i click the button is filling it up randomly.So what i want to do is be able to click a button and update the progress bar.
If you are using angular bootstrap's progressbar this is very easy. I just made a plunkr for it.
Your HTML
<div ng-controller="ProgressDemoCtrl">
<h3>Progress bar value is {{dynamic}}</h3>
<progressbar max="max" value="dynamic">
<span style="color:black; white-space:nowrap;">
{{dynamic}} / {{max}}
</span>
</progressbar>
<input type="button" ng-click="progress()" value="Click Me To Progress" />
</div>
</body>
</html>
and JS
angular.module('plunker', ['ui.bootstrap']);
var ProgressDemoCtrl = function ($scope) {
$scope.dynamic = 10;
$scope.max = 100;
$scope.progress = function(){
$scope.dynamic = $scope.dynamic + 10;
};
};

Resources