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"
Related
I cannot get the object's property to be read in ng-style(shape.radius || shape.length). I can't even get 1 to work at the moment, but would like to have an or statement included. Similar to my ng-class.
There is a button to generate shapes, and the shapes were created with a random size. Here is my code:
html:
<div ng-controller='ShapeController as sc'>
<div>
<p><input type="submit" value="Generate Random Shapes" ng-click="sc.generateShapes()"/></p>
<div ng-repeat="shape in sc.shapes">
<div class="shape" ng-class="{circle: shape.radius, square: shape.length}" ng-style="{'width': shape.length}"></div>
</div>
</div>
</div>
script:
var app = angular.module('app', []);
app.controller('ShapeController', function(){
var vm = this;
vm.shapes = [];
vm.randomShapes = [];
vm.width = 30;
function createCircle(radius) {
let circle = new Circle(radius);
vm.shapes.push(circle);
} // end createCircle
function createSquare(length) {
let square = new Square(length);
vm.shapes.push(square);
} // end createSquare
vm.generateShapes = function() {
let times = 50
for (let i = 0; i < times; i++) {
createCircle(getRandomNumber());
}
for (let i = 0; i < times; i++) {
createSquare(getRandomNumber());
}
sort(vm.shapes);
console.log(vm.shapes);
}; // end generateShapes
}); // end controller
function sort(arr) {
arr.sort(function(a,b){
return b.getArea() - a.getArea();
});
} // end sort function
function getRandomNumber() {
return Math.random() * (100-1) + 1;
}
width should be either in px(some unit like em, pt, etc) or %
ng-style="{'width': shape.length + 'px'}"
I found this code in the internet, it functions as a message box. The code works perfectly fine. However, it display all the messages stored in the file message.db.
My question is, how can I make it display only the last 20 posted messages? I'm sorry for asking this. I have no knowledge about programming. I appreciate any help...
Here is the snippet of the code:
<div class="container" ng-controller="MessageBoardCtrl">
<form>
<input type="email" placeholder="Email Address" ng-model="email" required/>
<textarea placeholder="Advertise your link here for Free..." rows="5" style="width:90%" ng-model="message" required=""></textarea>
<button class="btn btn-primary" ng-click="sendMessage()">Post</button>
</form>
<p>{{item.message}}</p>
<script>
function MessageBoardCtrl($scope, $http, $timeout) {
$scope.items = [];
$scope.message = '';
$scope.email = '';
$scope.lastTime = 0;
$scope.refreshMessages = function() {
$http.get('../templates/faucet.php/messages?time=' + $scope.lastTime).success(function(data) {
for(id in data) {
item = data[id];
$scope.items.unshift(item);
if($scope.lastTime<item.time)
$scope.lastTime = item.time;
}
});
}
$scope.sendMessage = function() {
if(!$scope.message)
return;
$http.post('../templates/faucet.php/add_message', {message: $scope.message, email: $scope.email}).success(function() {
$scope.message = '';
$scope.refreshMessages();
});
}
$scope.periodicRefresh = function() {
$scope.refreshMessages();
$timeout($scope.periodicRefresh, 5000, true);
}
$scope.periodicRefresh();
}
</script>
I found this function to limit the result:
function limitToFilter(){
return function(array, limit) {
if (!(array instanceof Array)) return array;
limit = int(limit);
var out = [],
i, n;
// check that array is iterable
if (!array || !(array instanceof Array))
return out;
// if abs(limit) exceeds maximum length, trim it
if (limit > array.length)
limit = array.length;
else if (limit < -array.length)
limit = -array.length;
if (limit > 0) {
i = 0;
n = limit;
} else {
i = array.length + limit;
n = array.length;
}
for (; i<n; i++) {
out.push(array[i]);
}
return out;
}
}
Now, I just need help on how to combine them together to make the script work. I hope someone can help. I really do not have any idea... Thanks.
I am still a little new to Angular, and I am having trouble setting the default select option, if that option is the only one in the array. What happens specifically is that the select does default, however, the shipping cost is not being calculated. It only calculates if the user chooses it from the drop down. I think the issue may be because with the ng-change on the select element, but I am not sure.
In my HTML:
<select class="form-control" ng-change="updateShipper()" name="shipMethod"
ng-model="currentOrder.LineItems[0].ShipperName"
ng-show="user.ShipMethod.ShipperSelectionType == 'UserDropDown'"
ng-options="shipper.Name as (shipper.Name + ' ' + (shipper.ShippingRate.Price | currency | xlat)) for shipper in shippers"
ng-required="!currentOrder.IsMultipleShip() && user.ShipMethod != null" >
<option value=""></option>
In my controller:
scope.$watch('shippers', function(val) {
if(angular.isDefined(val)){
$timeout(function() {
if(val.length === 1){
scope.currentOrder.LineItems[0].ShipperName = val[0].Name;
}
}, 0);
}
});
$scope.updateShipper = function(li) {
$scope.shippingUpdatingIndicator = true;
$scope.shippingFetchIndicator = true;
if (!li) { // at the order level
angular.forEach($scope.shippers, function(s) {
if (s.Name == $scope.currentOrder.LineItems[0].ShipperName)
$scope.currentOrder.Shipper = s;
});
angular.forEach($scope.currentOrder.LineItems, function(item) {
item.ShipperName = $scope.currentOrder.Shipper ? $scope.currentOrder.Shipper.Name : null;
item.ShipperID = $scope.currentOrder.Shipper ? $scope.currentOrder.Shipper.ID : null;
});
saveChanges(function() {
$scope.shippingUpdatingIndicator = false;
$scope.shippingFetchIndicator = false;
});
}
else { // at the lineitem level for multiple shipping
angular.forEach($scope.shippers, function(s) {
if (s.Name == li.ShipperName)
li.Shipper = s;
});
li.ShipperName = li.Shipper.Name;
li.ShipperID = li.Shipper.ID;
saveChanges(function() {
$scope.shippingUpdatingIndicator = false;
$scope.shippingFetchIndicator = false;
});
}
};
Try ng-init="updateShipper()". Then set the initial value of your model in the controller like $scope.currentOrder.LineItems[0].ShipperName = 0(or whatever).
I am trying to use the "minisCtrlOverall" controller in my ng-include file, but none of the functionality in my controller works for the included file unless I put ng-controller in the actual overall.html file. What I am trying to do is access the "ring-fill" class that is in my overall.html file from my controller. I want to add the class "active" too all "ring-fills" but its not working. I'm guessing this isn't working because the included files comes after the controller runs? Anyone know how I can fix this?
Controller:
angular.module('ciscoImaDashboardAdmin',[])
.controller('minisCtrlOverall', function ($scope, $rootScope, dummyData) {
$scope.overallOn = true;
$scope.switchView = function(element) {
var value = element.target.attributes['value'].value;
if(value == "overall") {
$scope.overallOn = true;
$scope.swimlaneOn = false;
}
else if(value == "swimlane") {
$scope.swimlaneOn = true;
$scope.overallOn = false;
}
};
var totalRings = 9;
var maxScore = 10;
var data_overall = {
average_score: 6
}
var ringToHighlight = Math.floor((data_overall.average_score/maxScore)*totalRings); //round down
var i = 0;
var rings = [];
var ringClass = 'path.ring-fill:not(.ring-border)';
$(ringClass).each(function(){
rings.push($(this)[0]);
});
while( i < ringToHighlight) {
fillPath(i);
i = i + 1;
}
function fillPath(i) {
if(i < ringToHighlight) {
var selectedRing = $(rings[i]);
selectedRing.attr("class", "ring-fill active");
}
}
});
HTML:
<div class="row mini" ng-show="overallOn" ng-controller="minisCtrlOverall">
<div class="col-sm-3">
<div ng-include="'svgs/overall.html'"></div>
</div>
</div>
I was going to ask this as a question, but I figured out a solution. So at this point, I'm looking for a critique of my solution.
I've got a static textarea, and an input with an ng-repeat directive.
As the user types a sentence into the textarea, a input is rendered for each word in the sentence.
Then if the user updates the text in any input, the corresponding word in the textarea sentence is updated (really the whole sentence is recreated).
Demo: http://plnkr.co/edit/bSjtOK?p=preview
Questions
Keeping in mind that I'm only 2 weeks into my AngularJS learning:
Did I write this in the "angular" way?
Is there something I could have done better?
Am I violating any no-nos?
Abbreviated Code
HTML
<textarea ng-model="sentence" ng-change="parseSentence()" style="width: 100%; height: 15em;"></textarea>
<input type="text" ng-repeat="w in words" ng-model="w.word" ng-change="buildSentance(w)" />
JavaScript
function WordCtrl($scope, debounce) {
$scope.words = [];
$scope.sentence = 'Hello there how are you today?';
// this is called when the textarea is changed
// it splits up the textarea's text and updates $scope.words
$scope.parseSentence = function() {
var words = $scope.sentence.split(/\s+/g);
var wordObjects = [];
for (var i=0;i<words.length;i++) {
wordObjects.push({word: words[i]});
}
if ((words.length == 1) && (words[0] === '')) {
$scope.words = [];
} else {
$scope.words = wordObjects;
}
};
$scope.parseSentenceDebounced = debounce($scope.parseSentence, 1000, false);
$scope.buildSentance = function(w) {
var words = [];
for (var i=0;i<$scope.words.length;i++) {
var word = $scope.words[i].word;
if (word.replace(/\s+/g,'') !== '') {
words.push(word);
}
}
$scope.sentence = words.join(' ');
// if the user puts a space in the input
// call parseSentence() to update $scope.words
if (w.word.indexOf(' ') > -1) {
$scope.parseSentenceDebounced();
}
}
$scope.parseSentence();
}
Interesting issue you are having. I put your code on my page and the first thing I noticed is that you cannot pass debounce in the controller method.
Next Problem I noticed is that you have an ng-change that changes the values on another box with ng-change. I changed the event to Keypress to stop the digest in a digest.
Here it is working in JSFiddle enter link description here
The code:
HTML
<body ng-app="portal">
<div ng-controller="WordCtrl">
<textarea ng-model="sentence" ng-keypress="parseSentence()" style="width: 100%; height: 15em;"></textarea>
<input type="text" ng-repeat="w in words" ng-model="w.word" ng-keypress="buildSentance(w)" />
</div>
</body>
Javascript
angular.module("portal",[]).controller("WordCtrl",function($scope) {
$scope.words = [];
$scope.sentence = 'Hello there how are you today?';
$scope.parseSentence = function () {
var words = $scope.sentence.split(/\s+/g);
var wordObjects = [];
for (var i = 0; i < words.length; i++) {
wordObjects.push({ word: words[i] });
}
if ((words.length == 1) && (words[0] === ''))
{
$scope.words = [];
}
else
{
$scope.words = angular.copy(wordObjects);
}
}
$scope.buildSentance = function (w) {
var words = [];
for (var i = 0; i < $scope.words.length; i++) {
var word = $scope.words[i].word;
if (word.replace(/\s+/g, '') !== '') {
words.push(word);
}
}
$scope.sentence = words.join(' ');
// if the user puts a space in the input
// call parseSentence() to update $scope.words
if (w.word.indexOf(' ') > -1) {
$scope.parseSentenceDebounced();
}
}
$scope.parseSentence();
});
Hope this solves your issue.