I am working on an Angular JS project , I am newbie in this technology . I have received an assignment from my boss .
Assignment is :
1 . There is a html file with the text "This is a Burger" .
2 . I have a Audio(.mp3) file with the sound "This is a Burger" .
this is javascript example Preload mp3 file in queue to avoid any delay in playing the next file in queue
What I want :
When Audio play then the text "This is Burger" should high light word by word .
Here is what I have done to achieve above task .
json
{
"config":{
"shuffleQuestions": true,
"showPager": false,
"allowBack": true,
"autoMove": true
},
"questions": [{
"Id": 1,
"Name": "This is a burger.1",
"Image": "assets/quiz/burgur.jpg",
"QuestionAudio":"assets/quiz/audio.mp3",
"QuestionAudiodelay":"100",
"QuestionAudioTimeline":"0.07,1.04,1.8,2.29,3.19",
"Options": [{ "Id": 1, "OptionsId": 1, "Name": "This is a burger.1", "IsAnswer": true }],
"QuestionType": { "Id": 1, "Name": "Multiple Choice", "IsActive": true } }]}
html
<div id="quiz">
<div class="row">
<div class="col-md-12"><h1 class="left">{{quiz.name}}</h1><hr /></div>
</div>
<div ng-show="mode=='quiz'">
<div ng-repeat="question in filteredQuestions">
<div class="row">
<h2>{{currentPage}}.</h2>
<div class="col-md-12">
<div class="card col-md-6">
<div class="flex-center">
<div class="card-block">
<img id="{{question.Id}}" class="img-responsive" ng-src="{{question.Image}}" style="width: 500px;">
</div>
</div>
</div>
<div class="row text-left options">
<div class="col-md-6" ng-repeat="option in question.Options">
<div class="option">
<p id="{{option.Id}}" ng-bind-html="allAnswerWithSpan"> </p>
</div>
</div>
<p id="optionAnswer"> </p>
<div class="col-md-6" ng-repeat="option in question.Options" >
<div class="option">
<button ng-click="playAudio()" class="btn btn-default">Play</button>
</div>
<audio id="myAudio" style="display: block !important;">
<source src="" type="audio/mpeg">
</audio>
<img id="playaudio" style="cursor:pointer;width: 25px;height: 25px; display:none;" src='images/audio_joshi.png'/>
</div>
</div>
</div>
<hr />
<div class="quizNav">
<div>
<button class="btn btn-default" ng-hide="IsHidden" ng-click="NextQuiz(currentPage - 1);">Prev</button>
<button id="Next" class="btn btn-primary" ng-show="IsVisible" ng-click="NextQuiz(currentPage + 1);">Next</button>
<button class="btn btn-primary" ng-hide="IsHidden" ng-click="onSubmit();" >Submit</button>
</div>
<br />
</div>
</div>
<hr />
</div>
js
'use strict';
var app = angular.module('quizApp', ['ngRoute', 'ngSanitize'])
// Routing has been added to keep flexibility in mind. This will be used in future.
angular.module('quizApp').config(['$routeProvider','$locationProvider',function ($routeProvider,$locationProvider) {
var routes = [
{
url: '/home',
template: 'templates/quiz.html',
controller: 'quizCtrl'
}
];
routes.forEach(function (r, index) {
$routeProvider.when(r.url, { templateUrl: r.template, controller: r.controller });
});
$routeProvider.otherwise({ redirectTo: '/home' });
//$locationProvider.html5Mode(true);
}]);
var quizCtrl = function ($scope, $http, helper) {
$scope.quizName = 'assets/quiz.json';
$scope.arrQuestion=[]; $scope.arrOptionsId=[]; $scope.addanswer=[];
$scope.allarray =[];
// Others are work in progress.
$scope.defaultConfig = {
'allowBack': true,
'allowReview': true,
'autoMove': false, // if true, it will move to next question automatically when answered.
'duration': 0, // indicates the time in which quiz needs to be completed. post that, quiz will be automatically submitted. 0 means unlimited.
'pageSize': 1,
'requiredAll': false, // indicates if you must answer all the questions before submitting.
'richText': false,
'shuffleQuestions': false,
'shuffleOptions': false,
'showClock': false,
'showPager': true,
'theme': 'block'
}
$scope.IsVisible = true;
$scope.IsHidden = true;
$scope.IsHidden = $scope.IsHidden ? true : true;
$scope.NextQuiz = function (index) {
if (index > 0 && index <= $scope.totalItems) {
$scope.currentPage = index;
$scope.mode = 'quiz';
}
if(index==$scope.totalItems){
$scope.IsHidden = false;
$scope.IsVisible = $scope.IsVisible ? false : true;
} $scope.qIndex++;
}
$scope.onClick = function (question, option) {
if (question.QuestionTypeId == 1) {
question.Options.forEach(function (element, index, array) {
if (element.Id != option.Id) {
element.Selected = false;
question.Answered = element.Id;
}
});
}
if ($scope.config.autoMove == true && $scope.currentPage < $scope.totalItems)
$scope.currentPage++;
}
$scope.onSubmit = function () {
var answers = [];
/* $scope.questions.forEach(function (q, index) { //console.log(answers.push({'QuizId': $scope.quiz.Id, 'QuestionId': q.Id, 'Answered': q.Answered}));
answers.push({ 'QuizId': $scope.quiz.Id, 'QuestionId': q.Id, 'Answered': q.Answered });
}); */
// Post your data to the server here. answers contains the questionId and the users' answer.
//$http.post('api/Quiz/Submit', answers).success(function (data, status) {
// alert(data);
//});
$scope.mode = 'result';
}
$scope.pageCount = function () {
return Math.ceil($scope.questions.length / $scope.itemsPerPage);
};
//If you wish, you may create a separate factory or service to call loadQuiz. To keep things simple, i have kept it within controller.
$scope.loadQuiz = function (file) {
$http.get(file)
.then(function (res) {
// $scope.quiz = res.data.quiz; console.log($scope.quiz.name);
$scope.config = helper.extend({}, $scope.defaultConfig, res.data.config);
$scope.questions = $scope.config.shuffleQuestions ? helper.shuffle(res.data.questions) : res.data.questions;
$scope.totalItems = $scope.questions.length;
$scope.itemsPerPage = $scope.config.pageSize;
$scope.currentPage = 1;
$scope.currentquestion=1;
$scope.mode = 'quiz';
if($scope.config.shuffleOptions)
$scope.shuffleOptions();
$scope.$watch('currentPage + itemsPerPage', function () {
var begin = (($scope.currentPage - 1) * $scope.itemsPerPage),
end = begin + $scope.itemsPerPage;
$scope.filteredQuestions = $scope.questions.slice(begin, end);
});
$scope.questions.forEach(function (question,key){
$scope.arrAnswer= question.Options[0].Name; $scope.arrOptionsId= question.Options[0].Id;
$scope.arraudio= question.QuestionAudio;
$scope.arraudiodelay= question.QuestionAudiodelay;
$scope.arraudiotimeline= question.QuestionAudioTimeline;
$scope.allarray=[$scope.arrAnswer,$scope.arraudio,$scope.arraudiodelay,$scope.arraudiotimeline];
$scope.arrQuestion.push($scope.allarray);
});
if($scope.currentPage==1)
{
// console.log($scope.arrQuestion);
$scope.qIndex = 0;
$scope.audioplay();
}
});
}
$scope.audioplay=function(){
var qIndex = $scope.qIndex;
$scope.QuestionAnswer=$scope.arrQuestion[qIndex][0];
$scope.QuestionAudio=$scope.arrQuestion[qIndex][1];
$scope.QuestionAudiodelay=$scope.arrQuestion[qIndex][2];
$scope.Questionaudiotimeline=$scope.arrQuestion[qIndex][3];
//console.log($scope.QuestionAnswer); console.log($scope.QuestionAudio);
//console.log($scope.QuestionAudiodelay);
console.log($scope.arrOptionsId);
$scope.QuestionAnswerArray = $scope.QuestionAnswer.split(' '); //alert($scope.QuestionAnswerArray.length);
$scope.allAnswerWithSpan = {};
for (var i = 0; i <$scope.QuestionAnswerArray.length; i++) {
$scope.addanswer[i] = '<span>' +$scope.QuestionAnswerArray[i]+ '</span>';
// console.log($scope.addanswer);
}
$scope.allAnswerWithSpan = $scope.addanswer.join(" ");
var audio =new Audio($scope.QuestionAudio);
audio.play();
audio[0].onended = function() {
audioIndex += 1;
playAudio(audioIndex);
};
}
$scope.playAudio=function(index){
/* $("p > span").removeClass("playing");
$("#myAudio")[0].src = $scope.QuestionAudio[index];
$("#myAudio")[0].play();
$("p > span:nth-child(" + (index + 1) + ")").addClass("playing"); */
}
$scope.shuffleOptions = function(){
$scope.questions.forEach(function (question) {
question.Options = helper.shuffle(question.Options);
});
}
$scope.loadQuiz($scope.quizName);
}
quizCtrl.$inject = ['$scope', '$http', 'helperService'];
app.controller('quizCtrl', quizCtrl);